video.c
Go to the documentation of this file.
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         /* If no config string is supplied, we should use the environment variable, otherwise set a sane default */
00127         if (!config_in || !(config_in[0])) {
00128                 /* None suppplied, lets see if the user supplied one from the shell */
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; // 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).
00203         } else { // (vid->mode == VIDEO_MODE_PAL)
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 ); // Make buffer big enough for PAL BGRA images.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines


ar_recog
Author(s): Graylin Trevor Jay and Christopher Crick
autogenerated on Fri Jan 25 2013 12:15:00