VHS Video Digitisation on GNU/Linux via USB Device 1D19:6108 (Dexatek Technology Ltd. Video Grabber)
This project provides software and comprehensive instructions for using the USB device 1D19:6108 (Dexatek Technology Ltd. Video Grabber) to perform VHS video digitisation on Linux. Originally sold by ALDI Australia around 2013 as part of the BAUHN DVD Maker (DK8723), this device functions as a composite and component video capture card.
The motivation for this project arises from the need to breathe new life into this hardware. The official software that came with the device was severely outdated and limited, featuring:
- A Windows XP-era kernel-mode driver 😨
- Archaic, proprietary 'ArcSoft ShowBiz' software 🤮
- No official support for Windows versions beyond Windows 7 👴🏻
- No support for GNU/Linux 😭
This project leverages FFMPEG and V4L2 in the backend, ensuring efficient and high-quality video processing.
Key features include:
- Ability to digitise copy-protected VHS tapes (unlike 'ArcSoft ShowBiz').
- Capture preview window.
- Support for Video Acceleration API (VAAPI).
- Preservation of interlacing.
- Detailed logging for painless debugging.
- Written in
bashfor easy customisation.
-
Install the required dependencies.
sudo dnf install ffmpeg v4l-utils alsa-utils
-
Clone the GitHub repository.
git clone https://github.com/KernelGhost/TapeShift.git cd TapeShift -
Plug in the 'Dexatek Technology Ltd. Video Grabber (1D19:6108)'.
-
Run the script.
./TapeShift.sh
https://github.com/KernelGhost/TapeShift/raw/refs/heads/main/Multimedia/Showcase.mp4
![]() |
![]() |
![]() |
Important
Following these instructions is generally no longer necessary unless you are using an older Linux kernel. Support for '1D19:6108' has been added to the cx231xx driver through my patch, which has now been merged.
-
Install the required development tools.
sudo dnf groupinstall "Development Tools" "Development Libraries" sudo dnf install kernel-devel kernel-headers
-
Initialise a bare git repository.
git init cx231xx_patch cd cx231xx_patch -
Enable the sparse checkout feature.
git config core.sparseCheckout true -
Add the Linux kernel source repository URL as the remote.
git remote add origin https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
-
Define the specific directories to clone in the sparse checkout.
echo "drivers/media/tuners/" >> .git/info/sparse-checkout echo "drivers/media/dvb-frontends/" >> .git/info/sparse-checkout echo "drivers/media/usb/cx231xx/" >> .git/info/sparse-checkout
-
Pull the data from the remote repository.
git fetch --depth 1 origin git checkout origin/master
-
Using your favourite text editor, modify
drivers/media/usb/cx231xx/cx231xx-cards.cto include USB device ID1D19:6108.Before:
/* table of devices that work with this driver */ struct usb_device_id cx231xx_id_table[] = { {USB_DEVICE(0x1D19, 0x6109), .driver_info = CX231XX_BOARD_PV_XCAPTURE_USB},
After:
/* table of devices that work with this driver */ struct usb_device_id cx231xx_id_table[] = { {USB_DEVICE(0x1D19, 0x6108), .driver_info = CX231XX_BOARD_PV_XCAPTURE_USB}, {USB_DEVICE(0x1D19, 0x6109), .driver_info = CX231XX_BOARD_PV_XCAPTURE_USB},
-
Create the following
Makefileatdrivers/media/usb/cx231xx/Makefile. Ensure that TABs are used instead of 4 spaces within the 'all:' and 'clean:' sections.# cx231xx driver makefile for out-of-tree compilation KERNEL_DIR ?= /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) obj-m += cx231xx.o cx231xx-y += cx231xx-video.o cx231xx-i2c.o cx231xx-cards.o cx231xx-core.o cx231xx-y += cx231xx-avcore.o cx231xx-417.o cx231xx-pcb-cfg.o cx231xx-vbi.o cx231xx-$(CONFIG_VIDEO_CX231XX_RC) += cx231xx-input.o cx231xx-alsa-objs := cx231xx-audio.o obj-$(CONFIG_VIDEO_CX231XX_ALSA) += cx231xx-alsa.o obj-$(CONFIG_VIDEO_CX231XX_DVB) += cx231xx-dvb.o ccflags-y += -I $(src)/../../tuners ccflags-y += -I $(src)/../../dvb-frontends all: make -C $(KERNEL_DIR) M=$(PWD) modules clean: make -C $(KERNEL_DIR) M=$(PWD) clean -
Run
make clean && makefrom within thedrivers/media/usb/cx231xxdirectory. The output should resemble:make -C /lib/modules/6.10.10-200.fc40.x86_64/build M=/home/rohanbarar/Desktop/cx231xx_patch/drivers/media/usb/cx231xx modules make[1]: Entering directory '/usr/src/kernels/6.10.10-200.fc40.x86_64' warning: the compiler differs from the one used to build the kernel The kernel was built by: gcc (GCC) 14.2.1 20240801 (Red Hat 14.2.1-1) You are using: gcc (GCC) 14.2.1 20240912 (Red Hat 14.2.1-3) CC [M] /home/rohanbarar/Desktop/cx231xx_patch/drivers/media/usb/cx231xx/cx231xx-video.o CC [M] /home/rohanbarar/Desktop/cx231xx_patch/drivers/media/usb/cx231xx/cx231xx-i2c.o CC [M] /home/rohanbarar/Desktop/cx231xx_patch/drivers/media/usb/cx231xx/cx231xx-cards.o CC [M] /home/rohanbarar/Desktop/cx231xx_patch/drivers/media/usb/cx231xx/cx231xx-core.o CC [M] /home/rohanbarar/Desktop/cx231xx_patch/drivers/media/usb/cx231xx/cx231xx-avcore.o CC [M] /home/rohanbarar/Desktop/cx231xx_patch/drivers/media/usb/cx231xx/cx231xx-417.o CC [M] /home/rohanbarar/Desktop/cx231xx_patch/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.o CC [M] /home/rohanbarar/Desktop/cx231xx_patch/drivers/media/usb/cx231xx/cx231xx-vbi.o CC [M] /home/rohanbarar/Desktop/cx231xx_patch/drivers/media/usb/cx231xx/cx231xx-input.o LD [M] /home/rohanbarar/Desktop/cx231xx_patch/drivers/media/usb/cx231xx/cx231xx.o CC [M] /home/rohanbarar/Desktop/cx231xx_patch/drivers/media/usb/cx231xx/cx231xx-audio.o LD [M] /home/rohanbarar/Desktop/cx231xx_patch/drivers/media/usb/cx231xx/cx231xx-alsa.o CC [M] /home/rohanbarar/Desktop/cx231xx_patch/drivers/media/usb/cx231xx/cx231xx-dvb.o MODPOST /home/rohanbarar/Desktop/cx231xx_patch/drivers/media/usb/cx231xx/Module.symvers CC [M] /home/rohanbarar/Desktop/cx231xx_patch/drivers/media/usb/cx231xx/cx231xx.mod.o LD [M] /home/rohanbarar/Desktop/cx231xx_patch/drivers/media/usb/cx231xx/cx231xx.ko BTF [M] /home/rohanbarar/Desktop/cx231xx_patch/drivers/media/usb/cx231xx/cx231xx.ko Skipping BTF generation for /home/rohanbarar/Desktop/cx231xx_patch/drivers/media/usb/cx231xx/cx231xx.ko due to unavailability of vmlinux CC [M] /home/rohanbarar/Desktop/cx231xx_patch/drivers/media/usb/cx231xx/cx231xx-alsa.mod.o LD [M] /home/rohanbarar/Desktop/cx231xx_patch/drivers/media/usb/cx231xx/cx231xx-alsa.ko BTF [M] /home/rohanbarar/Desktop/cx231xx_patch/drivers/media/usb/cx231xx/cx231xx-alsa.ko Skipping BTF generation for /home/rohanbarar/Desktop/cx231xx_patch/drivers/media/usb/cx231xx/cx231xx-alsa.ko due to unavailability of vmlinux CC [M] /home/rohanbarar/Desktop/cx231xx_patch/drivers/media/usb/cx231xx/cx231xx-dvb.mod.o LD [M] /home/rohanbarar/Desktop/cx231xx_patch/drivers/media/usb/cx231xx/cx231xx-dvb.ko BTF [M] /home/rohanbarar/Desktop/cx231xx_patch/drivers/media/usb/cx231xx/cx231xx-dvb.ko Skipping BTF generation for /home/rohanbarar/Desktop/cx231xx_patch/drivers/media/usb/cx231xx/cx231xx-dvb.ko due to unavailability of vmlinux make[1]: Leaving directory '/usr/src/kernels/6.10.10-200.fc40.x86_64' -
Copy the compiled driver to the correct location on your system.
sudo cp ./cx231xx.ko /lib/modules/$(uname -r)/kernel/drivers/media/usb/cx231xx -
(Optional) Create and enroll a key pair to sign the compiled driver. If you already have a set of keys, you can skip ahead to the next step.
-
Install OpenSSL.
sudo dnf install openssl
-
Create a directory to store the keys.
mkdir -p ~/keys cd ~/keys
-
Create the keys.
# Private Key openssl genrsa -out private_key_for_cx231xx.priv 2048 # Public Key openssl req -new -x509 -key private_key_for_cx231xx.priv -outform DER -out public_key_for_cx231xx.der -days 36500 -subj "/CN=Kernel Module Signing"
-
Enroll the public key within the UEFI.
sudo mokutil --import ~/keys/public_key_for_cx231xx.derNote: You will be prompted to create a one-time password. This does not need to be anything complex, and will only be requested once by the 'Perform MOK management' screen within the UEFI when enrolling the certificate (public key). Using something simple like 'a' or '0' as the password is fine.
-
Reboot the system and follow the prompts at startup to enroll the public key.
- In the MOK Manager screen, choose "Enroll MOK".
- Select "Continue" and enter the one-time password you created earlier.
- Confirm the enrollment to finish the process.
-
-
(Optional) Sign the driver using your new key pair.
sudo /usr/src/kernels/$(uname -r)/scripts/sign-file sha256 ~/keys/private_key_for_cx231xx.priv ~/keys/public_key_for_cx231xx.der /lib/modules/$(uname -r)/kernel/drivers/media/usb/cx231xx/cx231xx.ko
-
Disable the existing copy of the
cx231xxdriver and replace it with your new patched copy.sudo mv /lib/modules/$(uname -r)/kernel/drivers/media/usb/cx231xx/cx231xx.ko.xz /lib/modules/$(uname -r)/kernel/drivers/media/usb/cx231xx/cx231xx.ko.xz.bak sudo xz -zv /lib/modules/$(uname -r)/kernel/drivers/media/usb/cx231xx/cx231xx.ko sudo dracut --force
-
Unload and reload
cx231xxto switch to the patched copy of the driver.sudo modprobe -r cx231xx # Unload Old Driver sudo modprobe cx231xx # Load Patched Driver
-
Confirm the patched driver was loaded.
sudo modinfo cx231xx
Important
Steps marked as '(Optional)' are mandatory on systems with 'Secure Boot' enabled.
The process of manually compiling and signing the patched version of the driver will need to be repeated each time the kernel is updated.
While there are automated solutions available (e.g. DKMS), the method described above serves as a temporary workaround until my patch is merged into the cx231xx driver.
Note
You can easily undo all the above changes and switch back to the default version of the cx231xx driver by:
- Deleting
cx231xx.ko.xzfrom/lib/modules/$(uname -r)/kernel/drivers/media/usb/cx231xx/. - Using
mvto rename the default driver back to its original name (i.e., remove '.bak'). - Running
sudo dracut --force,sudo modprobe -r cx231xxandsudo modprobe cx231xx. - Removing the public key from the UEFI using
sudo mokutil --delete ~/keys/public_key_for_cx231xx.der. Please only do this if no other kernel modules have been signed using the same key!



