FFmpeg封装格式处理:视音频复用器(muxer)
打算记录一下基于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
-
/**
登入後複製 -
* 最简单的基于FFmpeg的视音频复用器
登入後複製 -
* Simplest FFmpeg Muxer
登入後複製 -
*
登入後複製登入後複製登入後複製登入後複製 -
* 雷霄骅 Lei Xiaohua
登入後複製 -
* leixiaohua1020@126.com
登入後複製 -
* 中国传媒大学/数字电视技术
登入後複製 -
* Communication University of China / Digital TV Technology
登入後複製 -
* http://blog.csdn.net/leixiaohua1020
登入後複製 -
*
登入後複製登入後複製登入後複製登入後複製 -
* 本程序可以将视频码流和音频码流打包到一种封装格式中。
登入後複製 -
* 程序中将MP3编码的音频码流和H.264编码(MPEG2TS封装中)的视频码流打包成
登入後複製 -
* MP4封装格式的文件。
登入後複製 -
* 需要注意的是本程序并不改变视音频的编码格式。
登入後複製 -
*
登入後複製登入後複製登入後複製登入後複製 -
* This software mux a video bitstream and a audio bitstream
登入後複製 -
* together into a file.
登入後複製 -
* In this example, it mux a H.264 bitstream (in MPEG2TS) and
登入後複製 -
* a MP3 bitstream file together into MP4 format file.
登入後複製 -
*
登入後複製登入後複製登入後複製登入後複製 -
*/
登入後複製登入後複製登入後複製 -
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製
-
#include <stdio.h></stdio.h>
登入後複製 -
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製
-
extern "C"
登入後複製 -
{
登入後複製登入後複製 -
#include "libavformat/avformat.h"
登入後複製 -
};
登入後複製 -
/*
登入後複製登入後複製 -
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.
登入後複製 -
*/
登入後複製登入後複製登入後複製 -
//'1': Use H.264 Bitstream Filter
登入後複製 -
#define USE_H264BSF 0
登入後複製 -
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製
-
/*
登入後複製登入後複製 -
FIX:AAC in some container format (FLV, MP4, MKV etc.) need
登入後複製 -
"aac_adtstoasc" bitstream filter (BSF)
登入後複製 -
*/
登入後複製登入後複製登入後複製 -
//'1': Use AAC Bitstream Filter
登入後複製 -
#define USE_AACBSF 0
登入後複製 -
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製
-
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製
-
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製
-
int main(int argc, char* argv[])
登入後複製 -
{
登入後複製登入後複製 -
AVOutputFormat *ofmt = NULL;
登入後複製 -
//输入对应一个AVFormatContext,输出对应一个AVFormatContext
登入後複製 -
//(Input AVFormatContext and Output AVFormatContext)
登入後複製 -
AVFormatContext *ifmt_ctx_v = NULL, *ifmt_ctx_a = NULL,*ofmt_ctx = NULL;
登入後複製 -
AVPacket pkt;
登入後複製 -
int ret, i;
登入後複製 -
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製
-
char *in_filename_v = "cuc_ieschool.ts";//输入文件名(Input file URL)
登入後複製 -
//char *in_filename_v = "cuc_ieschool.h264";
登入後複製 -
//char *in_filename_a = "cuc_ieschool.mp3";
登入後複製 -
//char *in_filename_a = "gowest.m4a";
登入後複製 -
//char *in_filename_a = "gowest.aac";
登入後複製 -
char *in_filename_a = "huoyuanjia.mp3";
登入後複製 -
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製
-
char *out_filename = "cuc_ieschool.mp4";//输出文件名(Output file URL)
登入後複製 -
av_register_all();
登入後複製 -
//输入(Input)
登入後複製 -
if ((ret = avformat_open_input(&ifmt_ctx_v, in_filename_v, 0, 0))
登入後複製 -
printf( "Could not open input file.");
登入後複製登入後複製 -
goto end;
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
}
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
if ((ret = avformat_find_stream_info(ifmt_ctx_v, 0))
登入後複製 -
printf( "Failed to retrieve input stream information");
登入後複製登入後複製 -
goto end;
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
}
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製
-
if ((ret = avformat_open_input(&ifmt_ctx_a, in_filename_a, 0, 0))
登入後複製 -
printf( "Could not open input file.");
登入後複製登入後複製 -
goto end;
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
}
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
if ((ret = avformat_find_stream_info(ifmt_ctx_a, 0))
登入後複製 -
printf( "Failed to retrieve input stream information");
登入後複製登入後複製 -
goto end;
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
}
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
printf("Input Information=====================\n");
登入後複製 -
av_dump_format(ifmt_ctx_v, 0, in_filename_v, 0);
登入後複製 -
av_dump_format(ifmt_ctx_a, 0, in_filename_a, 0);
登入後複製 -
printf("======================================\n");
登入後複製登入後複製 -
//输出(Output)
登入後複製 -
avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, out_filename);
登入後複製 -
if (!ofmt_ctx) {
登入後複製 -
printf( "Could not create output context\n");
登入後複製 -
ret = AVERROR_UNKNOWN;
登入後複製登入後複製登入後複製 -
goto end;
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
}
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
ofmt = ofmt_ctx->oformat;
登入後複製 -
int videoindex_v=-1,videoindex_out=-1;
登入後複製 -
for (i = 0; i nb_streams; i++) {
登入後複製登入後複製 -
//根据输入流创建输出流(Create output AVStream according to input AVStream)
登入後複製登入後複製 -
if(ifmt_ctx_v->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO){
登入後複製 -
videoindex_v=i;
登入後複製 -
AVStream *in_stream = ifmt_ctx_v->streams[i];
登入後複製 -
AVStream *out_stream = avformat_new_stream(ofmt_ctx, in_stream->codec->codec);
登入後複製登入後複製 -
if (!out_stream) {
登入後複製登入後複製 -
printf( "Failed allocating output stream\n");
登入後複製登入後複製 -
ret = AVERROR_UNKNOWN;
登入後複製登入後複製登入後複製 -
goto end;
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
}
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
videoindex_out=out_stream->index;
登入後複製 -
//复制AVCodecContext的设置(Copy the settings of AVCodecContext)
登入後複製登入後複製 -
if (avcodec_copy_context(out_stream->codec, in_stream->codec)
登入後複製登入後複製 -
printf( "Failed to copy context from input to output stream codec context\n");
登入後複製登入後複製 -
goto end;
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
}
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
out_stream->codec->codec_tag = 0;
登入後複製登入後複製 -
if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
登入後複製登入後複製 -
out_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
登入後複製登入後複製 -
break;
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
}
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
}
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製
-
int audioindex_a=-1,audioindex_out=-1;
登入後複製 -
for (i = 0; i nb_streams; i++) {
登入後複製登入後複製 -
//根据输入流创建输出流(Create output AVStream according to input AVStream)
登入後複製登入後複製 -
if(ifmt_ctx_a->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO){
登入後複製 -
audioindex_a=i;
登入後複製 -
AVStream *in_stream = ifmt_ctx_a->streams[i];
登入後複製 -
AVStream *out_stream = avformat_new_stream(ofmt_ctx, in_stream->codec->codec);
登入後複製登入後複製 -
if (!out_stream) {
登入後複製登入後複製 -
printf( "Failed allocating output stream\n");
登入後複製登入後複製 -
ret = AVERROR_UNKNOWN;
登入後複製登入後複製登入後複製 -
goto end;
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
}
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
audioindex_out=out_stream->index;
登入後複製 -
//复制AVCodecContext的设置(Copy the settings of AVCodecContext)
登入後複製登入後複製 -
if (avcodec_copy_context(out_stream->codec, in_stream->codec)
登入後複製登入後複製 -
printf( "Failed to copy context from input to output stream codec context\n");
登入後複製登入後複製 -
goto end;
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
}
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
out_stream->codec->codec_tag = 0;
登入後複製登入後複製 -
if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
登入後複製登入後複製 -
out_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
登入後複製登入後複製 -
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製
-
break;
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
}
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
}
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製
-
//输出一下格式------------------
登入後複製 -
printf("Output Information====================\n");
登入後複製 -
av_dump_format(ofmt_ctx, 0, out_filename, 1);
登入後複製 -
printf("======================================\n");
登入後複製登入後複製 -
//打开输出文件(Open output file)
登入後複製 -
if (!(ofmt->flags & AVFMT_NOFILE)) {
登入後複製 -
if (avio_open(&ofmt_ctx->pb, out_filename, AVIO_FLAG_WRITE)
登入後複製 -
printf( "Could not open output file '%s'", out_filename);
登入後複製 -
goto end;
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
}
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
}
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
//写文件头(Write file header)
登入後複製 -
if (avformat_write_header(ofmt_ctx, NULL)
登入後複製 -
printf( "Error occurred when opening output file\n");
登入後複製 -
goto end;
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
}
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
int frame_index=0;
登入後複製 -
int64_t cur_pts_v=0,cur_pts_a=0;
登入後複製 -
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製
-
//FIX
登入後複製登入後複製 -
#if USE_H264BSF
登入後複製登入後複製登入後複製 -
AVBitStreamFilterContext* h264bsfc = av_bitstream_filter_init("h264_mp4toannexb");
登入後複製 -
#endif
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
#if USE_AACBSF
登入後複製登入後複製登入後複製 -
AVBitStreamFilterContext* aacbsfc = av_bitstream_filter_init("aac_adtstoasc");
登入後複製 -
#endif
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製
-
while (1) {
登入後複製 -
AVFormatContext *ifmt_ctx;
登入後複製 -
int stream_index=0;
登入後複製 -
AVStream *in_stream, *out_stream;
登入後複製 -
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製
-
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製
-
//获取一个AVPacket(Get an AVPacket)
登入後複製 -
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)
登入後複製 -
ifmt_ctx=ifmt_ctx_v;
登入後複製 -
stream_index=videoindex_out;
登入後複製 -
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製
-
if(av_read_frame(ifmt_ctx, &pkt) >= 0){
登入後複製登入後複製 -
do{
登入後複製登入後複製 -
if(pkt.stream_index==videoindex_v){
登入後複製 -
cur_pts_v=pkt.pts;
登入後複製 -
break;
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
}
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
}while(av_read_frame(ifmt_ctx, &pkt) >= 0);
登入後複製登入後複製 -
}else{
登入後複製登入後複製登入後複製 -
break;
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
}
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
}else{
登入後複製登入後複製登入後複製 -
ifmt_ctx=ifmt_ctx_a;
登入後複製 -
stream_index=audioindex_out;
登入後複製 -
if(av_read_frame(ifmt_ctx, &pkt) >= 0){
登入後複製登入後複製 -
do{
登入後複製登入後複製 -
if(pkt.stream_index==audioindex_a){
登入後複製 -
cur_pts_a=pkt.pts;
登入後複製 -
break;
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
}
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
}while(av_read_frame(ifmt_ctx, &pkt) >= 0);
登入後複製登入後複製 -
}else{
登入後複製登入後複製登入後複製 -
break;
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
}
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製
-
}
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製
-
in_stream = ifmt_ctx->streams[pkt.stream_index];
登入後複製 -
out_stream = ofmt_ctx->streams[stream_index];
登入後複製 -
//FIX
登入後複製登入後複製 -
#if USE_H264BSF
登入後複製登入後複製登入後複製 -
av_bitstream_filter_filter(h264bsfc, in_stream->codec, NULL, &pkt.data, &pkt.size, pkt.data, pkt.size, 0);
登入後複製 -
#endif
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
#if USE_AACBSF
登入後複製登入後複製登入後複製 -
av_bitstream_filter_filter(aacbsfc, in_stream->codec, NULL, &pkt.data, &pkt.size, pkt.data, pkt.size, 0);
登入後複製 -
#endif
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
//FIX:No PTS (Example: Raw H.264)
登入後複製 -
//Simple Write PTS
登入後複製 -
if(pkt.pts==AV_NOPTS_VALUE){
登入後複製 -
//Write PTS
登入後複製 -
AVRational time_base1=in_stream->time_base;
登入後複製 -
//Duration between 2 frames (us)
登入後複製 -
int64_t calc_duration=(double)AV_TIME_BASE/av_q2d(in_stream->r_frame_rate);
登入後複製 -
//Parameters
登入後複製 -
pkt.pts=(double)(frame_index*calc_duration)/(double)(av_q2d(time_base1)*AV_TIME_BASE);
登入後複製 -
pkt.dts=pkt.pts;
登入後複製 -
pkt.duration=(double)calc_duration/(double)(av_q2d(time_base1)*AV_TIME_BASE);
登入後複製 -
frame_index++;
登入後複製 -
}
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
/* copy packet */
登入後複製 -
//转换PTS/DTS(Convert PTS/DTS)
登入後複製 -
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));
登入後複製 -
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));
登入後複製 -
pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);
登入後複製 -
pkt.pos = -1;
登入後複製 -
pkt.stream_index=stream_index;
登入後複製 -
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製
-
printf("Write 1 Packet. size:%5d\tpts:%8d\n",pkt.size,pkt.pts);
登入後複製 -
//写入(Write)
登入後複製 -
if (av_interleaved_write_frame(ofmt_ctx, &pkt)
登入後複製 -
printf( "Error muxing packet\n");
登入後複製 -
break;
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
}
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
av_free_packet(&pkt);
登入後複製 -
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製
-
}
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
//写文件尾(Write file trailer)
登入後複製 -
av_write_trailer(ofmt_ctx);
登入後複製 -
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製
-
#if USE_H264BSF
登入後複製登入後複製登入後複製 -
av_bitstream_filter_close(h264bsfc);
登入後複製 -
#endif
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
#if USE_AACBSF
登入後複製登入後複製登入後複製 -
av_bitstream_filter_close(aacbsfc);
登入後複製 -
#endif
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製
-
end:
登入後複製 -
avformat_close_input(&ifmt_ctx_v);
登入後複製 -
avformat_close_input(&ifmt_ctx_a);
登入後複製 -
/* close output */
登入後複製 -
if (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE))
登入後複製 -
avio_close(ofmt_ctx->pb);
登入後複製 -
avformat_free_context(ofmt_ctx);
登入後複製 -
if (ret
登入後複製 -
printf( "Error occurred.\n");
登入後複製 -
return -1;
登入後複製 -
}
登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製 -
return 0;
登入後複製

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

在Win11電腦上聽音樂或看電影,如果揚聲器或耳機聽起來不平衡,用戶可以根據自己的需求手動調整平衡等級。那我們要如何調整呢?針對這個問題,小編帶來了詳細的操作教學,希望可以幫助大家。如何在Windows11中平衡左右音訊通道?方法一:使用「設定」套用點擊鍵並點選設定。 Windows按一下系統,然後選擇聲音。選擇更多聲音設定。按一下您的揚聲器/耳機,然後選擇屬性。導航至“等級”選項卡,然後按一下“餘額”。確保“左”和

從我記事開始,家裡就有一對落地式的大尺寸音響,讓我一直認為電視只有配上一套完整的音響系統才能稱得上是電視。但是剛開始工作的時候,我買不起專業的家庭音響。經過查詢、了解產品定位後,我發現回音壁這個品類非常適合我,不論是音質、體積或價格都符合我的需求。因此,我決定選擇回音壁。精挑細選後,我選了2024年初Bose推出了這款全景聲回音壁產品:Bose家庭娛樂揚聲器Ultra。 (圖片來源:雷科技攝製)一般來說,想要體驗到「原汁原味」的杜比全景聲效果,需要我們在家中佈置一套經過測量、校準的環繞聲+天花板

1.首先我們右鍵點選任務列空白處,選擇【任務管理器】選項,或右鍵開始徽標,然後再選擇【任務管理器】選項。 2.在開啟的任務管理器介面,我們點選最右邊的【服務】選項卡。 3.在開啟的【服務】選項卡,點選下方的【開啟服務】選項。 4.在開啟的【服務】窗口,右鍵點選【InternetConnectionSharing(ICS)】服務,然後選擇【屬性】選項。 5.在開啟的屬性窗口,將【開啟方式】修改為【禁用】,點選【應用程式】後點選【確定】。 6.點選開始徽標,然後點選關機按鈕,選擇【重啟】,完成電腦重啟就行了。

