ffmpeg分析系列之一(注册编解码器)

您所在的位置:网站首页 除了ffmpeg是否还有其他编解码库 ffmpeg分析系列之一(注册编解码器)

ffmpeg分析系列之一(注册编解码器)

2024-07-16 02:27:12| 来源: 网络整理| 查看: 265

一. 调用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);



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