~ubuntu-branches/ubuntu/trusty/libdv/trusty

« back to all changes in this revision

Viewing changes to encodedv/dvconnect.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Kobras
  • Date: 2004-07-19 12:19:44 UTC
  • mfrom: (1.2.1 upstream) (2.1.1 warty)
  • Revision ID: james.westby@ubuntu.com-20040719121944-17vuryc01yeyx8hf
Tags: 0.103-2
* debian/rules: Provide separate doc directory for libdv4-dev.
* debian/libdv4-dev.links: No longer symlink doc dir to the one
  from libdv4.
* debian/NEWS: Only install into libdv4-dev. Closes: #259694

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
 *  codec.
8
8
 *
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.
13
13
 *   
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.
18
18
 *   
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. 
22
22
 *
23
23
 *  The libdv homepage is http://libdv.sourceforge.net/.  
24
24
 */
25
25
 
 
26
#ifdef HAVE_CONFIG_H
 
27
#include <config.h>
 
28
#endif // HAVE_CONFIG_H
 
29
 
 
30
#define _FILE_OFFSET_BITS 64
26
31
 
27
32
#include <stdio.h>
28
33
#include <sys/ioctl.h>
36
41
#include <pthread.h>
37
42
#include <signal.h>
38
43
 
39
 
#ifdef HAVE_CONFIG_H
40
 
#include <config.h>
41
 
#endif // HAVE_CONFIG_H
42
 
 
43
44
#if HAVE_LIBPOPT
44
45
#include <popt.h>
45
46
#endif
46
47
 
47
 
#include <malloc.h>
 
48
#include <stdlib.h>
48
49
 
49
50
static long cip_n_ntsc = 2436;
50
51
static long cip_d_ntsc = 38400;
51
52
static long cip_n_pal = 1;
52
53
static long cip_d_pal = 16;
53
54
static long syt_offset = 11000;
54
 
static int video1394_version = 2;
55
55
 
56
56
#define TARGETBUFSIZE   320
57
57
#define MAX_PACKET_SIZE 512
65
65
        VIDEO1394_BUFFER_READY
66
66
};
67
67
 
68
 
enum {
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
77
 
};
78
 
 
79
68
#define VIDEO1394_SYNC_FRAMES          0x00000001
80
69
#define VIDEO1394_INCLUDE_ISO_HEADERS  0x00000002
81
70
#define VIDEO1394_VARIABLE_PACKET_SIZE 0x00000004
82
71
 
83
72
struct video1394_mmap
84
73
{
85
 
        unsigned int channel;
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; 
91
 
        unsigned int fps;
92
 
        unsigned int flags;
93
 
};
94
 
 
95
 
struct video1394_mmap_v2
96
 
{
97
 
        unsigned int channel;
 
74
        int channel;
98
75
        unsigned int sync_tag;
99
76
        unsigned int nb_buffers;
100
77
        unsigned int buf_size;
118
95
{
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 */
122
99
};
123
100
 
 
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)
 
119
 
124
120
static int cap_start_frame = 0;
125
121
static int cap_num_frames = 0xfffffff;
126
122
static int cap_verbose_mode;
132
128
   ------------------------------------------------------------------------ */
133
129
 
134
130
static int max_buffer_blocks = 25*10;
 
131
static int ceil_buffer_blocks = 0;
135
132
 
136
133
struct buf_node {
137
134
        unsigned char data[144000]; /* FIXME: We are wasting space on NTSC! */
334
331
}
335
332
 
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,
 
335
                char *device)
338
336
{
339
 
        int viddev;
340
 
        unsigned char *recv_buf;
341
 
        struct video1394_mmap v;
342
 
        struct video1394_mmap_v2 v2;
343
 
        struct video1394_wait w;
 
337
        int viddev;
 
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];
346
 
        int outbuf_used = 0;
 
342
        unsigned char outbuf[2*65536];
 
343
        int outbuf_used = 0;
347
344
 
348
345
        cap_start_frame = start_frame;
349
346
        cap_num_frames = end_frame - start_frame;
352
349
        if (!filename || strcmp(filename, "-") == 0) {
353
350
                dst_fp = stdout;
354
351
        } else {
355
 
                dst_fp = fopen(filename, "rb");
 
352
                dst_fp = fopen(filename, "wb");
356
353
                if (!dst_fp) {
357
354
                        perror("fopen input file");
358
355
                        return(-1);
359
356
                }
360
357
        }
