ffmpeg分析系列之一(注册编解码器) |
您所在的位置:网站首页 › 除了ffmpeg是否还有其他编解码库 › ffmpeg分析系列之一(注册编解码器) |
一. 调用av_register_all函数注册所有的格式和编码解码器.
1.1 先调用avcodec_register_all函数注册所有的编码解码器.
1. 下面列出与H264相关的注册:
// 注册硬件加速器 REGISTER_HWACCEL (H264_DXVA2, h264_dxva2); REGISTER_HWACCEL (H264_VAAPI, h264_vaapi); // 注册解码器 REGISTER_DECODER (H264, h264); REGISTER_DECODER (H264_VDPAU, h264_vdpau); // 注册编码器 REGISTER_ENCODER (LIBX264, libx264); // 注册分析器 REGISTER_PARSER (H264, h264); // 注册位流分离器 REGISTER_BSF (H264_MP4TOANNEXB, h264_mp4toannexb); 2. 下面列出注册宏:#define REGISTER_HWACCEL(X,x) { \ extern AVHWAccel x##_hwaccel; \ if(CONFIG_##X##_HWACCEL) av_register_hwaccel(&x##_hwaccel); } #define REGISTER_ENCODER(X,x) { \ extern AVCodec x##_encoder; \ if(CONFIG_##X##_ENCODER) avcodec_register(&x##_encoder); } #define REGISTER_DECODER(X,x) { \ extern AVCodec x##_decoder; \ if(CONFIG_##X##_DECODER) avcodec_register(&x##_decoder); } #define REGISTER_ENCDEC(X,x) REGISTER_ENCODER(X,x); REGISTER_DECODER(X,x) #define REGISTER_PARSER(X,x) { \ extern AVCodecParser x##_parser; \ if(CONFIG_##X##_PARSER) av_register_codec_parser(&x##_parser); } #define REGISTER_BSF(X,x) { \ extern AVBitStreamFilter x##_bsf; \ if(CONFIG_##X##_BSF) av_register_bitstream_filter(&x##_bsf); } 以MPEG2VEDIO的解码器注册为例来说明:#define REGISTER_DECODER(MPEG2VEDIO,mpeg2video) { \ extern AVCodecmpeg2video_decoder; \ if(CONFIG_MPEG2VEDIO_DECODER) avcodec_register(&mpeg2video_decoder); } 调用:void avcodec_register(AVCodec*codec) { AVCodec **p; avcodec_init(); p = &first_avcodec; //初始化公共变量first_avcodec while(*p != NULL) p = &(*p)->next; *p = codec; codec->next = NULL; } 此处就会将mpeg2video_decoder注册到first_iformat结构体链表中, mpeg2video_decoder结构体在Mpeg12.c中定义。 AVCodec mpegvideo_decoder = { "mpegvideo", CODEC_TYPE_VIDEO, CODEC_ID_MPEG2VIDEO, sizeof(Mpeg1Context), mpeg_decode_init, NULL, mpeg_decode_end, mpeg_decode_frame, CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY, .flush= ff_mpeg_flush, .long_name= NULL_IF_CONFIG_SMALL("MPEG-1 video"), }; 3. 分析一下注册函数, 以avcodec_register函数为例: void avcodec_register(AVCodec *codec) { AVCodec **p; avcodec_init(); p = &first_avcodec; while (*p != NULL) p = &(*p)->next; *p = codec; codec->next = NULL; } 可以看到avcodec_register函数把输入的AVCodec连成一个链表, 其它注册函数与之类似, 就不多言了. 4. 上面调用了avcodec_init函数:void avcodec_init(void) { static int initialized = 0; if (initialized != 0) return; initialized = 1; dsputil_static_init (); } 这个函数只会真正执行一次. 5. 上面调用了dsputil_static_init函数:av_cold void dsputil_static_init(void) { int i; for(i=0;i ff_squareTbl[i] = (i - 256) * (i - 256); } for(i=0; i \ extern AVInputFormat x##_demuxer; \ if(CONFIG_##X##_DEMUXER) av_register_input_format(&x##_demuxer); } #define REGISTER_MUXDEMUX(X,x) REGISTER_MUXER(X,x); REGISTER_DEMUXER(X,x) #define REGISTER_PROTOCOL(X,x) { \ extern URLProtocol x##_protocol; \ if(CONFIG_##X##_PROTOCOL) av_register_protocol(&x##_protocol); }
av_register_input_format (AVInputFormat *format) { AVInputFormat **p; p = &first_iformat; //初始化公共变量first_iformat,这里包含了输入流的格式 while (*p != NULL) p = &(*p)->next; *p = format; format->next = NULL; } voidav_register_output_format(AVOutputFormat *format) { AVOutputFormat **p; p = &first_oformat; //初始化公共变量first_oformat,这里包含了输出流的格式 while (*p != NULL) p = &(*p)->next; *p = format; format->next = NULL; } int av_register_protocol(URLProtocol *protocol) { URLProtocol **p; p = & first_protocol; while (*p != NULL) p = &(*p)->next; *p = protocol; protocol->next = NULL; return 0; }
//以mpegts流为例,x_demuxer将会被mpegts_demux所代替。而mpegts_demux为一个AVInputFormat结构体,其定义在mpegts.c中。
AVInputFormat mpegts_demuxer = { "mpegts", NULL_IF_CONFIG_SMALL("MPEG-2 transport stream format"), sizeof(MpegTSContext), mpegts_probe, mpegts_read_header, mpegts_read_packet, mpegts_read_close, read_seek, mpegts_get_pcr, .flags = AVFMT_SHOW_IDS|AVFMT_TS_DISCONT, };此处的注册会将使所有的复用和解复用注册到first_iformat链表当中。 first_avcodec:全局的变量,将所有的编解码器链接成一个链表:REGISTER_ENCODER(X,x) + REGISTER_DECODER ---> avcodec_register(); first_iformat:全局的变量,将所有的解复用链接一个链表 REGISTER_MUXER(X,x) ---> av_register_input_format() first_oformat:全局的变量,将所以的复用链接成一个链表 。 REGISTER_MUXER(X,x) ----> av_register_output_format() first_protocol:全局的变量,将所有支持的协议链接成链表。 REGISTER_PROTOCOL(X,x) ----> av_register_protocol
ffmpeg支持协议: file , Gopher , HTTP , PIPE, RTP , TCP , UDP.定义在 Allformats.c中: REGISTER_PROTOCOL (FILE, file); REGISTER_PROTOCOL (GOPHER, gopher); REGISTER_PROTOCOL (HTTP, http); REGISTER_PROTOCOL (PIPE, pipe); REGISTER_PROTOCOL (RTP, rtp); REGISTER_PROTOCOL (TCP, tcp); REGISTER_PROTOCOL (UDP, udp);
|
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |