打算记录一下基于FFmpeg的封装格式处理方面的例子。包括了视音频分离,复用,封装格式转换。这是第3篇。 本文记录一个基于FFmpeg的视音频复用器(Simplest FFmpeg muxer)。视音频复用器(Muxer)即是将视频压缩数据(例如H.264)和音频压缩数据(例如AAC)合
打算记录一下基于FFmpeg的封装格式处理方面的例子。包括了视音频分离,复用,封装格式转换。这是第3篇。
本文记录一个基于FFmpeg的视音频复用器(Simplest FFmpeg muxer)。视音频复用器(Muxer)即是将视频压缩数据(例如H.264)和音频压缩数据(例如AAC)合并到一个封装格式数据(例如MKV)中去。如图所示。在这个过程中并不涉及到编码和解码。
本文记录的程序将一个H.264编码的视频码流文件和一个MP3编码的音频码流文件,合成为一个MP4封装格式的文件。
,一共初始化了3个AVFormatContext,其中2个用于输入,1个用于输出。3个AVFormatContext初始化之后,通过avcodec_copy_context()函数可以将输入视频/音频的参数拷贝至输出视频/音频的AVCodecContext结构体。然后分别调用视频输入流和音频输入流的av_read_frame(),从视频输入流中取出视频的AVPacket,音频输入流中取出音频的AVPacket,分别将取出的AVPacket写入到输出文件中即可。其间用到了一个不太常见的函数av_compare_ts(),是比较时间戳用的。通过该函数可以决定该写入视频还是音频。
本文介绍的视音频复用器,输入的视频不一定是H.264裸流文件,音频也不一定是纯音频文件。可以选择两个封装过的视音频文件作为输入。程序会从视频输入文件中“挑”出视频流,音频输入文件中“挑”出音频流,再将“挑选”出来的视音频流复用起来。 PS1:对于某些封装格式(例如MP4/FLV/MKV等)中的H.264,需要用到名称为“h264_mp4toannexb”的bitstream filter。
PS2:对于某些封装格式(例如MP4/FLV/MKV等)中的AAC,需要用到名称为“aac_adtstoasc”的bitstream filter。
简单介绍一下流程中各个重要函数的意义:
avformat_open_input():打开输入文件。
avcodec_copy_context():赋值AVCodecContext的参数。
avformat_alloc_output_context2():初始化输出文件。
avio_open():打开输出文件。
avformat_write_header():写入文件头。
av_compare_ts():比较时间戳,决定写入视频还是写入音频。这个函数相对要少见一些。
av_read_frame():从输入文件读取一个AVPacket。
av_interleaved_write_frame():写入一个AVPacket到输出文件。
av_write_trailer():写入文件尾。
代码
下面贴上代码:
<strong>[cpp]</strong> view plaincopy
Salin selepas log masuk
-
/**
Salin selepas log masuk
-
* 最简单的基于FFmpeg的视音频复用器
Salin selepas log masuk
-
* Simplest FFmpeg Muxer
Salin selepas log masuk
-
-
* 雷霄骅 Lei Xiaohua
Salin selepas log masuk
-
* leixiaohua1020@126.com
Salin selepas log masuk
-
* 中国传媒大学/数字电视技术
Salin selepas log masuk
-
* Communication University of China / Digital TV Technology
Salin selepas log masuk
-
* http://blog.csdn.net/leixiaohua1020
Salin selepas log masuk
-
-
* 本程序可以将视频码流和音频码流打包到一种封装格式中。
Salin selepas log masuk
-
* 程序中将MP3编码的音频码流和H.264编码(MPEG2TS封装中)的视频码流打包成
Salin selepas log masuk
-
* MP4封装格式的文件。
Salin selepas log masuk
-
* 需要注意的是本程序并不改变视音频的编码格式。
Salin selepas log masuk
-
-
* This software mux a video bitstream and a audio bitstream
Salin selepas log masuk
-
* together into a file.
Salin selepas log masuk
-
* In this example, it mux a H.264 bitstream (in MPEG2TS) and
Salin selepas log masuk
-
* a MP3 bitstream file together into MP4 format file.
Salin selepas log masuk
-
-
*/
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
-
#include <stdio.h></stdio.h>
Salin selepas log masuk
-
-
extern "C"
Salin selepas log masuk
-
-
#include "libavformat/avformat.h"
Salin selepas log masuk
-
};
Salin selepas log masuk
-
/*
Salin selepas log masuk
Salin selepas log masuk
-
FIX: H.264 in some container format (FLV, MP4, MKV etc.) need
Salin selepas log masuk
-
"h264_mp4toannexb" bitstream filter (BSF)
Salin selepas log masuk
-
*Add SPS,PPS in front of IDR frame
Salin selepas log masuk
-
*Add start code ("0,0,0,1") in front of NALU
Salin selepas log masuk
-
H.264 in some container (MPEG2TS) don't need this BSF.
Salin selepas log masuk
-
*/
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
//'1': Use H.264 Bitstream Filter
Salin selepas log masuk
-
#define USE_H264BSF 0
Salin selepas log masuk
-
-
/*
Salin selepas log masuk
Salin selepas log masuk
-
FIX:AAC in some container format (FLV, MP4, MKV etc.) need
Salin selepas log masuk
-
"aac_adtstoasc" bitstream filter (BSF)
Salin selepas log masuk
-
*/
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
//'1': Use AAC Bitstream Filter
Salin selepas log masuk
-
#define USE_AACBSF 0
Salin selepas log masuk
-
-
-
-
int main(int argc, char* argv[])
Salin selepas log masuk
-
-
AVOutputFormat *ofmt = NULL;
Salin selepas log masuk
-
//输入对应一个AVFormatContext,输出对应一个AVFormatContext
Salin selepas log masuk
-
//(Input AVFormatContext and Output AVFormatContext)
Salin selepas log masuk
-
AVFormatContext *ifmt_ctx_v = NULL, *ifmt_ctx_a = NULL,*ofmt_ctx = NULL;
Salin selepas log masuk
-
AVPacket pkt;
Salin selepas log masuk
-
int ret, i;
Salin selepas log masuk
-
-
char *in_filename_v = "cuc_ieschool.ts";//输入文件名(Input file URL)
Salin selepas log masuk
-
//char *in_filename_v = "cuc_ieschool.h264";
Salin selepas log masuk
-
//char *in_filename_a = "cuc_ieschool.mp3";
Salin selepas log masuk
-
//char *in_filename_a = "gowest.m4a";
Salin selepas log masuk
-
//char *in_filename_a = "gowest.aac";
Salin selepas log masuk
-
char *in_filename_a = "huoyuanjia.mp3";
Salin selepas log masuk
-
-
char *out_filename = "cuc_ieschool.mp4";//输出文件名(Output file URL)
Salin selepas log masuk
-
av_register_all();
Salin selepas log masuk
-
//输入(Input)
Salin selepas log masuk
-
if ((ret = avformat_open_input(&ifmt_ctx_v, in_filename_v, 0, 0))
Salin selepas log masuk
-
printf( "Could not open input file.");
Salin selepas log masuk
Salin selepas log masuk
-
goto end;
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
-
if ((ret = avformat_find_stream_info(ifmt_ctx_v, 0))
Salin selepas log masuk
-
printf( "Failed to retrieve input stream information");
Salin selepas log masuk
Salin selepas log masuk
-
goto end;
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
-
-
if ((ret = avformat_open_input(&ifmt_ctx_a, in_filename_a, 0, 0))
Salin selepas log masuk
-
printf( "Could not open input file.");
Salin selepas log masuk
Salin selepas log masuk
-
goto end;
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
-
if ((ret = avformat_find_stream_info(ifmt_ctx_a, 0))
Salin selepas log masuk
-
printf( "Failed to retrieve input stream information");
Salin selepas log masuk
Salin selepas log masuk
-
goto end;
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
-
printf("Input Information=====================\n");
Salin selepas log masuk
-
av_dump_format(ifmt_ctx_v, 0, in_filename_v, 0);
Salin selepas log masuk
-
av_dump_format(ifmt_ctx_a, 0, in_filename_a, 0);
Salin selepas log masuk
-
printf("======================================\n");
Salin selepas log masuk
Salin selepas log masuk
-
//输出(Output)
Salin selepas log masuk
-
avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, out_filename);
Salin selepas log masuk
-
if (!ofmt_ctx) {
Salin selepas log masuk
-
printf( "Could not create output context\n");
Salin selepas log masuk
-
ret = AVERROR_UNKNOWN;
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
goto end;
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
-
ofmt = ofmt_ctx->oformat;
Salin selepas log masuk
-
int videoindex_v=-1,videoindex_out=-1;
Salin selepas log masuk
-
for (i = 0; i nb_streams; i++) {
Salin selepas log masuk
Salin selepas log masuk
-
//根据输入流创建输出流(Create output AVStream according to input AVStream)
Salin selepas log masuk
Salin selepas log masuk
-
if(ifmt_ctx_v->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO){
Salin selepas log masuk
-
videoindex_v=i;
Salin selepas log masuk
-
AVStream *in_stream = ifmt_ctx_v->streams[i];
Salin selepas log masuk
-
AVStream *out_stream = avformat_new_stream(ofmt_ctx, in_stream->codec->codec);
Salin selepas log masuk
Salin selepas log masuk
-
if (!out_stream) {
Salin selepas log masuk
Salin selepas log masuk
-
printf( "Failed allocating output stream\n");
Salin selepas log masuk
Salin selepas log masuk
-
ret = AVERROR_UNKNOWN;
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
goto end;
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
-
videoindex_out=out_stream->index;
Salin selepas log masuk
-
//复制AVCodecContext的设置(Copy the settings of AVCodecContext)
Salin selepas log masuk
Salin selepas log masuk
-
if (avcodec_copy_context(out_stream->codec, in_stream->codec)
Salin selepas log masuk
Salin selepas log masuk
-
printf( "Failed to copy context from input to output stream codec context\n");
Salin selepas log masuk
Salin selepas log masuk
-
goto end;
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
-
out_stream->codec->codec_tag = 0;
Salin selepas log masuk
Salin selepas log masuk
-
if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
Salin selepas log masuk
Salin selepas log masuk
-
out_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
Salin selepas log masuk
Salin selepas log masuk
-
break;
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
-
-
-
int audioindex_a=-1,audioindex_out=-1;
Salin selepas log masuk
-
for (i = 0; i nb_streams; i++) {
Salin selepas log masuk
Salin selepas log masuk
-
//根据输入流创建输出流(Create output AVStream according to input AVStream)
Salin selepas log masuk
Salin selepas log masuk
-
if(ifmt_ctx_a->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO){
Salin selepas log masuk
-
audioindex_a=i;
Salin selepas log masuk
-
AVStream *in_stream = ifmt_ctx_a->streams[i];
Salin selepas log masuk
-
AVStream *out_stream = avformat_new_stream(ofmt_ctx, in_stream->codec->codec);
Salin selepas log masuk
Salin selepas log masuk
-
if (!out_stream) {
Salin selepas log masuk
Salin selepas log masuk
-
printf( "Failed allocating output stream\n");
Salin selepas log masuk
Salin selepas log masuk
-
ret = AVERROR_UNKNOWN;
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
goto end;
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
-
audioindex_out=out_stream->index;
Salin selepas log masuk
-
//复制AVCodecContext的设置(Copy the settings of AVCodecContext)
Salin selepas log masuk
Salin selepas log masuk
-
if (avcodec_copy_context(out_stream->codec, in_stream->codec)
Salin selepas log masuk
Salin selepas log masuk
-
printf( "Failed to copy context from input to output stream codec context\n");
Salin selepas log masuk
Salin selepas log masuk
-
goto end;
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
-
out_stream->codec->codec_tag = 0;
Salin selepas log masuk
Salin selepas log masuk
-
if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
Salin selepas log masuk
Salin selepas log masuk
-
out_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
Salin selepas log masuk
Salin selepas log masuk
-
-
break;
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
-
-
-
//输出一下格式------------------
Salin selepas log masuk
-
printf("Output Information====================\n");
Salin selepas log masuk
-
av_dump_format(ofmt_ctx, 0, out_filename, 1);
Salin selepas log masuk
-
printf("======================================\n");
Salin selepas log masuk
Salin selepas log masuk
-
//打开输出文件(Open output file)
Salin selepas log masuk
-
if (!(ofmt->flags & AVFMT_NOFILE)) {
Salin selepas log masuk
-
if (avio_open(&ofmt_ctx->pb, out_filename, AVIO_FLAG_WRITE)
Salin selepas log masuk
-
printf( "Could not open output file '%s'", out_filename);
Salin selepas log masuk
-
goto end;
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
-
-
//写文件头(Write file header)
Salin selepas log masuk
-
if (avformat_write_header(ofmt_ctx, NULL)
Salin selepas log masuk
-
printf( "Error occurred when opening output file\n");
Salin selepas log masuk
-
goto end;
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
-
int frame_index=0;
Salin selepas log masuk
-
int64_t cur_pts_v=0,cur_pts_a=0;
Salin selepas log masuk
-
-
//FIX
Salin selepas log masuk
Salin selepas log masuk
-
#if USE_H264BSF
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
AVBitStreamFilterContext* h264bsfc = av_bitstream_filter_init("h264_mp4toannexb");
Salin selepas log masuk
-
#endif
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
#if USE_AACBSF
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
AVBitStreamFilterContext* aacbsfc = av_bitstream_filter_init("aac_adtstoasc");
Salin selepas log masuk
-
#endif
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
-
while (1) {
Salin selepas log masuk
-
AVFormatContext *ifmt_ctx;
Salin selepas log masuk
-
int stream_index=0;
Salin selepas log masuk
-
AVStream *in_stream, *out_stream;
Salin selepas log masuk
-
-
-
//获取一个AVPacket(Get an AVPacket)
Salin selepas log masuk
-
if(av_compare_ts(cur_pts_v,ifmt_ctx_v->streams[videoindex_v]->time_base,cur_pts_a,ifmt_ctx_a->streams[audioindex_a]->time_base)
Salin selepas log masuk
-
ifmt_ctx=ifmt_ctx_v;
Salin selepas log masuk
-
stream_index=videoindex_out;
Salin selepas log masuk
-
-
if(av_read_frame(ifmt_ctx, &pkt) >= 0){
Salin selepas log masuk
Salin selepas log masuk
-
do{
Salin selepas log masuk
Salin selepas log masuk
-
if(pkt.stream_index==videoindex_v){
Salin selepas log masuk
-
cur_pts_v=pkt.pts;
Salin selepas log masuk
-
break;
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
-
}while(av_read_frame(ifmt_ctx, &pkt) >= 0);
Salin selepas log masuk
Salin selepas log masuk
-
}else{
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
break;
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
-
}else{
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
ifmt_ctx=ifmt_ctx_a;
Salin selepas log masuk
-
stream_index=audioindex_out;
Salin selepas log masuk
-
if(av_read_frame(ifmt_ctx, &pkt) >= 0){
Salin selepas log masuk
Salin selepas log masuk
-
do{
Salin selepas log masuk
Salin selepas log masuk
-
if(pkt.stream_index==audioindex_a){
Salin selepas log masuk
-
cur_pts_a=pkt.pts;
Salin selepas log masuk
-
break;
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
-
}while(av_read_frame(ifmt_ctx, &pkt) >= 0);
Salin selepas log masuk
Salin selepas log masuk
-
}else{
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
break;
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
-
-
-
-
in_stream = ifmt_ctx->streams[pkt.stream_index];
Salin selepas log masuk
-
out_stream = ofmt_ctx->streams[stream_index];
Salin selepas log masuk
-
//FIX
Salin selepas log masuk
Salin selepas log masuk
-
#if USE_H264BSF
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
av_bitstream_filter_filter(h264bsfc, in_stream->codec, NULL, &pkt.data, &pkt.size, pkt.data, pkt.size, 0);
Salin selepas log masuk
-
#endif
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
#if USE_AACBSF
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
av_bitstream_filter_filter(aacbsfc, in_stream->codec, NULL, &pkt.data, &pkt.size, pkt.data, pkt.size, 0);
Salin selepas log masuk
-
#endif
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
//FIX:No PTS (Example: Raw H.264)
Salin selepas log masuk
-
//Simple Write PTS
Salin selepas log masuk
-
if(pkt.pts==AV_NOPTS_VALUE){
Salin selepas log masuk
-
//Write PTS
Salin selepas log masuk
-
AVRational time_base1=in_stream->time_base;
Salin selepas log masuk
-
//Duration between 2 frames (us)
Salin selepas log masuk
-
int64_t calc_duration=(double)AV_TIME_BASE/av_q2d(in_stream->r_frame_rate);
Salin selepas log masuk
-
//Parameters
Salin selepas log masuk
-
pkt.pts=(double)(frame_index*calc_duration)/(double)(av_q2d(time_base1)*AV_TIME_BASE);
Salin selepas log masuk
-
pkt.dts=pkt.pts;
Salin selepas log masuk
-
pkt.duration=(double)calc_duration/(double)(av_q2d(time_base1)*AV_TIME_BASE);
Salin selepas log masuk
-
frame_index++;
Salin selepas log masuk
-
-
/* copy packet */
Salin selepas log masuk
-
//转换PTS/DTS(Convert PTS/DTS)
Salin selepas log masuk
-
pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
Salin selepas log masuk
-
pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
Salin selepas log masuk
-
pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);
Salin selepas log masuk
-
pkt.pos = -1;
Salin selepas log masuk
-
pkt.stream_index=stream_index;
Salin selepas log masuk
-
-
printf("Write 1 Packet. size:%5d\tpts:%8d\n",pkt.size,pkt.pts);
Salin selepas log masuk
-
//写入(Write)
Salin selepas log masuk
-
if (av_interleaved_write_frame(ofmt_ctx, &pkt)
Salin selepas log masuk
-
printf( "Error muxing packet\n");
Salin selepas log masuk
-
break;
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
-
av_free_packet(&pkt);
Salin selepas log masuk
-
-
-
//写文件尾(Write file trailer)
Salin selepas log masuk
-
av_write_trailer(ofmt_ctx);
Salin selepas log masuk
-
-
#if USE_H264BSF
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
av_bitstream_filter_close(h264bsfc);
Salin selepas log masuk
-
#endif
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
#if USE_AACBSF
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
av_bitstream_filter_close(aacbsfc);
Salin selepas log masuk
-
#endif
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
-
-
end:
Salin selepas log masuk
-
avformat_close_input(&ifmt_ctx_v);
Salin selepas log masuk
-
avformat_close_input(&ifmt_ctx_a);
Salin selepas log masuk
-
/* close output */
Salin selepas log masuk
-
if (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE))
Salin selepas log masuk
-
avio_close(ofmt_ctx->pb);
Salin selepas log masuk
-
avformat_free_context(ofmt_ctx);
Salin selepas log masuk
-
if (ret
Salin selepas log masuk
-
printf( "Error occurred.\n");
Salin selepas log masuk
-
return -1;
Salin selepas log masuk
-
-
return 0;
Salin selepas log masuk