Using the Hauppauge USB-Live2 with Linux

By Ted Felix November 2016

Introduction

I bought one of these to use for capturing the old home movies on VHS. After quite a few problems, it finally appears to be working well.

Status

After building ffmpeg from source (November 2016), the USB-Live2 is working as advertised. With unstable video sources, like VHS, it is up to the software to make sense out of the garbage that is produced by this adapter. Newer versions of ffmpeg tend to do a better job. The only snag I've run into is with the audio track being mangled when the video is particularly unstable. Again, this is most likely the ffmpeg's fault, and might be addressed in the future.

Plugging It In

Since video is very demanding and USB can only move so much data at a time, it's important that you connect this correctly. This goes for any USB video capture device.

The best case scenario is to have the USB-Live2 as the only USB device on the entire system. This is probably unrealistic as we likely need a keyboard to talk to the computer. However, other potentially demanding USB devices like mice, wifi adapters, hard drives, CD-ROM drives, flash drives, etc... need to be disconnected.

You might be able to plug things in such that the USB-Live2 has its own bus. You can use "lsusb -t" to see how the various devices are arranged on your system's USB busses:

$ lsusb -t
/:  Bus 08.Port 1: Dev 1, Class=root_hub, Driver=uhci_hcd/2p, 12M
    |__ Port 1: Dev 2, If 0, Class=Human Interface Device, Driver=usbhid, 12M
    |__ Port 1: Dev 2, If 1, Class=Human Interface Device, Driver=usbhid, 12M
    |__ Port 1: Dev 2, If 2, Class=Human Interface Device, Driver=usbhid, 12M
/:  Bus 07.Port 1: Dev 1, Class=root_hub, Driver=uhci_hcd/2p, 12M
/:  Bus 06.Port 1: Dev 1, Class=root_hub, Driver=uhci_hcd/2p, 12M
/:  Bus 05.Port 1: Dev 1, Class=root_hub, Driver=uhci_hcd/2p, 12M
/:  Bus 04.Port 1: Dev 1, Class=root_hub, Driver=uhci_hcd/2p, 12M
/:  Bus 03.Port 1: Dev 1, Class=root_hub, Driver=uhci_hcd/2p, 12M
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/6p, 480M
    |__ Port 2: Dev 3, If 0, Class=Vendor Specific Class, Driver=, 480M
    |__ Port 2: Dev 3, If 1, Class=Vendor Specific Class, Driver=cx231xx, 480M
    |__ Port 2: Dev 3, If 2, Class=Vendor Specific Class, Driver=, 480M
    |__ Port 2: Dev 3, If 3, Class=Vendor Specific Class, Driver=, 480M
    |__ Port 2: Dev 3, If 4, Class=Vendor Specific Class, Driver=, 480M
    |__ Port 2: Dev 3, If 5, Class=Vendor Specific Class, Driver=, 480M
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/6p, 480M
    |__ Port 2: Dev 3, If 0, Class=Vendor Specific Class, Driver=rt2800usb, 480M

