ffmpeg函数、结构体介绍

1 avcodec_init()函数

void avcodec_init(void);

初始化libavcodec,一般最先调用该函数 引入头文件: #include “libavcodec/avcodec.h”;实现在:
\ffmpeg\libavcodec\utils.c
该函数必须在调用libavcodec里的其它函数前调用,一般在程序启动或模块初始化时调用,如果你调用了多次也无所谓,因为后面的调用不会做任何事情.从函数的实现里你可以发现,代码中对多次调用进行了控制。该函数是非线程安全的

2 av_register_all()函数

void av_register_all(void);

初始化 libavformat和注册所有的muxers、demuxers和protocols,
一般在调用avcodec_init后调用该方法
引入头文件:#include “libavformat/avformat.h”;实现在:\ffmpeg\libavformat\allformats.c
其中会调用avcodec_register_all()注册多种音视频格式的编解码器,并注册各种文件的编解复用器,当然,你也可以不调用该函数,而通过选择调用特定的方法来提供支持。

3 avformat_alloc_context()函数

AVFormatContext *avformat_alloc_context(void);

分配一个AVFormatContext结构
引入头文件:#include “libavformat/avformat.h”
实现在:\ffmpeg\libavformat\options.c
其中负责申请一个AVFormatContext结构的内存,并进行简单初始化
avformat_free_context()可以用来释放该结构里的所有东西以及该结构本身
也是就说使用 avformat_alloc_context()分配的结构,需要使用avformat_free_context()来释放
有些版本中函数名可能为: av_alloc_format_context();

4 avformat_free_context()函数

void avformat_free_context(AVFormatContext *s);

释放一个AVFormatContext结构
引入头文件:#include “libavformat/avformat.h”
实现在:\ffmpeg\libavformat\utils.c
使用 avformat_alloc_context()分配的结构,采用该函数进行释放,除释放AVFormatContext结构本身内存之外,AVFormatContext中指针所指向的内存也会一并释放
有些版本中函数名猜测可能为: av_free_format_context();

5 AVFormatContext 结构体

typedef struct AVFormatContext {
    struct AVInputFormat *iformat;
    struct AVOutputFormat *oformat;
    AVIOContext *pb;
    unsigned int nb_streams;
    AVStream **streams;
    char filename[1024]; /**< input or output filename */
    ....
} AVFormatContext;

AVFormatContext在FFMpeg里是一个非常重要的的结构,是其它输入、输出相关信息的一个容器
引入头文件:#include “libavformat/avformat.h”
以上只列出了其中的部分成员
作为输入容器时 struct AVInputFormat *iformat; 不能为空, 其中包含了输入文件的音视频流信息,程序从输入容器从读出音视频包进行解码处理
作为输出容器时 struct AVOutputFormat *oformat; 不能为空, 程序把编码好的音视频包写入到输出容器中
AVIOContext *pb: I/O上下文,通过对该变量赋值可以改变输入源或输出目的
unsigned int nb_streams; 音视频流数量
AVStream **streams; 音视频流

6 AVIOContext 结构体

ypedef struct {
    unsigned char *buffer;  /**< Start of the buffer. */
    int buffer_size;        /**< Maximum buffer size */
    unsigned char *buf_ptr; /**< Current position in the buffer */
    unsigned char *buf_end; /**< End of the data, may be less than
                                 buffer+buffer_size if the read function returned
                                 less data than requested, e.g. for streams where
                                 no more data has been received yet. */
    void *opaque;           /**< A private pointer, passed to the read/write/seek/...
                                 functions. */
    int (*read_packet)(void *opaque, uint8_t *buf,int buf_size);
    int (*write_packet)(void *opaque, uint8_t *buf,int buf_size);
    int64_t (*seek)(void *opaque, int64_t offset,int whence);
    int64_t pos;            /**< position in the file of the current buffer */
    int must_flush;         /**< true if the next seek should flush */
    int eof_reached;        /**< true if eof reached */
    int write_flag;         /**< true if open for writing */
#if FF_API_OLD_AVIO
    attribute_deprecated int is_streamed;
#endif
    int max_packet_size;
    unsigned long checksum;
    unsigned char *checksum_ptr;
    unsigned long (*update_checksum)(unsigned long checksum, const uint8_t *buf, unsigned int size);
    int error;              /**< contains the error code or 0 if no error happened */
    /**
     * Pause or resume playback for network streaming protocols - e.g. MMS.
     */
    int (*read_pause)(void *opaque,int pause);
    int64_t (*read_seek)(void *opaque,int stream_index,
                         int64_t timestamp, int flags);
    /**
     * A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.
     */
    int seekable;
} AVIOContext;

