FFmpeg提供两种方式查找解码器,通过codecId查找avcodec_find_decoder()与通过名字查找avcodec_find_decoder_by_name()。同样地,也提供两种方式查找编码器,通过codecId查找avcodec_find_encoder()与通过名字查找avcodec_find_encoder_by_name()。源码位于libavcodec/allcodecs.c中。

查找编解码器过程如下图所示:

一、查找解码器

1、avcodec_find_decoder
通codecId来查找解码器的方法如下:

AVCodec *avcodec_find_decoder(enum AVCodecID id)
{return find_codec(id, av_codec_is_decoder);
}

函数体只有一行代码,就是调用find_codec()来查找,第一个参数为codecId,第二个参数为属于解码器类型,具体方法如下:

static 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;} elsereturn (AVCodec*)p;}}return (AVCodec*)experimental;
}

可以看到,是通过while循环调用av_codec_iterate()来迭代遍历,获取AVCodec,然后用id判断是否相等。如果id相等,就返回对应的AVCodec。我们来看下av_codec_iterate()的实现:

static void av_codec_init_static(void)
{for (int i = 0; codec_list[i]; i++) {if (codec_list[i]->init_static_data)codec_list[i]->init_static_data((AVCodec*)codec_list[i]);}
}const AVCodec *av_codec_iterate(void **opaque)
{uintptr_t i = (uintptr_t)*opaque;const AVCodec *c = codec_list[i];ff_thread_once(&av_codec_static_init, av_codec_init_static);if (c)*opaque = (void*)(i + 1);return c;
}

2、avcodec_find_decoder_by_name
通过名字查找解码器的方法如下:

AVCodec *avcodec_find_decoder_by_name(const char *name)
{return find_codec_by_name(name, av_codec_is_decoder);
}

主要调用find_codec_by_name(),第一个参数为解码器名字,第二个参数为属于解码器类型,具体方法如下:

static AVCodec *find_codec_by_name(const char *name, int (*x)(const AVCodec *))
{void *i = 0;const AVCodec *p;if (!name)return NULL;while ((p = av_codec_iterate(&i))) {if (!x(p))continue;if (strcmp(name, p->name) == 0)return (AVCodec*)p;}return NULL;
}

可以看到,是通过while循环调用av_codec_iterate()来迭代遍历,获取AVCodec,然后用名字进行比较。如果匹配成功,就返回对应的AVCodec。

二、查找编码器

1、avcodec_find_encoder
通过codecId查找编码器的方法如下:

AVCodec *avcodec_find_encoder(enum AVCodecID id)
{return find_codec(id, av_codec_is_encoder);
}

2、avcodec_find_encoder_by_name
通过名字查找编码器的方法如下:

AVCodec *avcodec_find_encoder_by_name(const char *name)
{return find_codec_by_name(name, av_codec_is_encoder);
}

三、编解码器列表与id

1、 编解码器列表
编解码器列表来自libavcodec/allcodecs.c,有声明全局变量(详情可查看:avcodec注册与介绍):

