ffmpeg 的 Mux 主要分为 三步操作:
avformat_write_header : 写文件头
av_write_frame/av_interleaved_write_frame: 写packet
av_write_trailer : 写文件尾
本文主要分析 av_write_trailer 。
<span style="font-size:14px;">int av_write_trailer(AVFormatContext *s)
{
int ret, i;
for (;; ) {
AVPacket pkt;
ret = interleave_packet(s, &pkt, NULL, 1);
if (ret < 0)
goto fail;
if (!ret)
break;
ret = write_packet(s, &pkt);
if (ret >= 0)
s->streams[pkt.stream_index]->nb_frames++;
av_packet_unref(&pkt);
if (ret < 0)
goto fail;
if(s->pb && s->pb->error)
goto fail;
}
if (!s->internal->header_written) {
ret = s->internal->write_header_ret ? s->internal->write_header_ret : write_header_internal(s);
if (ret < 0)
goto fail;
}
fail:
if (s->internal->header_written && s->oformat->write_trailer) {
if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb)
avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_TRAILER);
if (ret >= 0) {
ret = s->oformat->write_trailer(s);
} else {
s->oformat->write_trailer(s);
}
}
if (s->oformat->deinit)
s->oformat->deinit(s);
if (s->pb)
avio_flush(s->pb);
if (ret == 0)
ret = s->pb ? s->pb->error : 0;
for (i = 0; i < s->nb_streams; i++) {
av_freep(&s->streams[i]->priv_data);
av_freep(&s->streams[i]->index_entries);
}
if (s->oformat->priv_class)
av_opt_free(s->priv_data);
av_freep(&s->priv_data);
return ret;
}</span>
额外参考 : http://blog.csdn.net/leixiaohua1020/article/details/44201645