最简单的基于FFMPEG的封装格式转换器(无编解码) 中代码在FFmpeg 4.0环境中编译出现问题,查了一下网络,原来FFmpeg代码中就由remux的例子,就是doc/examples/remuxing.c
我执行mp4(H264、AAC)转mpegts跟踪了一下H264 SPS/PPS数据传递过程:
avcC读堆栈
0 mov_read_glbl libavformat/mov.c:1902
1 mov_read_default libavformat/mov.c:6837
2 ff_mov_read_stsd_entries libavformat/mov.c:2518
3 mov_read_stsd libavformat/mov.c:2583
4 mov_read_default libavformat/mov.c:6837
5 mov_read_default libavformat/mov.c:6837
6 mov_read_default libavformat/mov.c:6837
7 mov_read_default libavformat/mov.c:6837
8 mov_read_trak libavformat/mov.c:4165
9 mov_read_default libavformat/mov.c:6837
10 mov_read_moov libavformat/mov.c:1148
11 mov_read_default libavformat/mov.c:6837
12 mov_read_header libavformat/mov.c:7377
13 avformat_open_input libavformat/utils.c:631
14 main doc/examples/remuxing.c:70
SPS/PPS 被读取到 st->codecpar->extradata;其中st = c->fc->streams[c->fc->nb_streams-1],c是MOVContext *,而c->fc就是remuxing.c 中的AVFormatContext *ifmt_ctx。
然后 在remuxing.c中,avcodec_parameters_copy(out_stream->codecpar, in_codecpar);将SPS/PPS传递到ofmt_ctx
h264_extradata_to_annexb调研堆栈
0 h264_extradata_to_annexb libavcodec/h264_mp4toannexb_bsf.c:78
1 h264_mp4toannexb_init libavcodec/h264_mp4toannexb_bsf.c:154
2 av_bsf_init libavcodec/bsf.c:167
3 ff_stream_add_bitstream_filter libavformat/utils.c:5553
4 mpegts_check_bitstream libavformat/mpegtsenc.c:1859
5 do_packet_auto_bsf libavformat/mux.c:844
6 av_interleaved_write_frame libavformat/mux.c:1196
7 main doc/examples/remuxing.c:167
ff_stream_add_bitstream_filter 中
avcodec_parameters_copy(bsfc->par_in, in_par) 将 SPS/PPS 由 st = ofmt_ctx->streams[pkt->stream_index](do_packet_auto_bsf) 传递到 AVBSFContext *bsfc
av_dynarray_add_nofree(&st->internal->bsfcs, &st->internal->nb_bsfcs, bsfc) 将 bsfc 关联到 ofmt_ctx。
h264_extradata_to_annexb 中
SPS/PPS 添加 0x00000001 前缀 存储到 ctx->par_out->extradata 中,AVBSFContext *ctx 就是上面的 bsfc
h264_mp4toannexb_filter调用堆栈
0 h264_mp4toannexb_filter libavcodec/h264_mp4toannexb_bsf.c:184
1 av_bsf_receive_packet libavcodec/bsf.c:213
2 do_packet_auto_bsf libavformat/mux.c:864
3 av_interleaved_write_frame libavformat/mux.c:1196
4 main doc/examples/remuxing.c:167
h264_mp4toannexb_filter 中
alloc_and_copy(out, ctx->par_out->extradata, ctx->par_out->extradata_size, buf, nal_size, 1)
SPS/PPS 被添加到I帧前面输出到TS流。