361
358
 
362
 
        if ((viddev = open("/dev/video1394", O_RDWR)) < 0) {
363
 
                perror("open /dev/video1394");
364
 
                return -1;
365
 
        }
 
359
        if ((viddev = open(device, O_RDWR)) < 0) {
 
360
                perror("open video1394 device");
 
361
                return -1;
 
362
        }
366
363
 
367
364
        v.channel = channel;
368
365
        v.sync_tag = 0;
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;
374
372
                      
375
 
        switch (video1394_version) {
376
 
        case 1:
377
 
                if (ioctl(viddev, VIDEO1394_LISTEN_CHANNEL, &v) < 0) {
378
 
                        perror("VIDEO1394_LISTEN_CHANNEL");
379
 
                        return -1;
380
 
                }
381
 
 
382
 
                break;
383
 
        case 2:
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;
390
 
                v2.flags = v.flags;
391
 
 
392
 
                if (ioctl(viddev, VIDEO1394_LISTEN_CHANNEL, &v2) < 0) {
393
 
                        perror("VIDEO1394_LISTEN_CHANNEL");
394
 
                        return -1;
395
 
                }
396
 
 
397
 
                break;
398
 
        };
399
 
 
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");
404
 
                return -1;
405
 
        }
 
373
        if (ioctl(viddev, VIDEO1394_LISTEN_CHANNEL, &v) < 0) {
 
374
                perror("VIDEO1394_LISTEN_CHANNEL");
 
375
                return -1;
 
376
        }
 
377
 
 
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");
 
382
                return -1;
 
383
        }
406
384
 
407
385
        pthread_mutex_init(&queue_mutex, NULL);
408
386
        pthread_mutex_init(&wakeup_mutex, NULL);
416
394
        unused_buffers = v.nb_buffers;
417
395
        w.buffer = 0;
418
396
       
419
 
        while (cap_num_frames != 0) {
420
 
                struct video1394_wait wcopy;
421
 
                unsigned char * curr;
422
 
                int ofs;
423
 
 
424
 
                while (unused_buffers--) {
425
 
                        unsigned char * curr = recv_buf+ v.buf_size * w.buffer;
426
 
 
427
 
                        memset(curr, 0, v.buf_size);
428
 
                        
429
 
                        wcopy = w;
430
 
 
431
 
                        if (ioctl(viddev,VIDEO1394_LISTEN_QUEUE_BUFFER,
432
 
                                  &wcopy) < 0) {
433
 
                                perror("VIDEO1394_LISTEN_QUEUE_BUFFER");
434
 
                        }
435
 
                        w.buffer++;
436
 
                        w.buffer %= v.nb_buffers;
437
 
                }
438
 
                wcopy = w;
439
 
                if (ioctl(viddev, VIDEO1394_LISTEN_WAIT_BUFFER, &wcopy) < 0) {
440
 
                        perror("VIDEO1394_LISTEN_WAIT_BUFFER");
441
 
                }
442
 
                curr = recv_buf + v.buf_size * w.buffer;
443
 
                ofs = 0;
444
 
 
445
 
                while (ofs < VBUF_SIZE) {
446
 
                        while (outbuf_used < 4 && ofs < VBUF_SIZE) {
447
 
                                outbuf[outbuf_used++] = curr[ofs++];
448
 
                        }
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, 
453
 
                                               VBUF_SIZE - ofs);
454
 
                                        outbuf_used += VBUF_SIZE - ofs;
455
 
                                        ofs = VBUF_SIZE;
456
 
                                } else {
457
 
                                        memcpy(outbuf + outbuf_used,
458
 
                                               curr + ofs, len - outbuf_used);
459
 
                                        ofs += len - outbuf_used;
460
 
                                        outbuf_used = 0;
461
 
                                        handle_packet(outbuf, len - 8);
462
 
                                }
463
 
                        }
464
 
                }
465
 
 
466
 
                unused_buffers = 1;
467
 
        }
 
