当前位置:   article > 正文

FFmpeg源码分析:avcodec_find_decoder()查找解码器

FFmpeg源码分析:avcodec_find_decoder()查找解码器

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来查找解码器的方法如下:

  1. AVCodec *avcodec_find_decoder(enum AVCodecID id)
  2. {
  3. return find_codec(id, av_codec_is_decoder);
  4. }

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

  1. static AVCodec *find_codec(enum AVCodecID id, int (*x)(const AVCodec *))
  2. {
  3. const AVCodec *p, *experimental = NULL;
  4. void *i = 0;
  5. id = remap_deprecated_codec_id(id);
  6. while ((p = av_codec_iterate(&i))) {
  7. if (!x(p))
  8. continue;
  9. if (p->id == id) {
  10. if (p->capabilities & AV_CODEC_CAP_EXPERIMENTAL && !experimental) {
  11. experimental = p;
  12. } else
  13. return (AVCodec*)p;
  14. }
  15. }
  16. return (AVCodec*)experimental;
  17. }

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

  1. static void av_codec_init_static(void)
  2. {
  3. for (int i = 0; codec_list[i]; i++) {
  4. if (codec_list[i]->init_static_data)
  5. codec_list[i]->init_static_data((AVCodec*)codec_list[i]);
  6. }
  7. }
  8. const AVCodec *av_codec_iterate(void **opaque)
  9. {
  10. uintptr_t i = (uintptr_t)*opaque;
  11. const AVCodec *c = codec_list[i];
  12. ff_thread_once(&av_codec_static_init, av_codec_init_static);
  13. if (c)
  14. *opaque = (void*)(i + 1);
  15. return c;
  16. }

2、avcodec_find_decoder_by_name

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

  1. AVCodec *avcodec_find_decoder_by_name(const char *name)
  2. {
  3. return find_codec_by_name(name, av_codec_is_decoder);
  4. }

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

  1. static AVCodec *find_codec_by_name(const char *name, int (*x)(const AVCodec *))
  2. {
  3. void *i = 0;
  4. const AVCodec *p;
  5. if (!name)
  6. return NULL;
  7. while ((p = av_codec_iterate(&i))) {
  8. if (!x(p))
  9. continue;
  10. if (strcmp(name, p->name) == 0)
  11. return (AVCodec*)p;
  12. }
  13. return NULL;
  14. }

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

二、查找编码器

1、avcodec_find_encoder

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

  1. AVCodec *avcodec_find_encoder(enum AVCodecID id)
  2. {
  3. return find_codec(id, av_codec_is_encoder);
  4. }

2、avcodec_find_encoder_by_name

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

  1. AVCodec *avcodec_find_encoder_by_name(const char *name)
  2. {
  3. return find_codec_by_name(name, av_codec_is_encoder);
  4. }

三、编解码器列表与id

