ffplay的流程:
1、seek_flag为seek_by_bytes时,按照估计的pos执行avio_seek到位置。
2、read_thread这个读输入的线程开始av_read_frame,读取pkt。然后把pkt执行packet_queeu_put操作放入is->videoq和is->audioq等。
3、同时还有audio_thread video_thread等进行解码的线程。
video_thread调用decoder_decode_frame来解码视频帧。先从d->queue中取pkt,调用packet_queue_get函数得到pkt,然后将pkt数据输入到avcodec_decode_video2中进行解码。调用decode函数将输入的pkt解码成picture。
4、H264_decode_frame:
其中decode_nal_units,parse pkt得到nal,分别进行解码。
output_frame(h, pict, h->next_output_pic);进行输出。
但是output_frame在h->next_output_pic不为NULL且h->next_output_pic->recovered不为0的情况下才会执行。
Decode_nal_units之后h->next_output_pic不为NULL。
另外一个条件h->next_output_pic->recovered依赖于h->frame_recovered.
而h->frame_recovered变量在一开始h264_init_context中初始化为0.
Seek之后flush(ff_h264_flush_change)操作也会把fram_recovered置为0。
遇到NAL_IDR_SLICE才会改变frame_recovered为1。
因此直到解码完一个I帧之后才会开始output_frame。
总结下来:
H264 ts文件seek之后,从seek的位置开始读取pkt进行解码,但是直到解码到I帧才会开始输出。
以上过程用的FFmpeg代码版本是3.2.