397
        while (cap_num_frames != 0) {
 
398
        struct video1394_wait wcopy;
 
399
        unsigned char * curr;
 
400
        int ofs;
 
401
        
 
402
        while (unused_buffers--) {
 
403
                unsigned char * curr = recv_buf+ v.buf_size * w.buffer;
 
404
                
 
405
                memset(curr, 0, v.buf_size);
 
406
                
 
407
                wcopy = w;
 
408
                
 
409
                if (ioctl(viddev,VIDEO1394_LISTEN_QUEUE_BUFFER, &wcopy) < 0) {
 
410
                        perror("VIDEO1394_LISTEN_QUEUE_BUFFER");
 
411
                }
 
412
                w.buffer++;
 
413
                w.buffer %= v.nb_buffers;
 
414
        }
 
415
        wcopy = w;
 
416
        if (ioctl(viddev, VIDEO1394_LISTEN_WAIT_BUFFER, &wcopy) < 0) {
 
417
                perror("VIDEO1394_LISTEN_WAIT_BUFFER");
 
418
        }
 
419
        curr = recv_buf + v.buf_size * w.buffer;
 
420
        ofs = 0;
 
421
        
 
422
        while (ofs < VBUF_SIZE) {
 
423
                while (outbuf_used < 4 && ofs < VBUF_SIZE) {
 
424
                        outbuf[outbuf_used++] = curr[ofs++];
 
425
                }
 
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, 
 
430
                                VBUF_SIZE - ofs);
 
431
                                outbuf_used += VBUF_SIZE - ofs;
 
432
                                ofs = VBUF_SIZE;
 
433
                        } else {
 
434
                                memcpy(outbuf + outbuf_used,
 
435
                                curr + ofs, len - outbuf_used);
 
436
                                ofs += len - outbuf_used;
 
437
                                outbuf_used = 0;
 
438
                                handle_packet(outbuf, len - 8);
 
439
                        }
 
440
                }
 
441
        }
 
442
        unused_buffers = 1;
 
443
        }
468
444
 
469
445
        if (broken_frames) {
470
 
                fprintf(stderr, "\nCaptured %d broken frames!\n",
471
 
                        broken_frames);
472
 
        }
473
 
 
474
 
        munmap(recv_buf, v.nb_buffers * v.buf_size);
475
 
        
476
 
        if (ioctl(viddev, VIDEO1394_UNLISTEN_CHANNEL, &v.channel)<0) {
477
 
                perror("VIDEO1394_UNLISTEN_CHANNEL");
478
 
        }
479
 
 
480
 
        close(viddev);
 
446
                fprintf(stderr, "\nCaptured %d broken frames!\n", broken_frames);
 
447
        }
 
448
 
 
449
        munmap(recv_buf, v.nb_buffers * v.buf_size);
 
450
        
 
451
        if (ioctl(viddev, VIDEO1394_UNLISTEN_CHANNEL, &v.channel)<0) {
 
452
                perror("VIDEO1394_UNLISTEN_CHANNEL");
 
453
        }
 
454
        
 
455
        close(viddev);
481
456
 
482
457
        pthread_join(file_io_thread, NULL);
483
458
 
485
460
                fclose(dst_fp);
486
461
        }
487
462
 
488
 
        return 0;
 
463
        return 0;
489
464
}
490
465
 
491
466
/* ------------------------------------------------------------------------
492
467
   - sender
493
468
   ------------------------------------------------------------------------ */
494
469
 
 
470
static const char*const* src_filenames;
495
471
static FILE* src_fp;
496
472
static int is_eof = 0;
497
473
static unsigned char * underrun_data_frame = NULL;
498
474
static int underrun_frame_ispal = 0;
 
475
static unsigned char *device = NULL;
499
476
 
500
477
static pthread_mutex_t  wakeup_rev_mutex;
501
478
static pthread_cond_t   wakeup_rev_cond;
527
504
        is_eof = 1;
528
505
}
529
506
 
 
507
static int
 
508
open_next_input(void)
 
509
{
 
510
        if (src_fp && src_fp != stdin) {
 
511
                fclose (src_fp);
 
512
                src_fp = NULL;
 
513
        }
 
514
        if (!src_filenames || !*src_filenames)
 
515
                return 1;
 
516
        if (!strcmp (*src_filenames++, "-"))
 
517
                src_fp = stdin;
 
518
        else {
 
519
                src_fp = fopen(src_filenames[-1], "rb");
 
520
                if (!src_fp) {
 
521
                        perror("fopen input file");
 
522
                        return 1;
 
523
                }
 
524
        }
 
525
        return 0;
 
526
}
 
