用ffmpeg api开发转码,在过程:拉流–>avfilter分辨率缩放,重采样–>编码–>写出,avpacket.dts和frame.dts在过程中需要根据不同的timebase进行转换。
在 av_read_frame后得到AVPacket packet
AVPacket packet;
int ret_i = av_read_frame(_format_ctx_p, &packet);
需要把网络数据输入的timebase转换成解码codec的timebase。
if(packet.stream_index == FRAME_TYPE_AUDIO) {
av_packet_rescale_ts(&packet,
_format_ctx_p->streams[_audio_index_i]->time_base,//1/1000
_audio_codec_ctx_p->time_base);//1/48000
_output_ptr->output_frame((void*)&packet, _audio_codec_ctx_p);
}
if(packet.stream_index == FRAME_TYPE_VIDEO) {
av_packet_rescale_ts(&packet,
_format_ctx_p->streams[_video_index_i]->time_base,//1/1000
_video_codec_ctx_p->time_base);//1/25
_output_ptr->output_frame((void*)&packet, _video_codec_ctx_p);
}
如果需要解码,也需要转换一下timebase:
new_frame_p->pts = av_rescale_q(new_frame_p->pts, _format_ctx_p->streams[_audio_index_i]->time_base,
_audio_codec_ctx_p->time_base);
......
new_frame_p->pts = av_rescale_q(new_frame_p->pts, _format_ctx_p->streams[_video_index_i]->time_base,
_video_codec_ctx_p->time_base);
注意:_video_codec_ctx_p和_audio_codec_ctx_p是解码的codec:
_audio_stream_p = _format_ctx_p->streams[_audio_index_i];
_audio_codec_ctx_p = _audio_stream_p->codec;
_video_stream_p = _format_ctx_p->streams[_video_index_i];
_video_codec_ctx_p = _video_stream_p->codec;
在写入avfilter:av_buffersrc_add_frame_flags,和读取处理后的数据:av_buffersink_get_frame_flags,之后需要处理一下时间戳timebase转换。
AVRational vfilter_tb = _video_filter_ctx.buffersink_ctx->inputs[0]->timebase;
AVRational afilter_tb = _audio_filter_ctx.buffersink_ctx->inputs[0]->timebase;
......
if (视频)
filtered_frame->pts = av_rescale_q(filtered_frame->pts, vfilter_tb, _vcodec_ctx_p->time_base);
if (音频)
filtered_frame->pts = av_rescale_q(filtered_frame->pts, afilter_tb, _acodec_ctx_p->time_base);
然后在送去编码。
在编码后,把音视频avpacket进行muxing,需要进行timebase的转换:
if(视频)
av_packet_rescale_ts(pkt_p, _vcodec_ctx_p->time_base, standard_ration);
if(音频)
av_packet_rescale_ts(pkt_p, _acodec_ctx_p->time_base, standard_ration);
然后送去muxer写数据.