Getting a 4 channel saa7134 capture card to work on Linux.

And other notes on using analogue video capture cards. Applicable to any saa713x card. Make a software vectorscope or a wavefor monitor!

Update: I picked up another card with a similar chipset (saa7130). The card was detected by default but did not work well. Setting it manually to the reference design made it work straight away.

02.2021 uptate: For some reason a version of mplayer that got installed as an update stopped recognizing the -tv option. The option syntax has apparently changed, I updated the post to reflect that

Back to homepage

Recently I picked up an ABEST ABDVR 4 channel PCI video capture card. The card has no EEPROM, and becuase of that the saa7134 driver is unable to autoidentify it. In this post I'll show you how to configure v4l2 to get an image out of this card and how to use libav filters to make a vectorscope and a waveform monitor using mpv and bash.

It's an saa7134 based contraption with 4 digitizers connected to a PCI-to-PCI bridge. This setup allows for 4 independent capture processes running at the same time. The card has 4 BNC jacks. The label in black marker was added by me because there isn't any model name on the PCB.

lspci -v output shows the bridge IC and the 4 digitizers:


05:09.0 PCI bridge: Pericom Semiconductor PI7C8140A PCI-to-PCI Bridge (prog-if 00 [Normal decode])
	Flags: bus master, 66MHz, medium devsel, latency 66
	Bus: primary=05, secondary=06, subordinate=06, sec-latency=66
	Memory behind bridge: fc800000-fcafffff
	Capabilities: [80] Power Management version 2
	Capabilities: [90] CompactPCI hot-swap 
	Kernel modules: shpchp

06:0c.0 Multimedia controller: Philips Semiconductors SAA7134/SAA7135HL Video Broadcast Decoder (rev 01)
	Subsystem: Philips Semiconductors SAA713x-based TV tuner card
	Flags: bus master, medium devsel, latency 66, IRQ 18
	Memory at fca00000 (32-bit, non-prefetchable) [size=1K]
	Capabilities: [40] Power Management version 1
	Kernel driver in use: saa7134
	Kernel modules: saa7134

06:0d.0 Multimedia controller: Philips Semiconductors SAA7134/SAA7135HL Video Broadcast Decoder (rev 01)
	Subsystem: Philips Semiconductors SAA713x-based TV tuner card
	Flags: bus master, medium devsel, latency 66, IRQ 21
	Memory at fca00400 (32-bit, non-prefetchable) [size=1K]
	Capabilities: [40] Power Management version 1
	Kernel driver in use: saa7134
	Kernel modules: saa7134

06:0e.0 Multimedia controller: Philips Semiconductors SAA7134/SAA7135HL Video Broadcast Decoder (rev 01)
	Subsystem: Philips Semiconductors SAA713x-based TV tuner card
	Flags: bus master, medium devsel, latency 66, IRQ 22
	Memory at fca00800 (32-bit, non-prefetchable) [size=1K]
	Capabilities: [40] Power Management version 1
	Kernel driver in use: saa7134
	Kernel modules: saa7134

06:0f.0 Multimedia controller: Philips Semiconductors SAA7134/SAA7135HL Video Broadcast Decoder (rev 01)
	Subsystem: Philips Semiconductors SAA713x-based TV tuner card
	Flags: bus master, medium devsel, latency 66, IRQ 16
	Memory at fca00c00 (32-bit, non-prefetchable) [size=1K]
	Capabilities: [40] Power Management version 1
	Kernel driver in use: saa7134
	Kernel modules: saa7134

  

The card shows up as 4 video devices in /dev/, in my case video0 through video3

saa7134 module configuration

Since this card has no EEPROM, the saa7134 module cannot identify it and falls back to the GENERIC/UNKNOWN model. This model definition does not have inputs 1 and 2 enabled (each of the saa7134 ICs has 3 selectable video inputs) In case of my card, the video signal is coming in to input 1 instead of 0. To be able to capture video, we need to tell the saa7134 driver to treat it as a different card - one that has all 3 inputs enabled in the driver, and then we can select input 1.

If the driver fails to recognize the card, it prints a list of known IDs and card names to the kernel buffer. One of the listed cards, Philips Tiger - S Reference design, sounded like it would work so I set the driver to use that (id 109), instead of trying to autodetect.

Put this in /etc/modprobe.d/saa7134.conf:

options saa7134 card=109,109,109,109
  

There are 4 values, each one for one digitizer. You have to reboot or reload the saa7134 module to apply these changes

Viewing the video with mplayer and v4l2

As I mentioned, each of the digitizers receives the video signal on input 1. In order to view the video, you need to specify the input by adding --tv-input=1 to mplayer/mpv's parameters.

mpv tv:// --tv-driver=v4l2 --tv-device=/dev/video1 --tv-input=1 --tv-norm=0

You can pass other parameters as well, one of the more useful ones is --tv-norm= that allows you to select between NTSC, and a multitude of PAL or SECAM standards. There are many other parameters as well, but they are used for tv tuner cards.

I wrote a script that allows me to run two mpv processes in paralell to be able to see two streams at once.

#!/bin/bash

clean(){
    exit 0;
}

trap clean SIGINT

# set norm to 4 for PAL
mpv tv:// --tv-driver=v4l2 --tv-device=/dev/video0 --tv-input=1 --tv-norm=0 \
    --title="video0" &
mpv tv:// --tv-driver=v4l2 --tv-device=/dev/video1 --tv-input=1 --tv-norm=0 \
    --title="video1" &
wait
  

Two video streams being received by the card. The left camera's lens can be seen on the right image in the corner, which is the video from another camera

02.2021: Updated the script syntax for the new mpv/mplayer version

Digital waveform monitor and vectorscope

