00001 #include <stdio.h>
00002 #include <string.h>
00003 #include <unistd.h>
00004 #include <libraw1394/raw1394.h>
00005 #include <libdv/dv.h>
00006 #include <AR/config.h>
00007 #include <AR/ar.h>
00008 #include <AR/video.h>
00009
00010 #define VIDEO_MODE_PAL 0
00011 #define VIDEO_MODE_NTSC 1
00012 #define DEFAULT_VIDEO_MODE VIDEO_MODE_NTSC
00013
00014 #define ARV_BUF_FRAME_DATA 150000
00015 #define ARV_NTSC_FRAME_SIZE 120000
00016 #define ARV_PAL_FRAME_SIZE 144000
00017
00018 #define ARV_PACKET_NUM_NTSC 250
00019 #define ARV_PACKET_NUM_PAL 300
00020
00021 #define ARV_BIG_PACKET_SIZE 492
00022 #define ARV_PACKET_DATA_SIZE 480
00023
00024
00025
00026 static AR2VideoParamT *gVid = NULL;
00027
00028 static void ar2VideoCapture(AR2VideoParamT *vid);
00029 static int ar2VideoRawISOHandler(raw1394handle_t handle, int channel, size_t length, quadlet_t *data);
00030 static int ar2VideoBusResetHandler(raw1394handle_t handle, unsigned int generation);
00031 static int ar2VideoBufferInit(AR2VideoBufferT *buffer, int size);
00032 static int ar2VideoBufferClose(AR2VideoBufferT *buffer);
00033 static int ar2VideoBufferRead(AR2VideoBufferT *buffer, ARUint8 *dest, int size, int flag);
00034 static int ar2VideoBufferWrite(AR2VideoBufferT *buffer, ARUint8 *src, int size, int flag);
00035 static ARUint8 *ar2VideoBufferReadDV(AR2VideoParamT *vid);
00036
00037 int arVideoDispOption( void )
00038 {
00039 return ar2VideoDispOption();
00040 }
00041
00042 int arVideoOpen( char *config )
00043 {
00044 if( gVid != NULL ) {
00045 printf("Device has been opened!!\n");
00046 return -1;
00047 }
00048 gVid = ar2VideoOpen( config );
00049 if( gVid == NULL ) return -1;
00050
00051 return 0;
00052 }
00053
00054 int arVideoClose( void )
00055 {
00056 int result;
00057
00058 if( gVid == NULL ) return -1;
00059
00060 result = ar2VideoClose(gVid);
00061 gVid = NULL;
00062 return (result);
00063 }
00064
00065 int arVideoInqSize( int *x, int *y )
00066 {
00067 if( gVid == NULL ) return -1;
00068
00069 return ar2VideoInqSize( gVid, x, y );
00070 }
00071
00072 ARUint8 *arVideoGetImage( void )
00073 {
00074 if( gVid == NULL ) return NULL;
00075
00076 return ar2VideoGetImage( gVid );
00077 }
00078
00079 int arVideoCapStart( void )
00080 {
00081 if( gVid == NULL ) return -1;
00082
00083 return ar2VideoCapStart( gVid );
00084 }
00085
00086 int arVideoCapStop( void )
00087 {
00088 if( gVid == NULL ) return -1;
00089
00090 return ar2VideoCapStop( gVid );
00091 }
00092
00093 int arVideoCapNext( void )
00094 {
00095 if( gVid == NULL ) return -1;
00096
00097 return ar2VideoCapNext( gVid );
00098 }
00099
00100
00101
00102 int ar2VideoDispOption( void )
00103 {
00104 printf("ARVideo may be configured using one or more of the following options,\n");
00105 printf("separated by a space:\n\n");
00106 printf(" -mode=[PAL|NTSC]\n");
00107 printf(" specifies TV signal mode.\n");
00108 printf("\n");
00109
00110 return 0;
00111 }
00112
00113 AR2VideoParamT *ar2VideoOpen( char *config_in )
00114 {
00115 struct raw1394_portinfo g_pinf[16];
00116 AR2VideoParamT *vid;
00117 char *config, *a, line[256];
00118 int numcards;
00119 int i;
00120
00121 arMalloc( vid, AR2VideoParamT, 1 );
00122 vid->mode = DEFAULT_VIDEO_MODE;
00123 vid->debug = 0;
00124 vid->status = 0;
00125
00126
00127 if (!config_in || !(config_in[0])) {
00128
00129 char *envconf = getenv ("ARTOOLKIT_CONFIG");
00130 if (envconf && envconf[0]) {
00131 config = envconf;
00132 printf ("Using config string from environment [%s].\n", envconf);
00133 } else {
00134 config = NULL;
00135 printf ("No video config string supplied, using defaults.\n");
00136 }
00137 } else {
00138 config = config_in;
00139 printf ("Using supplied video config string [%s].\n", config_in);
00140 }
00141
00142 a = config;
00143 if( a != NULL) {
00144 for(;;) {
00145 while( *a == ' ' || *a == '\t' ) a++;
00146 if( *a == '\0' ) break;
00147
00148 if( strncmp( a, "-mode=", 6 ) == 0 ) {
00149 if( strncmp( &a[6], "PAL", 3 ) == 0 ) vid->mode = VIDEO_MODE_PAL;
00150 else if( strncmp( &a[6], "NTSC", 4 ) == 0 ) vid->mode = VIDEO_MODE_NTSC;
00151 else {
00152 ar2VideoDispOption();
00153 free( vid );
00154 return 0;
00155 }
00156 } else if( strncmp( a, "-debug", 6 ) == 0 ) {
00157 vid->debug = 1;
00158 } else {
00159 ar2VideoDispOption();
00160 free( vid );
00161 return 0;
00162 }
00163
00164 while( *a != ' ' && *a != '\t' && *a != '\0') a++;
00165 }
00166 }
00167
00168
00169 if ((vid->handle = raw1394_new_handle()) == NULL) {
00170 free( vid );
00171 perror("raw1394 - couldn't get handle");
00172 return NULL;
00173 }
00174
00175 if ((numcards = raw1394_get_port_info(vid->handle, g_pinf, 16)) < 0) {
00176 free( vid );
00177 perror("raw1394 - couldn't get card info");
00178 return NULL;
00179 }
00180 else {
00181 if( vid->debug ) {
00182 printf("NUMCARDS = %d\n", numcards);
00183 for (i = 0; i < numcards; i++) {
00184 printf("%2d: %s\n", g_pinf[i].nodes, g_pinf[i].name);
00185 }
00186 }
00187 }
00188
00189 if (raw1394_set_port(vid->handle, 0) < 0) {
00190 free(vid);
00191 perror("raw1394 - couldn't set port");
00192 return NULL;
00193 }
00194
00195 if ((vid->dv_decoder = dv_decoder_new((vid->mode == VIDEO_MODE_NTSC), FALSE, FALSE)) == 0) {
00196 free(vid);
00197 return NULL;
00198 }
00199 vid->dv_decoder->quality = 5;
00200 if (vid->mode == VIDEO_MODE_NTSC) {
00201 vid->dv_decoder->height = 480;
00202 vid->dv_decoder->arg_video_system = 1;
00203 } else {
00204 vid->dv_decoder->height = 576;
00205 vid->dv_decoder->arg_video_system = 2;
00206 }
00207 dv_init(FALSE, FALSE);
00208
00209 arMalloc( vid->buffer, AR2VideoBufferT, 1 );
00210 vid->buffer->init = 0;
00211 ar2VideoBufferInit( vid->buffer, ARV_BUF_FRAME_DATA );
00212
00213 arMalloc( vid->image, ARUint8, 720*576*4 );
00214
00215 return vid;
00216 }
00217
00218 int ar2VideoCapStart( AR2VideoParamT *vid )
00219 {
00220 if( vid->status != 0 ) return -1;
00221 vid->status = 1;
00222 vid->packet_num = 0;
00223
00224 pthread_create(&(vid->capture), NULL, (void * (*)(void *))ar2VideoCapture, vid);
00225
00226 return 0;
00227 }
00228
00229 int ar2VideoCapStop( AR2VideoParamT *vid )
00230 {
00231 if( vid->status != 1 ) return -1;
00232 vid->status = 2;
00233
00234 return 0;
00235 }
00236
00237 int ar2VideoCapNext( AR2VideoParamT *vid )
00238 {
00239 return 0;
00240 }
00241
00242 int ar2VideoClose( AR2VideoParamT *vid )
00243 {
00244 if( vid->status == 1 || vid->status == 2 ) vid->status = 0;
00245 else return -1;
00246
00247 pthread_join( vid->capture, NULL );
00248
00249 ar2VideoBufferClose(vid->buffer);
00250 free( vid->buffer );
00251 free( vid->image );
00252
00253 raw1394_stop_fcp_listen(vid->handle);
00254 raw1394_destroy_handle(vid->handle);
00255
00256 free( vid );
00257
00258 return 0;
00259 }
00260
00261
00262
00263 static void ar2VideoCapture(AR2VideoParamT *vid)
00264 {
00265 raw1394_set_userdata(vid->handle, vid);
00266 raw1394_set_bus_reset_handler(vid->handle, ar2VideoBusResetHandler);
00267 raw1394_set_iso_handler(vid->handle, 63, ar2VideoRawISOHandler);
00268 if( raw1394_start_iso_rcv(vid->handle, 63) < 0 ) {
00269 perror("raw1394 - couldn't start iso receive");
00270 exit(-1);
00271 }
00272
00273 for(;;) {
00274 if( vid->status == 1 ) {
00275 while ( vid->status == 1 ) {
00276 raw1394_loop_iterate(vid->handle);
00277 }
00278 raw1394_stop_iso_rcv(vid->handle, 63);
00279 }
00280 else if( vid->status == 2 ) usleep(10);
00281 else break;
00282 }
00283
00284 return;
00285 }
00286
00287 static int ar2VideoRawISOHandler(raw1394handle_t handle, int channel, size_t length, quadlet_t *data)
00288 {
00289 AR2VideoParamT *vid = (AR2VideoParamT *)raw1394_get_userdata(handle);
00290 ARUint8 *packet = (ARUint8 *)data;
00291 int len = 0;
00292
00293 if(length == ARV_BIG_PACKET_SIZE) {
00294 if(vid->packet_num == 0) {
00295 if(packet[12] == 0x1f && packet[13] == 0x07) {
00296 if( vid->debug ) printf("Receiving...\n");
00297 }
00298 else return 0;
00299 }
00300
00301 if (packet[12] == 0x1f && packet[13] == 0x07) {
00302 if(vid->packet_num == 0) {
00303 vid->packet_num++;
00304 len = ar2VideoBufferWrite(vid->buffer, (ARUint8 *)(data+3), ARV_PACKET_DATA_SIZE, 0);
00305 }
00306 else {
00307 vid->packet_num = 0;
00308 vid->packet_num++;
00309 len = ar2VideoBufferWrite(vid->buffer, (ARUint8 *)(data+3), ARV_PACKET_DATA_SIZE, 2);
00310 }
00311 }
00312 else {
00313 vid->packet_num++;
00314 if( (vid->mode == VIDEO_MODE_NTSC && vid->packet_num == ARV_PACKET_NUM_NTSC)
00315 || (vid->mode == VIDEO_MODE_PAL && vid->packet_num == ARV_PACKET_NUM_PAL) ) {
00316 len = ar2VideoBufferWrite(vid->buffer, (ARUint8 *)(data+3), ARV_PACKET_DATA_SIZE, 1);
00317 vid->packet_num = 0;
00318 }
00319 else {
00320 len = ar2VideoBufferWrite(vid->buffer, (ARUint8 *)(data+3), ARV_PACKET_DATA_SIZE, 0);
00321 }
00322 }
00323 }
00324
00325 return len;
00326 }
00327
00328 static int ar2VideoBusResetHandler(raw1394handle_t handle, unsigned int generation)
00329 {
00330 static int i = 0;
00331 AR2VideoParamT *vid = (AR2VideoParamT *)raw1394_get_userdata(handle);
00332
00333 fprintf(stderr,"reset %d\n", i++);
00334 if (i == 10) {
00335 vid->status = 0;
00336 }
00337
00338 return 0;
00339 }
00340
00341 ARUint8 *ar2VideoGetImage( AR2VideoParamT *vid )
00342 {
00343 return ar2VideoBufferReadDV( vid );
00344 }
00345
00346 static ARUint8 *ar2VideoBufferReadDV(AR2VideoParamT *vid)
00347 {
00348 static int f = 1;
00349 ARUint8 *tmp;
00350 int read_size;
00351 int pitches[3];
00352 unsigned char *pixels[3];
00353
00354 if( vid->buffer->init == 0 ) return NULL;
00355
00356 pthread_mutex_lock(&(vid->buffer->mutex));
00357 tmp = vid->buffer->buff_wait;
00358 vid->buffer->buff_wait = vid->buffer->buff_out;
00359 vid->buffer->buff_out = tmp;
00360
00361 vid->buffer->fill_size_out = vid->buffer->fill_size_wait;
00362 vid->buffer->read_size = 0;
00363 vid->buffer->fill_size_wait = 0;
00364 pthread_mutex_unlock(&(vid->buffer->mutex));
00365
00366 if( vid->mode == VIDEO_MODE_NTSC ) {
00367 if( vid->buffer->fill_size_out != ARV_NTSC_FRAME_SIZE ) return NULL;
00368 }
00369 else if( vid->mode == VIDEO_MODE_PAL ) {
00370 if( vid->buffer->fill_size_out != ARV_PAL_FRAME_SIZE ) return NULL;
00371 }
00372 if( f ) {
00373 dv_parse_header(vid->dv_decoder, vid->image);
00374 if( vid->mode == VIDEO_MODE_NTSC ) {
00375 if( vid->dv_decoder->width != 720 || vid->dv_decoder->height != 480 ) {
00376 printf("Image format is not correct.\n");
00377 return NULL;
00378 }
00379 }
00380 else if( vid->mode == VIDEO_MODE_PAL ) {
00381 if( vid->dv_decoder->width != 720 || vid->dv_decoder->height != 576 ) {
00382 printf("Image format is not correct.\n");
00383 return NULL;
00384 }
00385 }
00386 f = 0;
00387 }
00388
00389 pitches[0] = 720*AR_PIX_SIZE_DEFAULT;
00390 pixels[0] = vid->image;
00391 #if (AR_DEFAULT_PIXEL_FORMAT == AR_PIXEL_FORMAT_RGB)
00392 dv_decode_full_frame(vid->dv_decoder, vid->buffer->buff_out, e_dv_color_rgb, pixels, pitches );
00393 #elif (AR_DEFAULT_PIXEL_FORMAT == AR_PIXEL_FORMAT_BGRA)
00394 dv_decode_full_frame(vid->dv_decoder, vid->buffer->buff_out, e_dv_color_bgr0, pixels, pitches );
00395 #else
00396 # error Unsupported pixel format defined in <AR/config.h>.
00397 #endif
00398
00399 return vid->image;
00400 }
00401
00402 int ar2VideoInqSize(AR2VideoParamT *vid, int *x,int *y)
00403 {
00404 if( vid->mode == VIDEO_MODE_NTSC ) {
00405 *x = 720;
00406 *y = 480;
00407 }
00408 else if( vid->mode == VIDEO_MODE_PAL ) {
00409 *x = 720;
00410 *y = 576;
00411 }
00412 else return -1;
00413
00414 return 0;
00415 }
00416
00417 static int ar2VideoBufferInit(AR2VideoBufferT *buffer, int size)
00418 {
00419 if( buffer->init ) return -1;
00420
00421 buffer->size = size;
00422
00423 arMalloc( buffer->buff_in, ARUint8, size );
00424 arMalloc( buffer->buff_wait, ARUint8, size );
00425 arMalloc( buffer->buff_out, ARUint8, size );
00426 buffer->fill_size_in = 0;
00427 buffer->fill_size_wait = 0;
00428 buffer->fill_size_out = 0;
00429 buffer->read_size = 0;
00430
00431 pthread_mutex_init(&(buffer->mutex), NULL);
00432
00433 buffer->init = 1;
00434
00435 return 0;
00436 }
00437
00438 static int ar2VideoBufferClose(AR2VideoBufferT *buffer)
00439 {
00440 if( buffer->init == 0 ) return -1;
00441
00442 pthread_mutex_lock(&(buffer->mutex));
00443 free( buffer->buff_in );
00444 free( buffer->buff_wait );
00445 free( buffer->buff_out );
00446 pthread_mutex_unlock(&(buffer->mutex));
00447 pthread_mutex_destroy(&(buffer->mutex));
00448
00449 buffer->init = 0;
00450
00451 return 0;
00452 }
00453
00454 static int ar2VideoBufferRead(AR2VideoBufferT *buffer, ARUint8 *dest, int size, int flag)
00455 {
00456 ARUint8 *tmp;
00457 int read_size;
00458
00459 if( buffer->init == 0 ) return -1;
00460
00461 if( flag ) {
00462 pthread_mutex_lock(&(buffer->mutex));
00463 tmp = buffer->buff_wait;
00464 buffer->buff_wait = buffer->buff_out;
00465 buffer->buff_out = tmp;
00466
00467 buffer->fill_size_out = buffer->fill_size_wait;
00468 buffer->read_size = 0;
00469 buffer->fill_size_wait = 0;
00470 pthread_mutex_unlock(&(buffer->mutex));
00471 }
00472
00473 if( buffer->fill_size_out - buffer->read_size >= size ) read_size = size;
00474 else read_size = buffer->fill_size_out - buffer->read_size;
00475 memcpy(dest, buffer->buff_out + buffer->read_size, read_size);
00476 buffer->read_size += read_size;
00477
00478 return read_size;
00479 }
00480
00481 static int ar2VideoBufferWrite(AR2VideoBufferT *buffer, ARUint8 *src, int size, int flag)
00482 {
00483 ARUint8 *tmp;
00484 int write_size;
00485
00486 if( buffer->init == 0 ) return -1;
00487
00488 if( flag == 2 ) {
00489 buffer->fill_size_in = 0;
00490 }
00491
00492 if( buffer->size - buffer->fill_size_in > size ) write_size = size;
00493 else write_size = buffer->size - buffer->fill_size_in;
00494 memcpy(buffer->buff_in + buffer->fill_size_in, src, write_size);
00495 buffer->fill_size_in += write_size;
00496
00497 if( flag == 1 ) {
00498 pthread_mutex_lock(&(buffer->mutex));
00499 tmp = buffer->buff_wait;
00500 buffer->buff_wait = buffer->buff_in;
00501 buffer->buff_in = tmp;
00502
00503 buffer->fill_size_wait = buffer->fill_size_in;
00504 buffer->fill_size_in = 0;
00505 pthread_mutex_unlock(&(buffer->mutex));
00506 }
00507
00508 return write_size;
00509 }