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

Juergen Lock nox at jelal.kn-bremen.de
Wed May 27 21:38:13 UTC 2009


In article <2d1264630905270827q4e85376ds530488edf62b4c1a at mail.gmail.com> you write:
>> 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.
>
Actually my vlc invocation,

>>        vlc --demux rawvideo --rawvid-fps 25 --rawvid-width 768 --rawvid-height 576 --rawvid-chroma I422 vpipe

uses the raw video from the vpipe directly so there's no mpeg involved.
(But still the video is jerky.)

>> (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.)
>>
 And btw doing it with mplayer like this doesn't seem to be affected by
the jerkyness, only the colours are wrong.  (Maybe there's a way to do it
right with a more recent mplayer, but unfortunately there's no mplayer
svn snapshot in ports and they stopped doing formal releases so our
mplayer is now pretty old... ):

 So maybe the above is just a bug in vlc?  (And also, mplayer only uses
~8% cpu for this here while vlc uses around 20%...)

>>  Anyway, here comes the panic:
>>[...]

>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.
>
 Indeed, it has 8 GB.

>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.
>
 You are talking about these commits, right?

SVN rev 191011 on 2009-04-13 19:20:32Z by kib
  
  The bus_dmamap_load_uio(9) shall use pmap of the thread recorded in the
  uio_td to extract pages from, instead of unconditionally use kernel
  pmap.
  
  Submitted by:   Jason Harmening <jason.harmening gmail com> (amd64 version)
  PR:     amd64/133592
  Reviewed by:    scottl (original patch), jhb
  MFC after:      2 weeks

SVN rev 191809 on 2009-05-05 09:08:37Z by kib
  
  MFC r191011:
  The bus_dmamap_load_uio(9) shall use pmap of the thread recorded in the
  uio_td to extract pages from, instead of unconditionally use kernel
  pmap.

>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.
>
 I'm running that here now (after applying the patch; my 7-stable
checkout is from May 10 so it has the above commit), and there was no
panic yet.  Thanx! :)

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

 Will this also include the dvb-s(2) code that was mentioned on
this list once (I think by Konstantin)?

 Thanx again for all your work!
	Juergen


More information about the freebsd-multimedia mailing list