libav has a lot of various filters which can be used in most applications, including mpv and ffmpeg. Here's a script that runs mpv on one of the framegrabber inputs and creates a virtual waveform monitor and vectorscope using the libav filtergraph

mpv tv:// --tv-driver=v4l2 --tv-device=/dev/video1 --tv-input=1 --tv-norm=0 \
    --vf=lavfi='[split=3 [a][b][c], [b]waveform[wfm], [c]vectorscope=color4, scale=736x736[color], [a][wfm] vstack [left], [left][color] hstack ]'
  

The filtergraph is a very powerful tool. Here is a different example with all three displays on top of each other

mpv tv:// --tv-driver=v4l2 --tv-device=/dev/video1 --tv-input=1 --tv-norm=0 \
    --vf=lavfi='[split=3 [a][b][c], [b]waveform[wfm], [c]vectorscope=color4, scale=736x736[color], [a][wfm][color] vstack=3 ]'
  

These result in something like this (first command is the left image, second is the right image where the same filtergraph has been used with ffmpeg, temporarily piped to ffplay for preview)

Note: vstack and hstack filters need to have the input heights/width matching, so use the scale filter if your input video has the wrong dimensions. You can also pipe a video file as seen in the left screeshot. You can find the right scale size by trial and error as vstack and hstack will tell you the widths/heights of each of the inputs if they do not match.

It seems that mpv does not cooperate if there are newlines in the filtergraph code, and the filtergraph parameter needs to be enclosed in square brackets.

v4lctl and qv4l2

Other useful tools are v4lctl and qv4l2. v4lctl allows changing the framegrabber parameters on the fly as seen here, where mpv was run first and then the two v4lctl invocations were used to fix the input and the video format (left image)

q4l2 is a program that allows you to quickly try out various settings of the card with a Qt GUI (right image)

dmesg for the card

dmesg | grep saa

[   14.173125] saa7134: saa7130/34: v4l2 driver version 0, 2, 17 loaded
[   14.173515] saa7134: saa7134[0]: found at 0000:06:0c.0, rev: 1, irq: 18, latency: 66, mmio: 0xfca00000
[   14.173523] saa7134: saa7134[0]: subsystem: 1131:0000, board: Philips Tiger - S Reference design [card=109,insmod option]
[   14.173559] saa7134: saa7134[0]: board init: gpio is 10000
[   14.284270] saa7134: saa7134[0]: Huh, no eeprom present (err=-5)?
[   14.612219] saa7134: saa7134[0]: registered device video0 [v4l2]
[   14.612528] saa7134: saa7134[0]: registered device vbi0
[   14.612779] saa7134: saa7134[0]: registered device radio0
[   14.613802] saa7134: saa7134[1]: found at 0000:06:0d.0, rev: 1, irq: 21, latency: 66, mmio: 0xfca00400
[   14.613812] saa7134: saa7134[1]: subsystem: 1131:0000, board: Philips Tiger - S Reference design [card=109,insmod option]
[   14.613850] saa7134: saa7134[1]: board init: gpio is 10000
[   14.720164] saa7134: saa7134[1]: Huh, no eeprom present (err=-5)?
[   14.726553] saa7134: saa7134[1]: registered device video1 [v4l2]
[   14.726852] saa7134: saa7134[1]: registered device vbi1
[   14.726939] saa7134: saa7134[1]: registered device radio1
[   14.727998] saa7134: saa7134[2]: found at 0000:06:0e.0, rev: 1, irq: 22, latency: 66, mmio: 0xfca00800
[   14.728072] saa7134: saa7134[2]: subsystem: 1131:0000, board: Philips Tiger - S Reference design [card=109,insmod option]
[   14.730487] saa7134: saa7134[2]: board init: gpio is 10000
[   14.836166] saa7134: saa7134[2]: Huh, no eeprom present (err=-5)?
[   14.843338] saa7134: saa7134[2]: registered device video2 [v4l2]
[   14.843634] saa7134: saa7134[2]: registered device vbi2
[   14.843716] saa7134: saa7134[2]: registered device radio2
[   14.845232] saa7134: saa7134[3]: found at 0000:06:0f.0, rev: 1, irq: 16, latency: 66, mmio: 0xfca00c00
[   14.845244] saa7134: saa7134[3]: subsystem: 1131:0000, board: Philips Tiger - S Reference design [card=109,insmod option]
[   14.845280] saa7134: saa7134[3]: board init: gpio is 10000
[   14.952263] saa7134: saa7134[3]: Huh, no eeprom present (err=-5)?
[   14.958807] saa7134: saa7134[3]: registered device video3 [v4l2]
[   14.959088] saa7134: saa7134[3]: registered device vbi3
[   14.959174] saa7134: saa7134[3]: registered device radio3
[   15.253209] saa7134_dvb: dvb_init() allocating 1 frontend
[   15.473172] saa7134_dvb: dvb_init() allocating 1 frontend
[   15.473780] saa7134_dvb: dvb_init() allocating 1 frontend
[   15.474381] saa7134_dvb: dvb_init() allocating 1 frontend
[   15.719651] saa7134_alsa: saa7134 ALSA driver for DMA sound loaded
[   15.719729] saa7134_alsa: saa7134[0]/alsa: saa7134[0] at 0xfca00000 irq 18 registered as card -1
[   15.727797] saa7134_alsa: saa7134[1]/alsa: saa7134[1] at 0xfca00400 irq 21 registered as card -1
[   15.732485] saa7134_alsa: saa7134[2]/alsa: saa7134[2] at 0xfca00800 irq 22 registered as card -1
[   15.741261] saa7134_alsa: saa7134[3]/alsa: saa7134[3] at 0xfca00c00 irq 16 registered as card -1
      

Back to homepage