Subversion Repositories AndroidProjects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
204 chris 1
#include <stdio.h>
2
#include <string.h>
3
#include <unistd.h>
4
#include <libraw1394/raw1394.h>
5
#include <libdv/dv.h>
6
#include <AR/config.h>
7
#include <AR/ar.h>
8
#include <AR/video.h>
9
 
10
#define VIDEO_MODE_PAL             0
11
#define VIDEO_MODE_NTSC            1
12
#define DEFAULT_VIDEO_MODE         VIDEO_MODE_NTSC
13
 
14
#define ARV_BUF_FRAME_DATA    150000
15
#define ARV_NTSC_FRAME_SIZE   120000
16
#define ARV_PAL_FRAME_SIZE    144000
17
 
18
#define ARV_PACKET_NUM_NTSC      250
19
#define ARV_PACKET_NUM_PAL       300
20
 
21
#define ARV_BIG_PACKET_SIZE      492
22
#define ARV_PACKET_DATA_SIZE     480
23
 
24
 
25
 
26
static AR2VideoParamT   *gVid = NULL;
27
 
28
static void ar2VideoCapture(AR2VideoParamT *vid);
29
static int ar2VideoRawISOHandler(raw1394handle_t handle, int channel, size_t length, quadlet_t *data);
30
static int ar2VideoBusResetHandler(raw1394handle_t handle, unsigned int generation);
31
static int ar2VideoBufferInit(AR2VideoBufferT *buffer, int size);
32
static int ar2VideoBufferClose(AR2VideoBufferT *buffer);
33
static int ar2VideoBufferRead(AR2VideoBufferT *buffer, ARUint8 *dest, int size, int flag);
34
static int ar2VideoBufferWrite(AR2VideoBufferT *buffer, ARUint8 *src, int size, int flag);
35
static ARUint8 *ar2VideoBufferReadDV(AR2VideoParamT *vid);
36
 
37
int arVideoDispOption( void )
38
{
39
    return  ar2VideoDispOption();
40
}
41
 
42
int arVideoOpen( char *config )
43
{
44
    if( gVid != NULL ) {
45
        printf("Device has been opened!!\n");
46
        return -1;
47
    }
48
    gVid = ar2VideoOpen( config );
49
    if( gVid == NULL ) return -1;
50
 
51
    return 0;
52
}
53
 
54
int arVideoClose( void )
55
{
56
        int result;
57
 
58
    if( gVid == NULL ) return -1;
59
 
60
        result = ar2VideoClose(gVid);
61
        gVid = NULL;
62
    return (result);
63
}
64
 
65
int arVideoInqSize( int *x, int *y )
66
{
67
    if( gVid == NULL ) return -1;
68
 
69
    return ar2VideoInqSize( gVid, x, y );
70
}
71
 
72
ARUint8 *arVideoGetImage( void )
73
{
74
    if( gVid == NULL ) return NULL;
75
 
76
    return ar2VideoGetImage( gVid );
77
}
78
 
79
int arVideoCapStart( void )
80
{
81
    if( gVid == NULL ) return -1;
82
 
83
    return ar2VideoCapStart( gVid );
84
}
85
 
86
int arVideoCapStop( void )
87
{
88
    if( gVid == NULL ) return -1;
89
 
90
    return ar2VideoCapStop( gVid );
91
}
92
 
93
int arVideoCapNext( void )
94
{
95
    if( gVid == NULL ) return -1;
96
 
97
    return ar2VideoCapNext( gVid );
98
}
99
 
100
/*-------------------------------------------*/
101
 
102
int ar2VideoDispOption( void )
103
{
104
    printf("ARVideo may be configured using one or more of the following options,\n");
105
    printf("separated by a space:\n\n");
106
    printf(" -mode=[PAL|NTSC]\n");
107
    printf("    specifies TV signal mode.\n");
108
    printf("\n");
109
 
110
    return 0;
111
}
112
 