527
 
530
528
 
531
529
void fill_buf_queue(int fire)
532
530
{
534
532
 
535
533
        while ((f = get_free_block()) != NULL) {
536
534
                int isPAL;
 
535
again:
537
536
                if (read_frame(src_fp, f->data, &isPAL) < 0) {
538
 
                        is_eof = 1;
 
537
                        is_eof = open_next_input ();
 
538
                        if (!is_eof)
 
539
                                goto again;
539
540
                        push_back(&free_list, f);
540
541
                        return;
541
542
                }
588
589
        if (!f_node) {
589
590
                if (!is_eof) {
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;
 
596
                                        fprintf(stderr,
592
597
                                        "(raising buffer limit +25 => %d)!\n",
593
598
                                        max_buffer_blocks);
 
599
                                } else {
 
600
                                        fprintf(stderr,
 
601
                                                "(not raising buffer space, "
 
602
                                                "hard limit reached)\n");
 
603
                                }
594
604
 
595
 
                                max_buffer_blocks += 25;
596
605
 
597
606
                                pthread_mutex_lock(&wakeup_rev_mutex);
598
607
                                pthread_cond_wait(&wakeup_rev_cond, 
632
641
                cip_counter = cip_n;
633
642
        }
634
643
 
635
 
        for (i = 0; i < TARGETBUFSIZE && vdata < frame_size; i++) {
636
 
                unsigned char* p = targetbuf;
637
 
                int want_sync = 0;
 
644
        for (i = 0; i < TARGETBUFSIZE && vdata < frame_size; i++) {
 
645
                unsigned char* p = targetbuf;
 
646
                int want_sync = 0;
638
647
                cip_counter += cip_n;
639
 
 
 
648
                
640
649
                if (cip_counter > cip_d) {
641
650
                        want_sync = 1;
642
651
                        cip_counter -= cip_d;
643
652
                }
644
 
 
645
 
                *p++ = 0x01; /* Source node ID ! */
646
 
                *p++ = 0x78; /* Packet size in quadlets (480 / 4) */
647
 
                *p++ = 0x00;
648
 
                *p++ = continuity_counter;
649
 
                
650
 
                *p++ = 0x80; /* const */
 
653
                
 
654
                *p++ = 0x01; /* Source node ID ! */
 
655
                *p++ = 0x78; /* Packet size in quadlets (480 / 4) */
 
656
                *p++ = 0x00;
 
657
                *p++ = continuity_counter;
 
658
                
 
659
                *p++ = 0x80; /* const */
651
660
                *p++ = isPAL ? 0x80 : 0x00;
652
 
                *p++ = 0xff; /* timestamp */
653
 
                *p++ = 0xff; /* timestamp */
654
 
                
655
 
                /* Timestamping is now done in the kernel driver! */
656
 
                if (!want_sync) { /* video data */
657
 
                        continuity_counter++;
658
 
 
659
 
                        memcpy(p, frame + vdata, 480);
660
 
                        p += 480;
661
 
                        vdata += 480;
662
 
                }
663
 
 
664
 
                *packet_sizes++ = p - targetbuf;
665
 
                targetbuf += MAX_PACKET_SIZE;
666
 
        }
667
 
        *packet_sizes++ = 0;
 
661
                *p++ = 0xff; /* timestamp */
 
662
                *p++ = 0xff; /* timestamp */
 
663
                
 
664
                /* Timestamping is now done in the kernel driver! */
 
665
                if (!want_sync) { /* video data */
 
666
                        continuity_counter++;
 
667
                        
 
668
                        memcpy(p, frame + vdata, 480);
 
669
                        p += 480;
 
670
                        vdata += 480;
 
671
                }
 
672
                
 
673
                *packet_sizes++ = p - targetbuf;
 
674
                targetbuf += MAX_PACKET_SIZE;
 
675
        }
 
676
        *packet_sizes++ = 0;
668
677
 
669
678
        push_back(&free_list, f_node);
670
679
 
675
684
        return 0;
676
685
}
677
686
 
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)
681
690
{
682
 
        int viddev;
683
 
        unsigned char *send_buf;
684
 
        struct video1394_mmap v;
685
 
        struct video1394_mmap_v2 v2;
686
 
        struct video1394_queue_variable w;
 
691
        int viddev;
 
692
        unsigned char *send_buf;
 
693
        struct video1394_mmap v;
 
694
        struct video1394_queue_variable w;
687
695
        int unused_buffers;
688
696
        int got_frame;
689
 
        unsigned int packet_sizes[321];
690
 
 
691
 
        if (!filename || strcmp(filename, "-") == 0) {
 
697
        unsigned int packet_sizes[321];
 
698
 
 
699
        if ( filenames == NULL )
 
700
                return -1;
 
701
 
 
702
        src_filenames = filenames;
 
703
        if (!*src_filenames) {
 
704
                src_filenames = 0;
692
705
                src_fp = stdin;
693
 
        } else {
694
 
                src_fp = fopen(filename, "rb");
695
 
                if (!src_fp) {
696
 
                        perror("fopen input file");
697
 
                        return -1;
698
 
                }
699
706
        }
700
 
 
 
707
        else if (open_next_input ())
 
708
                return -1;
 
709
  
701
710
        if (underrun_data_filename) {
702
711
                FILE * fp = fopen(underrun_data_filename, "rb");
703
712
                if (!fp) {
704
713
                        perror("fopen underrun data file");
705
 
                        fclose(src_fp);
706
714
                        return -1;
707
715
                }
708
716
                underrun_data_frame = (unsigned char*) malloc(144000);
710
718
                               &underrun_frame_ispal) < 0) {
711
719
                        fprintf(stderr, "Short read on reading underrun data "
712
720
                                "frame...\n");
713
 
                        fclose(src_fp);
714
721
                        fclose(fp);
715
722
                        return -1;
716
723
                }
717
724
                fclose(fp);
718
725
        }
719
726
 
720
 
        if (start_frame > 0) {
 
727
        while (start_frame > 0) {
721
728
                int isPAL,i;
722
729
                unsigned char frame[144000]; /* PAL is large enough... */
723
730
 
727
734
                                        start_frame - i);
728
735
                        }
729
736
                        if (read_frame(src_fp, frame, &isPAL) < 0) {
730
 
                                return -1;
 
737
                                break;
731
738
                        }
732
739
                }
 