字节流 I/O 上下文
在结构的尾部增加变量可以减少版本冲突
移除、排序和修改已经存在的变量将会导致较大的版本冲突
sizeof(AVIOContext)在libav*.外部不可使用
AVIOContext里的函数指针不能直接调用,通常使用avio_alloc_context()函数来设置其中的函数指针
unsigned char *buffer: 缓存的起始指针
int buffer_size: 缓存的最大值
void *opaque: 在回调函数中使用的指针
int (*read_packet)(void *opaque, uint8_t *buf,int buf_size): 读文件回调方法
int (*write_packet)(void *opaque, uint8_t *buf,int buf_size): 写文件回调方法
int64_t (*seek)(void *opaque, int64_t offset,int whence): seek文件回调方法

7 avio_alloc_context()函数

//函数原型
AVIOContext *avio_alloc_context(
                  unsigned char *buffer,
                  int buffer_size,
                  int write_flag,
                  void *opaque,
                  int (*read_packet)(void *opaque, uint8_t *buf,int buf_size),
                  int (*write_packet)(void *opaque, uint8_t *buf,int buf_size),
                  int64_t (*seek)(void *opaque, int64_t offset,int whence));

为I/0缓存申请并初始化一个AVIOContext结构,结束使用时必须使用av_free()进行释放
unsigned char *buffer: 输入/输出缓存内存块,必须是使用av_malloc()分配的
int buffer_size: 缓存大小是非常重要的
int write_flag: 如果缓存为可写则设置为1,否则设置为0
void *opaque: 指针,用于回调时使用
int (*read_packet): 读包函数指针
int (*write_packet): 写包函数指针
int64_t (*seek): seek文件函数指针

8 av_open_input_file()函数

//函数原型
attribute_deprecated int av_open_input_file(
					   AVFormatContext **ic_ptr,
					   constchar *filename,
                       AVInputFormat *fmt,
                       int buf_size,
                       AVFormatParameters *ap);

以输入方式打开一个媒体文件,也即源文件,codecs并没有打开,只读取了文件的头信息.
引入头文件:#include “libavformat/avformat.h”
AVFormatContext **ic_ptr 输入文件容器
constchar *filename 输入文件名,全路径,并且保证文件存在
AVInputFormat *fmt 输入文件格式,填NULL即可
int buf_size,缓冲区大小,直接填0即可
AVFormatParameters *ap, 格式参数,添NULL即可
成功返回0,其它失败
不赞成使用 avformat_open_input 代替

9 av_close_input_file()函数

void av_close_input_file(AVFormatContext *s);

关闭使用avformat_close_input()打开的输入文件容器,但并不关系它的codecs
引入头文件:#include “libavformat/avformat.h”
使用av_open_input_file 打开的文件容器,可以使用该函数关闭
使用 av_close_input_file 关闭后,就不再需要使用avformat_free_context 进行释放了

10 av_find_stream_info()函数

int av_find_stream_info(AVFormatContext *ic);

通过读取媒体文件的中的包来获取媒体文件中的流信息,对于没有头信息的文件如(mpeg)是非常有用的,
该函数通常重算类似mpeg-2帧模式的真实帧率,该函数并未改变逻辑文件的position.
引入头文件:#include “libavformat/avformat.h”
也就是把媒体文件中的音视频流等信息读出来,保存在容器中,以便解码时使用
返回>=0时成功,否则失败

11 avcodec_find_decoder()函数

AVCodec *avcodec_find_decoder(enum CodecID id);

通过code ID查找一个已经注册的音视频解码器
引入 #include “libavcodec/avcodec.h”
实现在: \ffmpeg\libavcodec\utils.c
查找解码器之前,必须先调用av_register_all注册所有支持的解码器
查找成功返回解码器指针,否则返回NULL
音视频解码器保存在一个链表中,查找过程中,函数从头到尾遍历链表,通过比较解码器的ID来查找

12 avcodec_find_decoder_by_name()函数

AVCodec *avcodec_find_decoder_by_name(constchar *name);

通过一个指定的名称查找一个已经注册的音视频解码器
引入 #include “libavcodec/avcodec.h”
实现在: \ffmpeg\libavcodec\utils.c
查找解码器之前,必须先调用av_register_all注册所有支持的解码器
查找成功返回解码器指针,否则返回NULL
音视频解码器保存在一个链表中,查找过程中,函数从头到尾遍历链表,通过比较解码器的name来查找

13 avcodec_find_encoder()函数

AVCodec *avcodec_find_encoder(enum CodecID id);

通过code ID查找一个已经注册的音视频编码器
引入 #include “libavcodec/avcodec.h”
实现在: \ffmpeg\libavcodec\utils.c
查找编码器之前,必须先调用av_register_all注册所有支持的编码器
查找成功返回编码器指针,否则返回NULL
音视频编码器保存在一个链表中,查找过程中,函数从头到尾遍历链表,通过比较编码器的ID来查找

14 avcodec_find_encoder_by_name()函数

