文章插图
本文还是着重分析数据读取线程 。还是先上ffplay"藏宝图" 。
文章插图
从ffplay框架分析我们可以看到,ffplay有专?的线程read_thread()读取数据,且在调?av_read_frame读取数据包之前需要做例如打开?件,查找配置解码器,初始化?视频输出等准备阶段,主要包括三?步骤:
(1)初始化?作
avformat_alloc_context:创建上下? 。
ic->interrupt_callback.callback = decode_interrupt_cb; 设置超时时间回调 。
avformat_open_input:打开媒体文件,包括网络流,文件,内存流 。
avformat_find_stream_info:读取媒体?件的包获取更多的stream信息 。
avformat_seek_file:检测是否指定播放起始时间,如果指定时间则seek到指定位置 。
查找查找AVStream,将对应的index值记录到st_index[AVMEDIA_TYPE_NB],有如下2种方案 。
a.avformat_match_stream_specifier:根据?户指定来查找流 。
b.av_find_best_stream:使用这个接口查找流 。
从待处理流中获取相关参数,设置显示窗?的宽度、?度及宽?? 。
stream_component_open:打开?频、视频、字幕解码器,并创建相应的解码线程以及进?对应输出参数的初始化 。
(2)For循环读取数据
检测是否退出 。
检测是否暂停/继续 。
【超详细解析FFplay之数据读取线程】检测是否需要seek 。
检测video是否为attached_pic 。
检测队列是否已经有?够数据 。
检测码流是否已经播放结束 。
是否循环播放 。
是否?动退出 。
使?av_read_frame读取数据包 。
检测数据是否读取完毕 。
检测是否在播放范围内 。
到这步才将数据插?对应的队列 。
(3)退出线程处理
如果解复?器有打开则关闭avformat_close_input 。
调?SDL_PushEvent发送退出事件FF_QUIT_EVENT 。
释放互斥量wait_mutex 。
具体准备工作,调用了如下函数:
调?avformat_alloc_context创建解复?器上下? 。
// 1. 创建上下?结构体,这个结构体是最上层的结构体,表示输?上下?ic = avformat_alloc_context();
最终该ic 赋值给VideoState的ic变量 。// videoState的ic指向分配的icis->ic = ic;
ic->interrupt_callback
/* .设置中断回调函数,如果出错或者退出,就根据?前程序设置的状态选择继续check或者直接退出 。当执?耗时操作时(?般是在执?while或者for循环的数据读取时),会调?interrupt_ callback.callback.回调函数中返回1则代表ffmpeg结束耗时操作退出当前函数的调? 。回调函数中返回0则代表ffmpeg内部继续执?耗时操作,直到完成既定的任务(?如读取到既定 的数据包) 。*/ic->interrupt_callback.callback = decode_interrupt_cb;ic->interrupt_callback.opaque = is;
interrupt_callback?于ffmpeg内部在执?耗时操作时,检查调?者是否有退出请求,避免?户退出请求,而没有及时响应 。可以在ubuntu环境下,通过gdb ./ffplay_g来播放视频,然后在decode_interrupt_cb打断点 。
从调用栈关系看,这个回调函数的触发是在avformat_open_input这个节点,正真的触发是在retry_transfer_wrApper函数ff_check_interrupt 。
调用栈如下,顺序应该是从下到上:
decode_interrupt_cb 。
ff_check_interrupt 。
retry_transfer_wrapper 。
ffurl_read 。
read_packet_wrapper 。
fill_buffer 。
avio_read 。
av_probe_input_buffer2 。
init_input 。
avformat_open_input 。
#0 decode_interrupt_cb (ctx=0x7ffff7e36040) at fftools/ffplay.c:271 5#1 0x00000000007d99b7 in ff_check_interrupt (cb=0x7fffd00014b0) at libavformat/avio.c:667 #2 retry_transfer_wrapper (transfer_func=0x7dd950 <file_read>, size _min=1, 5 size=32768, buf=0x7fffd0001700 "", h=0x7fffd0001480) at libavformat/avio.c:374 #3 ffurl_read (h=0x7fffd0001480, buf=0x7fffd0001700 "", size=32768)at libavformat/avio.c:411#4 0x000000000068cd9c in read_packet_wrapper (size=<optimized out>, 10 buf=<optimized out>, s=0x7fffd00011c0) at libavformat/aviobuf.c: 535#5 fill_buffer (s=0x7fffd00011c0) at libavformat/aviobuf.c:584#6 avio_read (s=s@entry=0x7fffd00011c0, buf=0x7fffd0009710 "",size=size@entry=2048) at libavformat/aviobuf.c:677#7 0x00000000006b7780 in av_probe_input_buffer2 (pb=0x7fffd00011c0, 15 fmt=0x7fffd0000948,filename=filename@entry=0x31d50e0 "source.200kbps.768x320.flv",#logctx=logctx@entry=0x7fffd0000940, offset=offset@entry=0, 18 max_probe_size=1048576) at libavformat/format.c:262#8 0x00000000007b631d in init_input (options=0x7fffdd9bcb50, 20 filename=0x31d50e0 "source.200kbps.768x320.flv", s=0x7fffd000094 0)#at libavformat/utils.c:443#9 avformat_open_input (ps=ps@entry=0x7fffdd9bcbf8, 23 filename=0x31d50e0 "source.200kbps.768x320.flv", fmt=<optimized out>,
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 海盐奶茶做法,奶茶的详细做法
- 苏州园林的特点解析
- 关于住宅风水朝向解析
- 电动车电池寿命探究与解析
- 孕囊超过23厘米药流会怎样
- 青岛市|好找工作但对口率超低?汉语言文学专业到底是什么样的呢?
- HttpClient三个超时时间详解
- 负载均衡解析与Nginx实战
- 康熙王朝人物关系结构 康熙王朝人物解析
- 央视|今年以来线下的空调、洗衣机、冰箱都变贵了 央视:均价涨超10%