视音频复用器:从输入文件中挑出需要的视频/音频流,再合并放到一个文件中
不同封装格式中的数据存放方式不同,其差异需要一个av_bitstream_filter_filter(AVBitStreamFilterContext.....)进行转换
PS1:mp4(没有bsf)->annexb(有bsf)的转换需要用到名称为“h264_mp4toannexb”的bitstream filter。
【效果:1、Add SPS,PPS in front of IDR frame
2、Add start code ("0,0,0,1") in front of NALU】
PS2:对于某些封装格式(例如MP4/FLV/MKV等)中的AAC,需要用到名称为“aac_adtstoasc”的bitstream filter。
【应该某些编解码器只认toannexb,不认mp4格式】
/*
FIX: H.264 in some container format (FLV, MP4, MKV etc.) need
"h264_mp4toannexb" bitstream filter (BSF)
*Add SPS,PPS in front of IDR frame
*Add start code ("0,0,0,1") in front of NALU
H.264 in some container (MPEG2TS) don't need this BSF.
*/
/**
* 本程序可以将视频码流和音频码流打包到一种封装格式中。
* 程序中将AAC编码的音频码流和H.264编码的视频码流打包成MPEG2TS封装格式的文件。
* 需要注意的是本程序并不改变视音频的编码格式。 不涉及编解码 输入输出使用的是相同的编解码上下文
*/
#include <stdio.h>
#include <libavformat/avformat.h>
#define USE_H264BSF 0 //'1': Use H.264 Bitstream Filter
#define USE_AACBSF 0 //'1': Use AAC Bitstream Filter
int main(int argc, char* argv[])
{
AVFormatContext *ifmt_ctx_v = NULL, *ifmt_ctx_a = NULL,*ofmt_ctx = NULL;
AVPacket pkt;
int ret, i;
int videoindex_v=-1,videoindex_out=-1;
int audioindex_a=-1,audioindex_out=-1;
int frame_index=0;
int64_t cur_pts_v=0,cur_pts_a=0;
const char *in_filename_v = "cuc_ieschool.h264"; //itput file URL
const char *in_filename_a = "huoyuanjia.mp3"; //itput file URL
const char *out_filename = "cuc_ieschool.mp4"; //Output file URL
av_register_all();
//Input
avformat_open_input(&ifmt_ctx_v, in_filename_v, 0, 0)
avformat_find_stream_info(ifmt_ctx_v, 0)
avformat_open_input(&ifmt_ctx_a, in_filename_a, 0, 0)
avformat_find_stream_info(ifmt_ctx_a, 0)
//Output
avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, out_filename);
AVOutputFormat *ofmt = ofmt_ctx->oformat;
//Create output AVStream according to input AVStream
for (i = 0; i < ifmt_ctx_v->nb_streams; i++) {
if(ifmt_ctx_v->streams[i]->codec