740
                start_frame -= i;
 
741
                if (!start_frame)
 
742
                        break;
 
743
                if (open_next_input ())
 
744
                        return -1;
733
745
        }
734
746
 
735
 
        if ((viddev = open("/dev/video1394",O_RDWR)) < 0) {
736
 
                perror("open /dev/video1394");
737
 
                return -1;
738
 
        }
 
747
        if ((viddev = open(device,O_RDWR)) < 0) {
 
748
                perror("open video1394 device");
 
749
                if (src_fp && src_fp != stdin)
 
750
                        fclose (src_fp);
 
751
                return -1;
 
752
        }
739
753
                      
740
 
        v.channel = channel;
741
 
        v.sync_tag = 0;
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;
747
 
 
748
 
        switch (video1394_version) {
749
 
        case 1:
750
 
                if (ioctl(viddev, VIDEO1394_TALK_CHANNEL, &v) < 0) {
751
 
                        perror("VIDEO1394_TALK_CHANNEL");
752
 
                        return -1;
753
 
                }
754
 
 
755
 
                break;
756
 
        case 2:
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;
763
 
                v2.flags = v.flags;
764
 
 
765
 
                if (ioctl(viddev, VIDEO1394_TALK_CHANNEL, &v2) < 0) {
766
 
                        perror("VIDEO1394_TALK_CHANNEL");
767
 
                        return -1;
768
 
                }
769
 
 
770
 
                break;
771
 
        };
772
 
 
773
 
 
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");
778
 
                return -1;
779
 
        }
 
754
        v.channel = channel;
 
755
        v.sync_tag = 0;
 
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;
 
762
 
 
763
        if (ioctl(viddev, VIDEO1394_TALK_CHANNEL, &v) < 0) {
 
764
                perror("VIDEO1394_TALK_CHANNEL");
 
765
                close (viddev);
 
766
                if (src_fp && src_fp != stdin)
 
767
                        fclose (src_fp);
 
768
                return -1;
 
769
        }
 
770
 
 
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");
 
775
                close (viddev);
 
776
                if (src_fp && src_fp != stdin)
 
777
                fclose (src_fp);
 
778
                return -1;
 
779
        }
780
780
 