extern AVCodec ff_flv_encoder;
extern AVCodec ff_flv_decoder;
extern AVCodec ff_h264_decoder;
extern AVCodec ff_hevc_decoder;
extern AVCodec ff_mpeg4_encoder;
extern AVCodec ff_mpeg4_decoder;
extern AVCodec ff_msmpeg4v1_decoder;
extern AVCodec ff_msmpeg4v2_encoder;
extern AVCodec ff_msmpeg4v2_decoder;
extern AVCodec ff_msmpeg4v3_encoder;
extern AVCodec ff_msmpeg4v3_decoder;
extern AVCodec ff_vp8_decoder;
extern AVCodec ff_vp9_decoder;
extern AVCodec ff_wmv1_encoder;
extern AVCodec ff_wmv1_decoder;
extern AVCodec ff_wmv2_encoder;
extern AVCodec ff_wmv2_decoder;
extern AVCodec ff_wmv3_decoder;/* audio codecs */
extern AVCodec ff_aac_encoder;
extern AVCodec ff_aac_decoder;
extern AVCodec ff_ac3_encoder;
extern AVCodec ff_ac3_decoder;
extern AVCodec ff_amrnb_decoder;
extern AVCodec ff_amrwb_decoder;
extern AVCodec ff_ape_decoder;
extern AVCodec ff_eac3_encoder;
extern AVCodec ff_eac3_decoder;
extern AVCodec ff_flac_encoder;
extern AVCodec ff_flac_decoder;
extern AVCodec ff_mp3_decoder;
extern AVCodec ff_opus_encoder;
extern AVCodec ff_opus_decoder;
extern AVCodec ff_truehd_encoder;
extern AVCodec ff_truehd_decoder;
extern AVCodec ff_vorbis_encoder;
extern AVCodec ff_vorbis_decoder;
extern AVCodec ff_wmav1_encoder;
extern AVCodec ff_wmav1_decoder;
extern AVCodec ff_wmav2_encoder;
extern AVCodec ff_wmav2_decoder;/* PCM codecs */
extern AVCodec ff_pcm_alaw_encoder;
extern AVCodec ff_pcm_alaw_decoder;
extern AVCodec ff_pcm_mulaw_encoder;
extern AVCodec ff_pcm_mulaw_decoder;
extern AVCodec ff_pcm_s8_encoder;
extern AVCodec ff_pcm_s8_decoder;
extern AVCodec ff_pcm_s16le_encoder;
extern AVCodec ff_pcm_s16le_decoder;
extern AVCodec ff_pcm_s16le_planar_encoder;
extern AVCodec ff_pcm_s16le_planar_decoder;
extern AVCodec ff_pcm_s24le_encoder;
extern AVCodec ff_pcm_s24le_decoder;
extern AVCodec ff_pcm_s32le_encoder;
extern AVCodec ff_pcm_s32le_decoder;
extern AVCodec ff_pcm_s64le_encoder;
extern AVCodec ff_pcm_s64le_decoder;
extern AVCodec ff_pcm_u8_encoder;
extern AVCodec ff_pcm_u8_decoder;/* ADPCM codecs */
extern AVCodec ff_adpcm_ima_wav_encoder;
extern AVCodec ff_adpcm_ima_wav_decoder;
extern AVCodec ff_adpcm_ms_encoder;
extern AVCodec ff_adpcm_ms_decoder;/* subtitles */
extern AVCodec ff_ssa_encoder;
extern AVCodec ff_ssa_decoder;
extern AVCodec ff_ass_encoder;
extern AVCodec ff_ass_decoder;
extern AVCodec ff_movtext_encoder;
extern AVCodec ff_movtext_decoder;
extern AVCodec ff_pgssub_decoder;
extern AVCodec ff_sami_decoder;
extern AVCodec ff_srt_encoder;
extern AVCodec ff_srt_decoder;
extern AVCodec ff_subrip_encoder;
extern AVCodec ff_subrip_decoder;
extern AVCodec ff_ttml_encoder;
extern AVCodec ff_webvtt_encoder;
extern AVCodec ff_webvtt_decoder;/* external libraries */
extern AVCodec ff_aac_at_encoder;
extern AVCodec ff_aac_at_decoder;
extern AVCodec ff_ac3_at_decoder;
extern AVCodec ff_amr_nb_at_decoder;
extern AVCodec ff_eac3_at_decoder;
extern AVCodec ff_mp3_at_decoder;
extern AVCodec ff_libaom_av1_encoder;
extern AVCodec ff_libdav1d_decoder;
extern AVCodec ff_libfdk_aac_encoder;
extern AVCodec ff_libfdk_aac_decoder;
extern AVCodec ff_libmp3lame_encoder;
extern AVCodec ff_libopencore_amrnb_decoder;
extern AVCodec ff_libopencore_amrwb_decoder;
extern AVCodec ff_libopus_encoder;
extern AVCodec ff_libopus_decoder;
extern AVCodec ff_libshine_encoder;
extern AVCodec ff_libspeex_encoder;
extern AVCodec ff_libspeex_decoder;
extern AVCodec ff_libvorbis_encoder;
extern AVCodec ff_libvorbis_decoder;
extern AVCodec ff_libvpx_vp8_encoder;
extern AVCodec ff_libvpx_vp8_decoder;
extern AVCodec ff_libvpx_vp9_encoder;
extern AVCodec ff_libvpx_vp9_decoder;
extern AVCodec ff_libwebp_encoder;
extern AVCodec ff_libx264_encoder;
extern AVCodec ff_libx265_encoder;/* hwaccel hooks only, so prefer external decoders */
extern AVCodec ff_av1_decoder;
extern AVCodec ff_av1_cuvid_decoder;
extern AVCodec ff_av1_qsv_decoder;
extern AVCodec ff_libopenh264_encoder;
extern AVCodec ff_libopenh264_decoder;
extern AVCodec ff_h264_cuvid_decoder;
extern AVCodec ff_h264_nvenc_encoder;
extern AVCodec ff_h264_omx_encoder;
extern AVCodec ff_h264_qsv_encoder;
extern AVCodec ff_h264_v4l2m2m_encoder;
extern AVCodec ff_h264_vaapi_encoder;
extern AVCodec ff_h264_videotoolbox_encoder;
extern AVCodec ff_hevc_mediacodec_decoder;
extern AVCodec ff_hevc_nvenc_encoder;
extern AVCodec ff_hevc_qsv_encoder;
extern AVCodec ff_hevc_v4l2m2m_encoder;
extern AVCodec ff_hevc_vaapi_encoder;
extern AVCodec ff_hevc_videotoolbox_encoder;
extern AVCodec ff_mp3_mf_encoder;
extern AVCodec ff_mpeg4_cuvid_decoder;
extern AVCodec ff_mpeg4_mediacodec_decoder;
extern AVCodec ff_mpeg4_omx_encoder;
extern AVCodec ff_mpeg4_v4l2m2m_encoder;
extern AVCodec ff_vp9_cuvid_decoder;
extern AVCodec ff_vp9_mediacodec_decoder;
extern AVCodec ff_vp9_qsv_decoder;
extern AVCodec ff_vp9_vaapi_encoder;
extern AVCodec ff_vp9_qsv_encoder;

