A GNU/Linux driver for the Hauppauge WinTV-PVR-usb2

Please read this first: This page is kept here primarily for historical reference. The canonical Linux driver for this device is Mike Isely's pvrusb2 driver, which is part of the Linux kernel tree since 2.6.18. If you want to use the device under BSD Unix (like for instance FreeBSD or MacOS X), then the driver described here might still be of some use since it uses the portable libusb interface.

WARNING: This is not a finished, working driver yet. And it's not sponsored or approved by Hauppauge in any way either. Hauppauge won't even document the protocol that the PVR-usb2 deploys on your computer's USB bus. So don't annoy them with any questions you might have regarding this software, okay?

A note regarding hardware: This web page is only concerned with the WinTV-PVR-usb 2 version of the Hauppauge WinTV family of products. If you have its predecessor, the "plain" WinTV-PVR-usb, it won't work with the software published here because the devices use different chipsets. If you have that version of the hardware, take a look at the kernel driver by Andreas Gal instead.

What I have done & what you can download here: I have managed to make the USB device function while connected to a Linux machine, by sending it the same commands as the Windows driver sends to it, as determined by the use of the excellent program "usbsnoop" by Benoit Papillault. The effect is the capability to capture MPEG2 from the Hauppauge device and write it to standard output, which means it can be saved to a file or to a named pipe (if you want to stream it to some other program or to another computer).

Download or browse source files here:

How to use: There are two methods, one that lets you try out different settings via the Hauppauge driver for Windows, and one that just uses the same settings as the ones that I normally use, without any need to install or boot any Microsoft software.


Method 1:

To begin with, you need to install the Hauppauge driver for Windows on a machine that has the USB device connected. Then you need to install usbsnoop on the same system. The latest version of usbsnoop is probably the best one to use. Be sure to download a numbered version, not the one that lacks a version number. I have been using usbsnoop-1.8. On your Linux or BSD machine you also need to have libusb installed, including the header file "usb.h".

Then perform the following steps:

1. Boot Windows and start the Hauppauge Win2000 application. Select the input source you want (for example "Composite Video" or one of the tuner channels), and also choose the video resolution you'll be using. Then quit Win2000.

2. Start the usbsnoop program and install filters for the PVR-usb2 device. Follow the instructions for "usbsnoop". Then start Win2000 again and let it run for a few seconds, then stop the program. Uninstall the usbsnoop filters and close the program.

3. Boot into Linux and copy the usbsnoop log file from your Windows file system (by mounting that partition read-only for example).

4. Extract the firmware from the Windows driver binaries. You will need to access the file "pvrusb2_25_22329.exe" from your Linux system. Then extract like this:

mkdir foo
unzip -d foo pvrusb2_25_22329.exe
perl extract-firmware.pl foo/HCWUSB2.SYS
This will produce the files "fx2-firmware.bin" and "xxx-firmware.bin". Only fx2-firmware.bin is used by this method. The other firmware is also contained in the usbsnoop log and gets downloaded from there. If you use Method 2 instead, this firmware will be uploaded from the file xxx-firmware.bin. Note: the extracting script only knows of this particular driver version. You need to change the file offsets in the script if you want to use another version of the Hauppauge driver. Here is an explanation of how these offsets are determined.

Alternatively you can cold-start the PVR-usb2 from Windows and just leave it powered on.

5. Parse the usbsnoop log file (from step 3) like this:

perl usbreplayprep.pl < usbsnoop.log > usbcommands.txt

6. Compile the C program:

gcc -o usbreplay -g usbreplay.c -lusb

7. Start capturing:

perl capture.pl > movie.mpg

Break with ^C to stop capturing.


Method 2:

On your Linux or BSD machine you need to have libusb installed, including the header file "usb.h".

Then perform the following steps:

1. Extract the firmware from the Windows driver binaries. You will need to access the file "pvrusb2_25_22329.exe" from your Linux system. Then extract like this:

mkdir foo
unzip -d foo pvrusb2_25_22329.exe
perl extract-firmware.pl foo/HCWUSB2.SYS
This will produce the files "fx2-firmware.bin" and "xxx-firmware.bin". Note: the extracting script only knows of this particular driver version. You need to change the file offsets in the script if you want to use another version of the Hauppauge driver. Here is an explanation of how these offsets are determined.

2. Create a file of USB commands needed to initialize the device:

perl create-usbcommands.pl xxx-firmware.bin > usbcommands.txt
This will combine some USB commands containing my typical settings with the firmware that you extracted in step 1. Warning: there is no way of knowing if these commands will result in entirely different effects when used on your device. Don't blame me if the thing explodes...

3. Compile the C program:

gcc -o usbreplay -g usbreplay.c -lusb

4. Start capturing:

perl capture.pl > movie.mpg

Break with ^C to stop capturing.


Method 1 has been tested by me on an Intel P4 system running Linux 2.4.23-rc2 and on a Microsoft Xbox running Linux 2.4.22-xbox, using the usb-uhci and the ohci host drivers, respectively. It has also been reported to work on a 2.6.0-beta10 kernel with ehci, and recently also on BSD Unix: MacOS X (version 10.3.6) on libusb 0.1.9 beta 2004-10-23. Method 2 is still very new and has so far only been tested on two machines in Europe with PAL B/G.

Why a userspace driver? Well, the main reason is that doing as much as possible in user space makes development much more flexible. Bugs in the code will be less disastrous, and scripting is more convenient. If needed, the code can be turned into a kernel driver at a later stage.