1、 编解码器列表

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

  1. extern AVCodec ff_flv_encoder;
  2. extern AVCodec ff_flv_decoder;
  3. extern AVCodec ff_h264_decoder;
  4. extern AVCodec ff_hevc_decoder;
  5. extern AVCodec ff_mpeg4_encoder;
  6. extern AVCodec ff_mpeg4_decoder;
  7. extern AVCodec ff_msmpeg4v1_decoder;
  8. extern AVCodec ff_msmpeg4v2_encoder;
  9. extern AVCodec ff_msmpeg4v2_decoder;
  10. extern AVCodec ff_msmpeg4v3_encoder;
  11. extern AVCodec ff_msmpeg4v3_decoder;
  12. extern AVCodec ff_vp8_decoder;
  13. extern AVCodec ff_vp9_decoder;
  14. extern AVCodec ff_wmv1_encoder;
  15. extern AVCodec ff_wmv1_decoder;
  16. extern AVCodec ff_wmv2_encoder;
  17. extern AVCodec ff_wmv2_decoder;
  18. extern AVCodec ff_wmv3_decoder;
  19. /* audio codecs */
  20. extern AVCodec ff_aac_encoder;
  21. extern AVCodec ff_aac_decoder;
  22. extern AVCodec ff_ac3_encoder;
  23. extern AVCodec ff_ac3_decoder;
  24. extern AVCodec ff_amrnb_decoder;
  25. extern AVCodec ff_amrwb_decoder;
  26. extern AVCodec ff_ape_decoder;
  27. extern AVCodec ff_eac3_encoder;
  28. extern AVCodec ff_eac3_decoder;
  29. extern AVCodec ff_flac_encoder;
  30. extern AVCodec ff_flac_decoder;
  31. extern AVCodec ff_mp3_decoder;
  32. extern AVCodec ff_opus_encoder;
  33. extern AVCodec ff_opus_decoder;
  34. extern AVCodec ff_truehd_encoder;
  35. extern AVCodec ff_truehd_decoder;
  36. extern AVCodec ff_vorbis_encoder;
  37. extern AVCodec ff_vorbis_decoder;
  38. extern AVCodec ff_wmav1_encoder;
  39. extern AVCodec ff_wmav1_decoder;
  40. extern AVCodec ff_wmav2_encoder;
  41. extern AVCodec ff_wmav2_decoder;
  42. /* PCM codecs */
  43. extern AVCodec ff_pcm_alaw_encoder;
  44. extern AVCodec ff_pcm_alaw_decoder;
  45. extern AVCodec ff_pcm_mulaw_encoder;
  46. extern AVCodec ff_pcm_mulaw_decoder;
  47. extern AVCodec ff_pcm_s8_encoder;
  48. extern AVCodec ff_pcm_s8_decoder;
  49. extern AVCodec ff_pcm_s16le_encoder;
  50. extern AVCodec ff_pcm_s16le_decoder;
  51. extern AVCodec ff_pcm_s16le_planar_encoder;
  52. extern AVCodec ff_pcm_s16le_planar_decoder;
  53. extern AVCodec ff_pcm_s24le_encoder;
  54. extern AVCodec ff_pcm_s24le_decoder;
  55. extern AVCodec ff_pcm_s32le_encoder;
  56. extern AVCodec ff_pcm_s32le_decoder;
  57. extern AVCodec ff_pcm_s64le_encoder;
  58. extern AVCodec ff_pcm_s64le_decoder;
  59. extern AVCodec ff_pcm_u8_encoder;
  60. extern AVCodec ff_pcm_u8_decoder;
  61. /* ADPCM codecs */
  62. extern AVCodec ff_adpcm_ima_wav_encoder;
  63. extern AVCodec ff_adpcm_ima_wav_decoder;
  64. extern AVCodec ff_adpcm_ms_encoder;
  65. extern AVCodec ff_adpcm_ms_decoder;
  66. /* subtitles */
  67. extern AVCodec ff_ssa_encoder;
  68. extern AVCodec ff_ssa_decoder;
  69. extern AVCodec ff_ass_encoder;
  70. extern AVCodec ff_ass_decoder;
  71. extern AVCodec ff_movtext_encoder;
  72. extern AVCodec ff_movtext_decoder;
  73. extern AVCodec ff_pgssub_decoder;
  74. extern AVCodec ff_sami_decoder;
  75. extern AVCodec ff_srt_encoder;
  76. extern AVCodec ff_srt_decoder;
  77. extern AVCodec ff_subrip_encoder;
  78. extern AVCodec ff_subrip_decoder;
  79. extern AVCodec ff_ttml_encoder;
  80. extern AVCodec ff_webvtt_encoder;
  81. extern AVCodec ff_webvtt_decoder;
  82. /* external libraries */
  83. extern AVCodec ff_aac_at_encoder;
  84. extern AVCodec ff_aac_at_decoder;
  85. extern AVCodec ff_ac3_at_decoder;
  86. extern AVCodec ff_amr_nb_at_decoder;
  87. extern AVCodec ff_eac3_at_decoder;
  88. extern AVCodec ff_mp3_at_decoder;
  89. extern AVCodec ff_libaom_av1_encoder;
  90. extern AVCodec ff_libdav1d_decoder;
  91. extern AVCodec ff_libfdk_aac_encoder;
  92. extern AVCodec ff_libfdk_aac_decoder;
  93. extern AVCodec ff_libmp3lame_encoder;
  94. extern AVCodec ff_libopencore_amrnb_decoder;
  95. extern AVCodec ff_libopencore_amrwb_decoder;
  96. extern AVCodec ff_libopus_encoder;
  97. extern AVCodec ff_libopus_decoder;
  98. extern AVCodec ff_libshine_encoder;
  99. extern AVCodec ff_libspeex_encoder;
  100. extern AVCodec ff_libspeex_decoder;
  101. extern AVCodec ff_libvorbis_encoder;
  102. extern AVCodec ff_libvorbis_decoder;
  103. extern AVCodec ff_libvpx_vp8_encoder;
  104. extern AVCodec ff_libvpx_vp8_decoder;
  105. extern AVCodec ff_libvpx_vp9_encoder;
  106. extern AVCodec ff_libvpx_vp9_decoder;
  107. extern AVCodec ff_libwebp_encoder;
  108. extern AVCodec ff_libx264_encoder;
  109. extern AVCodec ff_libx265_encoder;
  110. /* hwaccel hooks only, so prefer external decoders */
  111. extern AVCodec ff_av1_decoder;
  112. extern AVCodec ff_av1_cuvid_decoder;
  113. extern AVCodec ff_av1_qsv_decoder;
  114. extern AVCodec ff_libopenh264_encoder;
  115. extern AVCodec ff_libopenh264_decoder;
  116. extern AVCodec ff_h264_cuvid_decoder;
  117. extern AVCodec ff_h264_nvenc_encoder;
  118. extern AVCodec ff_h264_omx_encoder;
  119. extern AVCodec ff_h264_qsv_encoder;
  120. extern AVCodec ff_h264_v4l2m2m_encoder;
  121. extern AVCodec ff_h264_vaapi_encoder;
  122. extern AVCodec ff_h264_videotoolbox_encoder;
  123. extern AVCodec ff_hevc_mediacodec_decoder;
  124. extern AVCodec ff_hevc_nvenc_encoder;
  125. extern AVCodec ff_hevc_qsv_encoder;
  126. extern AVCodec ff_hevc_v4l2m2m_encoder;
  127. extern AVCodec ff_hevc_vaapi_encoder;
  128. extern AVCodec ff_hevc_videotoolbox_encoder;
  129. extern AVCodec ff_mp3_mf_encoder;
  130. extern AVCodec ff_mpeg4_cuvid_decoder;
  131. extern AVCodec ff_mpeg4_mediacodec_decoder;
  132. extern AVCodec ff_mpeg4_omx_encoder;
  133. extern AVCodec ff_mpeg4_v4l2m2m_encoder;
  134. extern AVCodec ff_vp9_cuvid_decoder;
  135. extern AVCodec ff_vp9_mediacodec_decoder;
  136. extern AVCodec ff_vp9_qsv_decoder;
  137. extern AVCodec ff_vp9_vaapi_encoder;
  138. extern AVCodec ff_vp9_qsv_encoder;