113
AR2VideoParamT *ar2VideoOpen( char *config_in )
114
{
115
    struct raw1394_portinfo    g_pinf[16];
116
    AR2VideoParamT            *vid;
117
    char                      *config, *a, line[256];
118
    int                        numcards;
119
    int                        i;
120
 
121
    arMalloc( vid, AR2VideoParamT, 1 );
122
    vid->mode       = DEFAULT_VIDEO_MODE;
123
    vid->debug      = 0;
124
    vid->status     = 0;
125
 
126
        /* If no config string is supplied, we should use the environment variable, otherwise set a sane default */
127
        if (!config_in || !(config_in[0])) {
128
                /* None suppplied, lets see if the user supplied one from the shell */
129
                char *envconf = getenv ("ARTOOLKIT_CONFIG");
130
                if (envconf && envconf[0]) {
131
                        config = envconf;
132
                        printf ("Using config string from environment [%s].\n", envconf);
133
                } else {
134
                        config = NULL;
135
                        printf ("No video config string supplied, using defaults.\n");
136
                }
137
        } else {
138
                config = config_in;
139
                printf ("Using supplied video config string [%s].\n", config_in);
140
        }
141
 
142
    a = config;
143
    if( a != NULL) {
144
        for(;;) {
145
            while( *a == ' ' || *a == '\t' ) a++;
146
            if( *a == '\0' ) break;
147
 
148
            if( strncmp( a, "-mode=", 6 ) == 0 ) {
149
                if( strncmp( &a[6], "PAL", 3 ) == 0 )        vid->mode = VIDEO_MODE_PAL;
150
                else if( strncmp( &a[6], "NTSC", 4 ) == 0 )  vid->mode = VIDEO_MODE_NTSC;
151
                else {
152
                    ar2VideoDispOption();
153
                    free( vid );
154
                    return 0;
155
                }
156
            } else if( strncmp( a, "-debug", 6 ) == 0 ) {
157
                vid->debug = 1;
158
            } else {
159
                ar2VideoDispOption();
160
                free( vid );
161
                return 0;
162
            }
163
 
164
            while( *a != ' ' && *a != '\t' && *a != '\0') a++;
165
        }
166
    }
167
 
168
 
169
    if ((vid->handle = raw1394_new_handle()) == NULL) {
170
        free( vid );
171
        perror("raw1394 - couldn't get handle");
172
        return NULL;
173
    }
174
 
175
    if ((numcards = raw1394_get_port_info(vid->handle, g_pinf, 16)) < 0) {
176
        free( vid );
177
        perror("raw1394 - couldn't get card info");
178
        return NULL;
179
    }
180
    else {
181
        if( vid->debug ) {
182
            printf("NUMCARDS = %d\n", numcards);
183
            for (i = 0; i < numcards; i++) {
184
                printf("%2d: %s\n", g_pinf[i].nodes, g_pinf[i].name);
185
            }
186
        }
187
    }
188
 
189
    if (raw1394_set_port(vid->handle, 0) < 0) {
190
        free(vid);
191
        perror("raw1394 - couldn't set port");
192
        return NULL;
193
    }
194
 
195
    if ((vid->dv_decoder = dv_decoder_new((vid->mode == VIDEO_MODE_NTSC), FALSE, FALSE)) == 0) {
196
                free(vid);
197
        return NULL;
198
    }
199
    vid->dv_decoder->quality = 5;
200
        if (vid->mode == VIDEO_MODE_NTSC) {
201
                vid->dv_decoder->height = 480;
202
                vid->dv_decoder->arg_video_system = 1; // video standard: 0=autoselect [default], 1=525/60 4:1:1 (NTSC), 2=625/50 4:2:0 (PAL,IEC 61834 DV), 3=625/50 4:1:1 (PAL,SMPTE 314M DV).
203
        } else { // (vid->mode == VIDEO_MODE_PAL)
204
                vid->dv_decoder->height = 576;
205
                vid->dv_decoder->arg_video_system = 2;
206
        }
207
    dv_init(FALSE, FALSE);
208
 
209
    arMalloc( vid->buffer, AR2VideoBufferT, 1 );
210
    vid->buffer->init = 0;
211
    ar2VideoBufferInit( vid->buffer, ARV_BUF_FRAME_DATA );
212
 
213
    arMalloc( vid->image, ARUint8, 720*576*4 ); // Make buffer big enough for PAL BGRA images.
214
 
215
    return vid;
216
}
217
 
