ffmpeg分析系列之一(注册该注册的)

来源:互联网 发布:开淘宝店怎么卖汉服 编辑:程序博客网 时间:2024/04/28 05:01
  hello,各位好,本人是一名嵌入式软件工程师,目前正使用ffmpeg开发一款嵌入式多媒体播放器,《ffmpeg分析》系列博文是本人在阅读ffmpeg源代码时所做的笔记,希望对各位有点帮助。分析过程结合下面的例程:    http://dranger.com/ffmpeg/tutorial05.c 一. 调用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); }


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<256;i++) ff_cropTbl[i + MAX_NEG_CROP] = i;
    for(i=0;i<MAX_NEG_CROP;i++) {
         ff_cropTbl[i] = 0;
         ff_cropTbl[i + MAX_NEG_CROP + 256] = 255;
    }

     for(i=0;i<512;i++) {
         ff_squareTbl[i] = (i - 256) * (i - 256);
    }

     for(i=0; i<64; i++) inv_zigzag_direct16[ff_zigzag_direct[i]]= i+1;
}

      可以看到, 它初始化了一些静态数据. 1.2 注册所有的格式和外部库及协议.
1. 下面列出与H264相关的注册:

   // 注册分离器和混合器
     REGISTER_MUXDEMUX (H264, h264);

    // 注册文件协议
     REGISTER_PROTOCOL (FILE, file);


2. 下面列出注册宏:

#define REGISTER_MUXER(X,x) { \
    extern AVOutputFormat x##_muxer; \
    if(CONFIG_##X##_MUXER) av_register_output_format(&x##_muxer); }

#define REGISTER_DEMUXER(X,x) { \
    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); }


   这些注册函数与avcodec_register函数类似, 就不多言了.