2、编解码器id
编解码器id是个枚举类型AVCodecId,定义位于libavcodec/codec_id.h(有删减):

enum AVCodecID {AV_CODEC_ID_NONE,/* video codecs */AV_CODEC_ID_MPEG1VIDEO,AV_CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decodingAV_CODEC_ID_MPEG4,AV_CODEC_ID_MSMPEG4V1,AV_CODEC_ID_MSMPEG4V2,AV_CODEC_ID_MSMPEG4V3,AV_CODEC_ID_WMV1,AV_CODEC_ID_WMV2,AV_CODEC_ID_FLV1,AV_CODEC_ID_H264,AV_CODEC_ID_PNG,AV_CODEC_ID_VC1,AV_CODEC_ID_WMV3,AV_CODEC_ID_AVS,AV_CODEC_ID_JPEG2000,AV_CODEC_ID_GIF,AV_CODEC_ID_VP8,AV_CODEC_ID_VP9,AV_CODEC_ID_HEVC,
#define AV_CODEC_ID_H265 AV_CODEC_ID_HEVCAV_CODEC_ID_VVC,
#define AV_CODEC_ID_H266 AV_CODEC_ID_VVCAV_CODEC_ID_AV1,/* various PCM "codecs" */AV_CODEC_ID_PCM_S16LE = 0x10000,AV_CODEC_ID_PCM_S16BE,AV_CODEC_ID_PCM_S8,AV_CODEC_ID_PCM_U8,AV_CODEC_ID_PCM_MULAW,AV_CODEC_ID_PCM_ALAW,AV_CODEC_ID_PCM_S32LE,AV_CODEC_ID_PCM_S24LE,AV_CODEC_ID_PCM_S24DAUD,AV_CODEC_ID_PCM_S16LE_PLANAR,AV_CODEC_ID_PCM_F32LE,AV_CODEC_ID_PCM_F64LE,AV_CODEC_ID_PCM_S8_PLANAR,AV_CODEC_ID_PCM_S24LE_PLANAR,AV_CODEC_ID_PCM_S32LE_PLANAR,AV_CODEC_ID_PCM_S64LE = 0x10800,AV_CODEC_ID_PCM_F16LE,AV_CODEC_ID_PCM_F24LE,/* various ADPCM codecs */AV_CODEC_ID_ADPCM_IMA_QT = 0x11000,AV_CODEC_ID_ADPCM_IMA_WAV,AV_CODEC_ID_ADPCM_MS,AV_CODEC_ID_ADPCM_AFC = 0x11800,AV_CODEC_ID_ADPCM_IMA_OKI,/* AMR */AV_CODEC_ID_AMR_NB = 0x12000,AV_CODEC_ID_AMR_WB,/* audio codecs */AV_CODEC_ID_MP2 = 0x15000,AV_CODEC_ID_MP3, ///< preferred ID for decoding MPEG audio layer 1, 2 or 3AV_CODEC_ID_AAC,AV_CODEC_ID_AC3,AV_CODEC_ID_VORBIS,AV_CODEC_ID_WMAV1,AV_CODEC_ID_WMAV2,AV_CODEC_ID_FLAC,AV_CODEC_ID_APE,AV_CODEC_ID_EAC3,AV_CODEC_ID_TRUEHD,AV_CODEC_ID_OPUS,/* subtitle codecs */AV_CODEC_ID_DVD_SUBTITLE = 0x17000,AV_CODEC_ID_DVB_SUBTITLE,AV_CODEC_ID_SSA,AV_CODEC_ID_MOV_TEXT,AV_CODEC_ID_SRT,AV_CODEC_ID_MICRODVD   = 0x17800,AV_CODEC_ID_SAMI,AV_CODEC_ID_SUBRIP,AV_CODEC_ID_WEBVTT,AV_CODEC_ID_ASS,AV_CODEC_ID_TTML,AV_CODEC_ID_TTF = 0x18000,
};

