(一)FFPlay 系統結構及工作機制
(1) 主要線程大致邏輯:
l 主線程
av_register_all();
SDL_CreateThread(read_thread, is);
l 數據讀取線程
static intread_thread(void *arg)
{
………………………………………...........
ic = avformat_alloc_context();
ic->interrupt_callback.callback =decode_interrupt_cb;
ic->interrupt_callback.opaque = is;
err = avformat_open_input(&ic, is->filename, is->iformat,&format_opts);
if (err < 0) {
print_error(is->filename, err);
ret = -1;
goto fail;
}
err =avformat_find_stream_info(ic, opts);
for (i = 0; i < ic->nb_streams; i++)
ic->streams[i]->discard =AVDISCARD_ALL;
/* open the streams */
if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
stream_component_open(is,st_index[AVMEDIA_TYPE_AUDIO]);
}
ret = -1;
if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
}
if (is->show_mode == SHOW_MODE_NONE)
is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
if (st_index[AVMEDIA_TYPE_SUBTITLE] >=0) {
stream_component_open(is,st_index[AVMEDIA_TYPE_SUBTITLE]);
}
for (;;) {
if (is->abort_request)
break;
//start to read data
ret = av_read_frame(ic, pkt);
/*wait until the end */
while(!is->abort_request) {
SDL_Delay(100);
}
ret = 0;
fail:
/* close each stream */
if (is->audio_stream >= 0)
stream_component_close(is,is->audio_stream);
if (is->video_stream >= 0)
stream_component_close(is,is->video_stream);
if (is->subtitle_stream >= 0)
stream_component_close(is,is->subtitle_stream);
if (ic) {
avformat_close_input(&ic);
is->ic = NULL;
}
if (ret != 0) {
SDL_Event event;
event.type = FF_QUIT_EVENT;
event.user.data1 = is;
SDL_PushEvent(&event);
}
SDL_DestroyMutex(wait_mutex);
return 0;
}