Skip to content

Instantly share code, notes, and snippets.

@rudolfbyker
Last active November 26, 2023 20:56
Show Gist options
  • Save rudolfbyker/017abd82d6bb62c60627d1dc74ec18ac to your computer and use it in GitHub Desktop.
Save rudolfbyker/017abd82d6bb62c60627d1dc74ec18ac to your computer and use it in GitHub Desktop.
Using SAA713x TV Card on Debian

Using SAA713x TV Card on Debian

Useful links

APT packages to install on fresh Debian

  • ffmpeg
  • alsa-utils
  • v4l-utils

Setting up the driver

  1. Create a file at /etc/modprobe.d/saa7134.conf with the following contents:
    alias char-major-81 videodev
    alias char-major-81-0 saa7134
    options saa7134 card=109
    
  2. Reboot.

Viewing details about the TV card

List PCI devices

lspci
03:01.0 Multimedia controller: Philips Semiconductors SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (rev d1)

List Video4Linux devices

v4l2-ctl --list-inputs
ioctl: VIDIOC_ENUMINPUT
	Input       : 0
	Name        : Television
	Type        : 0x00000001 (Tuner)
	Audioset    : 0x00000000
	Tuner       : 0x00000000
	Standard    : 0x0000000000FFBFFF (PAL-B/B1/G/H/I/D/D1/K/M/N/Nc/60 NTSC-M/M-JP/M-KR SECAM-B/D/G/H/K/K1/L/Lc)
	Status      : 0x00000102 (no signal, no hsync lock)
	Capabilities: 0x00000004 (SDTV standards)

	Input       : 1
	Name        : Composite1
	Type        : 0x00000002 (Camera)
	Audioset    : 0x00000000
	Tuner       : 0x00000000
	Standard    : 0x0000000000FFBFFF (PAL-B/B1/G/H/I/D/D1/K/M/N/Nc/60 NTSC-M/M-JP/M-KR SECAM-B/D/G/H/K/K1/L/Lc)
	Status      : 0x00000000 (ok)
	Capabilities: 0x00000004 (SDTV standards)

	Input       : 2
	Name        : S-Video
	Type        : 0x00000002 (Camera)
	Audioset    : 0x00000000
	Tuner       : 0x00000000
	Standard    : 0x0000000000FFBFFF (PAL-B/B1/G/H/I/D/D1/K/M/N/Nc/60 NTSC-M/M-JP/M-KR SECAM-B/D/G/H/K/K1/L/Lc)
	Status      : 0x00000000 (ok)
	Capabilities: 0x00000004 (SDTV standards)
v4l2-ctl --list-formats-ext
ioctl: VIDIOC_ENUM_FMT
	Type: Video Capture

	[0]: 'GREY' (8-bit Greyscale)
	[1]: 'RGBO' (16-bit A/XRGB 1-5-5-5)
	[2]: 'RGBQ' (16-bit A/XRGB 1-5-5-5 BE)
	[3]: 'RGBP' (16-bit RGB 5-6-5)
	[4]: 'RGBR' (16-bit RGB 5-6-5 BE)
	[5]: 'BGR3' (24-bit BGR 8-8-8)
	[6]: 'RGB3' (24-bit RGB 8-8-8)
	[7]: 'BGR4' (32-bit BGRA/X 8-8-8-8)
	[8]: 'RGB4' (32-bit A/XRGB 8-8-8-8)
	[9]: 'YUYV' (YUYV 4:2:2)
	[10]: 'UYVY' (UYVY 4:2:2)
	[11]: '422P' (Planar YUV 4:2:2)
	[12]: 'YU12' (Planar YUV 4:2:0)
	[13]: 'YV12' (Planar YVU 4:2:0)
v4l2-ctl --all
Driver Info:
	Driver name      : saa7134
	Card type        : Philips Tiger - S Reference des
	Bus info         : PCI:0000:03:01.0
	Driver version   : 6.1.55
	Capabilities     : 0x85250015
		Video Capture
		Video Overlay
		VBI Capture
		Tuner
		Radio
		Read/Write
		Streaming
		Extended Pix Format
		Device Capabilities
	Device Caps      : 0x05210005
		Video Capture
		Video Overlay
		Tuner
		Read/Write
		Streaming
		Extended Pix Format
