ffmpeg实例muxer/demuxer小结

来源:互联网 发布:3d室内设计软件 编辑:程序博客网 时间:2024/04/30 07:12

参考雷老师: 

音视频分离demuxer简化版,里面详细描述了SPS/PPS的操作: http://blog.csdn.net/leixiaohua1020/article/details/39767055

音视频流分离demuxer:   http://blog.csdn.net/leixiaohua1020/article/details/39802819

音视频流复用muxer:          http://blog.csdn.net/leixiaohua1020/article/details/39802913


一 音视频分离需要注意

》纯音频分离:pkt写入文件的话,单独解码播放,需要增加adts信息(音频stream/pkt 都需要为解码器增加额外的包头参数信息),

ADTS AAC
ADTS_headerAAC ESADTS_headerAAC ES
...
ADTS_headerAAC ES

ADTS参考: http://blog.csdn.net/tx3344/article/details/7414543

》纯视频分离:pkt写入文件的话,单独解码播放,需要增加pps,sps信息(视频stream/pkt 都需要为解码器增加额外的包头参数信息),

  SDP中的H.264的SPS和PPS串,包含了初始化H.264解码器所需要的信息参数,包括编码所用的profile,level,图像的宽和高,deblock滤波器等。

  SPS和PPS信息存储在AVCodecContext结构体的extradata中。需要使用ffmpeg中名称为“h264_mp4toannexb”的bitstream filter处理。流的第一NALU是SPS->PPS->IDR

  SPS/PPS介绍参考:http://www.rosoo.net/a/201110/15236.html

                                      http://blog.csdn.net/sunnylgz/article/details/7680262

 SPS/PPS ffmpeg操作: http://blog.csdn.net/leixiaohua1020/article/details/39767055

》1分2,解码器上下文复制API挺有用avcodec_copy_context

》muxer/demuxer基本上就是基于pkt进行操作而非frame。

》获取文件中某路流的解码和格式信息API挺好用:

获取文件视频流pcodeCtx,pfmtCtx指针。

    /* select the video stream */      ret = av_find_best_stream(pFormatCtx, AVMEDIA_TYPE_VIDEO, -1, -1, &dec, 0);      if (ret < 0) {          printf( "Cannot find a video stream in the input file\n");          return ret;      }      video_stream_index = ret;      pCodecCtx = pFormatCtx->streams[video_stream_index]->codec;        /* init the video decoder */      if ((ret = avcodec_open2(pCodecCtx, dec, NULL)) < 0) {          printf( "Cannot open video decoder\n");          return ret;      }  


二 音视频分离简化版小结

    mkv分离出mp3,h264

音视频文件分离出单独的音,视频文件:直接用av_read_frame读取包,根据stream_index写入fwrite到对应文件;其中视频加入了pps/sps 通过API:av_bitstream_filter_filter,可以单独播放;mp3文件没有加ADTS应该是播放不了的,以后下下雷老师代码调测下。


三 音视频分离小结

mkv分离出mp3,h264

整体思路是通过打开muxer文件,获取codecCtx后,复制2份-->avio_open创建2个mp3,h264文件--》创建2个stream,avformat_new_stream()---》判断av_read_frame后的pkt进行交叉文件写入av_interleaved_write_frame(ofmt_ctx),这里简洁的技巧是,写入前,ofmt_ctx根据ofmt_ctx_v/ofmt_ctx_a动态更新参数。完成1 mkv >分2,stream mp3/h24 >合1 write_frame的流程。

avformat_open_input():打开输入文件。

avcodec_copy_context():赋值AVCodecContext的参数。

avformat_alloc_output_context2():初始化输出文件。

avio_open():打开输出文件。

avformat_write_header():写入文件头。

av_read_frame():从输入文件读取一个AVPacket。

av_interleaved_write_frame():写入一个AVPacket到输出文件。

av_write_trailer():写入文件尾。


  

四  音视频复用小结

mp3,h264合并成mkv,

参考三,针对PKT操作,用的API差不多,特别的API有

int av_compare_ts ( int64_t  ts_a, AVRational  tb_a, int64_t  ts_b, AVRational  tb_b   )

针对其返回值比较当前a,v的timestamp是否大于小于0;来读取本次audio pkt或者video pkt;

整体思路是,

打开2输入文件--》获取pFmtCtx,pCodecCtx 

--》新建2路流avformat_new_stream --》 写ofmtCtx文件头

--》循环开始:根据av_compare_ts读pkt 

--》av_bitstream_filter_filter(h264bsfc/aacbsfc,xx),音视频同步后

--》av_interleaved_write_frame,循环结束

--》av_write_trailer(ofmt_ctx);  



0 1
原创粉丝点击