赞
踩
FFmpeg是一个开源,免费,跨平台的视频和音频流方案,它提供了一套完整的录制、转换以及流化音视频的解决方案。而ffplay是有ffmpeg官方提供的一个基于ffmpeg的简单播放器。学习ffplay对于播放器流程、ffmpeg的调用等等是一个非常好的例子。本文就是对ffplay的一个基本的流程剖析,很多细节内容还需要继续钻研。
注:本文师基于ffmpeg-2.0版本进行分析,具体代码行还请对号入座,谢谢!
下图是一个使用“gcc+eygpt+graphviz+手工调整”生成的一个ffplay函数基本调用关系图,其中只保留了视频部分,去除了音频处理、字幕处理以及一些细节处理部分。
注:图中的数字表示了播放中的一次基本调用流程,X?序号表示退出流程。
从上图中我们可以了解到以下几种信息:
下面将对三个线程分别加以详细描述。
从read_thread开始说起而不是从main线程,主要原因是考虑按照视频数据转换的方式比较好理解。
read_thread的创建是在main-->stream_open函数中:
is->read_tid = SDL_CreateThread(read_thread, is); |
read_thread线程主要分为三部分:
主要包括SDL_mutex信号量创建、创建avformat上下文、打开输入文件、解析码流信息、查找音视频数据流并打开对应的数据流。
SDL_mutex *wait_mutex = SDL_CreateMutex(); |
该互斥量主要用于在对(VideoState *)is->continue_read_thread操作时加保护,如2887行和2925行:
//代码段一 /* if the queue are full, no need to read more */ if (infinite_buffer<1 && ……) { /* wait 10 ms */ SDL_LockMutex(wait_mutex); SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10); <-- line 2887 SDL_UnlockMutex(wait_mutex); continue; }
//代码段二 ret = av_read_frame(ic, pkt); if (ret < 0) { if (ret == AVERROR_EOF || url_feof(ic->pb)) eof = 1; if (ic->pb && ic->pb->error) break; SDL_LockMutex(wait_mutex); SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10); <-- line 2925 SDL_UnlockMutex(wait_mutex); continue; } |
而continue_read_thread从其名字上来看,是一个控制read_thread线程是否继续阻塞的信号量,上面两次阻塞的地方分别是:packet队列已满,需要等待一会(即超时10ms)或者收到信号重新循环;读数据失败,但是并不是IO错误(ic->pb->error),如读取网络实时数据时取不到数据,此时也需要等待或者收到信号重新循环。
注:seek操作时(L1216)和音频队列为空(L2327)时,会发送continue_read_thread信号。
(AVFormatContext *)ic = avformat_alloc_context(); |
此处创建的avformat上下文,类似于一个句柄,后续所有avformat相关的函数调用第一个参数都是该上下文指针,如avformat_open_input、avformat_find_stream_info以及一些和av相关的函数接口第一个参数也是该指针,如av_find_best_stream、av_read_frame等等。
err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts); |
创建好avformat上下文后,就打开is->filename指定的文件(或流),其中第三个和第四个参数可以传NULL,由ffmpeg自动侦测待输入流的文件格式,也可以通过is->iformat手动指定,format_opts参数表示设置的特殊属性。
通过调用avformat_open_input函数,我们可以得到输入流的一个基本信息。我们可以通过调用av_dump_format(ic, 0, is->filename, 0);来输出解析后的码流信息,可以得到如下数据:
Input #0, mpegts, from '/home/nfer/bak/cw880-latency.ts':0B f=0/0 Duration: N/A, bitrate: N/A Program 1 Stream #0:0[0x68]:Video:h264 ([27][0][0][0] / 0x001B), 90k tbn Stream |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。