781
781
        if (verbose_mode) {
782
782
                fprintf(stderr, "Filling buffers...\r");
801
801
                fprintf(stderr, "Transmitting...\r");
802
802
        }
803
803
 
804
 
        unused_buffers = v.nb_buffers;
805
 
        w.buffer = 0;
806
 
        got_frame = 1;
807
 
        w.packet_sizes = packet_sizes;
 
804
        unused_buffers = v.nb_buffers;
 
805
        w.buffer = 0;
 
806
        got_frame = 1;
 
807
        w.packet_sizes = packet_sizes;
808
808
        memset(packet_sizes, 0, sizeof(packet_sizes));
809
809
 
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;
815
 
 
816
 
                        if (!got_frame) {
817
 
                                break;
818
 
                        }
819
 
                        if (ioctl(viddev, VIDEO1394_TALK_QUEUE_BUFFER, &w)<0) {
820
 
                                perror("VIDEO1394_TALK_QUEUE_BUFFER");
821
 
                        }
 
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;
 
815
                        
 
816
                        if (!got_frame) {
 
817
                                break;
 
818
                        }
 
819
                        if (ioctl(viddev, VIDEO1394_TALK_QUEUE_BUFFER, &w)<0) {
 
820
                                perror("VIDEO1394_TALK_QUEUE_BUFFER");
 
821
                        }
822
822
                        if (verbose_mode) {
823
823
                                fprintf(stderr, "Sent frame %8d\r",
824
 
                                        start_frame);
 
824
                                start_frame);
825
825
                        }
826
 
                        w.buffer ++;
827
 
                        w.buffer %= v.nb_buffers;
 
826
                        w.buffer ++;
 
827
                        w.buffer %= v.nb_buffers;
828
828
                        start_frame++;
829
 
                }
830
 
                if (!got_frame) {
831
 
                        break;
832
 
                }
833
 
                if (ioctl(viddev, VIDEO1394_TALK_WAIT_BUFFER, &w) < 0) {
834
 
                        perror("VIDEO1394_TALK_WAIT_BUFFER");
835
 
                }
836
 
                unused_buffers = 1;
837
 
        }
838
 
 
839
 
        w.buffer = (v.nb_buffers + w.buffer - 1) % v.nb_buffers;
840
 
 
841
 
        if (ioctl(viddev, VIDEO1394_TALK_WAIT_BUFFER, &w) < 0) {
842
 
                perror("VIDEO1394_TALK_WAIT_BUFFER");
843
 
        }
844
 
 
845
 
        munmap(send_buf, v.nb_buffers * v.buf_size);
846
 
        
847
 
        if (ioctl(viddev, VIDEO1394_UNTALK_CHANNEL, &v.channel)<0) {
848
 
                perror("VIDEO1394_UNTALK_CHANNEL");
849
 
        }
850
 
 
851
 
        close(viddev);
 
829
                }
 
830
                if (!got_frame) {
 
831
                        break;
 
832
                }
 
833
                if (ioctl(viddev, VIDEO1394_TALK_WAIT_BUFFER, &w) < 0) {
 
834
                        perror("VIDEO1394_TALK_WAIT_BUFFER");
 
835
                }
 
836
                unused_buffers = 1;
 
837
        }
 
838
  
 
839
        w.buffer = (v.nb_buffers + w.buffer - 1) % v.nb_buffers;
 
840
        
 
841
        if (ioctl(viddev, VIDEO1394_TALK_WAIT_BUFFER, &w) < 0) {
 
842
                perror("VIDEO1394_TALK_WAIT_BUFFER");
 
843
        }
 
844
        
 
845
        munmap(send_buf, v.nb_buffers * v.buf_size);
 
846
        
 
847
        if (ioctl(viddev, VIDEO1394_UNTALK_CHANNEL, &v.channel)<0) {
 
848
                perror("VIDEO1394_UNTALK_CHANNEL");
 
849
        }
 
850
        
 
851
        close(viddev);
852
852
 
853
853
        pthread_join(file_io_thread, NULL);
854
854
 
855
 
        if (src_fp != stdin) {
856
 
                fclose(src_fp);
857
 
        }
858
 
 
859
 
        return 0;
 
855
  return 0;
860
856
}
861
857
 
