9
9
* libdv is free software; you can redistribute it and/or modify it
10
* under the terms of the GNU General Public License as published by
11
* the Free Software Foundation; either version 2, or (at your
10
* under the terms of the GNU Lesser Public License as published by
11
* the Free Software Foundation; either version 2.1, or (at your
12
12
* option) any later version.
14
14
* libdv is distributed in the hope that it will be useful, but
15
15
* WITHOUT ANY WARRANTY; without even the implied warranty of
16
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17
* General Public License for more details.
17
* Lesser Public License for more details.
19
* You should have received a copy of the GNU General Public License
20
* along with GNU Make; see the file COPYING. If not, write to
19
* You should have received a copy of the GNU Lesser Public License
20
* along with libdv; see the file COPYING. If not, write to
21
21
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23
23
* The libdv homepage is http://libdv.sourceforge.net/.
28
#endif // HAVE_CONFIG_H
30
#define _FILE_OFFSET_BITS 64
28
33
#include <sys/ioctl.h>
65
65
VIDEO1394_BUFFER_READY
69
VIDEO1394_LISTEN_CHANNEL = 0,
70
VIDEO1394_UNLISTEN_CHANNEL,
71
VIDEO1394_LISTEN_QUEUE_BUFFER,
72
VIDEO1394_LISTEN_WAIT_BUFFER,
73
VIDEO1394_TALK_CHANNEL,
74
VIDEO1394_UNTALK_CHANNEL,
75
VIDEO1394_TALK_QUEUE_BUFFER,
76
VIDEO1394_TALK_WAIT_BUFFER
79
68
#define VIDEO1394_SYNC_FRAMES 0x00000001
80
69
#define VIDEO1394_INCLUDE_ISO_HEADERS 0x00000002
81
70
#define VIDEO1394_VARIABLE_PACKET_SIZE 0x00000004
83
72
struct video1394_mmap
86
unsigned int sync_tag;
87
unsigned int nb_buffers;
88
unsigned int buf_size;
89
/* For VARIABLE_PACKET_SIZE: Maximum packet size */
90
unsigned int packet_size;
95
struct video1394_mmap_v2
98
75
unsigned int sync_tag;
99
76
unsigned int nb_buffers;
100
77
unsigned int buf_size;
119
96
unsigned int channel;
120
97
unsigned int buffer;
121
struct timeval filltime; /* time of buffer full */
98
struct timeval filltime; /* time of buffer full */
101
#define VIDEO1394_LISTEN_CHANNEL \
102
_IOWR('#', 0x10, struct video1394_mmap)
103
#define VIDEO1394_UNLISTEN_CHANNEL \
104
_IOW ('#', 0x11, int)
105
#define VIDEO1394_LISTEN_QUEUE_BUFFER \
106
_IOW ('#', 0x12, struct video1394_wait)
107
#define VIDEO1394_LISTEN_WAIT_BUFFER \
108
_IOWR('#', 0x13, struct video1394_wait)
109
#define VIDEO1394_TALK_CHANNEL \
110
_IOWR('#', 0x14, struct video1394_mmap)
111
#define VIDEO1394_UNTALK_CHANNEL \
112
_IOW ('#', 0x15, int)
113
#define VIDEO1394_TALK_QUEUE_BUFFER \
114
_IOW ('#', 0x16, size_t)
115
#define VIDEO1394_TALK_WAIT_BUFFER \
116
_IOW ('#', 0x17, struct video1394_wait)
117
#define VIDEO1394_LISTEN_POLL_BUFFER \
118
_IOWR('#', 0x18, struct video1394_wait)
124
120
static int cap_start_frame = 0;
125
121
static int cap_num_frames = 0xfffffff;
126
122
static int cap_verbose_mode;
336
333
int capture_raw(const char* filename, int channel, int nbuffers,
337
int start_frame, int end_frame, int verbose_mode)
334
int start_frame, int end_frame, int verbose_mode,
340
unsigned char *recv_buf;
341
struct video1394_mmap v;
342
struct video1394_mmap_v2 v2;
343
struct video1394_wait w;
338
unsigned char *recv_buf;
339
struct video1394_mmap v;
340
struct video1394_wait w;
344
341
int unused_buffers;
345
unsigned char outbuf[2*65536];
342
unsigned char outbuf[2*65536];
348
345
cap_start_frame = start_frame;
349
346
cap_num_frames = end_frame - start_frame;
352
349
if (!filename || strcmp(filename, "-") == 0) {
355
dst_fp = fopen(filename, "rb");
352
dst_fp = fopen(filename, "wb");
357
354
perror("fopen input file");
362
if ((viddev = open("/dev/video1394", O_RDWR)) < 0) {
363
perror("open /dev/video1394");
359
if ((viddev = open(device, O_RDWR)) < 0) {
360
perror("open video1394 device");
367
364
v.channel = channel;
369
366
v.nb_buffers = nbuffers;
370
367
v.buf_size = VBUF_SIZE;
371
368
v.packet_size = MAX_PACKET_SIZE;
369
v.syt_offset = syt_offset;
372
370
v.flags = VIDEO1394_INCLUDE_ISO_HEADERS;
373
371
w.channel = v.channel;
375
switch (video1394_version) {
377
if (ioctl(viddev, VIDEO1394_LISTEN_CHANNEL, &v) < 0) {
378
perror("VIDEO1394_LISTEN_CHANNEL");
384
v2.channel = v.channel;
385
v2.sync_tag = v.sync_tag;
386
v2.nb_buffers = v.nb_buffers;
387
v2.buf_size = v.buf_size;
388
v2.packet_size = v.packet_size;
389
v2.syt_offset = syt_offset;
392
if (ioctl(viddev, VIDEO1394_LISTEN_CHANNEL, &v2) < 0) {
393
perror("VIDEO1394_LISTEN_CHANNEL");
400
if ((recv_buf = (unsigned char *) mmap(
401
0, v.nb_buffers*v.buf_size, PROT_READ|PROT_WRITE,
402
MAP_SHARED, viddev, 0)) == (unsigned char *)-1) {
403
perror("mmap videobuffer");
373
if (ioctl(viddev, VIDEO1394_LISTEN_CHANNEL, &v) < 0) {
374
perror("VIDEO1394_LISTEN_CHANNEL");
378
if ((recv_buf = (unsigned char *) mmap(
379
0, v.nb_buffers*v.buf_size, PROT_READ|PROT_WRITE,
380
MAP_SHARED, viddev, 0)) == (unsigned char *)-1) {
381
perror("mmap videobuffer");
407
385
pthread_mutex_init(&queue_mutex, NULL);
408
386
pthread_mutex_init(&wakeup_mutex, NULL);
416
394
unused_buffers = v.nb_buffers;
419
while (cap_num_frames != 0) {
420
struct video1394_wait wcopy;
421
unsigned char * curr;
424
while (unused_buffers--) {
425
unsigned char * curr = recv_buf+ v.buf_size * w.buffer;
427
memset(curr, 0, v.buf_size);
431
if (ioctl(viddev,VIDEO1394_LISTEN_QUEUE_BUFFER,
433
perror("VIDEO1394_LISTEN_QUEUE_BUFFER");
436
w.buffer %= v.nb_buffers;
439
if (ioctl(viddev, VIDEO1394_LISTEN_WAIT_BUFFER, &wcopy) < 0) {
440
perror("VIDEO1394_LISTEN_WAIT_BUFFER");
442
curr = recv_buf + v.buf_size * w.buffer;
445
while (ofs < VBUF_SIZE) {
446
while (outbuf_used < 4 && ofs < VBUF_SIZE) {
447
outbuf[outbuf_used++] = curr[ofs++];
449
if (ofs != VBUF_SIZE) {
450
int len = outbuf[2] + (outbuf[3] << 8) + 8;
451
if (ofs + len - outbuf_used > VBUF_SIZE) {
452
memcpy(outbuf + outbuf_used, curr+ofs,
454
outbuf_used += VBUF_SIZE - ofs;
457
memcpy(outbuf + outbuf_used,
458
curr + ofs, len - outbuf_used);
459
ofs += len - outbuf_used;
461
handle_packet(outbuf, len - 8);
397
while (cap_num_frames != 0) {
398
struct video1394_wait wcopy;
399
unsigned char * curr;
402
while (unused_buffers--) {
403
unsigned char * curr = recv_buf+ v.buf_size * w.buffer;
405
memset(curr, 0, v.buf_size);
409
if (ioctl(viddev,VIDEO1394_LISTEN_QUEUE_BUFFER, &wcopy) < 0) {
410
perror("VIDEO1394_LISTEN_QUEUE_BUFFER");
413
w.buffer %= v.nb_buffers;
416
if (ioctl(viddev, VIDEO1394_LISTEN_WAIT_BUFFER, &wcopy) < 0) {
417
perror("VIDEO1394_LISTEN_WAIT_BUFFER");
419
curr = recv_buf + v.buf_size * w.buffer;
422
while (ofs < VBUF_SIZE) {
423
while (outbuf_used < 4 && ofs < VBUF_SIZE) {
424
outbuf[outbuf_used++] = curr[ofs++];
426
if (ofs != VBUF_SIZE) {
427
int len = outbuf[2] + (outbuf[3] << 8) + 8;
428
if (ofs + len - outbuf_used > VBUF_SIZE) {
429
memcpy(outbuf + outbuf_used, curr+ofs,
431
outbuf_used += VBUF_SIZE - ofs;
434
memcpy(outbuf + outbuf_used,
435
curr + ofs, len - outbuf_used);
436
ofs += len - outbuf_used;
438
handle_packet(outbuf, len - 8);
469
445
if (broken_frames) {
470
fprintf(stderr, "\nCaptured %d broken frames!\n",
474
munmap(recv_buf, v.nb_buffers * v.buf_size);
476
if (ioctl(viddev, VIDEO1394_UNLISTEN_CHANNEL, &v.channel)<0) {
477
perror("VIDEO1394_UNLISTEN_CHANNEL");
446
fprintf(stderr, "\nCaptured %d broken frames!\n", broken_frames);
449
munmap(recv_buf, v.nb_buffers * v.buf_size);
451
if (ioctl(viddev, VIDEO1394_UNLISTEN_CHANNEL, &v.channel)<0) {
452
perror("VIDEO1394_UNLISTEN_CHANNEL");
482
457
pthread_join(file_io_thread, NULL);
590
591
if (!underrun_data_frame) {
591
fprintf(stderr, "Buffer underrun "
592
fprintf(stderr, "Buffer underrun ");
593
if (ceil_buffer_blocks > 0 &&
594
max_buffer_blocks < ceil_buffer_blocks) {
595
max_buffer_blocks += 25;
592
597
"(raising buffer limit +25 => %d)!\n",
593
598
max_buffer_blocks);
601
"(not raising buffer space, "
602
"hard limit reached)\n");
595
max_buffer_blocks += 25;
597
606
pthread_mutex_lock(&wakeup_rev_mutex);
598
607
pthread_cond_wait(&wakeup_rev_cond,
632
641
cip_counter = cip_n;
635
for (i = 0; i < TARGETBUFSIZE && vdata < frame_size; i++) {
636
unsigned char* p = targetbuf;
644
for (i = 0; i < TARGETBUFSIZE && vdata < frame_size; i++) {
645
unsigned char* p = targetbuf;
638
647
cip_counter += cip_n;
640
649
if (cip_counter > cip_d) {
642
651
cip_counter -= cip_d;
645
*p++ = 0x01; /* Source node ID ! */
646
*p++ = 0x78; /* Packet size in quadlets (480 / 4) */
648
*p++ = continuity_counter;
650
*p++ = 0x80; /* const */
654
*p++ = 0x01; /* Source node ID ! */
655
*p++ = 0x78; /* Packet size in quadlets (480 / 4) */
657
*p++ = continuity_counter;
659
*p++ = 0x80; /* const */
651
660
*p++ = isPAL ? 0x80 : 0x00;
652
*p++ = 0xff; /* timestamp */
653
*p++ = 0xff; /* timestamp */
655
/* Timestamping is now done in the kernel driver! */
656
if (!want_sync) { /* video data */
657
continuity_counter++;
659
memcpy(p, frame + vdata, 480);
664
*packet_sizes++ = p - targetbuf;
665
targetbuf += MAX_PACKET_SIZE;
661
*p++ = 0xff; /* timestamp */
662
*p++ = 0xff; /* timestamp */
664
/* Timestamping is now done in the kernel driver! */
665
if (!want_sync) { /* video data */
666
continuity_counter++;
668
memcpy(p, frame + vdata, 480);
673
*packet_sizes++ = p - targetbuf;
674
targetbuf += MAX_PACKET_SIZE;
669
678
push_back(&free_list, f_node);
678
int send_raw(const char* filename, int channel, int nbuffers, int start_frame,
679
int end_frame, int verbose_mode,
680
const char * underrun_data_filename)
687
int send_raw(const char*const* filenames, int channel, int nbuffers,
688
int start_frame, int end_frame, int verbose_mode,
689
const char * underrun_data_filename, char *device)
683
unsigned char *send_buf;
684
struct video1394_mmap v;
685
struct video1394_mmap_v2 v2;
686
struct video1394_queue_variable w;
692
unsigned char *send_buf;
693
struct video1394_mmap v;
694
struct video1394_queue_variable w;
687
695
int unused_buffers;
689
unsigned int packet_sizes[321];
691
if (!filename || strcmp(filename, "-") == 0) {
697
unsigned int packet_sizes[321];
699
if ( filenames == NULL )
702
src_filenames = filenames;
703
if (!*src_filenames) {
694
src_fp = fopen(filename, "rb");
696
perror("fopen input file");
707
else if (open_next_input ())
701
710
if (underrun_data_filename) {
702
711
FILE * fp = fopen(underrun_data_filename, "rb");
704
713
perror("fopen underrun data file");
708
716
underrun_data_frame = (unsigned char*) malloc(144000);
727
734
start_frame - i);
729
736
if (read_frame(src_fp, frame, &isPAL) < 0) {
743
if (open_next_input ())
735
if ((viddev = open("/dev/video1394",O_RDWR)) < 0) {
736
perror("open /dev/video1394");
747
if ((viddev = open(device,O_RDWR)) < 0) {
748
perror("open video1394 device");
749
if (src_fp && src_fp != stdin)
742
v.nb_buffers = nbuffers;
743
v.buf_size = TARGETBUFSIZE * MAX_PACKET_SIZE;
744
v.packet_size = MAX_PACKET_SIZE;
745
v.flags = VIDEO1394_VARIABLE_PACKET_SIZE;
746
w.channel = v.channel;
748
switch (video1394_version) {
750
if (ioctl(viddev, VIDEO1394_TALK_CHANNEL, &v) < 0) {
751
perror("VIDEO1394_TALK_CHANNEL");
757
v2.channel = v.channel;
758
v2.sync_tag = v.sync_tag;
759
v2.nb_buffers = v.nb_buffers;
760
v2.buf_size = v.buf_size;
761
v2.packet_size = v.packet_size;
762
v2.syt_offset = syt_offset;
765
if (ioctl(viddev, VIDEO1394_TALK_CHANNEL, &v2) < 0) {
766
perror("VIDEO1394_TALK_CHANNEL");
774
if ((send_buf = (unsigned char *) mmap(
775
0, v.nb_buffers * v.buf_size, PROT_READ|PROT_WRITE,
776
MAP_SHARED, viddev, 0)) == (unsigned char *)-1) {
777
perror("mmap videobuffer");
756
v.nb_buffers = nbuffers;
757
v.buf_size = TARGETBUFSIZE * MAX_PACKET_SIZE;
758
v.packet_size = MAX_PACKET_SIZE;
759
v.flags = VIDEO1394_VARIABLE_PACKET_SIZE;
760
v.syt_offset = syt_offset;
761
w.channel = v.channel;
763
if (ioctl(viddev, VIDEO1394_TALK_CHANNEL, &v) < 0) {
764
perror("VIDEO1394_TALK_CHANNEL");
766
if (src_fp && src_fp != stdin)
771
if ((send_buf = (unsigned char *) mmap(
772
0, v.nb_buffers * v.buf_size, PROT_READ|PROT_WRITE,
773
MAP_SHARED, viddev, 0)) == (unsigned char *)-1) {
774
perror("mmap videobuffer");
776
if (src_fp && src_fp != stdin)
781
781
if (verbose_mode) {
782
782
fprintf(stderr, "Filling buffers...\r");
801
801
fprintf(stderr, "Transmitting...\r");
804
unused_buffers = v.nb_buffers;
807
w.packet_sizes = packet_sizes;
804
unused_buffers = v.nb_buffers;
807
w.packet_sizes = packet_sizes;
808
808
memset(packet_sizes, 0, sizeof(packet_sizes));
810
for (;start_frame < end_frame;) {
811
while (unused_buffers--) {
812
got_frame = (fill_buffer(
813
send_buf + w.buffer * v.buf_size,
814
packet_sizes) < 0) ? 0 : 1;
819
if (ioctl(viddev, VIDEO1394_TALK_QUEUE_BUFFER, &w)<0) {
820
perror("VIDEO1394_TALK_QUEUE_BUFFER");
810
for (;start_frame < end_frame;) {
811
while (unused_buffers--) {
812
got_frame = (fill_buffer(
813
send_buf + w.buffer * v.buf_size,
814
packet_sizes) < 0) ? 0 : 1;
819
if (ioctl(viddev, VIDEO1394_TALK_QUEUE_BUFFER, &w)<0) {
820
perror("VIDEO1394_TALK_QUEUE_BUFFER");
822
822
if (verbose_mode) {
823
823
fprintf(stderr, "Sent frame %8d\r",
827
w.buffer %= v.nb_buffers;
827
w.buffer %= v.nb_buffers;
833
if (ioctl(viddev, VIDEO1394_TALK_WAIT_BUFFER, &w) < 0) {
834
perror("VIDEO1394_TALK_WAIT_BUFFER");
839
w.buffer = (v.nb_buffers + w.buffer - 1) % v.nb_buffers;
841
if (ioctl(viddev, VIDEO1394_TALK_WAIT_BUFFER, &w) < 0) {
842
perror("VIDEO1394_TALK_WAIT_BUFFER");
845
munmap(send_buf, v.nb_buffers * v.buf_size);
847
if (ioctl(viddev, VIDEO1394_UNTALK_CHANNEL, &v.channel)<0) {
848
perror("VIDEO1394_UNTALK_CHANNEL");
833
if (ioctl(viddev, VIDEO1394_TALK_WAIT_BUFFER, &w) < 0) {
834
perror("VIDEO1394_TALK_WAIT_BUFFER");
839
w.buffer = (v.nb_buffers + w.buffer - 1) % v.nb_buffers;
841
if (ioctl(viddev, VIDEO1394_TALK_WAIT_BUFFER, &w) < 0) {
842
perror("VIDEO1394_TALK_WAIT_BUFFER");
845
munmap(send_buf, v.nb_buffers * v.buf_size);
847
if (ioctl(viddev, VIDEO1394_UNTALK_CHANNEL, &v.channel)<0) {
848
perror("VIDEO1394_UNTALK_CHANNEL");
853
853
pthread_join(file_io_thread, NULL);
855
if (src_fp != stdin) {
862
858
int rt_raisepri (int pri)
860
#ifdef _SC_PRIORITY_SCHEDULING
864
861
struct sched_param scp;
895
893
#define DV_CONNECT_OPT_CIP_N_NTSC 7
896
894
#define DV_CONNECT_OPT_CIP_D_NTSC 8
897
895
#define DV_CONNECT_OPT_SYT_OFFSET 9
898
#define DV_CONNECT_OPT_VIDEO1394_VERSION 10
899
#define DV_CONNECT_OPT_MAX_BUFFERS 11
900
#define DV_CONNECT_OPT_UNDERRUN_DATA 12
901
#define DV_CONNECT_OPT_AUTOHELP 13
896
#define DV_CONNECT_OPT_MAX_BUFFERS 10
897
#define DV_CONNECT_OPT_UNDERRUN_DATA 11
898
#define DV_CONNECT_OPT_AUTOHELP 12
899
#define DV_CONNECT_OPT_DEVICE 13
902
900
#define DV_CONNECT_NUM_OPTS 14
905
903
int main(int argc, const char** argv)
908
const char* filename;
909
906
int verbose_mode = 0;
910
907
int send_mode = 0;
911
908
int channel = 63;
1029
1018
descrip: "Help options",
1030
1019
}; /* autohelp */
1021
option_table[DV_CONNECT_OPT_DEVICE] = (struct poptOption) {
1024
argInfo: POPT_ARG_STRING,
1026
descrip: "Specify the video1394 device (default /dev/video1394/0)",
1032
1029
option_table[DV_CONNECT_NUM_OPTS] = (struct poptOption) {
1033
1030
NULL, 0, 0, NULL, 0 };
1035
1032
optCon = poptGetContext(NULL, argc,
1036
1033
(const char **)argv, option_table, 0);
1037
poptSetOtherOptionHelp(optCon, "<raw dv file or - for stdin/stdout>");
1034
poptSetOtherOptionHelp(optCon, "<raw dv files or '-- -' for stdin/stdout>");
1039
1036
while ((rc = poptGetNextOpt(optCon)) > 0) {
1065
1062
if (buffers < 0) {
1066
1063
fprintf(stderr, "Number of buffers should be > 0!\n");
1070
filename = poptGetArg(optCon);
1072
1067
setpriority (PRIO_PROCESS, 0, -20);
1073
1068
if (rt_raisepri (1) != 0) {
1074
1069
setpriority (PRIO_PROCESS, 0, -20);
1072
#if _POSIX_MEMLOCK > 0
1073
if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1)
1076
fprintf(stderr, "Cannot disable swapping\n");
1081
/* Prevent excessive underruns from locking down all mem. */
1082
ceil_buffer_blocks = 10*max_buffer_blocks;
1085
if ( device == NULL )
1086
device = "/dev/video1394/0";
1077
1088
if (send_mode) {
1078
send_raw(filename, channel, buffers, start, end, verbose_mode,
1089
send_raw(poptGetArgs(optCon), channel, buffers, start, end,
1090
verbose_mode, underrun_data, device);
1081
capture_raw(filename, channel, buffers, start, end,
1092
capture_raw(poptGetArg(optCon), channel, buffers, start, end,
1093
verbose_mode, device);