AVCodec是存储编解码器信息的结构体。



下面说一下最主要的几个变量:

const char *name:                                        编解码器的名字,比较短
const char *long_name:                               编解码器的名字,全称,比较长
enum AVMediaType type:                            指明了类型,是视频,音频,还是字幕
enum AVCodecID id:ID,                              不重复
const AVRational *supported_framerates:    支持的帧率(仅视频)
const enum AVPixelFormat *pix_fmts:           支持的像素格式(仅视频)
const int *supported_samplerates:                支持的采样率(仅音频)
const enum AVSampleFormat *sample_fmts:支持的采样格式(仅音频)
const uint64_t *channel_layouts:                  支持的声道数(仅音频)
int priv_data_size:                                         私有数据的大小

详细介绍几个变量:

1.enum AVMediaType type

AVMediaType定义如下:


1. enum AVMediaType {  
2. ///< Usually treated as AVMEDIA_TYPE_DATA  
3.     AVMEDIA_TYPE_VIDEO,  
4.     AVMEDIA_TYPE_AUDIO,  
5. ///< Opaque data information usually continuous  
6.     AVMEDIA_TYPE_SUBTITLE,  
7. ///< Opaque data information usually sparse  
8.     AVMEDIA_TYPE_NB  
9. };



2.enum AVCodecID id


AVCodecID定义如下:


1. enum AVCodecID {  
2.     AV_CODEC_ID_NONE,  
3.   
4. /* video codecs */  
5.     AV_CODEC_ID_MPEG1VIDEO,  
6. ///< preferred ID for MPEG-1/2 video decoding  
7.     AV_CODEC_ID_MPEG2VIDEO_XVMC,  
8.     AV_CODEC_ID_H261,  
9.     AV_CODEC_ID_H263,  
10.     AV_CODEC_ID_RV10,  
11.     AV_CODEC_ID_RV20,  
12.     AV_CODEC_ID_MJPEG,  
13.     AV_CODEC_ID_MJPEGB,  
14.     AV_CODEC_ID_LJPEG,  
15.     AV_CODEC_ID_SP5X,  
16.     AV_CODEC_ID_JPEGLS,  
17.     AV_CODEC_ID_MPEG4,  
18.     AV_CODEC_ID_RAWVIDEO,  
19.     AV_CODEC_ID_MSMPEG4V1,  
20.     AV_CODEC_ID_MSMPEG4V2,  
21.     AV_CODEC_ID_MSMPEG4V3,  
22.     AV_CODEC_ID_WMV1,  
23.     AV_CODEC_ID_WMV2,  
24.     AV_CODEC_ID_H263P,  
25.     AV_CODEC_ID_H263I,  
26.     AV_CODEC_ID_FLV1,  
27.     AV_CODEC_ID_SVQ1,  
28.     AV_CODEC_ID_SVQ3,  
29.     AV_CODEC_ID_DVVIDEO,  
30.     AV_CODEC_ID_HUFFYUV,  
31.     AV_CODEC_ID_CYUV,  
32.     AV_CODEC_ID_H264,  
33.     ...(代码太长,略)  
34. }



3.const enum AVPixelFormat *pix_fmts

AVPixelFormat定义如下:



1. enum AVPixelFormat {  
2.     AV_PIX_FMT_NONE = -1,  
3. ///< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)  
4. ///< packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr  
5. ///< packed RGB 8:8:8, 24bpp, RGBRGB...  
6. ///< packed RGB 8:8:8, 24bpp, BGRBGR...  
7. ///< planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)  
8. ///< planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)  
9. ///< planar YUV 4:1:0,  9bpp, (1 Cr & Cb sample per 4x4 Y samples)  
10. ///< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)  
11. ///<        Y        ,  8bpp  
12. ///<        Y        ,  1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb  
13. ///<        Y        ,  1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb  
14. ///< 8 bit with PIX_FMT_RGB32 palette  
15. ///< planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV420P and setting color_range  
16. ///< planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV422P and setting color_range  
17. ///< planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV444P and setting color_range  
18. ///< XVideo Motion Acceleration via common packet passing  
19.     AV_PIX_FMT_XVMC_MPEG2_IDCT,  
20.     ...(代码太长,略)  
21. }


4.const enum AVSampleFormat *sample_fmts



1. enum AVSampleFormat {  
2.     AV_SAMPLE_FMT_NONE = -1,  
3. ///< unsigned 8 bits  
4. ///< signed 16 bits  
5. ///< signed 32 bits  
6. ///< float  
7. ///< double  
8.   
9. ///< unsigned 8 bits, planar  
10. ///< signed 16 bits, planar  
11. ///< signed 32 bits, planar  
12. ///< float, planar  
13. ///< double, planar  
14.   
15. ///< Number of sample formats. DO NOT USE if linking dynamically  
16. };



每一个编解码器对应一个该结构体,查看一下ffmpeg的源代码,我们可以看一下H.264解码器的结构体如下所示(h264.c):


1. AVCodec ff_h264_decoder = {  
2. "h264",  
3.     .type           = AVMEDIA_TYPE_VIDEO,  
4.     .id             = CODEC_ID_H264,  
5. sizeof(H264Context),  
6.     .init           = ff_h264_decode_init,  
7.     .close          = ff_h264_decode_end,  
8.     .decode         = decode_frame,  
9. /*CODEC_CAP_DRAW_HORIZ_BAND |*/ CODEC_CAP_DR1 | CODEC_CAP_DELAY |  
10.                       CODEC_CAP_SLICE_THREADS | CODEC_CAP_FRAME_THREADS,  
11.     .flush= flush_dpb,  
12. "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),  
13.     .init_thread_copy      = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),  
14.     .update_thread_context = ONLY_IF_THREADS_ENABLED(decode_update_thread_context),  
15.     .profiles = NULL_IF_CONFIG_SMALL(profiles),  
16.     .priv_class     = &h264_class,  
17. };


JPEG2000解码器结构体(j2kdec.c)


1. AVCodec ff_jpeg2000_decoder = {  
2. "j2k",  
3.     .type           = AVMEDIA_TYPE_VIDEO,  
4.     .id             = CODEC_ID_JPEG2000,  
5. sizeof(J2kDecoderContext),  
6.     .init           = j2kdec_init,  
7.     .close          = decode_end,  
8.     .decode         = decode_frame,  
9.     .capabilities = CODEC_CAP_EXPERIMENTAL,  
10. "JPEG 2000"),  
11.     .pix_fmts =  
12. const enum PixelFormat[]) {PIX_FMT_GRAY8, PIX_FMT_RGB24, PIX_FMT_NONE}  
13. };


下面简单介绍一下遍历ffmpeg中的解码器信息的方法(这些解码器以一个链表的形式存储):


1.注册所有编解码器:av_register_all();

2.声明一个AVCodec类型的指针,比如说AVCodec* first_c;

3.调用av_codec_next()函数,即可获得指向链表下一个解码器的指针,循环往复可以获得所有解码器的信息。注意,如果想要获得指向第一个解码器的指针,则需要将该函数的参数设置为NULL。