① ffmpeg是如何转码的
ffmpeg转码的过程如下:
读取输入文件:
- 使用av_read_frame函数从输入文件中读取packet。
- 当av_read_frame返回AVERROR_EOF时,表示输入文件已无packet可读取,此时会传递NULL给后续的解码流程作为flush/drain的指示。
解码过程:
- 将读取到的packet传递给解码器,使用avcodec_send_packet函数。
- 如果avcodec_send_packet在第二次传递size为0的pkt时返回AVERROR_EOF,ffmpeg内部会忽略这一EOF。
- 使用avcodec_receive_frame函数从解码器获取解码后的frame。
- 当avcodec_receive_frame返回AVERROR_EOF时,表示解码器已无frame输出。
处理过滤器链:
- 在过滤器链中处理EOF,通常通过av_buffersink_get_frame_flags返回的EOF来检测。
- 这个EOF通常不会导致输出流的finished状态改变,但会触发编码器的flush操作。
编码过程:
- 将解码后的frame传递给编码器进行编码,编码后的packet会传递给后续的muxer或直接输出。
- 当解码器返回EOF,且后续无frame输入时,会调用send_filter_eof向过滤器链输入NULL,表示过滤器链可能仍有frame缓存。
- 等待过滤器链处理完所有缓存的frame,即avfilter_graph_request_oldest返回AVERROR_EOF,然后调用close_output_stream将ost的finished状态设置为ENCODER_FINISHED。
刷新编码器:
- 执行flush_encoders函数,通过传递NULL包,将编码器剩余的packet全部刷出。
- 这一步是确保所有编码后的数据都被正确处理并输出。
结束转码:
- 当所有输入数据都被处理完毕,且编码器、过滤器链和muxer都完成它们的工作后,ffmpeg会退出转码流程。
在整个转码过程中,ffmpeg会处理各种EOF场景,确保所有数据都被正确读取、解码、处理和编码,最终生成所需的输出文件。