cx88 panic, and a (hacky) way to grab composite/svideo in when it's not panicing :) (and vlc...) (Juergen Lock)

Jason Harmening jason.harmening at gmail.com
Wed May 27 15:48:33 UTC 2009


>
> 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 at 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 at 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 at 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 at 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 at 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.


More information about the freebsd-multimedia mailing list