218
int ar2VideoCapStart( AR2VideoParamT *vid )
219
{
220
    if( vid->status != 0 ) return -1;
221
    vid->status = 1;
222
    vid->packet_num = 0;
223
 
224
    pthread_create(&(vid->capture), NULL, (void * (*)(void *))ar2VideoCapture, vid);
225
 
226
    return 0;
227
}
228
 
229
int ar2VideoCapStop( AR2VideoParamT *vid )
230
{
231
    if( vid->status != 1 ) return -1;
232
    vid->status = 2;
233
 
234
    return 0;
235
}
236
 
237
int ar2VideoCapNext( AR2VideoParamT *vid )
238
{
239
    return 0;
240
}
241
 
242
int ar2VideoClose( AR2VideoParamT *vid )
243
{
244
    if( vid->status == 1 || vid->status == 2 ) vid->status = 0;
245
     else return -1;
246
 
247
    pthread_join( vid->capture, NULL );
248
 
249
    ar2VideoBufferClose(vid->buffer);
250
    free( vid->buffer );
251
    free( vid->image );
252
 
253
    raw1394_stop_fcp_listen(vid->handle);
254
    raw1394_destroy_handle(vid->handle);
255
 
256
    free( vid );
257
 
258
    return 0;
259
}
260
 
261
 
262
 
263
static void ar2VideoCapture(AR2VideoParamT *vid)
264
{
265
    raw1394_set_userdata(vid->handle, vid);
266
    raw1394_set_bus_reset_handler(vid->handle, ar2VideoBusResetHandler);
267
    raw1394_set_iso_handler(vid->handle, 63, ar2VideoRawISOHandler);
268
    if( raw1394_start_iso_rcv(vid->handle, 63) < 0 ) {
269
        perror("raw1394 - couldn't start iso receive");
270
        exit(-1);
271
    }
272
 
273
    for(;;) {
274
        if( vid->status == 1 ) {
275
            while ( vid->status == 1 ) {
276
                raw1394_loop_iterate(vid->handle);
277
            }
278
            raw1394_stop_iso_rcv(vid->handle, 63);
279
        }
280
        else if( vid->status == 2 ) usleep(10);
281
        else break;
282
    }
283
 
284
    return;
285
}
286
 
287
static int ar2VideoRawISOHandler(raw1394handle_t handle, int channel, size_t length, quadlet_t *data)
288
{
289
    AR2VideoParamT  *vid = (AR2VideoParamT *)raw1394_get_userdata(handle);
290
    ARUint8         *packet = (ARUint8 *)data;
291
    int              len = 0;
292
 
293
    if(length == ARV_BIG_PACKET_SIZE) {
294
        if(vid->packet_num == 0) {
295
            if(packet[12] == 0x1f && packet[13] == 0x07) {
296
                if( vid->debug ) printf("Receiving...\n");
297
            }
298
            else return 0;
299
        }
300
 
301
        if (packet[12] == 0x1f && packet[13] == 0x07) {
302
            if(vid->packet_num == 0) {
303
                vid->packet_num++;
304
                len = ar2VideoBufferWrite(vid->buffer, (ARUint8 *)(data+3), ARV_PACKET_DATA_SIZE, 0);
305
            }
306
            else {
307
                vid->packet_num = 0;
308
                vid->packet_num++;
309
                len = ar2VideoBufferWrite(vid->buffer, (ARUint8 *)(data+3), ARV_PACKET_DATA_SIZE, 2);
310
            }
311
        }
312
        else {
313
            vid->packet_num++;
314
            if( (vid->mode == VIDEO_MODE_NTSC && vid->packet_num == ARV_PACKET_NUM_NTSC)
315
             || (vid->mode == VIDEO_MODE_PAL  && vid->packet_num == ARV_PACKET_NUM_PAL) ) {
316
                len = ar2VideoBufferWrite(vid->buffer, (ARUint8 *)(data+3), ARV_PACKET_DATA_SIZE, 1);
317
                vid->packet_num = 0;
318
            }
319
            else {
320
                len = ar2VideoBufferWrite(vid->buffer, (ARUint8 *)(data+3), ARV_PACKET_DATA_SIZE, 0);
321
            }
322
        }
323
    }
324
 
325
    return len;
326
}
327
 