AVCodec *avcodec_find_encoder_by_name(constchar *name);

通过一个指定的名称查找一个已经注册的音视频编码器
引入 #include “libavcodec/avcodec.h”
实现在: \ffmpeg\libavcodec\utils.c
查找编码器之前,必须先调用av_register_all注册所有支持的编码器
查找成功返回编码器指针,否则返回NULL
音视频编码器保存在一个链表中,查找过程中,函数从头到尾遍历链表,通过比较编码器的名称来查找

15 avcodec_open()函数

int avcodec_open(AVCodecContext *avctx, AVCodec *codec);

使用给定的AVCodec初始化AVCodecContext
引入#include “libavcodec/avcodec.h”
方法: avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(), avcodec_find_decoder() and avcodec_find_encoder() 提供了快速获取一个codec的途径
该方法在编码和解码时都会用到
返回0时成功,打开作为输出时,参数设置不对的话,调用会失败

16 av_guess_format()函数

AVOutputFormat *av_guess_format(constchar *short_name,
                                constchar *filename,
                                constchar *mime_type);

返回一个已经注册的最合适的输出格式
引入#include “libavformat/avformat.h”
可以通过 const char *short_name 获取,如"mpeg"
也可以通过 const char *filename 获取,如"E:\a.mp4"

17 av_new_stream()函数

AVStream *av_new_stream(AVFormatContext *s, int id);

为媒体文件添加一个流,一般为作为输出的媒体文件容器添加音视频流
引入 #include “libavformat/avformat.h”
再打开源文件时用户一般不需要直接调用该方法

18 dump_format()函数

attribute_deprecated void dump_format(
									  AVFormatContext *ic,
                                      int index,
                                      constchar *url,
                                      int is_output);

该函数的作用就是检查下初始化过程中设置的参数是否符合规范
有些版本中为 av_ dump_format

19 av_set_parameters()函数

attribute_deprecated int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap);

设置初始化参数
不赞成跳过该方法,直接调用 avformat_write_header/av_write_header

20 av_write_header()函数

attribute_deprecated int av_write_header(AVFormatContext *s);

把流头信息写入到媒体文件中
返回0成功

21 AVPacket结构体

typedef struct AVPacket {
    int64_t pts;
    int64_t dts;
    uint8_t *data;
    int   size;
    int   stream_index;
    int   flags;
int   duration;
...
} AVPacket

AVPacket是个很重要的结构,该结构在读媒体源文件和写输出文件时都需要用到
int64_t pts; 显示时间戳
int64_t dts; 解码时间戳
uint8_t *data; 包数据
int size; 包数据长度
int stream_index; 包所属流序号
int duration; 时长
以上信息,如果是在读媒体源文件那么avcodec会初始化,如果是输出文件,用户需要对以上信息赋值

22 av_init_packet()函数

void av_init_packet(AVPacket *pkt);

使用默认值初始化AVPacket
定义AVPacket对象后,请使用av_init_packet进行初始化

23 av_free_packet()函数

void av_free_packet(AVPacket *pkt);

释放AVPacket对象

24 av_read_frame()函数

int av_read_frame(AVFormatContext *s, AVPacket *pkt);

从输入源文件容器中读取一个AVPacket数据包
该函数读出的包并不每次都是有效的,对于读出的包我们都应该进行相应的解码(视频解码/音频解码),
在返回值>=0时,循环调用该函数进行读取,循环调用之前请调用av_free_packet函数清理AVPacket

25 avcodec_decode_video2()函数

int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture,
                         int *got_picture_ptr,
                         AVPacket *avpkt);

解码视频流AVPacket // 使用av_read_frame读取媒体流后需要进行判断,如果为视频流则调用该函数解码 //
返回结果<0时失败,此时程序应该退出检查原因 // 返回>=0时正常,假设 读取包为:AVPacket vPacket 返回值为 int
vLen; 每次解码正常时,对vPacket做如下处理:
vPacket.size -= vLen;
vPacket.data += vLen;
如果vPacket.size == 0,则继续读下一流包,否则继续调度该方法进行解码,直到vPacket.size==0返回
got_picture_ptr > 0 时,表示解码到了AVFrame *picture,其后可以对picture进程处理

26 avcodec_decode_audio3()函数

int avcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples,
                         int *frame_size_ptr,
                         AVPacket *avpkt);

解码音频流AVPacket 使用av_read_frame读取媒体流后需要进行判断,如果为音频流则调用该函数解码
返回结果<0时失败,此时程序应该退出检查原因 返回>=0时正常,假设 读取包为:AVPacket vPacket 返回值为 int
vLen;
每次解码正常时,对vPacket做 如下处理: vPacket.size -= vLen; vPacket.data += vLen;
如果 vPacket.size == 0,则继续读下一流包,否则继续调度该方法进行解码,直到vPacket.size ==0

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值