Capture App Examples

Tune to channel 4 in the default profile and send MPEG transport stream to VLC at port 8802 and to a file at ~/out.m2t:

Tune to channel 45 in the DVBT_EU_UHF profile, send MPEG transport stream to /home/user/out.m2t in current directory, and automatically terminate capture after 28.7 minutes:

Capture audio only from channel 42 in the USA profile and send to sound card at /dev/dsp0:

Capture audio only from channel 42 in the USA profile and use a third-party app to handle the actual playback:

Capturing Raw Video

The best way I've found to capture raw video (e.g. from an analog TV station) is to use a named pipe to send the video frames to ffmpeg for encoding to an mpeg file. Future version of cx88 may have a live capture facility that can display the raw pixels directly to the screen (e.g. using SDL). The output from ffmpeg may also be piped into a player such as VLC for live viewing, but this is rather inefficient.

As in the above example, ffmpeg can be used to multiplex the audio and video output. The ffmpeg command above uses the OSS-compatible cx88 audio interface, and assumes that /dev/dsp1 is the OSS audio device that corresponds to cx88audio0. It also assumes that cx88video0 and cx88audio0 are the video and audio functions of the same capture card. Note that in the cx88 command, only the video data is sent to the named pipe.

ffmpeg can be a little daunting, so let's dissect the ffmpeg command:

Raw Video Picture-In-Picture (PiP)

As one of my friends pointed out when I told him I added PiP support to cx88, this is a rather ridiculous feature. Analog video is going away to a large extent, and at any rate the chances of anyone having two tuner card and two programs that they want to watch simultaneously are practically NIL. This feature was intended as a proof-of-concept to demonstrate that the cx88 driver's buffering system was flexible enough to handle hardware-based picture overlay. And because the buffer composition is handled directly by the CX2388x DMA engine, it may not work correctly when DMA bounce buffers are used (nothing bad or dangerous will happen, but parts of your video may be garbled if the bounce buffers prevent the two DMA engines from using the same physical location in memory).

But in case anyone cares, here's how you do PiP with the cx88 capture app:

  1. Run ffmpeg just as in the example above.
  2. Run cx88 as follows:
    • cx88 -c 42 -d /dev/cx88video0 -o "buffer=0;pip=/dev/cx88video1" -u file://${HOME}/vpipe -d /dev/cx88audio0 -x /usr/local/share/examples/cx88/cx88.xml.sample

When the application starts, both tuners will tune to channel 42. However, you can use the 'c' command to change the channels on each tuner individually--simply separate the channel strings for the primary and secondary tuners with a semicolon. To change just the primary channel, you can still use a normal channel string, e.g. "42" or "USA:42". To change just the secondary channel, prefix the channel string with a semicolon, e.g. ";USA:54". To change both simultaneously, use something like "USA:42;USA:54".

Optimizing Performance

As mentioned in the General Architecture section, the CX2388x has onboard SRAM that is used for driver-configurable FIFOs and is shared between all functions. The cx88 driver will allocate the SRAM based on the functions that are actually present and have drivers attached. So if, for example, you have a card that supports MPEG, video, and audio, but you only care about digital TV, then just load the cx88mpeg driver. If you don't load the cx88video or cx88audio drivers, the MPEG driver will receive all the SRAM.

But there are some other things you can do for more complex use cases. If you have two tuner cards and you want to use one only for digital TV and the other only for analog TV, then you can optimize the SRAM allocation on each card by disabling the audio & video functions on the digital-only card, and the MPEG function on the analog-only card. The cx88 driver respects FreeBSD's "disabled" device hint, so you can do something like the following:

The raw video driver supports further optimization of SRAM allocation by allowing you to disable the planar and VBI DMA channels (and therefore their SRAM allocations) if you don't plan on using them:

You can either add the above hints to /boot/device.hints and reboot, or you can add them on-the-fly using kenv(1). Note that these hints are only checked when the driver is loaded, so if you want kenv(1) settings to take effect you'll need to reload the cx88 kernel modules.

I2C Performance

As mentioned in the General Architecture section, the cx88 driver uses hardware-controlled I2C transactions for frontend devices. The hardware I2C facilities on the CX23888x are unable to perform large batch transfers, so an interrupt needs to be generated for roughly every byte that is transferred across the I2C bus. Because I2C is slow (100KHz), this approach still reduces CPU utilization and improves responsiveness when compared to a polled software-controlled approach. However, during large transfers (such as tuner firmware loads), the large number of interrupts may be disruptive toward real-time applications.