fwdv(4)
Source: sys/dev/firewire/fwdv.c, fwdv.h, CIP and DIF structures in
iec68113.h, shared iso plumbing in fw_helpers.h.
What it is
Section titled “What it is”A receive-only driver for DV camcorders: IEC 61883-2 isochronous input
plus AV/C tape transport control over FCP. It matches any 1394TA AV/C
unit (spec id 0x00a02d, version 0x010001), presents /dev/fwdvN, and
each read(2) returns one complete raw DIF frame: concatenate them
and you have a .dv file ffmpeg plays directly.
It is a listener, deliberately. No IRM bandwidth allocation, no oPCR connection management; it reads the camcorder’s oPCR[0] once, and if the output is online, uses whatever channel the camera already broadcasts on (default tunable: channel 63, the broadcast channel).
AV/C over FCP
Section titled “AV/C over FCP”Transport control is the AV/C command set carried by FCP: block writes
to 0xfffff0000b00 on the target, responses arriving as writes back to
0xfffff0000d00 on the host, where the driver holds a bind with four
pre-posted receive buffers. Commands serialize on a busy flag; a
response of INTERIM re-arms the wait, up to three times three seconds.
Four ioctls map to tape subunit opcodes: FWDV_PLAY, FWDV_STOP,
FWDV_FFWD, FWDV_REW. Success means the deck answered ACCEPTED, not
that the tape moved: it is a camcorder, promises are aspirational.
Stream lifecycle
Section titled “Stream lifecycle”First open starts the stream, further opens share it, last close tears it down.
A concurrent open during STARTING sleeps up to five seconds for the race winner to finish.
CIP demux and frame assembly
Section titled “CIP demux and frame assembly”Each iso packet is a 4-byte iso header, an 8-byte CIP header, then 80-byte DIF blocks. The CIP header carries the format (only DVCR is accepted), and its FDF field says NTSC or PAL and SD or HD. The first data packet latches the frame size: 120,000 bytes NTSC, 144,000 PAL, 200,000 DVCPRO-HD.
Frame boundaries come from the DIF blocks themselves: a HEADER-section block with sequence number 0 starts a frame. SYT timestamps in the CIP header are ignored entirely; cadence is DIF structure, nothing else.
Double buffering with freshest-frame-wins: if the previous frame was
never read, the swap still happens and the old one counts as dropped.
The reader sets read_in_progress before its unlocked uiomove, and
the iso side drops rather than swaps into a buffer being copied out.
One PAL quirk: some cameras signal PAL in the CIP but leave the DSF bit
clear in the header DIF, so the driver forces it.
Bus reset
Section titled “Bus reset”Unit children get no bus reset callbacks, and the running IR context is not stopped by one: capture just resumes when the talker does, on the same channel. If the camera renegotiates onto a different channel, the stream goes silent until close and reopen, since the channel is chosen only at stream start. AV/C keeps working across resets because the node id is re-read per command. And the OHCI resume path re-arms running IR contexts, so capture even survives S3.
Interfaces
Section titled “Interfaces”kldload firewire fwdv./dvctl play # FWDV_PLAY ioctlcat /dev/fwdv0 > tape.dv # one DIF frame per readffplay tape.dvFWDV_GINFO returns state, channel, detected system, frame size, frame
and drop counters, the EUI-64 and the CROM vendor/model strings.