Media Driver Info:
	Driver name      : saa7134
	Model            : saa7133[0]
	Serial           : 
	Bus info         : PCI:0000:03:01.0
	Media version    : 6.1.55
	Hardware revision: 0x14589003 (341348355)
	Driver version   : 6.1.55
Interface Info:
	ID               : 0x03000006
	Type             : V4L Video
Entity Info:
	ID               : 0x00000005 (5)
	Name             : saa7133[0] video (Philips Tiger
	Function         : V4L2 I/O
	Pad 0x0100000f   : 0: Sink
	  Link 0x0200001b: from remote pad 0x100000e of entity 'saa713x' (Analog Video Decoder): Data, Enabled
Priority: 2
Frequency for tuner 0: 0 (0.000000 MHz)
Tuner 0:
	Name                 : Television
	Type                 : Analog TV
	Capabilities         : 62.5 kHz multi-standard stereo lang1 lang2 freq-bands 
	Frequency range      : 44.000 MHz - 958.000 MHz
	Signal strength/AFC  : 0%/0
	Current audio mode   : mono
	Available subchannels: mono 
Video input : 0 (Television: no signal, no hsync lock)
Video Standard = 0x000000ff
	PAL-B/B1/G/H/I/D/D1/K
Format Video Capture:
	Width/Height      : 720/576
	Pixel Format      : 'BGR3' (24-bit BGR 8-8-8)
	Field             : Interlaced
	Bytes per Line    : 2160
	Size Image        : 1244160
	Colorspace        : SMPTE 170M
	Transfer Function : Default (maps to Rec. 709)
	YCbCr/HSV Encoding: Default (maps to ITU-R 601)
	Quantization      : Default (maps to Full Range)
	Flags             : 
Format Video Overlay:
	Left/Top    : 0/0
	Width/Height: 720/576
	Field       : Interlaced
	Chroma Key  : 0x00000000
	Global Alpha: 0x00
	Clip Count  : 0
	Clip Bitmap : No
Framebuffer Format:
	Capability    : Clipping List
	Flags         : 
	Width         : 720
	Height        : 576
	Pixel Format  : 'BGR3'
	Bytes per Line: 0
	Size image    : 0
	Colorspace    : SMPTE 170M
Crop Capability Video Capture:
	Bounds      : Left 0, Top 48, Width 720, Height 576
	Default     : Left 0, Top 48, Width 720, Height 576
	Pixel Aspect: 54/59
Selection Video Capture: crop, Left 0, Top 48, Width 720, Height 576, Flags: 
Selection Video Capture: crop_default, Left 0, Top 48, Width 720, Height 576, Flags: 
Selection Video Capture: crop_bounds, Left 0, Top 48, Width 720, Height 576, Flags: 
Streaming Parameters Video Capture:
	Frames per second: 25.000 (25/1)
	Read buffers     : 2

User Controls

                     brightness 0x00980900 (int)    : min=0 max=255 step=1 default=128 value=128 flags=slider
                       contrast 0x00980901 (int)    : min=0 max=127 step=1 default=68 value=68 flags=slider
                     saturation 0x00980902 (int)    : min=0 max=127 step=1 default=64 value=64 flags=slider
                            hue 0x00980903 (int)    : min=-128 max=127 step=1 default=0 value=0 flags=slider
                         volume 0x00980905 (int)    : min=-15 max=15 step=1 default=0 value=0 flags=slider
                           mute 0x00980909 (bool)   : default=0 value=0
                horizontal_flip 0x00980914 (bool)   : default=0 value=0
                         invert 0x00981960 (bool)   : default=0 value=0
             y_offset_odd_field 0x00981961 (int)    : min=0 max=128 step=1 default=0 value=0
            y_offset_even_field 0x00981962 (int)    : min=0 max=128 step=1 default=0 value=0
                       automute 0x00981963 (bool)   : default=1 value=1

List ALSA recording devices

arecord -l
card 1: SAA7134 [SAA7134], device 0: SAA7134 PCM [SAA7134 PCM]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

Probe with ffmpeg and ffprobe

ffmpeg -f v4l2 -list_formats all -i /dev/video0
[video4linux2,v4l2 @ 0x1554e80] Raw       :        gray :      8-bit Greyscale :
[video4linux2,v4l2 @ 0x1554e80] Raw       :    rgb555le : 16-bit A/XRGB 1-5-5-5 :
[video4linux2,v4l2 @ 0x1554e80] Raw       :    rgb555be : 16-bit A/XRGB 1-5-5-5 BE :
[video4linux2,v4l2 @ 0x1554e80] Raw       :    rgb565le :     16-bit RGB 5-6-5 :
[video4linux2,v4l2 @ 0x1554e80] Raw       :    rgb565be :  16-bit RGB 5-6-5 BE :
[video4linux2,v4l2 @ 0x1554e80] Raw       :       bgr24 :     24-bit BGR 8-8-8 :
[video4linux2,v4l2 @ 0x1554e80] Raw       :       rgb24 :     24-bit RGB 8-8-8 :
[video4linux2,v4l2 @ 0x1554e80] Raw       :        bgr0 : 32-bit BGRA/X 8-8-8-8 :
[video4linux2,v4l2 @ 0x1554e80] Raw       :        0rgb : 32-bit A/XRGB 8-8-8-8 :
[video4linux2,v4l2 @ 0x1554e80] Raw       :     yuyv422 :           YUYV 4:2:2 :
[video4linux2,v4l2 @ 0x1554e80] Raw       :     uyvy422 :           UYVY 4:2:2 :
[video4linux2,v4l2 @ 0x1554e80] Raw       :     yuv422p :     Planar YUV 4:2:2 :
[video4linux2,v4l2 @ 0x1554e80] Raw       :     yuv420p :     Planar YUV 4:2:0 :
[video4linux2,v4l2 @ 0x1554e80] Raw       :     yuv420p :     Planar YVU 4:2:0 :
ffprobe /dev/video0

Intersting: This is the only one showing the resolution!

Input #0, video4linux2,v4l2, from '/dev/video0':
  Duration: N/A, start: 2546.446776, bitrate: 124416 kb/s
  Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p, 720x576, 124416 kb/s, 25 fps, 25 tbr, 1000k tbn
ffprobe -f alsa hw:1

Note the hw:N here. This is what we will use for ffmpeg's -i option.

Input #0, alsa, from 'hw:1':
  Duration: N/A, start: 1699123043.658554, bitrate: 1024 kb/s
  Stream #0:0: Audio: pcm_s16le, 32000 Hz, 2 channels, s16, 1024 kb/s

Capturing

When capturing directly using ffmpeg, I could only get "progressive interleaved" video. Interleaving is a very naive deinterlacing algorithm: It simply combines two frames into one by using the odd rows from one and the even rows from the next. This produces a lot of visual artifacts.

It's better to capture the interlaced video directly (see capture_gstreamer_raw.sh) and run it through a more advanced deinterlacing filter like nnedi.

Other useful commands

Watch a video file from the beginning even though it's still being written to

tail -f tmp.mkv | ffmpeg -i - -f mpegts - | mpv -

Watch the stream from the TV card directly in the terminal

Use mpv for playback. Use ffmpeg to transcode into a format that mpv understands. Because we use mpv, this even works without installing a desktop environment.

ffmpeg -i /dev/video0 -f alsa -i hw:1 -c:v libx264 -preset fast -c:a aac -f mpegts - | mpv -
#!/usr/bin/env sh
# See https://www.linuxtv.org/wiki/index.php/V4L_capturing
set -eu
VIDEO_DEVICE=/dev/video0
VIDEO_CAPABILITIES="video/x-raw, format=YUY2"
AUDIO_DEVICE="hw:CARD=SAA7134,DEV=0"
AUDIO_CAPABILITIES="audio/x-raw, channels=1" # My VHS player only has mono output
TV_NORM="PAL"
gst-launch-1.0 -q \
v4l2src device="$VIDEO_DEVICE" do-timestamp=true norm="$TV_NORM" pixel-aspect-ratio=1 \
! $VIDEO_CAPABILITIES \
! queue max-size-buffers=0 max-size-time=0 max-size-bytes=0 \
! mux. \
alsasrc device="$AUDIO_DEVICE" do-timestamp=true \
! $AUDIO_CAPABILITIES \
! queue max-size-buffers=0 max-size-time=0 max-size-bytes=0 \
! mux. \
matroskamux name=mux \
! queue max-size-buffers=0 max-size-time=0 max-size-bytes=0 \
! fdsink fd=1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment