打开输入的aac和h264文件,并找到对应的数据流;创建并打开一个输出文件,为该文件创建视频/音频数据流;同时拷贝输入数据流的编码器信息;创建并初始化一个AVIOContext以访问url指示的资源;写入媒体文件的数据头数据。
在各自数据流时间基中比较当前视频帧和音频帧pts的顺序,选取下一帧打包到容器的数据包为音频帧还是视频帧
从对应的输入文件中读取一帧的数据包
若当前数据包pts为非法值
根据帧率计算出该数据包持续时间,并根据输入数据流时间基,换算成输入数据流中的持续时间
根据帧持续时间和帧数计算出当前数据流时间,再根据输入数据流时间基,换算成输入数据流中的时间戳
将pts,dts和duration从输入数据流时间基转换为输出数据流时间基
写入数据包至媒体文件
释放读取的数据包,更新当前视频帧或音频帧pts,重复上述2—6步操作;直至结束后给媒体文件写入文件尾。
C++音视频开发学习资料:点击领取→音视频开发(资料文档+视频教程+面试题)(FFmpeg+WebRTC+RTMP+RTSP+HLS+RTP)
int avformat_alloc_output_context2(AVFormatContext **ctx,
AVOutputFormat *oformat,
const char *format_name,
const char *filename);
ctx:返回创建的AVFormatContext,失败返回NULL。
oformat:用于申请ctx的格式,如果为NULL,则使用format_name和filename。
format_name:用于申请ctx的格式名称,如果为NULL,则使用filename。
filename:用于申请ctx的文件名称,可能为NULL。
返回值:>=0表示成功,否则失败。
avformat_new_stream:增加一路数据流到媒体文件。
AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c);
s:媒体文件句柄。
c:unused, does nothing。
返回值:创建的数据流,为NULL表示失败。
C++音视频开发学习资料:点击领取→音视频开发(资料文档+视频教程+面试题)(FFmpeg+WebRTC+RTMP+RTSP+HLS+RTP)
avcodec_copy_context:将源AVCodecContext的设置复制到目标AVCodecContext。生成的目标编解码器上下文将是未打开的,在使用此AVCodecContext对视频/音频数据进行解码/编码之前,需要调用avcodec_open2。
int avcodec_copy_context(AVCodecContext *dest,
const AVCodecContext *src);
int avio_open(AVIOContext **s, const char *url, int flags);
s:返回指向创建的AVIOContext结构体的指针,NULL表示创建失败。
url:要访问的url。
flags:如何访问url的标志;AVIO_FLAG_READ / AVIO_FLAG_WRITE / AVIO_FLAG_READ_WRITE。
返回值:>=0表示成功,否则失败。
avformat_write_header:申请数据流的私有数据,并将数据流header写入到输出文件
int avformat_write_header(AVFormatContext *s, AVDictionary **options);
s:必须使用 avformat_alloc_context() 分配的媒体文件句柄。它的 oformat 字段必须设置为所需的输出格式;它的 pb 字段必须设置为已打开的 AVIOContext。
options:选项参数。
返回值:AVERROR表示失败。如果编解码器未在avformat_init中初始化,AVSTREAM_INIT_IN_WRITE_HEADER表示成功;已初始化,AVSTREAM_INIT_IN_INIT_OUTPUT表示成功。
av_compare_ts:在各自的时间基中比较时间戳
int av_compare_ts(int64_t ts_a, AVRational tb_a,
int64_t ts_b, AVRational tb_b);
int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt);
int av_write_trailer(AVFormatContext *s);
/* The operation is mathematically equivalent to a * bq / cq */
int64_t av_rescale_q_rnd(int64_t a, AVRational bq, AVRational cq,
enum AVRounding);
enum AVRounding {
AV_ROUND_ZERO = 0, ///趋近于0
AV_ROUND_INF = 1, ///趋远于0
AV_ROUND_DOWN = 2, ///< Round toward -infinity.
AV_ROUND_UP = 3, ///< Round toward +infinity.
AV_ROUND_NEAR_INF = 5, ///四舍五入
AV_ROUND_PASS_MINMAX = 8192, ///< Flag to pass INT64_MIN/MAX through instead of rescaling, this avoids special cases for AV_NOPTS_VALUE
留言与评论(共有 0 条评论) “” |