FFmpeg常规处理流程

python ffmpeg转换速度 ffmpeg转码效率_时间戳


大流程可以划分为输入、输出、转码、播放四大块。其中转码涉及比较多的处理环节,从图中可以看出,转码功能在整个功能图中占比很大。转码的核心功能在解码和编码两个部分,但在一个可用程序中,编码解码与输入输出是难以分割的。解复用器为解码器提供输入,解码器会输出原始帧,对原始帧可进行各种复杂的滤镜处理,滤镜处理后的帧经编码器生成编码帧,多路流的编码帧经复用器输出到输出文件。

转码过程中的时间戳处理

在封装格式处理中,不深入理解时间戳也没有关系。但在编解码处理中,时间戳处理是很重要的一个细节,必须要搞清楚。

容器(文件层)中的时间基(AVStream.time_base)与编解码器上下文(视频层)里的时间基(AVCodecContex.time_base)不一样,解码编码过程中需要进行时间基转换。

视频按帧进行播放,所以原始视频帧时间基为 1/framerate。视频解码前需要处理输入 AVPacket 中各时间参数,将输入容器中的时间基转换为 1/framerate 时间基;视频编码后再处理输出 AVPacket 中各时间参数,将 1/framerate 时间基转换为输出容器中的时间基。

音频按采样点进行播放,所以原始音频帧时间为 1/sample_rate。音频解码前需要处理输入 AVPacket 中各时间参数,将输入容器中的时间基转换为 1/sample_rate 时间基;音频编码后再处理输出 AVPacket 中各时间参数,将 1/sample_rate 时间基转换为输出容器中的时间基。如果引入音频 FIFO,从 FIFO 从读出的音频帧时间戳信息会丢失,需要使用 1/sample_rate 时间基重新为每一个音频帧生成 pts,然后再送入编码器。

解码前的时间基转换:

av_packet_rescale_ts(ipacket, sctx->i_stream->time_base, sctx->o_codec_ctx->time_base);

编码后的时间基转换:

av_packet_rescale_ts(&opacket, sctx->o_codec_ctx->time_base, sctx->o_stream->time_base);