862
858
int rt_raisepri (int pri)
863
859
{
 
860
#ifdef _SC_PRIORITY_SCHEDULING
864
861
        struct sched_param scp;
865
862
 
866
863
        /*
878
875
                        return (-1);
879
876
                }
880
877
        }
 
878
#endif
881
879
        return (0);
882
880
}
883
881
 
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
903
901
 
904
902
 
905
903
int main(int argc, const char** argv)
906
904
{
907
905
#if HAVE_LIBPOPT
908
 
        const char* filename;
909
906
        int verbose_mode = 0;
910
907
        int send_mode = 0;
911
908
        int channel = 63;
996
993
                descrip:    "syt offset (default: 10000 range: 10000-26000)"
997
994
        }; /* syt offset */
998
995
 
999
 
        option_table[DV_CONNECT_OPT_VIDEO1394_VERSION] = (struct poptOption) {
1000
 
                longName:   "video-1394-version", 
1001
 
                argInfo:    POPT_ARG_INT, 
1002
 
                arg:        &video1394_version,
1003
 
                descrip:    "video 1394 version to use 1 "
1004
 
                "(older kernels or CVS versions), 2 (current kernels >2.4.9?)"
1005
 
        }; /* video 1394 version */
1006
 
 
1007
996
        option_table[DV_CONNECT_OPT_MAX_BUFFERS] = (struct poptOption) {
1008
997
                longName:   "buffers", 
1009
998
                shortName:  'b', 
1029
1018
                descrip: "Help options",
1030
1019
        }; /* autohelp */
1031
1020
 
 
1021
        option_table[DV_CONNECT_OPT_DEVICE] = (struct poptOption) {
 
1022
                longName:   "device", 
 
1023
                shortName:  'd', 
 
1024
                argInfo: POPT_ARG_STRING,
 
1025
                arg:     &device,
 
1026
                descrip: "Specify the video1394 device (default /dev/video1394/0)",
 
1027
        }; /* device */
 
1028
 
1032
1029
        option_table[DV_CONNECT_NUM_OPTS] = (struct poptOption) { 
1033
1030
                NULL, 0, 0, NULL, 0 };
1034
1031
 
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>");
1038
1035
 
1039
1036
        while ((rc = poptGetNextOpt(optCon)) > 0) {
1040
1037
                switch (rc) {
1064
1061
        }
1065
1062
        if (buffers < 0) {
1066
1063
                fprintf(stderr, "Number of buffers should be > 0!\n");
1067
 
                return -1;
 
1064
                return -1;
1068
1065
        }
1069
1066
 
1070
 
        filename = poptGetArg(optCon);
1071
 
 
1072
1067
        setpriority (PRIO_PROCESS, 0, -20);
1073
1068
        if (rt_raisepri (1) != 0) {
1074
1069
                setpriority (PRIO_PROCESS, 0, -20);
1075
1070
        }
1076
1071
 
 
1072
#if _POSIX_MEMLOCK > 0
 
1073
        if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1)
 
1074
        {
 
1075
                if (verbose_mode)
 
1076
                        fprintf(stderr, "Cannot disable swapping\n");
 
1077
        } 
 
1078
        else
 
1079
#endif
 
1080
        {
 
1081
                /* Prevent excessive underruns from locking down all mem. */
 
1082
                ceil_buffer_blocks = 10*max_buffer_blocks;
 
1083
        }
 
1084
 
 
1085
        if ( device == NULL )
 
1086
                device = "/dev/video1394/0";
 
1087
 
1077
1088
        if (send_mode) {
1078
 
                send_raw(filename, channel, buffers, start, end, verbose_mode,
1079
 
                         underrun_data);
 
1089
                send_raw(poptGetArgs(optCon), channel, buffers, start, end,
 
1090
                        verbose_mode, underrun_data, device);
1080
1091
        } else {
1081
 
                capture_raw(filename, channel, buffers, start, end, 
1082
 
                            verbose_mode);
 
1092
                capture_raw(poptGetArg(optCon), channel, buffers, start, end, 
 
1093
                            verbose_mode, device);
1083
1094
        }
1084
1095
        return 0;
1085
1096
#else
1088
1099
#endif
1089
1100
}
1090
1101
 
1091
 
 
1092
 
 
1093
 
 
1094
 
 
1095
 
 
1096
 
 
1097
 
 
1098
 
 
1099
 
 
1100
 
 
1101
 
 
1102
 
 
1103