FFmpeg源码分析:avcodec_find_decoder()查找解码器相关推荐

  1. FFMPEG源码分析(二)

    ffmpeg源码分析之数据流 本文主要介绍ffmpeg的数据流,在ffmpeg中主要分有三个主要用途用于媒体流的解码播放,媒体流的转换(解码之后再编码)和媒体流录制. 媒体流的解码播放 在ffmpeg ...

  2. FFMPEG 源码分析

    FFMPEG基本概念: ffmpeg是一个开源的编解码框架,它提供了一个音视频录制,解码和编码库.FFMPEG是在linux下开发的,但也有windows下的编译版本. ffmpeg项目由以下几部分组 ...

  3. ffmpeg源码分析-parse_optgroup

    本系列 以 ffmpeg4.2 源码为准,下载地址:链接:百度网盘 提取码:g3k8 ffmpeg 源码分析系列以一条简单的命令开始,ffmpeg -i a.mp4 b.flv,分析其内部逻辑. a. ...

  4. ffmpeg源码分析-transcode_step

    本系列 以 ffmpeg4.2 源码为准,下载地址:链接:百度网盘 提取码:g3k8 ffmpeg 源码分析系列以一条简单的命令开始,ffmpeg -i a.mp4 b.flv,分析其内部逻辑. a. ...

  5. FFmpeg源码分析-直播延迟-内存泄漏

    FFmpeg源码分析-直播延迟-内存泄漏|FFmpeg源码分析方法|ffmpeg播放为什么容易产生延迟|解复用.解码内存泄漏分析 专注后台服务器开发,包括C/C++,Linux,Nginx,ZeroM ...

  6. ffmpeg源码分析-ffmpeg_parse_options

    本系列 以 ffmpeg4.2 源码为准,下载地址:链接:百度网盘 提取码:g3k8 ffmpeg 源码分析系列以一条简单的命令开始,ffmpeg -i a.mp4 b.flv,分析其内部逻辑. a. ...

  7. FFMPEG源码分析(一)

    FFMPEG源码分析(一) ffmpeg之前公司项目中就使用过,但是多停留于应用层面,实现某个功能时,需要哪些结构体以及调用哪些函数.最近想系统的学习一下ffmpeg,于是开始看雷霄骅https:// ...

  8. ffmpeg源码分析与应用示例(一)——H.264解码与QP提取

    本文包含以下内容 1.H.264解码流程详述与对应ffmpeg源码解析 2.针对一个应用实例介绍通过修改ffmpeg源码解决问题的方案 具有较强的综合性. 先介绍一下在第二部分中将要解决的实际问题:自 ...

  9. FFmpeg源码分析:avformat_find_stream_info分析码流信息

    FFmpeg在调用avformat_open_input()之后,可能码流信息不够完整,可以使用avformat_find_stream_info()获取更多的码流信息.比如获取视频帧率.视频宽高,重 ...

  10. ffmpeg源码分析_ffmpeg音视频同步的几种策略

    在前面的文章中,我们介绍了播放器的视频渲染及音频渲染的相关知识,这些都是单独进行的,一旦在现实开发中将视频及音频结合在一起播放就会出现音视频不同步的问题. 下面我们就来分析一下如何解决音视频同步的问题 ...