328
static int ar2VideoBusResetHandler(raw1394handle_t handle, unsigned int generation)
329
{
330
    static int       i = 0;
331
    AR2VideoParamT  *vid = (AR2VideoParamT *)raw1394_get_userdata(handle);
332
 
333
    fprintf(stderr,"reset %d\n", i++);
334
    if (i == 10) {
335
        vid->status = 0;
336
    }
337
 
338
    return 0;
339
}
340
 
341
ARUint8 *ar2VideoGetImage( AR2VideoParamT *vid )
342
{
343
    return ar2VideoBufferReadDV( vid );
344
}
345
 
346
static ARUint8 *ar2VideoBufferReadDV(AR2VideoParamT *vid)
347
{
348
    static int     f = 1;
349
    ARUint8       *tmp;
350
    int            read_size;
351
    int            pitches[3];
352
    unsigned char *pixels[3];
353
 
354
    if( vid->buffer->init == 0 ) return NULL;
355
 
356
    pthread_mutex_lock(&(vid->buffer->mutex));
357
    tmp = vid->buffer->buff_wait;
358
    vid->buffer->buff_wait = vid->buffer->buff_out;
359
    vid->buffer->buff_out = tmp;
360
 
361
    vid->buffer->fill_size_out = vid->buffer->fill_size_wait;
362
    vid->buffer->read_size = 0;
363
    vid->buffer->fill_size_wait = 0;
364
    pthread_mutex_unlock(&(vid->buffer->mutex));
365
 
366
    if( vid->mode == VIDEO_MODE_NTSC ) {
367
        if( vid->buffer->fill_size_out != ARV_NTSC_FRAME_SIZE ) return NULL;
368
    }
369
    else if( vid->mode == VIDEO_MODE_PAL ) {
370
        if( vid->buffer->fill_size_out != ARV_PAL_FRAME_SIZE ) return NULL;
371
    }
372
    if( f ) {
373
        dv_parse_header(vid->dv_decoder, vid->image);
374
        if( vid->mode == VIDEO_MODE_NTSC ) {
375
            if( vid->dv_decoder->width != 720 || vid->dv_decoder->height != 480 ) {
376
                printf("Image format is not correct.\n");
377
                return NULL;
378
            }
379
        }
380
        else if( vid->mode == VIDEO_MODE_PAL ) {
381
            if( vid->dv_decoder->width != 720 || vid->dv_decoder->height != 576 ) {
382
                printf("Image format is not correct.\n");
383
                return NULL;
384
            }
385
        }
386
        f = 0;
387
    }
388
 
389
    pitches[0] = 720*AR_PIX_SIZE_DEFAULT;
390
    pixels[0] =  vid->image;
391
#if (AR_DEFAULT_PIXEL_FORMAT == AR_PIXEL_FORMAT_RGB)
392
    dv_decode_full_frame(vid->dv_decoder, vid->buffer->buff_out, e_dv_color_rgb, pixels, pitches );
393
#elif (AR_DEFAULT_PIXEL_FORMAT == AR_PIXEL_FORMAT_BGRA)
394
    dv_decode_full_frame(vid->dv_decoder, vid->buffer->buff_out, e_dv_color_bgr0, pixels, pitches );
395
#else
396
#  error Unsupported pixel format defined in <AR/config.h>.
397
#endif
398
 
399
    return vid->image;
400
}
401
 
