## 1概述
libavcodec提供了通用的编解码框架,并包含多个视频,音频,字幕编码器,解码器,和几个比特流筛选器。FFMPEG 是一套通用的音视频处理框架,很多编解码器也是通过外部库实现的,比如libx264,libmp3lame,aac...。FFPEG 做的工作就是将这些编解码器封装成统一 的接口,在面对不同的编码格式时,对于使用者来说是无感的,这带来了很强的方便性,兼容性。
## 2 Decoding
对于这一部分来说,最重要的就是avcodec_send_packet() , avcodec_receive_frame() 两个函数,一个负责将packet 推到解码器去解码, 另一个回收解完码的数据。avcodec_send_packet() 输入参数是packet, 通常是一个视频帧,或几个完整的音频帧,与旧的API avcodec_decode_audio4 /avcodec_decode_video2 不同,它必须通过调用avcodec_receive_frame()多次 将数据完全接收,才能继续send_packet。这样避免了解码结束出现丢帧的情况。输入packe 里面的datat也可以为空,当data 为空时,会被认为是一个eof 包,标志着流结束,这时会返回AVERROR_EOF。
函数原型 | 作用 |
Avcodec *avcodec_find_decoder(enum AVCodecID Id) | 在已注册的解码器中,查找匹配的解码器 |
AVCodec *avcodec_find_decoder_by_name(char*name) | 在已注册的解码器中,根据名字查找匹配的解码器 |
int avcodec_default_get_buff2(AVCodecContext *s, | 本默认调用AvCodecContext.getbuff2,通过它自定义buff, |
void avcodec_align_dimension(AVCodecContext *s, | 修改宽高, |
void avcodec_align_dimension2(AVCodectext *s, | 修改的宽高,且是linesize的倍数 |
int avcodec_enum_to_chroma_pos(int *xpos ,int *ypos, | 将 AVChromaLocation 转换为 swscale x/y 色度位置。 |
|
|
AVChromaLocation avcodec_chroma_pos_to_enum ( | 将 swscale x/y 色度位置转换为 AVChromaLocation。 |
int avcodec_decode_subtitle2 (AVCodecContext *avctx, AVSubtitle *sub, | 解码字幕 |
| 将原始数据包数据作为解码器的输入提供。 |
| 从解码器返回解码器的解码输出数据。 |
int avcodec_get_hw_frames_parameters (AVCodecContext *avctx, | 创建并返回 AVHWFrames 上下文 值足以进行硬件解码。 |
3 Encoding
对于编码部分来收,最重要也就两支API:avcodec_send_frame()/avcodec_receive_packet(),一个负责向编码器提供原始视频或音频帧,一个负责从编码器读取编码数据。同样的传入的frame data也可以为NULL,会被认为是流的结束,会返回AVERROR_EOF。
函数原型 | 作用 |
AVCodec * avcodec_find_encoder (enum AVCodecID id) | 查找具有匹配编解码器id的注册编码器。 |
AVCodec * avcodec_find_encoder_by_name (const char *name) | 查找具有指定名称的注册编码器。 |
int avcodec_encode_subtitle (AVCodecContext *avctx, uint8_t *buf, int buf_size, const AVSubtitle *sub) | 编码字幕 |
int avcodec_send_frame (AVCodecContext *avctx, | 向编码器提供原始视频或音频帧。 |
int avcodec_receive_packet (AVCodecContext *avctx, | 从编码器读取编码数据。 |
4 Utility functions
这里重点介绍一下bitstream filter,比如向AAC,必须在每帧数据前面加上adts ,否则解码器会失败, 有些原始码流adts 数据只存在于文件头部,后面data 部分没有。 这就需要AVBitStreamFilter 将这parse 出的data 补上这些信息。 与此之外比如还有h264 , 用时候会缺乏同步字等等信息。 以下为AVCodec 库开出的通用函数API。如何使用BSF ,请参考:https://blog.youkuaiyun.com/weixin_40840000/article/details/107826566?utm_source=app
函数原型 | 作用 |
void avcodec_string (char *buf, int buf_size, AVCodecContext *enc, int encode) | 如果可用,返回指定profile的名称 |
const char * av_get_profile_name (const AVCodec *codec, int profile) | 如果可用,为指定的profile get 一个名称。 |
const char * avcodec_profile_name (enum AVCodecID codec_id, int profile) |
|
int avcodec_default_execute (AVCodecContext *c, int(*func)(AVCodecContext *c2, void *arg2), void *arg, int *ret, int count, int size) |
|
int avcodec_default_execute2 (AVCodecContext *c, int(*func)(AVCodecContext *c2, void *arg2, int, int), void *arg, int *ret, int count) |
|
int avcodec_fill_audio_frame (AVFrame *frame, int nb_channels, enum AVSampleFormat sample_fmt, const uint8_t *buf, int buf_size, int align) | 填充avframe音频数据和行大小指针 |
void avcodec_flush_buffers (AVCodecContext *avctx) | 重置内部解码器状态/刷新内部缓冲器 |
int av_get_bits_per_sample (enum AVCodecID codec_id) | 返回每个样本的的bit 位数 |
enum AVCodecID av_get_pcm_codec (enum AVSampleFormat fmt, int be) | 返回与样本格式相关联的pcm编解码器 |
int av_get_exact_bits_per_sample (enum AVCodecID codec_id) | 返回每个采样sample 的位数 |
int av_get_audio_frame_duration (AVCodecContext *avctx, int frame_bytes) | 返回音频帧持续时间 |
int av_get_audio_frame_duration2 (AVCodecParameters *par, int frame_bytes) | 同上 |
const AVBitStreamFilter * av_bsf_get_by_name (const char *name) | 获得通过给定的filename, 获得bsf |
const AVBitStreamFilter * av_bsf_iterate (void **opaque) | 遍历bsf |
int av_bsf_alloc (const AVBitStreamFilter *filter, AVBSFContext **ctx) | 为给定的比特流过滤器分配上下文 |
int av_bsf_init (AVBSFContext *ctx) | 为给定的比特流过滤器分配上下文 |
int av_bsf_send_packet (AVBSFContext *ctx, AVPacket *pkt) | 为给定的比特流过滤器分配上下文 |
int av_bsf_receive_packet (AVBSFContext *ctx, AVPacket *pkt) | 为给定的比特流过滤器分配上下文 |
void av_bsf_flush (AVBSFContext *ctx) | 为给定的比特流过滤器分配上下文 |
void av_bsf_free (AVBSFContext **ctx) | 释放比特流过滤器上下文和与之相关联的所有内容;向提供的指针中写入null |
const AVClass * av_bsf_get_class (void) | 获取avbsfcontext的avclass |
AVBSFList * av_bsf_list_alloc (void) | 获取avbsfcontext的avclass |
void av_bsf_list_free (AVBSFList **lst) | 释放bsf list |
enum AVMediaType avcodec_get_type (enum AVCodecID codec_id) | 获取给定编解码器的类型。 |
const char * avcodec_get_name (enum AVCodecID id) | 获取给定编解码器的类型。 |
int avcodec_is_open (AVCodecContext *s) |
|
int av_codec_is_encoder (const AVCodec *codec) |
|
int av_codec_is_decoder (const AVCodec *codec) |
|
const AVCodecDescriptor * avcodec_descriptor_get (enum AVCodecID id) |
|
const AVCodecDescriptor * avcodec_descriptor_next (const AVCodecDescriptor *prev) | 遍历AVCodecDescriptor |
const AVCodecDescriptor * avcodec_descriptor_get_by_name (const char *name) |
|
AVCPBProperties * av_cpb_properties_alloc (size_t *size) | 分配一个cpb属性结构,并将其字段初始化为默认值 |