美文网首页
FFmpeg笔记(六)-- 编解码相关类、结构体

FFmpeg笔记(六)-- 编解码相关类、结构体

作者: rookiesss | 来源:发表于2020-05-18 17:53 被阅读0次
    AVFormatContext

    AVFormatContext是一个描述编解码格式上下文的数据结构。

    struct AVInputFormat *iformat;//输入数据的封装格式
    AVIOContext *pb;//输入数据的缓存
    unsigned int nb_streams;//音频流+视频流的总数
    AVStream **streams;//音视频流
    char filename[1024];//文件名
    int64_t duration;//时长(单位:微秒us,转换为秒需要除以1000000)
    int bit_rate;//比特率(单位bps,转换为kbps需要除以1000)
    AVDictionary *metadata;//元数据
    
    AVStream

    AVStream是存储每一个视频/音频流信息的结构体。
    结构体参数来自:这里

    int index; //在AVFormatContext中的索引,这个数字是自动生成的,可以通过这个数字从AVFormatContext::streams表中索引到该流。
    int id;//流的标识,依赖于具体的容器格式。解码:由libavformat设置。编码:由用户设置,如果未设置则由libavformat替换。
    AVCodecContext *codec;//指向该流对应的AVCodecContext结构,调用avformat_open_input时生成。
    AVRational time_base;//这是表示帧时间戳的基本时间单位(以秒为单位)。该流中媒体数据的pts和dts都将以这个时间基准为粒度。
    int64_t start_time;//流的起始时间,以流的时间基准为单位。如需设置,100%确保你设置它的值真的是第一帧的pts。
    int64_t duration;//解码流的持续时间。如果源文件未指定持续时间,但指定了比特率,则将根据比特率和文件大小估计该值。
    int64_t nb_frames; //此流中的帧数(如果已知)或0。
    enum AVDiscard discard;//选择哪些数据包可以随意丢弃,不需要去demux。
    AVRational sample_aspect_ratio;//样本长宽比(如果未知,则为0)。
    AVDictionary *metadata;//元数据信息。
    AVRational avg_frame_rate;//平均帧速率。解封装:可以在创建流时设置为libavformat,也可以在avformat_find_stream_info()中设置。
    //封装:可以由调用者在avformat_write_header()之前设置。
    AVPacket attached_pic;//附带的图片。比如说一些MP3,AAC音频文件附带的专辑封面。
    int probe_packets;//编解码器用于probe的包的个数。
    int codec_info_nb_frames;//在av_find_stream_info()期间已经解封装的帧数。
    int request_probe;//流探测状态,1表示探测完成,0表示没有探测请求,rest 执行探测。
    int skip_to_keyframe;//表示应丢弃直到下一个关键帧的所有内容。
    int skip_samples;//在从下一个数据包解码的帧开始时要跳过的采样数。
    int64_t start_skip_samples;//如果不是0,则应该从流的开始跳过的采样的数目。
    int64_t first_discard_sample;//如果不是0,则应该从流中丢弃第一个音频样本。
    
    int64_t pts_reorder_error[MAX_REORDER_DELAY+1];
    uint8_t pts_reorder_error_count[MAX_REORDER_DELAY+1];//内部数据,从pts生成dts。
    
    int64_t last_dts_for_order_check;
    uint8_t dts_ordered;
    uint8_t dts_misordered;//内部数据,用于分析dts和检测故障mpeg流。
    AVRational display_aspect_ratio;//显示宽高比。
    
    AVIOContext

    AVIOContext是FFMPEG管理输入输出数据的结构体。

    unsigned char *buffer;//缓存开始位置
    int buffer_size;//缓存大小(默认32768)
    unsigned char *buf_ptr;//当前指针读取到的位置
    unsigned char *buf_end;//缓存结束的位置
    void *opaque;//URLContext结构体
    
    AVCodecContext

    AVCodecContext是一个描述编解码器上下文的数据结构。
    注释来自这里

    enum AVMediaType codec_type:编解码器的类型(视频,音频...)
    struct AVCodec  *codec:采用的解码器AVCodec(H.264,MPEG2...)
    int bit_rate:平均比特率
    uint8_t *extradata; int extradata_size:针对特定编码器包含的附加信息(例如对于H.264解码器来说,存储SPS,PPS等)
    AVRational time_base:根据该参数,可以把PTS转化为实际的时间(单位为秒s)
    int width, height:如果是视频的话,代表宽和高
    int refs:运动估计参考帧的个数(H.264的话会有多帧,MPEG2这类的一般就没有了)
    int sample_rate:采样率(音频)
    int channels:声道数(音频)
    enum AVSampleFormat sample_fmt:采样格式
    int profile:型(H.264里面就有,其他编码标准应该也有)
    int level:级(和profile差不太多)
    
    AVCodec

    解码器。结构来自:这里

    /**
     * AVCodec.
     * H.264的解码器对象: ff_h264_decoder
     */
    typedef struct AVCodec 
    {
        // 解码器名字
        const char *name;
        // 解码器完整名
        const char *long_name;
        // 媒体类型
        // AVMEDIA_TYPE_VIDEO
        // AVMEDIA_TYPE_AUDIO
        // AVMEDIA_TYPE_DATA
        enum AVMediaType type;
            // 解码器ID(AV_CODEC_ID_H264)
        enum AVCodecID id;
        // 能力集
        // H264: CODEC_CAP_DR1|CODEC_CAP_DELAY|CODEC_CAP_SLICE_THREADS|CODEC_CAP_FRAME_THREADS
        int capabilities;
        // 支持的帧率(V)
        const AVRational *supported_framerates;
        // 支持的像素格式(V)
        // AV_PIX_FMT_YUV420P
        // AV_PIX_FMT_RGB24
        const enum AVPixelFormat *pix_fmts;
        // 支持的采样率(A)
        const int *supported_samplerates;
        // 支持的采样格式(A)
        const enum AVSampleFormat *sample_fmts;
        // 支持的声道数(A)
        const uint64_t *channel_layouts;
        // (这里的3条感觉就是打补丁打出来的字段)
        // 由解码器支持低分辨率的最大值,不能直接访问,使用av_codec_get_max_lowres()
        uint8_t max_lowres;
        // AVClass针对私有上下文
        const AVClass *priv_class;
        // 公认的配置文件数组,如果未知则为NULL,数组由FF_PROFILE_UNKNOWN表示终止
        const AVProfile *profiles;
        // 私有数据总长度
        int priv_data_size;
        // 下一个链接对象
        struct AVCodec *next;
        
        // 假如被定义了, 那么当他们被创建时则被线程上下文调用。
        // 假如编解码器在调用init()时分配了可写表, 那么在这里重新分配.
        // priv_data将被设置为原件的副本
        int (*init_thread_copy)(AVCodecContext *);
        /**
         * 将必要的上下文变量从上一个线程复制到当前线程的上下文,(跨线程拷贝)。
         * 假如没有被定义, 下一个线程将自动启动; 否则, 编解码器必须调用call ff_thread_finish_setup().
         *
         * 目标和源很少指向相同的上下文, 在这种情况下应该跳过memcpy()的调用。
         */
        int (*update_thread_context)(AVCodecContext *dst, const AVCodecContext *src);
        // 私有的指定的编解码器默认值.
        const AVCodecDefault *defaults;
        // 初始化编解码器的静态数据, 由avcodec_register()来调用.
        void (*init_static_data)(struct AVCodec *codec);
        // 根据AVCodecContext来初始化
        int (*init)(AVCodecContext *);
        int (*encode_sub)(AVCodecContext *, uint8_t *buf, int buf_size, const struct AVSubtitle *sub);
        // 编码数据到AVPacket.
        // @参数 avctx: 编解码上下文
        // @参数 avpkt: 输出的AVPacket,(可能包含上层调用者提供的缓冲区)
        // @参数[in] frame: AVFrame包含了未加工的数据来编码
        // @参数[out] got_packet_ptr: 设置为0或1来表示一个非空的AVPacket返回值avpkt
        // @返回值 0表示成功,其他错误代码表示错误
        int (*encode2)(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr);
        // 执行解码,从数据包AVPacket中进行解码转为outdata和outdata_size,提供AVCodecContext来定义编解码上下文信息
        int (*decode)(AVCodecContext *, void *outdata, int *outdata_size, AVPacket *avpkt);
        // 关闭编解码器对象
        int (*close)(AVCodecContext *);
        // 编码+解码的API函数, 用来解耦packet/frame数据流(就是提供自己玩的接口,而不是打包操作). 
        // 这些API和avcodec_ prefixed的API差不多,除了下面这些:
        // - 如果编解码器关闭或者是错误类型,那么就不要使用。
        // - 在调用AVCodec->send_packet()之前,改变了AVPacket参数数据
        // - 假如AV_CODEC_CAP_DELAY没有被设置、漏包或者帧压根没有被发送
        // 发送帧
        int (*send_frame)(AVCodecContext *avctx, const AVFrame *frame);
        // 发送包
        int (*send_packet)(AVCodecContext *avctx, const AVPacket *avpkt);
        // 接受帧
        int (*receive_frame)(AVCodecContext *avctx, AVFrame *frame);
        // 接受包
        int (*receive_packet)(AVCodecContext *avctx, AVPacket *avpkt);
        // 刷新缓冲区
        void (*flush)(AVCodecContext *);
        // 内部的编解码能力.
        // 可以查看FF_CODEC_CAP_*系列宏,在头文件internal.h中
        int caps_internal;
     
    }
    
    AVPacket

    AVPacket是FFmpeg中很重要的一个数据结构,它保存了解复用(demuxer)之后,解码(decode)之前的数据(仍然是压缩后的数据)和关于这些数据的一些附加的信息,如显示时间戳(pts),解码时间戳(dts),数据时长(duration),所在流媒体的索引(stream_index)等等。详情看这里

    pts: (int64_t)显示时间,结合AVStream->time_base转换成时间戳
    dts: (int64_t)解码时间,结合AVStream->time_base转换成时间戳
    size: (int)data的大小
    stream_index: (int)packet在stream的index位置
    flags: (int)标示,结合AV_PKT_FLAG使用,其中最低为1表示该数据是一个关键帧。
    #define AV_PKT_FLAG_KEY    0x0001 //关键帧
    #define AV_PKT_FLAG_CORRUPT 0x0002 //损坏的数据
    #define AV_PKT_FLAG_DISCARD  0x0004 /丢弃的数据
    side_data_elems: (int)边缘数据元数个数
    duration: (int64_t)数据的时长,以所属媒体流的时间基准为单位,未知则值为默认值0
    pos: (int64_t )数据在流媒体中的位置,未知则值为默认值-1
    convergence_duration:该字段已deprecated,不在使用
    关于数据缓存,AVPacket本身只是个容器,不直接的包含数据,而是通过数据缓存的指针引用数据。
    uint8_t *data:指向保存压缩数据的指针,这就是AVPacket的实际数据。
    AVPacketSideData *side_data:容器提供的一些附加数据
    AVBufferRef *buf:用来管理data指针引用的数据缓存,其使用在后面介绍。
    
    AVFrame

    AVFrame用来存储解码后的(或原始)音频或视频数据,位于avcodec.h文件中。
    AVFrame必须由av_frame_alloc()分配内存,同时必须由av_frame_free()释放。
    AVFrame分配内存后能够被多次用来存储不同的数据(例如:decoder解码后的帧)。av_frame_unref释放任何持帧的引用,并结构体还原到未被使用的状态。来自这里
    一个AVPacket包含一个视频帧(AVFrame),也可以包含多个音频帧。
    一帧音频的数据量 = channel数 * nb_samples样本数 * 每个样本占用的字节数。

    uint8_t *   data [AV_NUM_DATA_POINTERS];//解码后原始数据(对视频来说是YUV,RGB,对音频来说是PCM)。
    int linesize[AV_NUM_DATA_POINTERS];//在视频中,表示图片一行数据的大小。
    uint8_t **extended_data;//指向数据平面/通道。
    int width, height;//一个视频帧的宽度和高度。
    int nb_samples;//这个AVFrame中的每个音频声道的样本数。
    int format;//表示解码后的数据类型或格式,-1表示未被设置或不能识别的类型。
    int key_frame;//是否为关键帧,1->关键帧,0->非关键帧。
    enum AVPictureType pict_type;//帧的类型。
    AVRational sample_aspect_ratio;//视频帧的宽高比,0表示未知。
    int64_t pts;//显示时间戳,表示该什么时候被显示。
    int64_t pkt_dts;//从AVPacket中拷贝的值。
    int coded_picture_number;//编码帧序号。
    int display_picture_number;//显示帧需要。
    void *opaque;//用户私有信息。
    int repeat_pict;//解码时,每帧图片延迟的时间,extra_delay = repeat_pict / (2*fps)。
    int interlaced_frame;//是否是隔行扫描
    int sample_rate;//音频的采样率。
    uint64_t channel_layout;//音频的布局方式。
    enum AVColorRange color_range;
    enum AVColorPrimaries color_primaries;
    enum AVColorTransferCharacteristic color_trc;
    enum AVColorSpace colorspace;
    enum AVChromaLocation chroma_location;
    int64_t best_effort_timestamp;//大多数情况下AVFrame的pts和best_effort_timestamp值是一样的
    int64_t pkt_pos;//记录最后一个进入解码器的packet在输入文件中的位置偏移量。
    int64_t pkt_duration;//对应packet的时长,单位是AVStream->time_base。
    AVDictionary *metadata;
    int decode_error_flags;
    int channels;//音频通道个数
    int pkt_size;//对应packet的大小。
    int8_t *qscale_table;
    int qstride;
    int qscale_type;
    AVBufferRef *qp_table_buf;
    AVBufferRef *hw_frames_ctx;
    AVBufferRef *opaque_ref;
    
    AVSampleFormat

    音频数据格式。名称尾有p表示分片,如音频有两个声道,分片左声道存linesize[0],右声道存linesize[1],不分片都存linesize[0],左右左右...的顺序依次存储。

    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_NB           ///< Number of sample formats. DO NOT USE if linking dynamically
    };
    
    
    AVPictureType

    视频帧类型。

    enum AVPictureType {
        AV_PICTURE_TYPE_NONE = 0, ///< Undefined
        AV_PICTURE_TYPE_I,     ///< Intra
        AV_PICTURE_TYPE_P,     ///< Predicted
        AV_PICTURE_TYPE_B,     ///< Bi-dir predicted
        AV_PICTURE_TYPE_S,     ///< S(GMC)-VOP MPEG-4
        AV_PICTURE_TYPE_SI,    ///< Switching Intra
        AV_PICTURE_TYPE_SP,    ///< Switching Predicted
        AV_PICTURE_TYPE_BI,    ///< BI type
    };
    

    相关文章

      网友评论

          本文标题:FFmpeg笔记(六)-- 编解码相关类、结构体

          本文链接:https://www.haomeiwen.com/subject/swtzwhtx.html