烦
2023/03/23阅读:17主题:橙心
ffmpag 相关基础API 入门
ffmpag 相关基础API 入门
FFmpeg基本组成模块FFmpeg框架的基本组成包含AVFormat、AVCodec、AVFilter、AVDevice、AVUtil等模块库。
以我目前理解总结,有容器format、流stream、编码器codec、上下文contex、 数据包packet。
AVFormatContext 非常重要,重中之重。使用ffmpeg少不了AVFormatContext,可以简单认为是容器,容器又有输入和输出容器。


获取AVFormatContext的函数有
int avformat_open_input(AVFormatContext **ps, const char *url,
const AVInputFormat *fmt, AVDictionary **options);
/**
* 打开一个输入流并读取头部。 编解码器未打开。
* 必须使用 avformat_close_input() 关闭流。
*
* @param ps 指向用户提供的 AVFormatContext 的指针(由 avformat_alloc_context 分配)。
* 可能是一个指向 NULL 的指针,在这种情况下,一个 AVFormatContext 由这个分配
*函数并写入ps。
* 请注意,用户提供的 AVFormatContext 将在失败时被释放。
* @param url 要打开的流的 URL。
* @param fmt 如果非空,这个参数强制一个特定的输入格式。
* 否则会自动检测格式。
* @param options 一个充满 AVFormatContext 和 demuxer-private 选项的字典。
* 返回时,此参数将被销毁并替换为包含
* 未找到的选项。 可以为 NULL。
*
* @return 0 成功,负 AVERROR 失败。
*
* @note 如果要使用自定义 IO,请预分配格式上下文并设置其 pb 字段。
*/
int avformat_alloc_output_context2(AVFormatContext **ctx, const AVOutputFormat *oformat,
const char *format_name, const char *filename);
/* 为输出格式分配一个 AVFormatContext。
* avformat_free_context() 可用于释放上下文和
* 由其中的框架分配的所有内容。
*
* @param *ctx设置为创建的格式上下文,或者设置为 NULL
* 失败案例
* @param oformat 用于分配上下文的格式,如果为 NULL
* 改为使用格式名称和文件名
* @param format_name 用于分配的输出格式的名称
* 上下文,如果使用 NULL 文件名代替
* @param filename 用于分配的文件名
* 上下文,可能为 NULL
* @return >= 0 在成功的情况下,负的 AVERROR 代码在成功的情况下
* 失败
*/
以传入参数来获取AVFormatContext。以上两个的主要区别,在于输入和输出,avformat_open_input,打开一个文件,初始化AVFormatContex里的AVInputFormat ,avformat_alloc_output_context2初始化AVOutputFormat ,输出文件。
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options),寻找音视频流信息,通常用于一些没有头信息的封装格式,例如 MPEG。

AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c);创建数据流,可以是音频流或音视频流。

const AVCodec *avcodec_find_encoder(enum AVCodecID id);根据编码类型,找到编码器。

fmt->video_codec 视频编码器类型如下:

fmt->audio_codec 音频编码类型如下:

AVCodecContext *avcodec_alloc_context3(const AVCodec *codec); 申请编码器上下文,设置编码参数;传编码器,返回上下文。

int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options);打开编码器

int avcodec_parameters_from_context(AVCodecParameters *par,const AVCodecContext *codec);
将配置编码器参数的上下文拷贝到,容器中音视频流的上下文。

void av_dump_format(AVFormatContext *ic,int index,const char *url,int is_output);打印媒体流的相关信息。

int avio_open(AVIOContext **s, const char *url, int flags);正式打开avio,初始化音视频IO。

int avformat_write_header(AVFormatContext *s, AVDictionary **options); 写入音视频头部;要特别注意 avformat_write_header
这个函数,必须是容器里面的所有流都初始化完成了,才能调 avformat_write_header
。

打开输入文件时,需要avformat_alloc_context() ,申请存储空间;
int av_find_best_stream(AVFormatContext *ic,
enum AVMediaType type,
int wanted_stream_nb,/ -1 自动给分配/
int related_stream,
AVCodec **decoder_ret,
int flags); 获取流的的索引值

申请AVPacket,av_packet_alloc();
int av_read_frame(AVFormatContext *s, AVPacket *pkt); 获取音视频码流数据,pkt指向存储数据的位置,根据pkt的索引值找到对应的音视频码流。就是流的索引值。

int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b);音视频时间戳比较。用于音视频同步。

int av_buffer_realloc(AVBufferRef **buf, size_t size); 为buf分配内存空间。

void av_packet_rescale_ts(AVPacket *pkt, AVRational tb_src, AVRational tb_dst); 时间戳转换;

int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt); 把 AVPacket
写入输出文件

作者介绍