402
int ar2VideoInqSize(AR2VideoParamT *vid, int *x,int *y)
403
{
404
    if( vid->mode == VIDEO_MODE_NTSC ) {
405
        *x = 720;
406
        *y = 480;
407
    }
408
    else if( vid->mode == VIDEO_MODE_PAL ) {
409
        *x = 720;
410
        *y = 576;
411
    }
412
    else return -1;
413
 
414
    return 0;
415
}
416
 
417
static int ar2VideoBufferInit(AR2VideoBufferT *buffer, int size)
418
{
419
    if( buffer->init ) return -1;
420
 
421
    buffer->size = size;
422
 
423
    arMalloc( buffer->buff_in,   ARUint8, size );
424
    arMalloc( buffer->buff_wait, ARUint8, size );
425
    arMalloc( buffer->buff_out,  ARUint8, size );
426
    buffer->fill_size_in   = 0;
427
    buffer->fill_size_wait = 0;
428
    buffer->fill_size_out  = 0;
429
    buffer->read_size      = 0;
430
 
431
    pthread_mutex_init(&(buffer->mutex), NULL);
432
 
433
    buffer->init = 1;
434
 
435
    return 0;
436
}
437
 
438
static int ar2VideoBufferClose(AR2VideoBufferT *buffer)
439
{
440
    if( buffer->init == 0 ) return -1;
441
 
442
    pthread_mutex_lock(&(buffer->mutex));
443
    free( buffer->buff_in   );
444
    free( buffer->buff_wait );
445
    free( buffer->buff_out  );
446
    pthread_mutex_unlock(&(buffer->mutex));
447
    pthread_mutex_destroy(&(buffer->mutex));
448
 
449
    buffer->init = 0;
450
 
451
    return 0;
452
}
453
 
454
static int ar2VideoBufferRead(AR2VideoBufferT *buffer, ARUint8 *dest, int size, int flag)
455
{
456
    ARUint8   *tmp;
457
    int        read_size;
458
 
459
    if( buffer->init == 0 ) return -1;
460
 
461
    if( flag ) {
462
        pthread_mutex_lock(&(buffer->mutex));
463
        tmp = buffer->buff_wait;
464
        buffer->buff_wait = buffer->buff_out;
465
        buffer->buff_out = tmp;
466
 
467
        buffer->fill_size_out = buffer->fill_size_wait;
468
        buffer->read_size = 0;
469
        buffer->fill_size_wait = 0;
470
        pthread_mutex_unlock(&(buffer->mutex));
471
    }
472
 
473
    if( buffer->fill_size_out - buffer->read_size >= size ) read_size = size;
474
     else                                                   read_size = buffer->fill_size_out - buffer->read_size;
475
    memcpy(dest, buffer->buff_out + buffer->read_size, read_size);
476
    buffer->read_size += read_size;
477
 
478
    return read_size;
479
}
480
 
481
static int ar2VideoBufferWrite(AR2VideoBufferT *buffer, ARUint8 *src, int size, int flag)
482
{
483
    ARUint8   *tmp;
484
    int        write_size;
485
 
486
    if( buffer->init == 0 ) return -1;
487
 
488
    if( flag == 2 ) {
489
        buffer->fill_size_in = 0;
490
    }
491
 
492
    if( buffer->size - buffer->fill_size_in > size ) write_size = size;
493
     else                                            write_size = buffer->size - buffer->fill_size_in;
494
    memcpy(buffer->buff_in + buffer->fill_size_in, src, write_size);
495
    buffer->fill_size_in += write_size;
496
 
497
    if( flag == 1 ) {
498
        pthread_mutex_lock(&(buffer->mutex));
499
        tmp = buffer->buff_wait;
500
        buffer->buff_wait = buffer->buff_in;
501
        buffer->buff_in = tmp;
502
 
503
        buffer->fill_size_wait = buffer->fill_size_in;
504
        buffer->fill_size_in = 0;
505
        pthread_mutex_unlock(&(buffer->mutex));
506
    }
507
 
508
    return write_size;
509
}