以转码音频为例,在fffmpeg.c里,大循环是:
while(1){
transcode_step{
process_input //解码
reap_filters //编码
}
flush_encoders //输入文件读取完毕后,输出编码器中剩余的AVPacket。
/* 打印统计信息 */
print_report(1, timer_start, av_gettime_relative());
}
读取解码前的数据
if (debug_ts) {
av_log(NULL, AV_LOG_INFO, "demuxer -> ist_index:%d type:%s"
"next_dts:%snext_dts_time:%s next_pts:%s next_pts_time:%s pkt_pts:%s pkt_pts_time:%spkt_dts:%s pkt_dts_time:%s off:%s off_time:%s\n",
ifile->ist_index +pkt.stream_index, av_get_media_type_string(ist->dec_ctx->codec_type),
av_ts2str(ist->next_dts),av_ts2timestr(ist->next_dts, &AV_TIME_BASE_Q),
av_ts2str(ist->next_pts),av_ts2timestr(ist->next_pts, &AV_TIME_BASE_Q),
av_ts2str(pkt.pts),av_ts2timestr(pkt.pts, &ist->st->time_base),
av_ts2str(pkt.dts),av_ts2timestr(pkt.dts, &ist->st->time_base),
av_ts2str(input_files[ist->file_index]->ts_offset),
av_ts2timestr(input_files[ist->file_index]->ts_offset,&AV_TIME_BASE_Q));
}
demuxer -> ist_index:0 type:audionext_dts:46439 next_dts_time:0.046439 next_pts:46439 next_pts_time:0.046439pkt_pts:1310720 pkt_pts_time:0.0464399 pkt_dts:1310720 pkt_dts_time:0.0464399off:0 off_time:0
//修改包信息
if (debug_ts) {
av_log(NULL, AV_LOG_INFO, "demuxer+ffmpeg -> ist_index:%dtype:%s pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s off:%soff_time:%s\n",
ifile->ist_index +pkt.stream_index, av_get_media_type_string(ist->dec_ctx->codec_type),
av_ts2str(pkt.pts),av_ts2timestr(pkt.pts, &ist->st->time_base),
av_ts2str(pkt.dts),av_ts2timestr(pkt.dts, &ist->st->time_base),
av_ts2str(input_files[ist->file_index]->ts_offset),
av_ts2timestr(input_files[ist->file_index]->ts_offset,&AV_TIME_BASE_Q));
}
demuxer+ffmpeg -> ist_index:0 type:audiopkt_pts:1310720 pkt_pts_time:0.0464399 pkt_dts:1310720 pkt_dts_time:0.0464399off:0 off_time:0
//进行来做解码
//reap_filters用来处理解码后的数据
reap_filters{
//读取一帧解码后的数据。
static void do_audio_out(AVFormatContext*s, OutputStream *ost, AVFrame *frame){
if(debug_ts) {
av_log(NULL, AV_LOG_INFO, "encoder <- type:audio "
"frame_pts:%sframe_pts_time:%s time_base:%d/%d\n",
av_ts2str(frame->pts),av_ts2timestr(frame->pts, &enc->time_base),
enc->time_base.num,enc->time_base.den);
}
//例子:encoder <-type:audio frame_pts:2048 frame_pts_time:0.0464399 time_base:1/44100
if (avcodec_encode_audio2(enc, &pkt, frame, &got_packet) < 0){
av_log(NULL, AV_LOG_FATAL, "Audio encoding failed(avcodec_encode_audio2)\n");
exit_program(1);
}
update_benchmark("encode_audio %d.%d", ost->file_index,ost->index);
if (got_packet) {
//修改帧信息
av_packet_rescale_ts(&pkt, enc->time_base,ost->st->time_base);
if (debug_ts) {
av_log(NULL, AV_LOG_INFO, "encoder -> type:audio "
"pkt_pts:%spkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s\n",
av_ts2str(pkt.pts),av_ts2timestr(pkt.pts, &ost->st->time_base),
av_ts2str(pkt.dts),av_ts2timestr(pkt.dts, &ost->st->time_base));
}
//例子为:encoder ->type:audio pkt_pts:0 pkt_pts_time:0 pkt_dts:0 pkt_dts_time:0
//写入容器
write_frame(s, &pkt, ost); {
if (debug_ts) {
av_log(NULL, AV_LOG_INFO, "muxer <- type:%s "
"pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s size:%d\n",
av_get_media_type_string(ost->enc_ctx->codec_type),
av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &ost->st->time_base),
av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &ost->st->time_base),
pkt->size
);
}
}
} //if (got_packet)
}//do_audio_out
} //reap_filters
static void flush_encoders(void)
{
。。。
//进行循环
for (;;) {
AVPacket pkt;
int pkt_size;
int got_packet;
av_init_packet(&pkt);
pkt.data = NULL;
pkt.size = 0;
update_benchmark(NULL);
ret = encode(enc, &pkt, NULL, &got_packet);
//当got_packet为1时,也就是获得输出包,写入文件;当got_packet为0时,也就是获取不到输出包,退出循环。
。。。
}
}
//打印统计信息
print_report{
。。。
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
"%02d:%02d:%02d.%02d ", hours, mins, secs, (100 * us) / AV_TIME_BASE);
//此处可以看出(100*us/AV_TIME_BASE是取整的,比如us等与5333,结果就为0。
。。。
av_log(NULL, AV_LOG_VERBOSE, "%"PRIu64" packets muxed (%"PRIu64" bytes); ",
ost->packets_written, ost->data_size);
。。。
}
问题:
如上图,音频共94个包,但是复用的是95个包,这会导致音频时长稍有变化。