Backing up MiniDV tapes on Linux with FireWire


I had ~20 MiniDV tapes that I wanted to back up and share with family. To transfer them, I used an old Canon MV400 camcorder. I got a PCIe FireWire card online that I installed in my desktop computer. Most of the workflow was straightforward once the connection worked, but intermittent capture stalls led to troubleshooting DMA access through the system’s IOMMU.

MiniDV already stores digital video. Transferring it through the camera’s DV connection copies the recorded DV stream to the computer. The camera handles reading the tape, while the computer receives the data over FireWire.

The physical connection was:

MiniDV tape → Canon MV400 → FireWire cable → PCIe FireWire card → Linux

I used a FireWire card from VBESTLIFE and installed it in a PCIe x1 slot.

For capture, I used dvgrab. It can control the camcorder’s transport, rewind the tape, start playback, split recordings and save the incoming DV stream.

The transfer runs at playback speed so 20h of videos takes 20h to capture.

The main problem was that capture sometimes stalled partway through a tape. Kernel logs showed:

firewire_ohci 0000:06:00.0: AMD-Vi: Event logged
[IO_PAGE_FAULT domain=0x0011 address=0xfff72000 flags=0x0050]

My LLM explained that AMD-Vi is AMD’s implementation of an IOMMU, an input/output memory management unit. Devices such as a FireWire controller use DMA—direct memory access—to transfer data into RAM. The IOMMU translates device-visible addresses and controls which memory the device can access.

Those page faults pointed to a problem with the controller’s DMA access through the IOMMU. They provided stronger evidence than the capture application simply appearing to hang: the kernel was reporting memory-access faults associated with the card.

My LLM proposed a workaround that I applied as a kernel boot parameter:

iommu=pt

This selects IOMMU passthrough by default, allowing DMA to bypass address translation. On my system, the parameter was added to the options line in the systemd-boot entry, and this fixed the issue.

I added a small Python wrapper around dvgrab to make processing multiple tapes easier. Each run handled one tape, created a separate capture directory, launched the capture command, and recorded a session log. Once started, dvgrab rewound the tape and began playback automatically.

Some tapes switched between 32 kHz and 48 kHz audio within a single capture. I think dvgrab retained the earlier sample rate. This caused the audio to play at the wrong speed and pitch. For clips with 48 kHz audio incorrectly labeled as 32 kHz, I corrected the playback speed with FFmpeg:

ffmpeg -i input.mp4 -c:v copy -af "asetrate=48000,aresample=48000" -c:a aac -b:a 192k output_audio_fixed.mp4

What remains is to go through the recordings and edit them for sharing.