Android系统攻城狮头像
Linux FFmpeg深度解析之avcodec_find_encoder_by_name调用流程与实战(二十四)封面图

Linux FFmpeg深度解析之avcodec_find_encoder_by_name调用流程与实战(二十四)

简介: CSDN博客专家、《Android系统多媒体进阶实战》作者

博主新书推荐:《Android系统多媒体进阶实战》🚀
Android Audio工程师专栏地址: Audio工程师进阶系列【原创干货持续更新中……】🚀
Android多媒体专栏地址: 多媒体系统工程师系列【原创干货持续更新中……】🚀
专题一 二:AAOS车载系统+AOSP14系统攻城狮入门视频实战课 🚀
专题三:Android14 Binder之HIDL与AIDL通信实战课 🚀
专题四:Android15快速自定义与集成音效实战课 🚀
专题五:Android15音频策略实战课 🚀
专题六:Android15音频性能实战课(无声/杂音/断音/爆音实战案例) 🚀

人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

更多原创,欢迎关注:Android系统攻城狮

点击获取二维码

欢迎关注Android系统攻城狮

🌻1.前言

本篇目的:理解avcodec_find_encoder_by_name()如何按编码器名称精确查找AVCodec描述符,并通过创建编码上下文验证查找结果。

按AVCodecID查找时,FFmpeg会从匹配格式的实现中选择一个编码器。如果应用已经确定要使用哪个具体实现,例如构建中注册的mpeg4编码器,就可以按名称查找。

avcodec_find_encoder_by_name()只查找名称完全匹配的编码器描述符,不会创建上下文,也不会打开或运行编码器。

编码器名称

avcodec_find_encoder_by_name

遍历已注册编码器并精确比较

返回AVCodec或NULL

🌻2.应用场景和用法

2.1按具体编码器实现选择

按名称查找适合应用需要固定编码器实现的情况,例如针对特定硬件编码器或明确指定软件编码器。编码器名称取自AVCodec.name,必须与当前构建实际注册的名称一致。

场景按名称查找的作用注意事项
固定软件实现选择指定的软件编码器名称需精确匹配
选择硬件编码器定位某个已注册的硬件编码器还要检查设备和像素格式支持
产品配置指定编码器将配置项映射到FFmpeg编码器名名称不存在时应提供错误或回退
诊断构建能力验证目标编码器是否被编译和注册查找成功仍不等于编码参数可用
2.2函数原型与返回语义
const AVCodec *avcodec_find_encoder_by_name(const char *name);
参数或返回值含义
name编码器的注册名称
返回值名称匹配的编码器描述符;无匹配项时返回NULL

内部查找先判断名称是否为NULL,然后遍历注册的编码器,过滤解码器,并使用区分大小写的字符串比较匹配AVCodec.name。它不会按long_name查找,也不会把类似的名称自动转换为目标编码器。

返回的AVCodec由FFmpeg管理,不需要调用者释放。创建运行上下文仍需调用avcodec_alloc_context3(),设置参数后再调用avcodec_open2()。

🌻3.调用流程剖析

3.1按名称遍历注册表

avcodec_find_encoder_by_name()把名称和编码器类型判断函数传给内部find_codec_by_name()。遍历中只有满足编码器类型且AVCodec.name与输入字符串完全相同的条目才会返回。

是

否

传入名称

名称是否为空

返回NULL

遍历注册编码器

比较AVCodec.name

返回匹配项或NULL

3.2从名称查找进入编码任务

名称匹配成功后,返回值仍然只是描述符。调用者把它传给avcodec_alloc_context3(),然后配置编码参数并调用avcodec_open2()。

如果名称不存在,查找函数返回NULL。如果名称存在但当前硬件、像素格式或其他参数不匹配,错误会在后续编码器打开阶段出现,不能把两类失败混为一谈。

🌻4.实战案例

4.1准备编码器名称

案例使用FFmpeg常见的软件编码器名称mpeg4。具体名称是否可用取决于当前构建注册的编码器。

4.2按名称查找并创建上下文

程序通过名称获取描述符,再创建编码上下文并配置视频参数。avcodec_open2()用于确认该描述符能否按当前参数初始化。

4.3完整代码
#include <libavcodec/avcodec.h>
#include <libavutil/pixfmt.h>

int
main (void)
{
  const char *encoder_name = "mpeg4";
  const AVCodec *codec = NULL;
  AVCodecContext *context = NULL;
  int ret = 1;

  /* 名称需要与注册的AVCodec.name完全匹配 */
  codec = avcodec_find_encoder_by_name (encoder_name);
  if (codec == NULL)
    goto done;

  /* 查找只返回描述符,编码上下文需要单独创建 */
  context = avcodec_alloc_context3 (codec);
  if (context == NULL)
    goto done;

  context->width = 640;
  context->height = 480;
  context->time_base = (AVRational) { 1, 25 };
  context->framerate = (AVRational) { 25, 1 };
  context->pix_fmt = AV_PIX_FMT_YUV420P;

  /* 验证编码器能否按当前参数打开 */
  if (avcodec_open2 (context, codec, NULL) < 0)
    goto done;

  ret = 0;

done:
  /* 上下文由调用者释放,编码器描述符由FFmpeg管理 */
  avcodec_free_context (&context);

  return ret;
}

🌻5.总结

avcodec_find_encoder_by_name()按AVCodec.name精确查找编码器描述符,编码器上下文创建和运行仍由后续API负责。

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/u010164190/article/details/169331987

文章来源转载

评论

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--