In the above, the USB-Live2 is on Bus 02 (cx231xx is the driver for the USB-Live2's Conexant CX23102 chip), while the keyboard/mouse are on Bus 08 and the wifi (rt2800usb) is on Bus 01. Because the USB-Live2 has its own bus, it seems to work fine.

The USB-Live2 will drop frames if other USB devices get in its way. It's best to make it the only USB device on the system.

Setup Considerations

Other random things to consider. I need to expand this section a bit. Just throwing it out there to get things started.

Configuring

Once the USB-Live2 is connected, we need to set it up. First, find the device with v4l2-ctl.

$ v4l2-ctl --list-devices
Hauppauge USB Live 2 (usb-0000:00:1d.7-2):
	/dev/video0
	/dev/vbi0

According to that, we can use /dev/video0 to talk to the USB-Live2. (/dev/vbi0 is the Vertical Blanking Interval where closed captioning and teletext are transmitted.)

Let's check the current settings:

$ v4l2-ctl -d /dev/video0 --all
Driver Info (not using libv4l2):
	Driver name   : cx231xx
	Card type     : Hauppauge USB Live 2
	Bus info      : usb-0000:00:1d.7-2
	Driver version: 3.13.11
	Capabilities  : 0x85000011
		Video Capture
		VBI Capture
		Read/Write
		Streaming
		Device Capabilities
	Device Caps   : 0x05000001
		Video Capture
		Read/Write
		Streaming
Priority: 2
Video input : 0 (Composite1: 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  : 'YUYV'
	Field         : Interlaced
	Bytes per Line: 1440
	Size Image    : 829440
	Colorspace    : Broadcast NTSC/PAL (SMPTE170M/ITU601)
Crop Capability Video Capture:
	Bounds      : Left 0, Top 0, Width 720, Height 576
	Default     : Left 0, Top 0, Width 720, Height 576
	Pixel Aspect: 54/59
Streaming Parameters Video Capture:
	Frames per second: 25.000 (25/1)
	Read buffers     : 2

User Controls

                     brightness (int)    : min=0 max=255 step=1 default=128 value=128 flags=slider
                       contrast (int)    : min=0 max=127 step=1 default=64 value=64 flags=slider
                     saturation (int)    : min=0 max=127 step=1 default=64 value=64 flags=slider
                            hue (int)    : min=-128 max=127 step=1 default=0 value=0 flags=slider
                         volume (int)    : min=0 max=65535 step=655 default=60928 value=60928 flags=slider
                        balance (int)    : min=0 max=65535 step=655 default=32768 value=32768 flags=slider
                           bass (int)    : min=0 max=65535 step=655 default=32768 value=32768 flags=slider
                         treble (int)    : min=0 max=65535 step=655 default=32768 value=32768 flags=slider
                           mute (bool)   : default=0 value=0

There's a lot of interesting info there, but most important right now is the "Video Standard" section which tells us our device is set for PAL:

Video Standard = 0x000000ff
	PAL-B/B1/G/H/I/D/D1/K

This is fine if you live in PAL-land (most of Europe). However, if you live in NTSC-land (USA, Japan, etc...) you'll need to change the configuration. You can list the supported standards like this:

$ v4l2-ctl -d /dev/video0 --list-standards
ioctl: VIDIOC_ENUMSTD
	Index       : 0
	ID          : 0x000000000000B000
	Name        : NTSC
	Frame period: 1001/30000
	Frame lines : 525

  ...

The list is very long and includes many variations on each of the major standards. Pick the one that suits you best. For me, it's NTSC. We can use v4l2-ctl to configure the device for NTSC like this:

$ v4l2-ctl -d /dev/video0 -s ntsc
Standard set to 0000b000

If you have the wrong standard set, you will likely get no video at all since the USB-Live2 won't be able to make any sense out of the incoming video signal.

At this point, it's a good idea to make sure video is working. Plug a video source into the USB-Live2. I use my set-top cable converter box instead of running my old VCR and wearing out tapes while testing.

As a brief aside, I need to mention that there are two main video toolkits for Linux. One is known as "ffmpeg", the other is "libav". They are very closely related as libav is a branch of ffmpeg. As of this writing (October 2016), libav and ffmpeg are merging back together, and ffmpeg is once again becoming the standard toolkit for Linux video. Throughout you will see me mention the commands from both toolkits. E.g. ffmpeg and avconv. Or ffplay and avplay.

Use ffplay (or avplay) to monitor what's coming in:

$ ffplay -f video4linux2 /dev/video0

Note that there is no sound. We need to figure out where the USB-Live2's sound hardware is before we can test sound. ALSA's arecord command can be used to list sound devices:

$ arecord -l
**** List of CAPTURE Hardware Devices ****
card 0: Intel [HDA Intel], device 0: AD1984A Analog [AD1984A Analog]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: Intel [HDA Intel], device 2: AD1984A Alt Analog [AD1984A Alt Analog]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: Cx231xxAudio [Cx231xx Audio], device 0: Cx231xx Audio [Conexant cx231xx Capture]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

The motherboard sound hardware is on "card 0" while the USB-Live2 sound hardware is on "card 1". When using ALSA, the proper device name for card 1 is "hw:1". Let's check the audio with ffplay (or avplay):

$ ffplay -f alsa -i hw:1

I'm not sure how to combine the two in ffplay. I assume that ffmpeg would need to be used to combine the audio/video into one stream which could then be piped to ffplay.

Capturing

Given that our video is on "/dev/video0" and our audio is on "hw:1", we can capture some video to a file using ffmpeg (or avconv):

$ sudo nice --20 ffmpeg -f alsa -i hw:1 -f video4linux2 -i /dev/video0 -t 02:10:00 -r:v ntsc -preset ultrafast test.mp4

Let's walk through this command line....

"sudo" says to run this as root. This gives ffmpeg the ability to raise priority if it wants to. I'm not sure how valuable this is. See limits.conf(5) for an alternate (safer) way to give users the same ability to raise priority.

"nice --20" says to raise the priority of ffmpeg by 20. This should give ffmpeg priority over the machine if some other unexpected process comes to life (e.g. updatedb).

"-f alsa -i hw:1" says to force the format of the next file to "alsa" and that the next input file is "hw:1". In other words, use ALSA's hw:1 for audio input.

"-f video4linux2 -i /dev/video0" says to use video4linux2's "/dev/video0" for video input.

"-t 02:10:00" says to record for two hours and ten minutes. Perfect for capturing an entire VHS tape in SP mode.

"-r:v ntsc" says that we want the destination file to use the NTSC video standard. Make sure this matches the USB-Live2's video standard setting or else frames may be dropped. [Need to try dropping this with the latest ffmpeg. I think they preserve the standard of the input now. They used to default to 25fps.]

"-preset ultrafast" says that we want the H.264 codec to use less CPU. This will increase the size of the final video file. However, if we don't do this, the computer might not be able to keep up with the incoming video. Use the "top" command to monitor how much CPU ffmpeg is using and adjust the -preset setting to avoid using too much. Valid -preset settings are: ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow. See https://trac.ffmpeg.org/wiki/Encode/H.264 for more.

"test.mp4" is the destination video file. An mp4 file by default uses the H.264 video codec and the AAC audio codec.

Quality Control

Just some random notes on quality control. I need to expand this section.

Frame Drops. Test with a financial channel that has a moving ticker at the bottom. That makes frame drops easy to see.

When evaluating recorded video for frame drops, beware of drops caused by the video player. Slow the video player down to make sure you are seeing the actual recorded video. (E.g. in vlc use the square bracket keys to slow down/speed up playback. 0.5x makes frame drops obvious.)

Audio Sync. Check toward the end of the file where audio sync issues become worse.

More Info

https://trac.ffmpeg.org/wiki/WikiStart#CommunityContributedDocumentation - the ffmpeg documentation.

https://trac.ffmpeg.org/wiki/Encode/H.264 - H.264 encoding guide.

http://slhck.info/articles/crf - H.264 crf guide.

Quite a bit of documentation can be had from the command line. For ffmpeg (or avconv), try these:

$ man ffmpeg
$ ffmpeg -help full | less

For help on the H.264 encoder and all of its options:

$ x264 --fullhelp | less

Digitising VHS Tapes on Linux - Lots of interesting stuff here. Mentions that dropped frames still happen. Doesn't mention rtbufsize.

VHS to iTunes Compatible MP4 - This is where I saw rtbufsize.

Experience with Ubuntu 14.04

With the video apps that come with Ubuntu 14.04, I was unsuccessful at getting the USB-Live2 to work consistently. With avconv (ffmpeg), sometimes it works fine. Other times it captures for a while at 30fps and then the capture drops to 15fps. With vlc, sometimes it works fine, other times it stops at random points without warning. Possible sources of the problem:

I've been experimenting with capturing from my cable box in two hour chunks. This appears to work fine. So it appears that the issue is the unstable signal from the VCR. Is the hardware having trouble with the signal? Or is the Linux driver handling errors poorly? Perhaps it is passing them on to vlc and ffmpeg who then behave differently when faced with bad input.

Informal statistical analysis of reviews on Amazon mentioning VHS:

Given the 30 reviews on Amazon that indicate that this works fine in Windows for transferring VHS, I would say the problem is in the Linux drivers/software. Actually, there are two reviews that indicate success with VHS in Ubuntu 12.04. Could be a regression.

One solution that should work fine would be to get a VCR with Time-Base Correction built-in. These go for around $300 on ebay. This would get me through the project without having to dig through the drivers and improve them.

Other options:

I also tried the Canopus ADVC-100. Turns out its DV implementation is non-standard and is only supported in very old versions of Linux. Unfortunately I was unable to use my Sony Digital 8 camcorder (DCR-TR7000) as a pass-through device. Somehow, Linux's 1394 implementation appears to be in "DV Out" mode to the camcorder and takes priority over the analog ins, thus defeating pass-through mode. I know that I've done this successfully with Windows and Adobe Premiere.

License

Copyright (C) 2016, Ted Felix

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. See http://www.gnu.org/licenses/fdl.html for the full text of this license.

<- Back to my Linux page.

Copyright ©2016, Ted Felix. Disclaimer