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_list[i];

    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)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/871255.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Goland 通道

channel通道 目录 channel通道 channel介绍 channel基本使用 有缓存通道和无缓存通道的区别 通道的初始化,写入数据到通道,从通道读取数据及基本的注意事项 channel的关闭和遍历 channel的关闭 为什么关闭 如何优雅地关闭通道 channel的遍历 chan…

小众好玩的赛车游戏:环道巨星 CIRCUIT SUPERSTARS中文安装包

《环道巨星》(Circuit Superstars)是一款由赛车迷亲手为其他赛车迷打造的俯视角赛车游戏。荟集史上各类赛车运动,旨在提供刺激好玩的驾驶体验;而游戏自带的高技术难度将促使玩家长时间磨砺技巧,以达成完美的一圈。 游戏…

【系统架构设计师】九、软件工程(面向对象方法|逆向工程)

目录 六、面向对象方法 6.1 基本概念 6.2 面向对象的分析 6.2.1 用例关系 6.2.2 类之间的关系 6.3 面向对象的设计 6.4 面向对象设计原则与设计模式 6.5 面向对象软件的测试 七、逆向工程 历年真题练习 六、面向对象方法 面向对象的分析方法 (Object-Oriented Analys…

【Linux网络】数据链路层【上】{初识数据链路层/以太网/路由表/MAC地址表/ARP表/NAT表}

文章目录 1.初识数据链路层2.认识以太网2.0前导知识以太网帧和MAC帧CMSA/CD以太网的最小帧长限制是64字节IP层和MAC层 2.1以太网帧格式 3.预备知识计算机网络通信以太网和wifi路由表/MAC地址表/ARP表/NAT表/ACL表 用于同一种数据链路节点的两个设备之间进行信息传递。 1.初识数…

Apache AGE 聚合函数

简介 一般来说,聚合函数 aggr(expr) 会处理每个聚合键在传入记录中找到的所有匹配行(键使用等价性进行比较)。 在常规聚合(即形式为 aggr(expr) 的情况下),聚合值列表是候选值列表,其中所有空…

Clion 使用gdbserver调试FreeSWITCH源码

1.准备环境 window安装clion安装好gdb、ssh、已经编译好的freeswitch可执行文件的docker镜像2.配置clion Settings -> Tools ->SSH Configurations Settings-Build, Execution, Deployment-Toolchains(其实设不设置都行,用默认也行的) Settings-Build, Execution, Depl…

DockerCompose拉取DockerHub镜像,并部署OpenMetaData

参考博主:http://t.csdnimg.cn/i49ET 一、DockerCompose拉取DockerHub镜像 方法一(不太行): 在daemon.json文件中添加一些国内还在服务的镜像站(可能某些镜像会没有) ([ -f /etc/docker/daemon.json ] ||…

人工智能大模型如何助力电商产品经理打造高效的商品工业属性画像

摘要 商品工业属性画像是电商产品经理在进行商品管理、推荐、搜索、广告等业务时的重要依据。通过对商品的工业属性(如品类、品牌、规格、功能、风格等)的准确识别和标注,可以提高商品的展示效果、匹配度、转化率和用户满意度。然而&#xf…

从概念到完成:Midjourney——设计思维与AI技术的完美结合

文章目录 本文来自 Python学研大本营 作者 学研君 去年 AI 爆火的时候,学研君也赶时髦用上了 Midjourney。平时用它生成图片,感觉生成的图片好看,比上网四处找图更省时省事,更合心意,还不用担心版权问题。 给大家看一下…

102.qt qml-最全Table交互之多列固定、行列拖拽、自定义委托、标题交互使用教程

自定义实现的Table控件,支持跨qt版本,兼容qt5,qt6! 截图如下所示: 黑色风格如下所示: 视频演示入口:Qt QML QianWindowV2.5(新增曲线综合示例、QML最全Table交互示例、支持qt5/qt6)_哔哩哔哩_bilibili 1.示例页面入口…

【单片机毕业设计选题24061】-基于蓝牙的单片机通信系统

系统功能: 1、本系统硬件由两块STM32单片机,DHT11,光敏传感器,12864oled和HC-05蓝牙模块组成。 2、单片机1HC-05蓝牙模块做为主机,单片机2HC-05蓝牙模块做为从机。 3、单片机从机将采集到温湿度,光照强度等信息通过…

使用mybatis的statementHander拦截器监控表和字段并发送钉钉消息

新建mybatis的statementHander拦截器拦截器 类 面试题&#xff1a; 2.实现 解析Sql时引入JSqlParser JSqlParser 是一个 SQL 语句解析器。 它将 SQL转换为可遍历的 Java 类层次结构。 <dependency><groupId>com.github.jsqlparser</groupId><artifac…

[IDEA插件] JarEditor 编辑jar包(直接新增、修改、删除jar包内的class文件)

文章目录 1. 安装插件 JarEditor2. 在IDEA中添加外部JAR包3. JarEditor 使用介绍 之前我们需要修改jar内文件的时候需要解压jar包&#xff0c;反编译class&#xff0c;新建java源文件&#xff0c;修改代码&#xff0c;再编译成class&#xff0c;替换jar包内的class文件。 现在…

数据库作业5---视图

创建表 创建部门表&#xff08;dept&#xff09;和员工表&#xff08;emp&#xff09; create table dept(dept_id int primary key auto_increment comment 部门编号,dept_name char(20) comment 部门名称);insert into dept(dept_name) values(销售部),(财务部),(生产部),(…

Day03-索引模板,DSL语句,集群迁移API,ES集群状态统计API,KQL语句及分片重路由API实战

Day03-索引模板&#xff0c;DSL语句&#xff0c;集群迁移API&#xff0c;ES集群状态统计API&#xff0c;KQL语句及分片重路由API实战 1、索引模板1.1 什么是索引模板1.2 查看索引模板1.3 创建/修改索引模板1.4 删除索引模板 2、ES的DSL语句查询2.1 什么是DSL2.2 全文检索-match…

tusimple车道线检测 标注自己的数据集

一、打开labelme工具进行数据标注 二、数据格式转换 2.1 标签转换 运行Anaconda Prompt&#xff0c;进入json标签文件所在目录&#xff0c;逐个转换&#xff0c;分布运行 labelme_json_to_dataset 0000.json labelme_json_to_dataset 0001.json labelme_json_to_dataset 000…

redis查询慢,你们是如何查询优化?(运维篇3)

1、查看是否写入了bigkey 如果你查询慢日志发现&#xff0c;并不是复杂度过高的命令导致的&#xff0c;而都是 SET / DEL 这种简单命令出现在慢日志中&#xff0c;那么你就要怀疑你的实例否写入了 bigkey。 Redis 在写入数据时&#xff0c;需要为新的数据分配内存&#xff0c;相…

2024年公共文化与社会服务国际会议(ICPCSS 2024)

2024年公共文化与社会服务国际会议 2024 International Conference on Public Culture and Social Services 【1】会议简介 2024年公共文化与社会服务国际会议是一个集学术性、实践性和国际性于一体的盛会。我们期待与您共同探讨公共文化与社会服务的未来发展方向&#xff0c;为…

【linux】服务器设置所有用户创建虚拟环境到默认路径

【linux】服务器设置所有用户创建虚拟环境到默认路径 【创作不易&#xff0c;点点赞关注收藏】&#x1f600; 需要安装anaconda3的小伙伴可以看一下我前面的博文linux安装anaconda3 一、情况说明 我的anaconda3安装在"/public/apps/anaconda3/“&#xff0c;我希望所有…

C#实现最短路径算法

创建点集 double r 200 * 500;double width 1920;double height 1080;int col (int)(r / width);int row (int)(r / height);List<(double, double)> list1 new List<(double, double)>();for (int i 0; i < row; i){var y i * height;if (y < r){va…