ffmpeg 找到编解码器,和编解码器上下文后,是如何初始化具体的编解码器的?aac 初始化流程大致如下

1.当使用 avcodec_find_encoder_by_name找到编码器的时候,

const AVCodec * aacencoder = avcodec_find_encoder_by_name("libx264");

编码器 有值的是:

id AV_CODEC_ID_H264 (27)

long_name libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10

name libx264

pix_fmts AV_PIX_FMT_YUV420P (0)

type AVMEDIA_TYPE_VIDEO (0)

2.当调用 AVCodecContext *aacencodercontext = avcodec_alloc_context3(aacencoder); 后。

编码器中和上面一样,没有啥变化

编码器上下文里面有内容的是:

编码器上下文中的 codec_id 和 codec_type 是有值的,其他的都重新赋值了默认值

codec_id AV_CODEC_ID_H264 (27)

codec_type AVMEDIA_TYPE_VIDEO (0)

如下举例的默认值:

s->time_base = (AVRational){0,1};

s->framerate = (AVRational){ 0, 1 };

s->pkt_timebase = (AVRational){ 0, 1 };

3.当调用了 avcodec_open2(encoderAVCodecContext, encoderAVCodec, NULL) 方法后,很多参数就会被设置。

我们可以想象,假设encoder 是AAC ,那么哪些参数会被设置呢?

第一个就是一个 avframe 有多少个 样本帧,

3.1从最开始的avcodec_find_encoder 或者 avcodec_find_decoder开始看起。

方法在 D:\Ctool\yinshipin\ffmpeg-6.0source\libavcodec\allcodecs.c 文件中。

const AVCodec *avcodec_find_encoder(enum AVCodecID id)

{

return find_codec(id, av_codec_is_encoder);

}

const AVCodec *avcodec_find_decoder(enum AVCodecID id)

{

return find_codec(id, av_codec_is_decoder);

}

3.2 find_codec 方式 其核心是av_codec_iterate方法

static const AVCodec *find_codec(enum AVCodecID id, int (*x)(const AVCodec *))

{

const AVCodec *p, *experimental = NULL;

void *i = 0;

id = remap_deprecated_codec_id(id);

while ((p = av_codec_iterate(&i))) {

if (!x(p))

continue;

if (p->id == id) {

if (p->capabilities & AV_CODEC_CAP_EXPERIMENTAL && !experimental) {

experimental = p;

} else

return p;

}

}

return experimental;

}

3.3 av_codec_iterate 方法 实际是是从 codec_list 中找到对应的 codec,这个list很长,包括所有的 编码器 和 解码器 在ffmepg 内部的名字。

const AVCodec *av_codec_iterate(void **opaque)

{

uintptr_t i = (uintptr_t)*opaque;

const FFCodec *c = codec_listi;

ff_thread_once(&av_codec_static_init, av_codec_init_static);

if (c) {

*opaque = (void*)(i + 1);

return &c->p;

}

return NULL;

}

我们可以看到,在 codec_list 对应的aac有多个,我们用 ff_aac_encoder 来说明。

在search 代码后,发现,ff_aac_encoder 的定义是在 aacenc.c 中,其中有

从 D:\Ctool\yinshipin\ffmpeg-6.0source\libavcodec\aacenc.c 中可以看到如下的信息,

字段 .init = aac_encode_init,应该是一个函数,

从 aac_encode_init 函数中可以看到,frame_size是1024

avctx->frame_size = 1024;

const FFCodec ff_aac_encoder = {

.p.name = "aac",

CODEC_LONG_NAME("AAC (Advanced Audio Coding)"),

.p.type = AVMEDIA_TYPE_AUDIO,

.p.id = AV_CODEC_ID_AAC,

.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |

AV_CODEC_CAP_SMALL_LAST_FRAME,

.priv_data_size = sizeof(AACEncContext),

.init = aac_encode_init,

FF_CODEC_ENCODE_CB(aac_encode_frame),

.close = aac_encode_end,

.defaults = aac_encode_defaults,

.p.supported_samplerates = ff_mpeg4audio_sample_rates,

.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,

.p.sample_fmts = (const enum AVSampleFormat\[\]){ AV_SAMPLE_FMT_FLTP,

AV_SAMPLE_FMT_NONE },

.p.priv_class = &aacenc_class,

};

到这里,还有一个问题:ff_aac_encoder 是什么时候被初始化的呢?

实际上 ret = avcodec_open2(avcodecContext,nullptr,nullptr); 内部是做了这个事情的。

核心代码是在

if (codec2->init) {

实际上就会调用到:

static av_cold int aac_encode_init(AVCodecContext *avctx)

相关推荐
狗凯之家源码网13 小时前
吃瓜主题 3.0 视频源码深度评测与实战指南
音视频
美狐美颜sdk17 小时前
视频美颜SDK中的YUV与RGBA格式有什么区别?直播APP开发解析
人工智能·计算机视觉·音视频·美颜sdk·直播美颜sdk·视频美颜sdk
音视频牛哥17 小时前
不止于超低延迟:SmartMediaKit iOS Unity3D RTSP/RTMP 播放器的核心竞争力
音视频·unity3d rtsp播放器·unity3d rtmp播放器·smartmediakit·ios unity rtsp·ios unity rtmp·unity3d ios播放器
辰辰观影20 小时前
网盘视频播放器怎么选?2026全平台推荐
经验分享·音视频
guhy fighting20 小时前
怎么去除视频的logo?现在有方法了,使用Remove Logo Now快速去除视频logo
音视频
呆呆的猫20 小时前
【视频生成】2、VDN-MiniMax-H3
音视频
沐禾安信1 天前
MOV转MP4怎么转换?苹果视频打不开这样解决
音视频·格式转换·mov转mp4
小豆庄1 天前
视频隐私脱敏怎么处理:识别追踪与本地方案的选型思路
密码学·音视频·视频
Android系统攻城狮1 天前
Linux FFmpeg深度解析之av_dump_format调用流程与实战(十一)
linux·运维·服务器·ffmpeg·1024程序员节·音视频进阶
七牛云行业应用1 天前
爆火OpenFilm 0.2.6:开源 AI 视频 Agent 的安装、编辑与渲染流程(2026 年 10 月 )
人工智能·开源·音视频