# zigford.org

About | Links | Scripts
Sharing linux/windows scripts and tips

### Converting VHS and DV to Modern Formats - Part 1

May 26, 2019 — Jesse Harris

Over the past 10 years I've been meaning to convert my family's VHS tapes to a modern format. Originally that would have been DVD, but as it seems that DVD and Blu-Ray would have a limited lifespan, I've opted to go directly to modern encoding formats.

This will be a multi-part series stepping through all the challenges with converting these formats using Linux. This post, focuses around getting Video Grabber's (USB Dongles) to work under Linux.

In order to get VHS content to a modern video format, you will need a compatible USB capture device, a VHS Player and a PC.

The process should be fairly straight forward, but there were a number of issues which made the task difficult to achieve without compromise.

Conceptually it should be as follows:

1. Connect VHS Player to USB Capture Device
2. Connect USB Capture Device to PC
3. Install->Launch Capture software
4. Press Record in the Software
5. Press Play on the VHS player

Step 2 is where it get's tricky on Linux. While there are a significant number of capture devices supported on Linux, it is still luck-of-the-draw when purchasing a device with Linux in mind.

From what I have found many devices are rebranded. E.g. Four same branded devices may contain 4 different chipsets. Maybe only 2 of them contain the Linux supported chipset. To make matters worse, vendors don't typically list the chipset on their site or packaging.

The following is a description of my journey to get a couple of different capture devices to work on Linux. Your mileage may vary.

In my case, I had two USB capture devices. One was very old Pinnacle Dazzle obtained from my Dad that he was throwing out and the other was purchased at Aldi by my Mother-In-Law. This one had no label on the device, but the box stated:
Bauhn DVD Maker

### Dazzle

I started with the Dazzle. This unit looked very old. Sometimes with Linux, Old= Good. As devices age, the likelihood that some enthusiastic Linux hacker will add driver support goes up (I don't actually know this and cannot prove it, but you probably can't disprove it either, so there).

So, I plugged it in and typed `lsusb`

        Bus 003 Device 007: ID 2304:021d Pinnacle Systems, Inc. Dazzle DVC130

Figure 1. Content snipped for brevity

The important part of the `lsusb` output is the ID `2304:021d`

We now know what this beast is. Let's check if the kernel has already recognized it. You can usually do this by checking your kernel messages and see if a driver module loaded and told you it registered anything. Therefore: `dmesg`

        [14842.638559] usb 3-11.3: new high-speed USB device number 7 using xhci_hcd
        [14842.714905] usb 3-11.3: New USB device found, idVendor=2304, idProduct=021d, bcdDevice= 0.00
        [14842.714907] usb 3-11.3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
        [14842.714908] usb 3-11.3: Product: DVC 130
        [14842.714909] usb 3-11.3: Manufacturer: Pinnacle Systems, Inc.
        [14843.570702] usb 3-11.2: reset low-speed USB device number 5 using xhci_hcd

Figure 2

The output shows the `idVendor` and `idProduct` match the ID from the output of `lsusb` in Figure 1

Essentially, the kernel is reporting the USB device, but the absence of messages from drivers other than `usb` are not a good sign.

We know by the output of `dmesg` that a kernel module has not loaded. It is time to check that the kernel modules we need are indeed compiled and available. Luckily for me, I'm running Gentoo so always have the kernel source at hand. With video capture devices, these parts of the kernel are referred to as the Video For Linux subsystem. (Technically, Video for Linux 2)

These kernel modules can be found under: Drivers->Media->USB.

            Device Drivers  --->
                <*> Multimedia support  --->
                    [*] Analog TV support
                    [*] Media USB Adapters  --->
                        <M> USB video devices based on Nogatech NT1003/1004/1005
                        <M> STK1160 USB video capture support
                        <M> WIS GO7007 MPEG encoder support
                        <M>   WIS GO7007 USB support
                        <M>   WIS GO7007 Loader support
                        <M> Conexant cx231xx USB video capture support
                        <M> Empia EM28xx USB devices support

Figure 3 shows kernel options to enable video capture

After enabling all the relevant looking ones, I compiled them all and unplugged and re plugged my device, then checked `dmesg` again. Still no luck.