The other reason is that it is an unnecessary pain in the **** to use kernel drivers for things that can just as easily be done by a userspace program. Sure, there are situations where you want to keep some state information for each device within the kernel, but it's not necessary to put all the control logic in a kernel module. On the contrary, if a userspace program and a more abstract API is used, the logic can be separated from the nuts and bolts of the operating system, and the chance is greater that the driver code will work on other systems.

Hardware observations. Inspection of one WinTV-PVR-usb2 unit revealed the following contents:

CX23416-12Conexant MPEG II A/V encoder
HY57V653220BHyundai 8 Mbyte RAM
SAA7115HLPhilips PAL/NTSC/SECAM decoder
MSG3415GMicronas Multistandard Sound Processor
CY7C68013Cypress USB 2.0 controller
XC9572XLXilinx logic device, unknown purpose
TPI8PSB01NLG metal box containing a PAL TV tuner

On the circuit board it says:

www.hauppauge.com (c) 2002      290000-03

There is a single jumper (open) on the middle of the board. I have no idea what it's for...

Frequently asked questions

Does this driver work with MythTV or Freevo?

No, not yet. As far as I understand it, both MythTV and Freevo require kernel device drivers that conform to the Video for Linux, aka "v4l" specification. The present driver is much too primitive in its current state, and it has no interface to the Linux kernel yet (except of course in the form of the portable libusb interface). There are several things that need to be identified and separated out from the USB initialization sequence in order to create a v4l-conforming kernel driver.

So is there any other PVR software that can be used?

As a matter of fact, yes there is. I wrote a "lightweight" PVR system to make the driver a little more useful in its current state. It's called GLOTV. [Note: version 1.0 of GLOTV can be downloaded here and it has built-in support for the libusb driver — this support has been removed in GLOTV 2.0 and later!]

What privileges are needed to run the program?

By default, you need root privileges to access the device through the /proc/bus/usb/* files. If you don't want to run the capture script as root, you can either try configuring a USB policy daemon that gives you access, or you can make "usbreplay" setuid-root. This is the easiest solution so that's what I do.


Contact information

If you want to chat about this software, try subscribing to the "pvrusb-user" mailing list on SourceForge. It's a part of the SourceForge pvrusb project for the the original PVR-usb device, but no one seems to mind discussions about the PVR-usb2 as well.

Happy Hacking,
Björn Danielsson


News

2005-05-03
Added link to the V4L2 kernel driver by Mike Isely. This is a rewrite of the earlier kernel driver by Aurelien Alleaume.

2005-03-03
Added a new script "create-usbcommands.pl" that completely eliminates the need to connect the device to a Microsoft-infected machine during the installation process. But: this also hardwires the settings to the ones I normally use, i.e. 5-6 Mbit/s, 720x576 PAL. It might not work in your environment, and I can't guarantee that it won't blow up your WinTV-PVR-usb2.

2005-02-11
Added Michel Jansens audio modifications for MacOS X to "changesource.pl". Also updated the firmware extraction script to match "pvrusb2_25_22329.exe". The FX2 firmware is unchanged from previous versions.

2005-01-14
First report of successful video capture on a non-Linux system (MacOS X), and also on a bigendian CPU. Hooray for libusb!

2004-10-06
Added code for NTSC tuner in "changesource.pl". Thanks to Kelsie Flynn for finding the parameters for NTSC channels.

2004-09-13
Added link to the V4L2 kernel driver by Aurelien Alleaume that is replacing this driver.

2004-02-25
Switching between TV tuner and RCA inputs is now possible, in the middle of a session. At least it works for me. Please report back if you find differences in the usbsnoop logs in your setup. Audio and video and the TV channel can be switched separately, or all together. A new script "changesource.pl" is used for this, and it obsoletes the old "changechannel.pl" script.

Also updated the firmware extraction script. The offsets are now adapted to "pvrusb2_23_21351.exe". The firmware itself hasn't changed as far as I could determine.

(And yes, I lied in the previous news item about it being the last update of the current programs.)

2004-02-07
New script added: "changechannel.pl". It writes to a named pipe created by "capture.pl" and read by "usbreplay" (these have also been updated). This will probably be the last update to these programs. It's time to redesign and rewrite the code...

2004-02-02
Small update: "capture.pl" now saves the pid of the "usbreplay" process in a file, and "usbreplay.c" drops any setuid privileges it might have, immediately after opening the usb device. This is to make it easier to manage the capturing process from other programs.
Also added a FAQ section to this web page.

2004-01-14
Fixed a bug in "capture.pl" that stopped some UHF channels from working. The delimiting frequency is still 300 MHz. Maybe it should be much higher?

2003-12-28
Updated "capture.pl" to include extremely rudimentary tuner support. A command file must first be prepared like this: pick a command file that works with the coaxial input. Find a line that looks like:

00000000: 08 61 04 ** ** ce ** 81 af 55 4f
There may be several such lines. Pick the last one before the first read-command from endpoint 84, and change it to:
00000000: 08 61 04 $FREQ ce $B 81 af 55 4f
Then start "capture.pl" with this command file as the first argument and the desired frequency in MHz as the second argument. The MHz number must contain a decimal point. For example, the UHF channel known as "37" in PAL countries must be written as 599.25. VHF channel 6 is written 182.25 and so on. The spacing between channels is 7 MHz for VHF, 8 MHz for UHF. For NTSC I think the spacing is 6 MHz, but I have only tested the tuner with PAL sources.

2003-12-22
Cold-starting can now be done from Linux. What was missing earlier was the initialization of the CY7C68013 chip. This is done via the USB cable, but for some unknown reason this transaction wasn't visible in my usbsnoop log. An extra initialization stage has now been added to fix this.

2003-12-07
First version uploaded. Needs to be cold-started from Windows.