FFMPEG 之 AVCodec

本文详细介绍了FFmpeg和libavcodec在音视频处理中的作用,包括通用的编解码框架、解码过程中的核心函数如avcodec_send_packet()和avcodec_receive_frame(),以及编码部分的avcodec_send_frame()和avcodec_receive_packet()。此外,还提到了bitstreamfilter的重要性和相关函数,如av_bsf_alloc()和av_bsf_receive_packet(),用于处理如AAC和H264等编码格式的额外信息需求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

## 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,
AVFrame,int flag)

本默认调用AvCodecContext.getbuff2,通过它自定义buff,

void avcodec_align_dimension(AVCodecContext *s,
int *width,int *height)

修改宽高,

void avcodec_align_dimension2(AVCodectext *s,
int width
,int height,int linesize)

修改的宽高,且是linesize的倍数

int avcodec_enum_to_chroma_pos(int *xpos ,int *ypos,
enum AVChromaLocation pos)

将 AVChromaLocation 转换为 swscale x/y 色度位置。 

 

 

 AVChromaLocation avcodec_chroma_pos_to_enum (
int xpos, int ypos)

将 swscale x/y 色度位置转换为 AVChromaLocation。

int avcodec_decode_subtitle2 (AVCodecContext *avctx, AVSubtitle *sub,
int *got_sub_ptr, AVPacket *avpkt)

解码字幕


int avcodec_send_packet (AVCodecContext *avctx, const AVPacket *avpkt)

将原始数据包数据作为解码器的输入提供。


int avcodec_receive_frame (AVCodecContext *avctx, AVFrame *frame)

从解码器返回解码器的解码输出数据。

int avcodec_get_hw_frames_parameters (AVCodecContext *avctx,
AVBufferRef *device_ref,
enum AVPixelFormat hw_pi

创建并返回 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,
const AVFrame *frame)

向编码器提供原始视频或音频帧。

int avcodec_receive_packet (AVCodecContext *avctx,
AVPacket *avpkt)

从编码器读取编码数据。

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属性结构,并将其字段初始化为默认值

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值