1. 程式人生 > >ffmpeg 原始碼簡單分析 : av_register_all()

ffmpeg 原始碼簡單分析 : av_register_all()

此前寫了好幾篇ffmpeg原始碼分析文章,列表如下:

============================

前一陣子看了一下ffmpeg的原始碼,並且做了一些註釋,在此貼出來以作備忘。

本文分析一下ffmpeg註冊複用器,編碼器等的函式av_register_all()。該函式在所有基於ffmpeg的應用程式中幾乎都是第一個被呼叫的。只有呼叫了該函式,才能使用複用器,編碼器等。

可見解複用器註冊都是用

REGISTER_DEMUXER  (X,x)

例如:

REGISTER_DEMUXER  (AAC, aac)

可見複用器

註冊都是用

REGISTER_MUXER    (X,x))

例如:

REGISTER_MUXER    (ADTS, adts)

既有解複用器又有複用器的話,可以用

REGISTER_MUXDEMUX (X,x));

例如:

REGISTER_MUXDEMUX (AC3, ac3);

我們來看一下巨集的定義,這裡以解複用器為例:

  1. #define REGISTER_DEMUXER(X,x) { \
  2.     extern AVInputFormat ff_##x##_demuxer; \  
  3.     if(CONFIG_##X##_DEMUXER) av_register_input_format(&ff_##x##_demuxer); }  

注意:define裡面的##可能不太常見,它的含義就是拼接兩個字串,比如

#define Conn(x,y) x##y

那麼

int  n = Conn(123,456);  結果就是n=123456;

我們以REGISTER_DEMUXER  (AAC, aac)為例,則它等效於

  1. extern AVInputFormat ff_aac_demuxer;   
  2. if(CONFIG_AAC_DEMUXER) av_register_input_format(&ff_aac_demuxer);   

從上面這段程式碼我們可以看出,真正註冊的函式是av_register_input_format(&ff_aac_demuxer),那我就看看這個和函式的作用,檢視一下av_register_input_format()的程式碼:
  1. void av_register_input_format(AVInputFormat *format)  
  2. {  
  3.     AVInputFormat **p;  
  4.     p = &first_iformat;  
  5.     while (*p != NULL) p = &(*p)->next;  
  6.     *p = format;  
  7.     format->next = NULL;  
  8. }  

這段程式碼是比較容易理解的,首先先提一點,first_iformat是個什麼東東呢?其實它是Input Format連結串列的頭部地址,是一個全域性靜態變數,定義如下:
  1. /** head of registered input format linked list */
  2. static AVInputFormat *first_iformat = NULL;  
由此我們可以分析出av_register_input_format()的含義,一句話概括就是:遍歷連結串列並把當前的Input Format加到連結串列的尾部。
至此REGISTER_DEMUXER  (X, x)分析完畢。

同理,複用器道理是一樣的,只是註冊函式改為av_register_output_format();

既有解複用器又有複用器的話,有一個巨集定義:

  1. #define REGISTER_MUXDEMUX(X,x)  REGISTER_MUXER(X,x); REGISTER_DEMUXER(X,x)

可見是分別註冊了複用器和解複用器。

此外還有網路協議的註冊,註冊函式為ffurl_register_protocol(),在此不再詳述。

下面貼出它的原始碼(allformats.c)

  1. /* 
  2.  *雷霄驊 
  3.  *[email protected] 
  4.  *中國傳媒大學/數字電視技術 
  5.  */
  6. /* 
  7.  * Register all the formats and protocols 
  8.  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard 
  9.  * 
  10.  * This file is part of FFmpeg. 
  11.  * 
  12.  * FFmpeg is free software; you can redistribute it and/or 
  13.  * modify it under the terms of the GNU Lesser General Public 
  14.  * License as published by the Free Software Foundation; either 
  15.  * version 2.1 of the License, or (at your option) any later version. 
  16.  * 
  17.  * FFmpeg is distributed in the hope that it will be useful, 
  18.  * but WITHOUT ANY WARRANTY; without even the implied warranty of 
  19.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
  20.  * Lesser General Public License for more details. 
  21.  * 
  22.  * You should have received a copy of the GNU Lesser General Public 
  23.  * License along with FFmpeg; if not, write to the Free Software 
  24.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 
  25.  */
  26. #include "avformat.h"
  27. #include "rtp.h"
  28. #include "rdt.h"
  29. #include "url.h"
  30. //定義的巨集?巨集的速度會快一點?註冊AVOutputFormat
  31. //define中,#用來把引數轉換成字串,##則用來連線前後兩個引數,把它們變成一個字串。
  32. //感覺有點像JAva中的EL,可以隨意拼接字串
  33. #define REGISTER_MUXER(X,x) { \
  34.     extern AVOutputFormat ff_##x##_muxer; \  
  35.     if(CONFIG_##X##_MUXER) av_register_output_format(&ff_##x##_muxer); }  
  36. //定義的巨集?巨集的速度會快一點?註冊AVInputFormat
  37. #define REGISTER_DEMUXER(X,x) { \
  38.     extern AVInputFormat ff_##x##_demuxer; \  
  39.     if(CONFIG_##X##_DEMUXER) av_register_input_format(&ff_##x##_demuxer); }  
  40. //註冊函式av_register_input_format
  41. //定義的巨集?巨集的速度會快一點?兩個一起註冊!
  42. #define REGISTER_MUXDEMUX(X,x)  REGISTER_MUXER(X,x); REGISTER_DEMUXER(X,x)
  43. //定義的巨集?巨集的速度會快一點?註冊URLProtocol
  44. //extern URLProtocol ff_##x##_protocol;
  45. //在librtmp中,對應的就是ff_rtmp_protocol
  46. //這樣就把librtmp整合起來了
  47. //由此可見URLProtocol的名字是固定的
  48. #define REGISTER_PROTOCOL(X,x) { \
  49.     extern URLProtocol ff_##x##_protocol; \  
  50.     if(CONFIG_##X##_PROTOCOL) ffurl_register_protocol(&ff_##x##_protocol, sizeof(ff_##x##_protocol)); }  
  51. //註冊函式ffurl_register_protocol
  52. void av_register_all(void)  
  53. {  
  54.     staticint initialized;  
  55.     if (initialized)  
  56.         return;  
  57.     initialized = 1;  
  58.     //註冊所有的codec
  59.     avcodec_register_all();  
  60.     //註冊所有的MUXER(複用器和解複用器)
  61.     /* (de)muxers */
  62.     REGISTER_MUXER    (A64, a64);  
  63.     REGISTER_DEMUXER  (AAC, aac);  
  64.     REGISTER_MUXDEMUX (AC3, ac3);  
  65.     REGISTER_DEMUXER  (ACT, act);  
  66.     REGISTER_DEMUXER  (ADF, adf);  
  67.     REGISTER_MUXER    (ADTS, adts);  
  68.     REGISTER_MUXDEMUX (ADX, adx);  
  69.     REGISTER_DEMUXER  (AEA, aea);  
  70.     REGISTER_MUXDEMUX (AIFF, aiff);  
  71.     REGISTER_MUXDEMUX (AMR, amr);  
  72.     REGISTER_DEMUXER  (ANM, anm);  
  73.     REGISTER_DEMUXER  (APC, apc);  
  74.     REGISTER_DEMUXER  (APE, ape);  
  75.     REGISTER_DEMUXER  (APPLEHTTP, applehttp);  
  76.     REGISTER_MUXDEMUX (ASF, asf);  
  77.     REGISTER_MUXDEMUX (ASS, ass);  
  78.     REGISTER_MUXER    (ASF_STREAM, asf_stream);  
  79.     REGISTER_MUXDEMUX (AU, au);  
  80.     REGISTER_MUXDEMUX (AVI, avi);  
  81.     REGISTER_DEMUXER  (AVISYNTH, avisynth);  
  82.     REGISTER_MUXER    (AVM2, avm2);  
  83.     REGISTER_DEMUXER  (AVS, avs);  
  84.     REGISTER_DEMUXER  (BETHSOFTVID, bethsoftvid);  
  85.     REGISTER_DEMUXER  (BFI, bfi);  
  86.     REGISTER_DEMUXER  (BINTEXT, bintext);  
  87.     REGISTER_DEMUXER  (BINK, bink);  
  88.     REGISTER_MUXDEMUX (BIT, bit);  
  89.     REGISTER_DEMUXER  (BMV, bmv);  
  90.     REGISTER_DEMUXER  (C93, c93);  
  91.     REGISTER_MUXDEMUX (CAF, caf);  
  92.     REGISTER_MUXDEMUX (CAVSVIDEO, cavsvideo);  
  93.     REGISTER_DEMUXER  (CDG, cdg);  
  94.     REGISTER_MUXER    (CRC, crc);  
  95.     REGISTER_MUXDEMUX (DAUD, daud);  
  96.     REGISTER_DEMUXER  (DFA, dfa);  
  97.     REGISTER_MUXDEMUX (DIRAC, dirac);  
  98.     REGISTER_MUXDEMUX (DNXHD, dnxhd);  
  99.     REGISTER_DEMUXER  (DSICIN, dsicin);  
  100.     REGISTER_MUXDEMUX (DTS, dts);  
  101.     REGISTER_MUXDEMUX (DV, dv);  
  102. 相關推薦

    ffmpeg 原始碼簡單分析 av_register_all()

    此前寫了好幾篇ffmpeg原始碼分析文章,列表如下: ============================ 前一陣子看了一下ffmpeg的原始碼,並且做了一些註釋,在此貼出來以作備忘。 本文分析一下ffmpeg註冊

    ffmpeg 原始碼簡單分析 av_read_frame()

    此前寫了好幾篇ffmpeg原始碼分析文章,列表如下: ============================ ffmpeg中的av_read_frame()的作用是讀取碼流中的音訊若干幀或者視訊一幀。例如,解碼視訊的時

    FFmpeg原始碼簡單分析makefile

    =====================================================FFmpeg的庫函式原始碼分析文章列表:【架構圖】【通用】【解碼】【編碼】【其它】【指令碼】【H.264】================================

    FFmpeg原始碼簡單分析結構體成員管理系統-AVClass

    =====================================================FFmpeg的庫函式原始碼分析文章列表:【架構圖】【通用】【解碼】【編碼】【其它】【指令碼】【H.264】================================

    FFmpeg原始碼簡單分析avcodec_open2()

    =====================================================FFmpeg的庫函式原始碼分析文章列表:【架構圖】【通用】【解碼】【編碼】【其它】【指令碼】【H.264】================================

    FFmpeg原始碼簡單分析avformat_close_input()

    =====================================================FFmpeg的庫函式原始碼分析文章列表:【架構圖】【通用】【解碼】【編碼】【其它】【指令碼】【H.264】================================

    FFmpeg原始碼簡單分析av_write_frame()

    =====================================================FFmpeg的庫函式原始碼分析文章列表:【架構圖】【通用】【解碼】【編碼】【其它】【指令碼】【H.264】================================

    FFmpeg原始碼簡單分析常見結構體的初始化和銷燬(AVFormatContext,AVFrame等)

    =====================================================FFmpeg的庫函式原始碼分析文章列表:【架構圖】【通用】【解碼】【編碼】【其它】【指令碼】【H.264】================================

    FFmpeg原始碼簡單分析記憶體的分配和釋放(av_malloc()、av_free()等)

    =====================================================FFmpeg的庫函式原始碼分析文章列表:【架構圖】【通用】【解碼】【編碼】【其它】【指令碼】【H.264】================================

    FFmpeg原始碼簡單分析avcodec_encode_video()

    =====================================================FFmpeg的庫函式原始碼分析文章列表:【架構圖】【通用】【解碼】【編碼】【其它】【指令碼】【H.264】================================

    FFmpeg原始碼簡單分析configure

    =====================================================FFmpeg的庫函式原始碼分析文章列表:【架構圖】【通用】【解碼】【編碼】【其它】【指令碼】【H.264】================================

    FFmpeg的H.264解碼器原始碼簡單分析概述

    =====================================================H.264原始碼分析文章列表:【編碼 - x264】【解碼 - libavcodec H.264 解碼器】================================

    FFmpeg的HEVC解碼器原始碼簡單分析CTU解碼(CTU Decode)部分-TU

    =====================================================HEVC原始碼分析文章列表:【解碼 -libavcodec HEVC 解碼器】==============================================

    FFmpeg的H.264解碼器原始碼簡單分析解碼器主幹部分

    =====================================================H.264原始碼分析文章列表:【編碼 - x264】【解碼 - libavcodec H.264 解碼器】================================

    FFmpeg的H.264解碼器原始碼簡單分析熵解碼(Entropy Decoding)部分

    =====================================================H.264原始碼分析文章列表:【編碼 - x264】【解碼 - libavcodec H.264 解碼器】================================

    H264編碼器5( x264原始碼簡單分析x264_slice_write() 與H264 編碼簡介)

      x264原始碼簡單分析:x264_slice_write() 來自:https://blog.csdn.net/leixiaohua1020/article/details/45536607     H264 編碼簡介 https://blo

    H264編碼器4( x264原始碼簡單分析概述)

    來自:https://blog.csdn.net/leixiaohua1020/article/details/45536607   ===================================================== H.264原始碼分析文章列表:

    FFmpeg原始碼簡單分析 avio open2

                    =====================================================FFmpeg的庫函式原始碼分析文章列表:【架構圖】【通用】【解碼】【編碼】【其它】【指令碼】【H.264】=================================

    FFmpeg原始碼簡單分析 avcodec encode video

                    =====================================================FFmpeg的庫函式原始碼分析文章列表:【架構圖】【通用】【解碼】【編碼】【其它】【指令碼】【H.264】=================================

    FFmpeg源代碼簡單分析常見結構體的初始化和銷毀(AVFormatContext,AVFrame等)

    new init _array border 代碼 alloc ecc .com VC 結構體 初始化 銷毀 AVFormatContext avformat_alloc_context() avfo