赞
踩
FFmpeg提供两种方式查找解码器,通过codecId查找avcodec_find_decoder()与通过名字查找avcodec_find_decoder_by_name()。同样地,也提供两种方式查找编码器,通过codecId查找avcodec_find_encoder()与通过名字查找avcodec_find_encoder_by_name()。源码位于libavcodec/allcodecs.c中。
查找编解码器过程如下图所示:
通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;
- } else
- return (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;
- }
通过名字查找解码器的方法如下:
- 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。
通过codecId查找编码器的方法如下:
- AVCodec *avcodec_find_encoder(enum AVCodecID id)
- {
- return find_codec(id, av_codec_is_encoder);
- }
通过名字查找编码器的方法如下:
- AVCodec *avcodec_find_encoder_by_name(const char *name)
- {
- return find_codec_by_name(name, av_codec_is_encoder);
- }
编解码器列表来自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;
编解码器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 decoding
- AV_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_HEVC
- AV_CODEC_ID_VVC,
- #define AV_CODEC_ID_H266 AV_CODEC_ID_VVC
- AV_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 3
- AV_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,
- };
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。