最新文章

  1. css less 不要作用到子对象_不要盲目的在项目中使用LESS CSS
  2. VMWARE安装LINUX
  3. 一个QQ多用户登陆的实例代码
  4. 设计模式-Adapter模式
  5. matlab与quartus的联合数据交换(NCO与文件数据的混频处理)
  6. “设为桌面图标”的ASP源代码
  7. mysql 回收空间_MySQL表的碎片整理和空间回收小结
  8. CVPR2019 大会信息即时跟进(附CVPR2019全部论文下载、GitHub地址)
  9. python 单元测试 工具_Django单元测试工具test client使用详解
  10. android 控件描边取消重叠
  11. 项目管理工具之maven
  12. 如何在windows 2008 server 新建用户
  13. 我的世界服务器为什么显示崩溃,我的世界服务器崩溃的指令 | 手游网游页游攻略大全...
  14. 音乐播放小程序demo
  15. 与次爱的人相濡以沫,与最爱的人相忘于江湖
  16. 基础篇:6.4)形位公差-符号 Symbol
  17. iText生成pdf带目录
  18. 用java写布尔矩阵奇偶性
  19. 这有清理C盘空间的妙招,学会了就不怕内存满了
  20. Linux进阶学习笔记之——文件服务器之三:FTP服务器

热门文章

  1. 夜神模拟器使用命令行直接运行指定的模拟器
  2. 简单3步,给小程序加个官方的吐槽功能吧!
  3. temp在python里的意思_python temp是什么
  4. WIN10系统安装金蝶K3 WISE14.0以下客户端版本
  5. Scratch 游戏项目学习法 —— 接苹果(六)让苹果掉到下面
  6. icloud连接服务器时出现问题_苹果iCloud连接超时/验证失败解决方法
  7. java2实用教程第三版
  8. Python学习——语法错误与异常
  9. c#自动发送邮箱程序
  10. 用python计算工资工资_php项目中用python来预测薪资(工资)