FFmpeg api 讲解

1. 相关 api

1. void av_register_all(void);
    注册所有的muxers , demuxers 和 protocoal ,也可以选择具体的某一个来单独注册 。 
    固定写法

2. void avcodec_register_all(void); 注册所有的编解码器,固定写法即可。
3. AVFormatContext *avformat_alloc_context(void);
    初始化一个 AVFormatContext 分配内存存并初始化默认值。 
    AVFormatContext 结构体封装了av的一些基本信息,不可以外部初始化

4. int avformat_open_input(AVFormatContext **ps, const char *url,
                        AVInputFormat *fmt, AVDictionary **options);
   打开一个流并读取它的头信息 , 这时候并没有打开 codecs 。
   
   url: 硬盘文件或者网络路径
   fmt: NULL
   options : NULL
   

5. int avformat_find_stream_info(AVFormatContext *ic,
                                    AVDictionary **options);                                 

6. int av_find_best_stream(AVFormatContext *ic,
                    enum AVMediaType type,
                    int wanted_stream_nb,
                    int related_stream,
                    AVCodec **decoder_ret,
                    int flags);
在文件中找到最好的那路 音频或者视频 流 
type : 枚举类型,常用的有 音频 , 视频
wanted_stream_nb : -1
related_stream: -1 
decoder_ret : 不知道可以写 NULL
flags : 0

7. AVOutputFormat *av_guess_format(const char *short_name,
                            const char *filename,
                            const char *mime_type);
从已经注册过的格式里面选择一个最匹配的
short_name : NULL
filename : 输出文件的全路径
mime_type :NULL

8. AVStream *avformat_new_stream(AVFormatContext *s, 
                                const AVCodec *c);
    添加一个新的流到媒体文件中,                                
                                

9. int avcodec_parameters_copy(AVCodecParameters *dst, const 	
                                AVCodecParameters *src);
    从原始的media里面拷贝codec到目标文件里

10. int avformat_write_header(AVFormatContext *s, AVDictionary 
                            **options);
    创建一个新的流,并且将header信息说不出到给定的文件

11. void av_init_packet(AVPacket *pkt);
    初始化一个 给定的packet ,为可选的参数赋默认值。 ,这里并不涉及到数据大小内存变化。 

12. int avio_open(AVIOContext **s, const char *url, int flags);
    使用给定的 url 和 flag 打开一个输出环境 。 
    flags: AVIO_FLAG_WRITE , AVIO_FLAG_READ

13. int av_read_frame(AVFormatContext *s, AVPacket *pkt);
    给流中不断的获取frame , 
    note: 此 frame是未解码的原始数据
    

14. int64_t av_rescale_q_rnd(int64_t a, AVRational b, AVRational cq,
                     enum AVRounding c) av_const;
    时间刻度转换 。 将以 "时钟基c" 表示的 数值a 转换成以 "时钟基b" 来表示。

15. int64_t av_rescale_q(int64_t a, AVRational b, AVRational c) av_const;
    具体来说是将以 "时钟基c" 表示的 数值a 转换成以 "时钟基b" 来表示。

16. int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt);
    (Write a packet to an output media file ensuring correct interleaving.)

17. int av_write_trailer(AVFormatContext *s);

18. int avcodec_send_packet(AVCodecContext *avctx, 
                    const AVPacket *avpkt);

    解码 并将解码后的数据放到 avpkt 中。 

19.  int avcodec_receive_frame(AVCodecContext *avctx, 
                    AVFrame *frame);
    从decoder中获取已经解码后的数据帧
    

20. int avformat_alloc_output_context2(AVFormatContext **ctx, 						AVOutputFormat *oformat,
                const char *format_name, 
                const char *filename);
    给 输出 文件初始化  , 创建上下文并且根据输出文件格式生成容器
     本质上调用了avformat_alloc_context、av_guess_format 这两个函数

21. AVCodec *avcodec_find_encoder(enum AVCodecID id);
    获取一个已经注册过的encoder , 
    ig: AVCodec *codec = avcodec_find_encoder(AV_CODEC_ID_MJPEG);

22. int avcodec_open2(AVCodecContext *avctx, 
                const AVCodec *codec, 
                AVDictionary **options);
    使用给定的codec 来初始化一个 avctx ,以便于后续使用

23. int avcodec_send_frame(AVCodecContext *avctx, 
                const AVFrame *frame);
    将 frame 使用给定的 encoder 进行编码 

24. int avcodec_receive_packet(AVCodecContext *avctx, 
                AVPacket *avpkt);
    从encoder中读取已经编码后的数据包,放到avpkt中。
    

25. int av_image_alloc(uint8_t *pointers[4], 
                int linesizes[4],  
                int w, int h, 
                enum AVPixelFormat pix_fmt, 
                int align);
参数说明: 
    pointers[4]:保存图像通道的地址。如果是RGB,则前三个指针分别指向R,G,B的内存地址。第四个指针保留不用
    linesizes[4]:保存图像每个通道的内存对齐的步长,即一行的对齐内存的宽度,此值大小等于图像宽度。
     w:      要申请内存的图像宽度。
     h:      要申请内存的图像高度。
    pix_fmt:  要申请内存的图像的像素格式。
    align:   用于内存对齐的值。

  返回值:所申请的内存空间的总大小。如果是负值,表示申请失败。

26. int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, 
                        int width, int height, int align)
    
    通过指定像素格式、图像宽、图像高来计算所需的内存大小

    重点说明一个参数align:此参数是设定内存对齐的对齐数,也就是按多大的字节进行内存对齐。比如设置为1,表示按1字节对齐,那么得到的结果就是与实际的内存大小一样。再比如设置为4,表示按4字节对齐。也就是内存的起始地址必须是4的整倍数。
    

27. int av_image_fill_arrays(uint8_t *dst_data[4], 
                int dst_linesize[4],                         
                const uint8_t *src,  
                enum AVPixelFormat pix_fmt, 
                int width, int height, int align);
    
    av_image_fill_arrays()函数自身不具备内存申请的功能,此函数类似于格式化已经申请的内存,即通过av_malloc()函数申请的内存空间。

参数具体说明:
  dst_data[4]:  对申请的内存格式化为三个通道后,分别保存其地址
  dst_linesize[4]:  格式化的内存的步长(即内存对齐后的宽度)
  *src:        av_alloc()函数申请的内存地址。
 pix_fmt:    申请 src内存时的像素格式
width:        申请src内存时指定的宽度
height:      申请scr内存时指定的高度

align:   申请src内存时指定的对齐字节数。

通过以上实例可以看到,
(a)计算所需内存大小av_image_get_bufferz_size() --> 
(b) 按计算的内存大小申请所需内存 av_malloc()  --> 
(c) 对申请的内存进行格式化 av_image_fill_arrays();