QQ信箱:QQ號@qq.com,英文QQ信箱:英文或數字@qq.com,foxmail信箱帳號:自行設定帳號@foxmail.com,手機信箱帳號:手機號碼@qq.com。教學適用型號:iPhone13系統:IOS15.3版本:QQ信箱6.3.3解析1QQ信箱有四種格式,常用的QQ信箱:QQ號@qq.com,英文QQ信箱:英文或數位@qq.com,foxmail信箱帳號:自己設定帳號@foxmail.com,手機信箱帳號:手機號碼@qq.com。補充:qq信箱是什麼1最早的QQ信箱還只是QQ使用者之間

在PHP開發過程中,處理特殊字元是常見的問題,尤其是在字串處理中經常會遇到特殊字元轉義的情況。其中,將特殊字元轉換單引號是比較常見的需求,因為在PHP中,單引號是一種常用的字串包裹方式。在本文中,我們將介紹如何在PHP中處理特殊字元轉換單引號,並提供具體的程式碼範例。在PHP中,特殊字元包括但不限於單引號(')、雙引號(")、反斜線()等。在字串

本站4月17日消息,集邦諮詢(TrendForce)近日發布報告,認為英偉達Blackwell新平台產品需求看漲,預估帶動台積電2024年CoWoS封裝總產能提升逾150%。英偉達Blackwell新平台產品包含B系列的GPU,以及整合英偉達自家GraceArmCPU的GB200加速卡等。集邦諮詢確認為供應鏈目前非常看好GB200,預估2025年出貨量預計超過百萬片,在英偉達高階GPU中的佔比達到40-50%。在英偉達計畫下半年交付GB200以及B100等產品,但上游晶圓封裝方面須進一步採用更複

如果您在Windows11/10PC上遇到RealtekHD音訊驅動程式失敗錯誤代碼0x00005b3,請參考下列步驟以解決問題。我們將指導您進行故障排除並解決該錯誤。錯誤代碼0x00005b3可能是由於音訊驅動程式的安裝問題導致的。可能是目前的驅動程式損壞或部分卸載,從而影響新驅動程式的安裝。此問題也可能由磁碟空間不足或與Windows版本不相容的音訊驅動程式引起。安裝RealtekHD音訊驅動程式失敗! ! [錯誤代碼:0x00005B3]如果Realtek音訊驅動程式安裝精靈出現問題,請繼續閱讀

本站7月9日訊息,AMDZen5架構「Strix」系列處理器會有兩種封裝方案,其中較小的StrixPoint將採用FP8封裝,而StrixHalo將會採用FP11封裝。圖源:videocardz訊息源@Olrak29_最新曝料稱StrixHalo的FP11封裝尺寸為37.5mm*45mm(1687平方毫米),和英特爾AlderLake、RaptorLakeCPU的LGA-1700封裝尺寸相同。 AMD最新的PhoenixAPU採用FP8封裝方案,尺寸為25*40mm,這意味著StrixHalo的F
