zoukankan      html  css  js  c++  java
  • FFmpeg AVCodec

    FFmpeg编解码

    FFmpeg支持绝大多数视频编解码格式,如何遍历FFmpeg编解码器?

    编解码器以链表形式存储,使用av_codec_next() 函数可以获取编解码器指针,当参数为NULL时,获取第一个编解码器指针,循环遍历,获取所有编解码器信息

    void avcodecInfo()
    {
         av_register_all();
         AVCodec *c_temp = av_codec_next(NULL);
         while(c_temp!=NULL){
             if (c_temp->encode2!=NULL) {
                 switch (c_temp->type){
                     case AVMEDIA_TYPE_VIDEO:
                         printf("[video encode] %10s
    ", c_temp->name);
                         break;
                     case AVMEDIA_TYPE_AUDIO:
                         printf("[audio encode] %10s
    ", c_temp->name);
                         break;
                     default:
                         printf("[other encode] %10s
    ", c_temp->name);
                         break;
                 }
             }
             c_temp=c_temp->next;
         }
    }
    

    AVCodec登场

    遍历FFmpeg编解码器的时候,出现了AVCodec,什么是AVCodec?

    AVCodec是存储编解码器信息的结构体,包含了编解码器的基本信息,例如编解码器的名称,编解码类型(video or audio),以及编解码的参数等。下面列举了常用字段:

    • 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; //支持声道数(音频)
    • const AVClass *priv_class; //私有数据

    AVCodec结构体

    mpeg2video(video)编码器结构体
    Video
    pcm_bluray(audio)解码器结构体
    Audio
    注意:在编解码的时候,要设置为编解码器支持的格式,例如给mpeg2video编码器设置pix_fmts为AV_PIX_FMT_NV12,则会报出以下错误:

    Error:Specified pixel format nv12 is invalid or not supported

    AVCodec结构体内容

    typedef struct AVCodec {
        /**
         * Name of the codec implementation.
         * The name is globally unique among encoders and among decoders (but an
         * encoder and a decoder can share the same name).
         * This is the primary way to find a codec from the user perspective.
         */
        const char *name;   
        /**
         * Descriptive name for the codec, meant to be more human readable than name.
         * You should use the NULL_IF_CONFIG_SMALL() macro to define it.
         */
        const char *long_name;  
        enum AVMediaType type; 
        enum AVCodecID id;       
        /**
         * Codec capabilities.
         * see AV_CODEC_CAP_*
         */
        int capabilities;
        const AVRational *supported_framerates; ///< array of supported framerates, or NULL if any, array is terminated by {0,0} 
        const enum AVPixelFormat *pix_fmts;     ///< array of supported pixel formats, or NULL if unknown, array is terminated by -1
        const int *supported_samplerates;       ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0
        const enum AVSampleFormat *sample_fmts; ///< array of supported sample formats, or NULL if unknown, array is terminated by -1
        const uint64_t *channel_layouts;         ///< array of support channel layouts, or NULL if unknown. array is terminated by 0
        uint8_t max_lowres;                     ///< maximum value for lowres supported by the decoder
        const AVClass *priv_class;              ///< AVClass for the private context
        const AVProfile *profiles;              ///< array of recognized profiles, or NULL if unknown, array is terminated by {FF_PROFILE_UNKNOWN}
    
        /*****************************************************************
         * No fields below this line are part of the public API. They
         * may not be used outside of libavcodec and can be changed and
         * removed at will.
         * New public fields should be added right above.
         *****************************************************************
         */
        int priv_data_size;
        struct AVCodec *next;
        /**
         * @name Frame-level threading support functions
         * @{
         */
        /**
         * If defined, called on thread contexts when they are created.
         * If the codec allocates writable tables in init(), re-allocate them here.
         * priv_data will be set to a copy of the original.
         */
        int (*init_thread_copy)(AVCodecContext *);
        /**
         * Copy necessary context variables from a previous thread context to the current one.
         * If not defined, the next thread will start automatically; otherwise, the codec
         * must call ff_thread_finish_setup().
         *
         * dst and src will (rarely) point to the same context, in which case memcpy should be skipped.
         */
        int (*update_thread_context)(AVCodecContext *dst, const AVCodecContext *src);
        /** @} */
    
        /**
         * Private codec-specific defaults.
         */
        const AVCodecDefault *defaults;
    
        /**
         * Initialize codec static data, called from avcodec_register().
         */
        void (*init_static_data)(struct AVCodec *codec);
    
        int (*init)(AVCodecContext *);
        int (*encode_sub)(AVCodecContext *, uint8_t *buf, int buf_size,
                          const struct AVSubtitle *sub);
        /**
         * Encode data to an AVPacket.
         *
         * @param      avctx          codec context
         * @param      avpkt          output AVPacket (may contain a user-provided buffer)
         * @param[in]  frame          AVFrame containing the raw data to be encoded
         * @param[out] got_packet_ptr encoder sets to 0 or 1 to indicate that a
         *                            non-empty packet was returned in avpkt.
         * @return 0 on success, negative error code on failure
         */
        int (*encode2)(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame,
                       int *got_packet_ptr);
        int (*decode)(AVCodecContext *, void *outdata, int *outdata_size, AVPacket *avpkt);
        int (*close)(AVCodecContext *);
        /**
         * Encode API with decoupled packet/frame dataflow. The API is the
         * same as the avcodec_ prefixed APIs (avcodec_send_frame() etc.), except
         * that:
         * - never called if the codec is closed or the wrong type,
         * - if AV_CODEC_CAP_DELAY is not set, drain frames are never sent,
         * - only one drain frame is ever passed down,
         */
        int (*send_frame)(AVCodecContext *avctx, const AVFrame *frame);
        int (*receive_packet)(AVCodecContext *avctx, AVPacket *avpkt);
    
        /**
         * Decode API with decoupled packet/frame dataflow. This function is called
         * to get one output frame. It should call ff_decode_get_packet() to obtain
         * input data.
         */
        int (*receive_frame)(AVCodecContext *avctx, AVFrame *frame);
        /**
         * Flush buffers.
         * Will be called when seeking
         */
        void (*flush)(AVCodecContext *);
        /**
         * Internal codec capabilities.
         * See FF_CODEC_CAP_* in internal.h
         */
        int caps_internal;
    
        /**
         * Decoding only, a comma-separated list of bitstream filters to apply to
         * packets before decoding.
         */
        const char *bsfs;
    } AVCodec;
    

    关联类型

    从AVCodec中,字段除了基本数据类型,还涉及到了其它结构体和枚举,例如AVMediaType,AVCodecID,AVRational,AVPixelFormat,AVSampleFormat,AVClass等。

    AVMediaType媒体类型,是视频,音频,字幕等。

    enum AVMediaType {
        AVMEDIA_TYPE_UNKNOWN = -1,  ///< Usually treated as AVMEDIA_TYPE_DATA
        AVMEDIA_TYPE_VIDEO,
        AVMEDIA_TYPE_AUDIO,
        AVMEDIA_TYPE_DATA,          ///< Opaque data information usually continuous
        AVMEDIA_TYPE_SUBTITLE,
        AVMEDIA_TYPE_ATTACHMENT,    ///< Opaque data information usually sparse
        AVMEDIA_TYPE_NB
    };
    

    AVCodecID编解码器唯一标识符

    enum AVCodecID {
        AV_CODEC_ID_NONE,
    
        /* video codecs */
        AV_CODEC_ID_MPEG1VIDEO,
        AV_CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decoding
    #if FF_API_XVMC
        AV_CODEC_ID_MPEG2VIDEO_XVMC,
    #endif /* FF_API_XVMC */
        AV_CODEC_ID_H261,
        AV_CODEC_ID_H263,
        AV_CODEC_ID_RV10,
        AV_CODEC_ID_RV20,
        .......
    }
    

    AVPixelFormat视频格式,如RGB,YUV等

    enum AVPixelFormat {
        AV_PIX_FMT_NONE = -1,
        AV_PIX_FMT_YUV420P,   ///< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
        AV_PIX_FMT_YUYV422,   ///< packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
        AV_PIX_FMT_RGB24,     ///< packed RGB 8:8:8, 24bpp, RGBRGB...
        AV_PIX_FMT_BGR24,     ///< packed RGB 8:8:8, 24bpp, BGRBGR...
        AV_PIX_FMT_YUV422P,   ///< planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
        AV_PIX_FMT_YUV444P,   ///< planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
        AV_PIX_FMT_YUV410P,   ///< planar YUV 4:1:0,  9bpp, (1 Cr & Cb sample per 4x4 Y samples)
        AV_PIX_FMT_YUV411P,   ///< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
        AV_PIX_FMT_GRAY8,     ///<        Y        ,  8bpp
        AV_PIX_FMT_MONOWHITE, ///<        Y        ,  1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb
        AV_PIX_FMT_MONOBLACK, ///<        Y        ,  1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb
        AV_PIX_FMT_PAL8,      ///< 8 bits with AV_PIX_FMT_RGB32 palette
        AV_PIX_FMT_YUVJ420P,  ///< planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting color_range
        AV_PIX_FMT_YUVJ422P,  ///< planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting color_range
        AV_PIX_FMT_YUVJ444P,  ///< planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting color_range
    #if FF_API_XVMC
        AV_PIX_FMT_XVMC_MPEG2_MC,///< XVideo Motion Acceleration via common packet passing
        AV_PIX_FMT_XVMC_MPEG2_IDCT,
        AV_PIX_FMT_XVMC = AV_PIX_FMT_XVMC_MPEG2_IDCT,
    #endif /* FF_API_XVMC */
        AV_PIX_FMT_UYVY422,   
        ......
    }
    

    AVSampleFormat采样格式,其中带P结尾的为平面格式。例如对于双通道音频,设左通道为L,右通道为R,如果是平面格式,在内存中的排列为LLLLLL……RRRRRR……,对于非平面格式,内存中排列为LRLRLRLRLR……

    enum AVSampleFormat {
        AV_SAMPLE_FMT_NONE = -1,
        AV_SAMPLE_FMT_U8,          ///< unsigned 8 bits
        AV_SAMPLE_FMT_S16,         ///< signed 16 bits
        AV_SAMPLE_FMT_S32,         ///< signed 32 bits
        AV_SAMPLE_FMT_FLT,         ///< float
        AV_SAMPLE_FMT_DBL,         ///< double
    
        AV_SAMPLE_FMT_U8P,         ///< unsigned 8 bits, planar
        AV_SAMPLE_FMT_S16P,        ///< signed 16 bits, planar
        AV_SAMPLE_FMT_S32P,        ///< signed 32 bits, planar
        AV_SAMPLE_FMT_FLTP,        ///< float, planar
        AV_SAMPLE_FMT_DBLP,        ///< double, planar
        AV_SAMPLE_FMT_S64,         ///< signed 64 bits
        AV_SAMPLE_FMT_S64P,        ///< signed 64 bits, planar
    
        AV_SAMPLE_FMT_NB           ///< Number of sample formats. DO NOT USE if linking dynamically
    };
    
  • 相关阅读:
    模块入门–搜索
    [hadoop源码阅读][2]package结构
    [hadoop源码阅读][8]datanodeDataStorage
    [hadoop源码阅读][4]org.apache.hadoop.io
    [hadoop源码阅读][6]org.apache.hadoop.ipcprotocol和心跳分析
    [hadoop源码阅读][1]源码目录结构
    [hadoop源码阅读][4]org.apache.hadoop.io.compress系列3使用压缩
    [hadoop源码阅读][3]新旧api区别
    [hadoop源码阅读][6]org.apache.hadoop.ipcipc总体结构和RPC
    [hadoop源码阅读][8]datanodeFSDataset
  • 原文地址:https://www.cnblogs.com/wangyaoguo/p/8192273.html
Copyright © 2011-2022 走看看