I wrote a really simple DV capture program myself (see below), and it
works just fine with the Debian packaged kernel
(linux-image-2.6.32-trunk-amd64 2.6.32-3). dvgrab continues to fail. I
conclude that dvgrab is at fault, not the kernel.
Note that this program writes DV to stdout; you had better redirect it!
Ben.
/* BEGIN */
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libraw1394/raw1394.h>
static unsigned long long total_len;
static unsigned int dropped_packets;
static unsigned int dropped_frames;
static unsigned int complete_frames;
static unsigned int seq_count;
static unsigned int next_seq_num;
static unsigned int next_block_num;
static unsigned char frame_buf[144000];
static enum raw1394_iso_disposition
receive(raw1394handle_t handle,
unsigned char * data,
unsigned int len,
unsigned char channel,
unsigned char tag,
unsigned char sy,
unsigned int cycle,
unsigned int dropped)
{
total_len += len;
dropped_packets += dropped;
if (len == 488)
{
unsigned int seq_num, typed_block_num, block_num;
// Skip firewire header
data += 8;
// Find position of these blocks in the sequence
seq_num = data[1] >> 4;
typed_block_num = data[2];
block_num = -1;
switch (data[0] >> 5)
{
case 0:
// Header: position 0
if (typed_block_num == 0)
block_num = 0;
break;
case 3:
// Audio: position 6 or 102
if (typed_block_num < 9)
block_num = 6 + typed_block_num * 16;
break;
case 4:
// Video: any other position divisible by 6
if (typed_block_num < 135)
block_num = 7 + typed_block_num + typed_block_num / 15;
break;
}
// Are these the blocks we're expecting?
if (seq_num == next_seq_num && block_num == next_block_num)
{
// Set sequence count from the first block of the frame
if (seq_num == 0 && block_num == 0)
seq_count = (data[3] & 0x80) ? 12 : 10;
// Append blocks to frame
memcpy(frame_buf + (seq_num * 150 + block_num) * 80, data, 480);
// Advance position in sequence
next_block_num = block_num + 6;
if (next_block_num == 150)
{
// Advance to next sequence
next_block_num = 0;
++next_seq_num;
if (next_seq_num == seq_count)
{
// Finish frame
write(1, frame_buf, seq_count * 150 * 80);
++complete_frames;
next_seq_num = 0;
}
}
}
else if (next_seq_num != 0 || next_block_num != 0)
{
++dropped_frames;
next_seq_num = 0;
next_block_num = 0;
}
}
return RAW1394_ISO_OK;
}
int main(void)
{
raw1394handle_t handle;
int n_ports, n_ports_again, i;
struct raw1394_portinfo * ports;
handle = raw1394_new_handle();
if (!handle)
{
perror("raw1394_new_handle");
return 1;
}
n_ports = raw1394_get_port_info(handle, NULL, 0);
assert(n_ports >= 0);
ports = calloc(n_ports, sizeof(*ports));
if (!ports)
{
perror("calloc");
return 1;
}
n_ports_again = raw1394_get_port_info(handle, ports, n_ports);
if (n_ports > n_ports_again)
n_ports = n_ports_again;
if (n_ports == 0)
{
fprintf(stderr, "no remote ports found\n");
return 1;
}
for (i = 0; i < n_ports; i++)
fprintf(stderr, "node %d name \"%s\"\n", ports[i].nodes, ports[i].name);
fprintf(stderr, "selected node %d\n", ports[0].nodes);
if (raw1394_set_port(handle, 0))
{
perror("raw1394_set_port");
return 1;
}
if (raw1394_iso_recv_init(handle, receive, /*buf_packets=*/ 600,
/*max_packet_size=*/ 496, /*channel=*/ 63,
/*mode=*/ RAW1394_DMA_DEFAULT,
/*irq_interval=*/ 100))
{
perror("raw1394_iso_recv_init");
return 1;
}
if (raw1394_iso_recv_start(handle, -1, -1, -1))
{
perror("raw1394_iso_recv_start");
return 1;
}
fprintf(stderr, "Press any key to exit\n");
for (;;)
{
int fw_fd = raw1394_get_fd(handle);
fd_set rfds, xfds;
FD_ZERO(&rfds);
FD_ZERO(&xfds);
FD_SET(0, &rfds);
FD_SET(fw_fd, &rfds);
FD_SET(fw_fd, &xfds);
if (select(fw_fd + 1, &rfds, NULL, &xfds, NULL) <= 0 ||
FD_ISSET(0, &rfds) || FD_ISSET(fw_fd, &xfds) ||
raw1394_loop_iterate(handle) < 0)
break;
}
raw1394_iso_stop(handle);
raw1394_iso_shutdown(handle);
fprintf(stderr, "Total length received: %llu\n", total_len);
fprintf(stderr, "Dropped packets: %u\n", dropped_packets);
fprintf(stderr, "Dropped frames: %u\n", dropped_frames);
fprintf(stderr, "Complete frames: %u\n", complete_frames);
return 0;
}
/* END */
--
Ben Hutchings
Horngren's Observation:
Among economists, the real world is often a special case.
Attachment:
signature.asc
Description: This is a digitally signed message part