This is the point I recommend most people give up. I myself am not a big fan of giving up. So what do I do? I bust out my trusty screw driver and pop that sucker open to see whats inside. Under the magnifying glass I read out and google all the names on the chips. One of them catches my eye:

go7007

Well would you look at that. There is a module for this chipset. Perhaps all we need to do, is teach it to use my USB device. I start exploring the `.c` files to find which one of them contains definitions looking like USB device and product IDs. I began poking around in the source files looking for a `struct` recording all the supported USB Product and Device ID's.

Here is the `struct` I found in `go7007-usb.c`

            static const struct usb_device_id go7007_usb_id_table[] = {
                {
                            .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION |
                                                    USB_DEVICE_ID_MATCH_INT_INFO,
                            .idVendor       = 0x0eb1,  /* Vendor ID of WIS Technologies */
                            .idProduct      = 0x7007,  /* Product ID of GO7007SB chip */
                            .bcdDevice_lo   = 0x200,   /* Revision number of XMen */
                            .bcdDevice_hi   = 0x200,
                            .bInterfaceClass        = 255,
                            .bInterfaceSubClass     = 0,
                            .bInterfaceProtocol     = 255,
                            .driver_info    = (kernel_ulong_t)GO7007_BOARDID_XMEN,

                },
                {}
            };

Figure 4

The figure above is one device in the `struct,` so in `vim` of course, I yank yank a bit of text here and there and try to add support for my own USB device. The main thing to get right, is to substitute the `idVendor` and `idProduct` from the `struct` with the ID's we discovered in Figure 1 and Figure 2.

For other interfaces of the `struct` I'm mostly guessing, but hoping I can just copy some of the other devices, recompile and it might work. But if it doesn't work, change things around a bit, like some of the other cards and try again.

If done correctly, the kernel module should load automatically when the device is plugged in.

Sadly, I tried many combinations, caused a couple of kernel panics and sometimes the card would load and I could get to see a blue screen when viewing the device, but no content :( I was also able to setup a USB trace and see that the driver was successfully uploading the firmware to the device.

In the end, I gave up on this device.

PS, I tried to capture using this device from a Windows VM. The device was so old it would only work on 32-bit Windows 7 or older. While I was able to get a driver, I could not find the original special software required to capture and regular DirectShow capture to VirtualDub or OBS didn't work either.

### Bauhn DVD Maker

This devices seemed a tad more modern. It has cables for capturing Component and Composite. It came with a CD with drivers and software for Windows. Other than that, there was little evidence online of this device. No-one mentioned this model and certainly not in relation to Linux. I tried the obvious tests (lsusb, dmesg) but didn't spend too much time trying to make it work for Linux.

On my Windows 7 VM though, I did have some luck. I got the software working and was able to capture some VHS tapes. Although the capture was successful there was no flexibility with the file format. The files came out in MPEG 2 (essentially DVD type files), which are okay, but if I wanted these files to be online, I would need to re-encode them. That would mean a potential degradation in quality. I mean, come on! Haven't these videos degraded in quality enough!

What I wanted to do, was for the videos to be captured in a near lossless format and then re-encode to 2 files. 1 for showing on the internets (so that means smallish file size, optimized for streaming and compatibility) and 2 for archival purposes (use the most forward leaning tech available large close to lossless).

My thinking is that future generations will be having to convert historical videos to another format and I want to make a large lossless file available for that purpose.

I decided to crack open the Bauhn DVD maker and see what makes it tick.

Okay, I know how to do this, google all the little numbers and words. It didn't take long to discover the chip and the existing Linux module for this baby. Like the `go7007`, the `cx231xx` module supports many devices that use this chip. Again, I had a crack at setting up the .c driver and adding in the Product and Device ID's to make it work. And guess what?

Boom It worked. And that, my friends is joy. I tested using VLC --> Media --> Open Capture Device..., then click the 'Video device name' dropdown box and choose /dev/video0

You can download my patch file against kernel 4.19.44

Now onto the task of actually doing something with the video files which I will cover in my next post.

Tags: linux, ffmpeg, gentoo, kernel