Date: Wed, 27 May 2009 10:27:09 -0500 From: Jason Harmening <jason.harmening@gmail.com> To: freebsd-multimedia@freebsd.org Subject: Re: cx88 panic, and a (hacky) way to grab composite/svideo in when it's not panicing :) (and vlc...) (Juergen Lock) Message-ID: <2d1264630905270827q4e85376ds530488edf62b4c1a@mail.gmail.com>
next in thread | raw e-mail | index | archive | help
> > Hi! > > (I had meant to post this earlier, but...) > > I finally got around playing with this cx88 card on FreeBSD, and can > report I was able to grab pal-b composite in using the cx88 tool > and ffmpeg ...when its not panicing. First, what I did: I applied > the following patch that: > > 1) adds a missing case CX88_CARD_ID_WINTV_HVR4000 that prevented > my card from working, and > > 2) allows selecting non-tuner inputs by passing `magic' channel names > via -c: "input_mux2" (composite in on my card), "input_mux3" (most likely > s-video in here), and "input_mux4" (I don't know if that's used on my > card, but it might be on others.) > > Index: client/analog/cx88_analog_driver_factory.h > @@ -53,6 +53,8 @@ > case CX88_CARD_ID_PCHDTV_HD5500: > return (new pchdtv_hd5500(cx88conf, tunerconf, devnode, captures, mode, slave, pip_driver, error)); > case CX88_CARD_ID_PIXELVIEW_XCAPTURE: > + // XXX this one was missing - probably need to add some more... > + case CX88_CARD_ID_WINTV_HVR4000: > return (new cx88_analog_driver(cx88conf, tunerconf, devnode, captures, mode, slave, pip_driver, error)); > default: > return NULL; > Index: client/analog/cx88_analog_driver.cpp > @@ -351,6 +351,14 @@ > } > cx88_video_capture capture; > capture.in_input_source = CX88_VIDEO_INPUT_MUX1; > + // XXX hack to allow selecting non-tuner inputs > + if (!m_channel_name.compare("input_mux2")) > + capture.in_input_source = CX88_VIDEO_INPUT_MUX2; > + else if (!m_channel_name.compare("input_mux3")) > + capture.in_input_source = CX88_VIDEO_INPUT_MUX3; > + else if (!m_channel_name.compare("input_mux4")) > + capture.in_input_source = CX88_VIDEO_INPUT_MUX4; > + > capture.in_input_type = CX88_VIDEO_INPUT_COMPOSITE; > capture.in_input_options = 0; > capture.in_lock_timeout_ms = 1000; > > then I edited cx88.xml to `define' input_mux2 to be pal-b by adding a > new profile "EU_UHF_PALB" for it and using that as its `channel': > (thats why this is a hack, and btw the default doesn't work, you still > have to specify input_mux2 via -c.) > > <?xml version="1.0"?> > <cx88> > <config> > <libtuner> > OR51132_VSB_FW=/usr/local/share/cx88/or51132_vsb.fw<br/> > OR51132_QAM_FW=/usr/local/share/cx88/or51132_qam.fw > </libtuner> > <alias name="nbc" channel="USA:21"/> > <alias name="pbs" channel="USA:22"/> > <alias name="abc" channel="USA:33"/> > <alias name="cbs" channel="USA:43"/> > <alias name="wb" channel="USA:49"/> > <alias name="fox" channel="USA:56"/> > <alias name="input_mux2" channel="EU_UHF_PALB:56"/> > <default>input_mux2</default> > </config> > <profile name="USA"> > <modulation>VSB8</modulation> > <bandwidth>6000000</bandwidth> > <analog_video>NTSC-M</analog_video> > <analog_audio>BTSC</analog_audio> > <range> > <start>2</start> > <freq>57000000</freq> > <end>4</end> > </range> > <range> > <start>5</start> > <freq>79000000</freq> > <end>6</end> > </range> > <range> > <start>7</start> > <freq>177000000</freq> > <end>13</end> > </range> > <range> > <start>14</start> > <freq>473000000</freq> > <end>83</end> > </range> > </profile> > <profile name="DVBT_EU_VHF"> > <modulation>OFDM</modulation> > <bandwidth>7000000</bandwidth> > <inversion>auto</inversion> > <range> > <start>1</start> > <freq>50000000</freq> > <end>3</end> > </range> > <range> > <start>5</start> > <freq>50000000</freq> > <end>12</end> > </range> > </profile> > <profile name="DVBT_EU_UHF"> > <modulation>OFDM</modulation> > <bandwidth>8000000</bandwidth> > <inversion>auto</inversion> > <range> > <start>21</start> > <freq>474000000</freq> > <end>69</end> > </range> > </profile> > <profile name="DVBT_FR"> > <modulation>OFDM</modulation> > <bandwidth>8000000</bandwidth> > <inversion>auto</inversion> > <range> > <start>21</start> > <freq>474167000</freq> > <end>69</end> > </range> > </profile> > <profile name="EU_UHF_PALB"> > <modulation>VSB8</modulation> > <bandwidth>6000000</bandwidth> > <analog_video>PAL-B</analog_video> > <analog_audio>none</analog_audio> > <range> > <start>21</start> > <freq>474000000</freq> > <end>69</end> > </range> > </profile> > </cx88> > > ..and then I was able to basically do the same thing as outlined on > http://corona.homeunix.net/cx88wiki/Overview/TipsAndTricks > , i.e. doing a > mkfifo vpipe > and then running > ffmpeg -deinterlace -b 10000k -pix_fmt yuv422p -s 768x576 -r 25 -f rawvideo -i vpipe -vcodec mpeg2video -y out.mpg > in one shell followed by > cx88 -d /dev/cx88video0 -u file://${PWD}/vpipe -x cx88.xml -c input_mux2 > in another. I also played with vlc (I mainly wanted to be able to have > composite in in a window, thats also why I didn't play with audio yet), > but that still seems to suffer from sync(?) problems, i.e. I get jerky > video after a while. If anyone wants to investigate, instead of ffmpeg > above I ran I've seen the jittery video with direct piping to VLC myself, and I don't know why it behaves that way--my guess is an encoding/decoding side-effect. It seems to work fine when you just generate a .mpeg file using ffmpeg, but then you can't watch video live:(. Ultimately instead of piping to VLC (which is inefficient because ffmpeg encodes raw pixels to mpeg, and VLC then decodes them back to raw pixels), we instead need to just be able to spit the raw pixels directly to a screen buffer in a viewer app when doing live capture. > vlc --demux rawvideo --rawvid-fps 25 --rawvid-width 768 --rawvid-height 576 --rawvid-chroma I422 vpipe > (I first wanted to do this with mplayer but the closest I got, > mplayer -demuxer rawvideo -rawvideo w=768:h=576:format=422p:size=884736 vpipe > still gets false colours.) > > Anyway, here comes the panic: > > triton# kgdb /boot/kernel/kernel.symbols /var/crash/vmcore.5 > GNU gdb 6.1.1 [FreeBSD] > Copyright 2004 Free Software Foundation, Inc. > GDB is free software, covered by the GNU General Public License, and you are > welcome to change it and/or distribute copies of it under certain conditions. > Type "show copying" to see the conditions. > There is absolutely no warranty for GDB. Type "show warranty" for details. > This GDB was configured as "amd64-marcel-freebsd"... > > Unread portion of the kernel message buffer: > > > Fatal trap 12: page fault while in kernel mode > cpuid = 3; apic id = 03 > fault virtual address = 0x80146c000 > fault code = supervisor write data, page not present > instruction pointer = 0x8:0xffffffff80826f06 > stack pointer = 0x10:0xffffffff0a72cb00 > frame pointer = 0x10:0xffffffff0a72cb40 > code segment = base 0x0, limit 0xfffff, type 0x1b > = DPL 0, pres 1, long 1, def32 0, gran 1 > processor eflags = interrupt enabled, resume, IOPL = 0 > current process = 4463 (irq20: cx88video0+) > trap number = 12 > panic: page fault > cpuid = 3 > KDB: stack backtrace: > db_trace_self_wrapper() at db_trace_self_wrapper+0x2a > panic() at panic+0x182 > trap_fatal() at trap_fatal+0x2b3 > trap_pfault() at trap_pfault+0x294 > trap() at trap+0x312 > calltrap() at calltrap+0x8 > --- trap 0xc, rip = 0xffffffff80826f06, rsp = 0xffffffff0a72cb00, rbp = 0xffffffff0a72cb40 --- > bcopy() at bcopy+0x16 > cx88_video_intr() at cx88_video_intr+0x2c9 > ithread_loop() at ithread_loop+0x180 > fork_exit() at fork_exit+0x11f > fork_trampoline() at fork_trampoline+0xe > --- trap 0, rip = 0, rsp = 0xffffffff0a72cd30, rbp = 0 --- > Uptime: 1h36m15s > Physical memory: 8178 MB > Dumping 655 MB: 640 624 608 592 576 560 544 528 512 496 480 > <7>kbdc: TEST_AUX_PORT status:0000 > 464 > <7>kbdc: RESET_AUX return code:00fa > 448 > <7>kbdc: RESET_AUX status:00aa > <7>kbdc: RESET_AUX ID:0000 > 432 416 400 384 368 352 > <7>kbdc: TEST_AUX_PORT status:0000 > 336 > <7>kbdc: RESET_AUX return code:00fa > 320 > <7>kbdc: RESET_AUX status:00aa > <7>kbdc: RESET_AUX ID:0000 > 304 288 272 256 240 224 208 192 176 160 144 128 112 96 80 64 48 32 16 > > Reading symbols from /boot/kernel/linprocfs.ko...Reading symbols from /boot/kernel/linprocfs.ko.symbols...done. > done. > Loaded symbols for /boot/kernel/linprocfs.ko > Reading symbols from /boot/kernel/linux.ko...Reading symbols from /boot/kernel/linux.ko.symbols...done. > done. > Loaded symbols for /boot/kernel/linux.ko > Reading symbols from /boot/kernel/netgraph.ko...Reading symbols from /boot/kernel/netgraph.ko.symbols...done. > done. > Loaded symbols for /boot/kernel/netgraph.ko > Reading symbols from /boot/kernel/ng_ether.ko...Reading symbols from /boot/kernel/ng_ether.ko.symbols...done. > done. > Loaded symbols for /boot/kernel/ng_ether.ko > Reading symbols from /boot/kernel/ng_pppoe.ko...Reading symbols from /boot/kernel/ng_pppoe.ko.symbols...done. > done. > Loaded symbols for /boot/kernel/ng_pppoe.ko > Reading symbols from /boot/kernel/ng_socket.ko...Reading symbols from /boot/kernel/ng_socket.ko.symbols...done. > done. > Loaded symbols for /boot/kernel/ng_socket.ko > Reading symbols from /boot/kernel/snd_hda.ko...Reading symbols from /boot/kernel/snd_hda.ko.symbols...done. > done. > Loaded symbols for /boot/kernel/snd_hda.ko > Reading symbols from /boot/kernel/sound.ko...Reading symbols from /boot/kernel/sound.ko.symbols...done. > done. > Loaded symbols for /boot/kernel/sound.ko > Reading symbols from /boot/kernel/atapicam.ko...Reading symbols from /boot/kernel/atapicam.ko.symbols...done. > done. > Loaded symbols for /boot/kernel/atapicam.ko > Reading symbols from /boot/kernel/green_saver.ko...Reading symbols from /boot/kernel/green_saver.ko.symbols...done. > done. > Loaded symbols for /boot/kernel/green_saver.ko > Reading symbols from /boot/kernel/radeon.ko...Reading symbols from /boot/kernel/radeon.ko.symbols...done. > done. > Loaded symbols for /boot/kernel/radeon.ko > Reading symbols from /boot/kernel/drm.ko...Reading symbols from /boot/kernel/drm.ko.symbols...done. > done. > Loaded symbols for /boot/kernel/drm.ko > Reading symbols from /boot/modules/cx88video.ko...done. > Loaded symbols for /boot/modules/cx88video.ko > Reading symbols from /boot/modules/iicdev.ko...done. > Loaded symbols for /boot/modules/iicdev.ko > Reading symbols from /boot/kernel/iicbus.ko...Reading symbols from /boot/kernel/iicbus.ko.symbols...done. > done. > Loaded symbols for /boot/kernel/iicbus.ko > Reading symbols from /boot/modules/cx88i2c.ko...done. > Loaded symbols for /boot/modules/cx88i2c.ko > Reading symbols from /boot/modules/cx88.ko...done. > Loaded symbols for /boot/modules/cx88.ko > #0 doadump () at pcpu.h:195 > 195 pcpu.h: No such file or directory. > in pcpu.h > (kgdb) bt > #0 doadump () at pcpu.h:195 > #1 0xffffffff8055b468 in boot (howto=260) > at /usr/home/nox/src72s/src/sys/kern/kern_shutdown.c:418 > #2 0xffffffff8055b8cc in panic (fmt=Variable "fmt" is not available. > ) > at /usr/home/nox/src72s/src/sys/kern/kern_shutdown.c:574 > #3 0xffffffff80827af3 in trap_fatal (frame=0xc, eva=Variable "eva" is not available. > ) > at /usr/home/nox/src72s/src/sys/amd64/amd64/trap.c:757 > #4 0xffffffff80827ed4 in trap_pfault (frame=0xffffffff0a72ca50, usermode=0) > at /usr/home/nox/src72s/src/sys/amd64/amd64/trap.c:673 > #5 0xffffffff80828882 in trap (frame=0xffffffff0a72ca50) > at /usr/home/nox/src72s/src/sys/amd64/amd64/trap.c:444 > #6 0xffffffff8080bf8e in calltrap () > at /usr/home/nox/src72s/src/sys/amd64/amd64/exception.S:209 > #7 0xffffffff80826f06 in bcopy () > at /usr/home/nox/src72s/src/sys/amd64/amd64/support.S:123 > #8 0xffffffff808064f8 in _bus_dmamap_sync (dmat=0xffffff00c93b0a80, map=Variable "map" is not available. > ) > at /usr/home/nox/src72s/src/sys/amd64/amd64/busdma_machdep.c:935 > #9 0xffffffff80f09389 in cx88_video_intr () from /boot/modules/cx88video.ko > #10 0xffffffff00000006 in ?? () > #11 0x0000000000000005 in ?? () > #12 0xffffff00085f7d18 in ?? () > #13 0x0000000000000005 in ?? () > #14 0x0000002000000002 in ?? () > ---Type <return> to continue, or q <return> to quit--- > #15 0x0000000000000000 in ?? () > #16 0x0000000200000001 in ?? () > #17 0x000000000031c024 in ?? () > #18 0xffffff00084a1280 in ?? () > #19 0xffffff000149aa00 in ?? () > #20 0x0000000000000000 in ?? () > #21 0xffffff0004ac43c0 in ?? () > #22 0xffffff000149aa48 in ?? () > #23 0xffffffff0a72cc20 in ?? () > #24 0xffffffff8053a220 in ithread_loop (arg=0xffffff00085f78a8) > at /usr/home/nox/src72s/src/sys/kern/kern_intr.c:1088 > Previous frame inner to this frame (corrupt stack?) > (kgdb) fr 8 > #8 0xffffffff808064f8 in _bus_dmamap_sync (dmat=0xffffff00c93b0a80, map=Variable "map" is not available. > ) > at /usr/home/nox/src72s/src/sys/amd64/amd64/busdma_machdep.c:935 > 935 bcopy((void *)bpage->vaddr, > (kgdb) l > 930 dmat->bounce_zone->total_bounced++; > 931 } > 932 > 933 if (op & BUS_DMASYNC_POSTREAD) { > 934 while (bpage != NULL) { > 935 bcopy((void *)bpage->vaddr, > 936 (void *)bpage->datavaddr, > 937 bpage->datacount); > 938 bpage = STAILQ_NEXT(bpage, links); > 939 } > (kgdb) p/x bpage->vaddr > $1 = 0xffffffff0ba63000 > (kgdb) p/x bpage->datavaddr > $2 = 0x80146c000 > (kgdb) p/x bpage->datacount > $3 = 0x1000 > (kgdb) p/x bpage > $4 = 0xffffff00329881c0 > (kgdb) q > > uname -a: > > FreeBSD triton.kn-bremen.de 7.2-STABLE FreeBSD 7.2-STABLE #0: Sun May 10 19:06:01 CEST 2009 nox@triton.kn-bremen.de:/usr/obj/usr/home/nox/src72s/src/sys/TRITON amd64 > > pciconf -lv of the card: (I only kldload'ed cx88video here...) > > cx88video0@pci0:4:6:0: class=0x040000 card=0x69020070 chip=0x880014f1 rev=0x05 hdr=0x00 > vendor = 'Conexant Systems, Inc.' > device = '23880 Conexant 23880 Video Capture (NTSC)' > class = multimedia > subclass = video > none1@pci0:4:6:1: class=0x048000 card=0x69020070 chip=0x881114f1 rev=0x05 hdr=0x00 > vendor = 'Conexant Systems, Inc.' > device = 'CX2388x TV Capture Chip' > class = multimedia > none2@pci0:4:6:2: class=0x048000 card=0x69020070 chip=0x880214f1 rev=0x05 hdr=0x00 > vendor = 'Conexant Systems, Inc.' > device = 'CX2388x TV Capture Chip' > class = multimedia > none3@pci0:4:6:4: class=0x048000 card=0x69020070 chip=0x880414f1 rev=0x05 hdr=0x00 > vendor = 'Conexant Systems, Inc.' > device = 'CX2388x TV Capture Chip' > class = multimedia > > And finally, whats the state of the dvb-s(2) code? This card has that > too... (I can't test dvb-t since that seems to need a `real' antenna > here which I don't have.) > > Thanx, > Juergen > Crap, I was wondering when someone would run into that panic:(. So here's what I believe is the problem behind the panic: 1) I'm guessing you have more than 4 gigs of RAM in your machine. 2) CX23880/1/2/3-based cards can only do DMA to 32-bit physical addresses, which means that with > 4gigs on amd64, the OS will use bounce buffers if (parts of) the original data buffer was above the 4gig boundary. Those bounce buffers need to be synchronized w/ the original buffer via bus_dmamap_sync() whenever DMA'ed data becomes available in the bounce buffers. When doing analog video capture, the cx88 app supplies the kernel driver with buffers that are allocated in userspace. The root of the problem is that the current version of cx88 in ports calls bus_dmamap_sync() in its interrupt handler, which will run in an arbitrary process context. This is a Bad Idea(tm) when synchronizing user-allocated buffers, because for those cases bus_dmamap_sync() must be called in the context of the allocating process (at least on i386/amd64). This fix is to move the bus_dmamap_sync() calls to the ioctl case where the driver gets the "buffer available" signal from the interrupt handler, as that will always be called in the context of the cx88 process. Judging by your backtrace (thanks for doing that, btw), that's exactly what's happening here. There's another problem, though too: FreeBSD 7-STABLE has(had) a bug where bounce buffering requirements aren't correctly calculated for userspace buffers. I submitted a patch for this which is already in 8-CURRENT, and I *think* it's been MFC'ed into the latest 7-STABLE. The good news is I already have a fix for the bus_dmamap_sync() problem in my current SVN branch (available anonymously at svn://corona.homeunix.net/projects/pchdtv). So if you have the FreeBSD fix I just mentioned and you sync to this repo, your panic should disappear. The cx88 driver in the repo adds a new kernel module. The code in mpeg/ now builds a module called cx88mpegcore.ko. cx88mpeg.ko is now a wrapper around this module which is built from the cx23880/ directory. So now you have to load cx88mpegcore before you can load cx88mpeg. The reason for this is that the driver now supports cx23885/7-based PCI-e cards, which Konstantin & I are working on polishing so we can do a formal release to ports Really Soon Now.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?2d1264630905270827q4e85376ds530488edf62b4c1a>