2、编解码器id

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

  1. enum AVCodecID {
  2. AV_CODEC_ID_NONE,
  3. /* video codecs */
  4. AV_CODEC_ID_MPEG1VIDEO,
  5. AV_CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decoding
  6. AV_CODEC_ID_MPEG4,
  7. AV_CODEC_ID_MSMPEG4V1,
  8. AV_CODEC_ID_MSMPEG4V2,
  9. AV_CODEC_ID_MSMPEG4V3,
  10. AV_CODEC_ID_WMV1,
  11. AV_CODEC_ID_WMV2,
  12. AV_CODEC_ID_FLV1,
  13. AV_CODEC_ID_H264,
  14. AV_CODEC_ID_PNG,
  15. AV_CODEC_ID_VC1,
  16. AV_CODEC_ID_WMV3,
  17. AV_CODEC_ID_AVS,
  18. AV_CODEC_ID_JPEG2000,
  19. AV_CODEC_ID_GIF,
  20. AV_CODEC_ID_VP8,
  21. AV_CODEC_ID_VP9,
  22. AV_CODEC_ID_HEVC,
  23. #define AV_CODEC_ID_H265 AV_CODEC_ID_HEVC
  24. AV_CODEC_ID_VVC,
  25. #define AV_CODEC_ID_H266 AV_CODEC_ID_VVC
  26. AV_CODEC_ID_AV1,
  27. /* various PCM "codecs" */
  28. AV_CODEC_ID_PCM_S16LE = 0x10000,
  29. AV_CODEC_ID_PCM_S16BE,
  30. AV_CODEC_ID_PCM_S8,
  31. AV_CODEC_ID_PCM_U8,
  32. AV_CODEC_ID_PCM_MULAW,
  33. AV_CODEC_ID_PCM_ALAW,
  34. AV_CODEC_ID_PCM_S32LE,
  35. AV_CODEC_ID_PCM_S24LE,
  36. AV_CODEC_ID_PCM_S24DAUD,
  37. AV_CODEC_ID_PCM_S16LE_PLANAR,
  38. AV_CODEC_ID_PCM_F32LE,
  39. AV_CODEC_ID_PCM_F64LE,
  40. AV_CODEC_ID_PCM_S8_PLANAR,
  41. AV_CODEC_ID_PCM_S24LE_PLANAR,
  42. AV_CODEC_ID_PCM_S32LE_PLANAR,
  43. AV_CODEC_ID_PCM_S64LE = 0x10800,
  44. AV_CODEC_ID_PCM_F16LE,
  45. AV_CODEC_ID_PCM_F24LE,
  46. /* various ADPCM codecs */
  47. AV_CODEC_ID_ADPCM_IMA_QT = 0x11000,
  48. AV_CODEC_ID_ADPCM_IMA_WAV,
  49. AV_CODEC_ID_ADPCM_MS,
  50. AV_CODEC_ID_ADPCM_AFC = 0x11800,
  51. AV_CODEC_ID_ADPCM_IMA_OKI,
  52. /* AMR */
  53. AV_CODEC_ID_AMR_NB = 0x12000,
  54. AV_CODEC_ID_AMR_WB,
  55. /* audio codecs */
  56. AV_CODEC_ID_MP2 = 0x15000,
  57. AV_CODEC_ID_MP3, ///< preferred ID for decoding MPEG audio layer 1, 2 or 3
  58. AV_CODEC_ID_AAC,
  59. AV_CODEC_ID_AC3,
  60. AV_CODEC_ID_VORBIS,
  61. AV_CODEC_ID_WMAV1,
  62. AV_CODEC_ID_WMAV2,
  63. AV_CODEC_ID_FLAC,
  64. AV_CODEC_ID_APE,
  65. AV_CODEC_ID_EAC3,
  66. AV_CODEC_ID_TRUEHD,
  67. AV_CODEC_ID_OPUS,
  68. /* subtitle codecs */
  69. AV_CODEC_ID_DVD_SUBTITLE = 0x17000,
  70. AV_CODEC_ID_DVB_SUBTITLE,
  71. AV_CODEC_ID_SSA,
  72. AV_CODEC_ID_MOV_TEXT,
  73. AV_CODEC_ID_SRT,
  74. AV_CODEC_ID_MICRODVD = 0x17800,
  75. AV_CODEC_ID_SAMI,
  76. AV_CODEC_ID_SUBRIP,
  77. AV_CODEC_ID_WEBVTT,
  78. AV_CODEC_ID_ASS,
  79. AV_CODEC_ID_TTML,
  80. AV_CODEC_ID_TTF = 0x18000,
  81. };

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/446339
推荐阅读
相关标签
  

闽ICP备14008679号