int bg_avdec_start(void * priv) { int i; const gavl_video_format_t * format; avdec_priv * avdec = priv; if(!bgav_start(avdec->dec)) { return 0; } for(i = 0; i < avdec->current_track->num_video_streams; i++) { gavl_video_format_copy(&(avdec->current_track->video_streams[i].format), bgav_get_video_format(avdec->dec, i)); gavl_metadata_copy(&avdec->current_track->video_streams[i].m, bgav_get_video_metadata(avdec->dec, i)); avdec->current_track->video_streams[i].duration = bgav_video_duration(avdec->dec, i); } for(i = 0; i < avdec->current_track->num_audio_streams; i++) { gavl_audio_format_copy(&(avdec->current_track->audio_streams[i].format), bgav_get_audio_format(avdec->dec, i)); gavl_metadata_copy(&avdec->current_track->audio_streams[i].m, bgav_get_audio_metadata(avdec->dec, i)); avdec->current_track->audio_streams[i].duration = bgav_audio_duration(avdec->dec, i); } for(i = 0; i < avdec->current_track->num_text_streams; i++) { gavl_metadata_copy(&avdec->current_track->text_streams[i].m, bgav_get_text_metadata(avdec->dec, i)); avdec->current_track->text_streams[i].duration = bgav_text_duration(avdec->dec, i); avdec->current_track->text_streams[i].timescale = bgav_get_text_timescale(avdec->dec, i); } for(i = 0; i < avdec->current_track->num_overlay_streams; i++) { gavl_metadata_copy(&avdec->current_track->overlay_streams[i].m, bgav_get_overlay_metadata(avdec->dec, i)); avdec->current_track->overlay_streams[i].duration = bgav_overlay_duration(avdec->dec, i); format = bgav_get_overlay_format(avdec->dec, i); gavl_video_format_copy(&avdec->current_track->overlay_streams[i].format, format); } return 1; }
void *the_thread_opener(void *xp) { ReadMedia *rm = NULL; int num_urls=0, num_tracks=0, audio_stream_count=0, video_stream_count =0; rm = (ReadMedia *)xp; rm->setState(STATE_OPENING); // AFTER WE KILL THE THREADS, THERE IS NO NEED TO LOCK AV mutex // ALL functions that want to get info on the file, seek, // or decode a frame, MUST first check the state. If the // state is STATE_READY, then it can perform it's function, // locking on the necessary variables that might conflict with // the AV. // clearFile deletes old file and creates new File rm->clearFile(); if(!bgav_open(rm->getFile(), rm->getFilename())) { printf( "Could not open file %s\n", rm->getFilename()); rm->setState( STATE_EMPTY ); rm->closeFile(); rm->callOpenCallback(); pthread_exit(NULL); //return NULL; } else { printf("opened %s\n", rm->getFilename()); } // check to see if it is a redirector if(bgav_is_redirector( rm->getFile() )) { num_urls = bgav_redirector_get_num_urls( rm->getFile() ); printf( "Found redirector with %d urls inside, we will try to use the first one.\n", num_urls); printf( "Name %d: %s\n", 1, bgav_redirector_get_name(rm->getFile() , 0)); printf("URL %d: %s\n", 1, bgav_redirector_get_url(rm->getFile(), 0)); sprintf(rm->getFilename(), "%s", bgav_redirector_get_url(rm->getFile(), 0) ); rm->clearFile(); if (!bgav_open( rm->getFile(), rm->getFilename() )) { printf("Could not open redirector\n"); rm->setState( STATE_EMPTY ); rm->closeFile(); rm->callOpenCallback(); pthread_exit(NULL); //return NULL; } else { printf("opened redirector %s\n", rm->getFilename()); } } num_tracks = bgav_num_tracks(rm->getFile()); if ( num_tracks ) { bgav_select_track(rm->getFile(), 0); } else { printf("No tracks associated with file:%s\n", rm->getFilename() ); rm->setState( STATE_EMPTY ); rm->closeFile(); rm->callOpenCallback(); pthread_exit(NULL); } audio_stream_count = bgav_num_audio_streams(rm->getFile(), 0); if( audio_stream_count ) bgav_set_audio_stream(rm->getFile(), 0, BGAV_STREAM_DECODE); video_stream_count = bgav_num_video_streams(rm->getFile(), 0); if( video_stream_count ) bgav_set_video_stream(rm->getFile(), 0, BGAV_STREAM_DECODE); rm->setVideoStreamCount(video_stream_count); rm->setAudioStreamCount(audio_stream_count); //printf("astream_count = %d, vstream_count=%d\n", audio_stream_count, video_stream_count); if(!bgav_start(rm->getFile())) { printf( "failed to start file\n"); rm->setState( STATE_EMPTY ); rm->closeFile(); rm->callOpenCallback(); pthread_exit(NULL) ; //return NULL; } if( !rm->initFormat() ){ rm->setState( STATE_EMPTY ); rm->closeFile(); rm->callOpenCallback(); pthread_exit(NULL) ; } if( !rm->startAVThreads() ){ rm->setState( STATE_EMPTY ); rm->closeFile(); rm->callOpenCallback(); pthread_exit(NULL) ; } // AV threads are now running, blocking will be necessary // STATE_READY and callOpenCallback is set/called in the // fifo fill callbacks rm->signalAV(); rm->signalAV(); //extra signal for second thread pthread_exit(NULL); //return NULL; }