FFMPeg代码分析:AVFrame结构体及其相关的函数

来源:互联网 发布:手机微信群群发软件 编辑:程序博客网 时间:2024/04/29 11:07

AVFrame结构体保存的是解码后和原始的音视频信息。AVFrame通过函数av_frame_alloc()初始化,该函数仅仅分配AVFrame实例本身,而没有分配其内部的缓存。AVFrame实例由av_frame_free()释放;AVFrame实例通常分配一次,重复使用,如分配一个AVFrame实例来保留解码器中输出的视频帧(此时应在恰当的时候使用av_frame_unref()清理参考帧并将AVFrame归零)。该类所描述的数据通常由AVBuffer的API来保存一个引用计数,并保存于AVFrame.buf /AVFrame.extended_buf,在至少存在一个参考的时候(如AVFrame.buf[0] != NULL),则该对象被标记为“被引用”。在此情况下,AVFrame所包含的每一组数据必须包含于AVFrame的缓存中。

AVFrame的定义如下:

typedef struct AVFrame {#define AV_NUM_DATA_POINTERS 8    /**     * pointer to the picture/channel planes.     * This might be different from the first allocated byte     *     * Some decoders access areas outside 0,0 - width,height, please     * see avcodec_align_dimensions2(). Some filters and swscale can read     * up to 16 bytes beyond the planes, if these filters are to be used,     * then 16 extra bytes must be allocated.     */    uint8_t *data[AV_NUM_DATA_POINTERS];//指向实际音视频数据的指针    /**     * For video, size in bytes of each picture line.     * For audio, size in bytes of each plane.     *     * For audio, only linesize[0] may be set. For planar audio, each channel     * plane must be the same size.     *     * For video the linesizes should be multiplies of the CPUs alignment     * preference, this is 16 or 32 for modern desktop CPUs.     * Some code requires such alignment other code can be slower without     * correct alignment, for yet other it makes no difference.     *     * @note The linesize may be larger than the size of usable data -- there     * may be extra padding present for performance reasons.     */    int linesize[AV_NUM_DATA_POINTERS];    /**     * pointers to the data planes/channels.     *     * For video, this should simply point to data[].     *     * For planar audio, each channel has a separate data pointer, and     * linesize[0] contains the size of each channel buffer.     * For packed audio, there is just one data pointer, and linesize[0]     * contains the total size of the buffer for all channels.     *     * Note: Both data and extended_data should always be set in a valid frame,     * but for planar audio with more channels that can fit in data,     * extended_data must be used in order to access all channels.     */    uint8_t **extended_data;    /**     * width and height of the video frame     */    int width, height;//视频的分辨率    /**     * number of audio samples (per channel) described by this frame     */    int nb_samples;//音频采样频率    /**     * format of the frame, -1 if unknown or unset     * Values correspond to enum AVPixelFormat for video frames,     * enum AVSampleFormat for audio)     */    int format;//解码后的视频帧的格式,为AVPixelFormat 枚举类型(YUV420,YUV422,RGB24等    /**     * 1 -> keyframe, 0-> not     */    int key_frame;//是否关键帧,1是0否    /**     * Picture type of the frame.     */    enum AVPictureType pict_type;//帧类型,IPB#if FF_API_AVFRAME_LAVC    attribute_deprecated    uint8_t *base[AV_NUM_DATA_POINTERS];#endif    /**     * Sample aspect ratio for the video frame, 0/1 if unknown/unspecified.     */    AVRational sample_aspect_ratio;//视频的宽高比    /**     * Presentation timestamp in time_base units (time when frame should be shown to user).     */    int64_t pts;//当前帧的显示时间戳    /**     * PTS copied from the AVPacket that was decoded to produce this frame.     */    int64_t pkt_pts;    /**     * DTS copied from the AVPacket that triggered returning this frame. (if frame threading isnt used)     * This is also the Presentation time of this AVFrame calculated from     * only AVPacket.dts values without pts values.     */    int64_t pkt_dts;    /**     * picture number in bitstream order     */    int coded_picture_number;//当前帧以解码顺序的编号    /**     * picture number in display order     */    int display_picture_number;//当前帧以输出顺序的编号    /**     * quality (between 1 (good) and FF_LAMBDA_MAX (bad))     */    int quality;#if FF_API_AVFRAME_LAVC    attribute_deprecated    int reference;    /**     * QP table     */    attribute_deprecated    int8_t *qscale_table;//量化参数表    /**     * QP store stride     */    attribute_deprecated    int qstride;    attribute_deprecated    int qscale_type;    /**     * mbskip_table[mb]>=1 if MB didn't change     * stride= mb_width = (width+15)>>4     */    attribute_deprecated    uint8_t *mbskip_table;    /**     * motion vector table     * @code     * example:     * int mv_sample_log2= 4 - motion_subsample_log2;     * int mb_width= (width+15)>>4;     * int mv_stride= (mb_width << mv_sample_log2) + 1;     * motion_val[direction][x + y*mv_stride][0->mv_x, 1->mv_y];     * @endcode     */    attribute_deprecated    int16_t (*motion_val[2])[2];//运动矢量表    /**     * macroblock type table     * mb_type_base + mb_width + 2     */    attribute_deprecated    uint32_t *mb_type;//宏块类型    /**     * DCT coefficients     */    attribute_deprecated    short *dct_coeff;//变换系数    /**     * motion reference frame index     * the order in which these are stored can depend on the codec.     */    attribute_deprecated    int8_t *ref_index[2];//参考帧索引#endif    /**     * for some private data of the user     */    void *opaque;    /**     * error     */    uint64_t error[AV_NUM_DATA_POINTERS];#if FF_API_AVFRAME_LAVC    attribute_deprecated    int type;#endif    /**     * When decoding, this signals how much the picture must be delayed.     * extra_delay = repeat_pict / (2*fps)     */    int repeat_pict;//表示有多少帧被延迟显示,延迟即重复。    /**     * The content of the picture is interlaced.     */    int interlaced_frame;//隔行视频标识    /**     * If the content is interlaced, is top field displayed first.     */    int top_field_first;    /**     * Tell user application that palette has changed from previous frame.     */    int palette_has_changed;#if FF_API_AVFRAME_LAVC    attribute_deprecated    int buffer_hints;    /**     * Pan scan.     */    attribute_deprecated    struct AVPanScan *pan_scan;#endif    /**     * reordered opaque 64bit (generally an integer or a double precision float     * PTS but can be anything).     * The user sets AVCodecContext.reordered_opaque to represent the input at     * that time,     * the decoder reorders values as needed and sets AVFrame.reordered_opaque     * to exactly one of the values provided by the user through AVCodecContext.reordered_opaque     * @deprecated in favor of pkt_pts     */    int64_t reordered_opaque;#if FF_API_AVFRAME_LAVC    /**     * @deprecated this field is unused     */    attribute_deprecated void *hwaccel_picture_private;    attribute_deprecated    struct AVCodecContext *owner;    attribute_deprecated    void *thread_opaque;    /**     * log2 of the size of the block which a single vector in motion_val represents:     * (4->16x16, 3->8x8, 2-> 4x4, 1-> 2x2)     */    attribute_deprecated    uint8_t motion_subsample_log2;#endif    /**     * Sample rate of the audio data.     */    int sample_rate;    /**     * Channel layout of the audio data.     */    uint64_t channel_layout;    /**     * AVBuffer references backing the data for this frame. If all elements of     * this array are NULL, then this frame is not reference counted.     *     * There may be at most one AVBuffer per data plane, so for video this array     * always contains all the references. For planar audio with more than     * AV_NUM_DATA_POINTERS channels, there may be more buffers than can fit in     * this array. Then the extra AVBufferRef pointers are stored in the     * extended_buf array.     */    AVBufferRef *buf[AV_NUM_DATA_POINTERS];    /**     * For planar audio which requires more than AV_NUM_DATA_POINTERS     * AVBufferRef pointers, this array will hold all the references which     * cannot fit into AVFrame.buf.     *     * Note that this is different from AVFrame.extended_data, which always     * contains all the pointers. This array only contains the extra pointers,     * which cannot fit into AVFrame.buf.     *     * This array is always allocated using av_malloc() by whoever constructs     * the frame. It is freed in av_frame_unref().     */    AVBufferRef **extended_buf;    /**     * Number of elements in extended_buf.     */    int        nb_extended_buf;    AVFrameSideData **side_data;    int            nb_side_data;    /**     * frame timestamp estimated using various heuristics, in stream time base     * Code outside libavcodec should access this field using:     * av_frame_get_best_effort_timestamp(frame)     * - encoding: unused     * - decoding: set by libavcodec, read by user.     */    int64_t best_effort_timestamp;    /**     * reordered pos from the last AVPacket that has been input into the decoder     * Code outside libavcodec should access this field using:     * av_frame_get_pkt_pos(frame)     * - encoding: unused     * - decoding: Read by user.     */    int64_t pkt_pos;    /**     * duration of the corresponding packet, expressed in     * AVStream->time_base units, 0 if unknown.     * Code outside libavcodec should access this field using:     * av_frame_get_pkt_duration(frame)     * - encoding: unused     * - decoding: Read by user.     */    int64_t pkt_duration;    /**     * metadata.     * Code outside libavcodec should access this field using:     * av_frame_get_metadata(frame)     * - encoding: Set by user.     * - decoding: Set by libavcodec.     */    AVDictionary *metadata;    /**     * decode error flags of the frame, set to a combination of     * FF_DECODE_ERROR_xxx flags if the decoder produced a frame, but there     * were errors during the decoding.     * Code outside libavcodec should access this field using:     * av_frame_get_decode_error_flags(frame)     * - encoding: unused     * - decoding: set by libavcodec, read by user.     */    int decode_error_flags;#define FF_DECODE_ERROR_INVALID_BITSTREAM   1#define FF_DECODE_ERROR_MISSING_REFERENCE   2    /**     * number of audio channels, only used for audio.     * Code outside libavcodec should access this field using:     * av_frame_get_channels(frame)     * - encoding: unused     * - decoding: Read by user.     */    int channels;    /**     * size of the corresponding packet containing the compressed     * frame. It must be accessed using av_frame_get_pkt_size() and     * av_frame_set_pkt_size().     * It is set to a negative value if unknown.     * - encoding: unused     * - decoding: set by libavcodec, read by user.     */    int pkt_size;    /**     * YUV colorspace type.     * It must be accessed using av_frame_get_colorspace() and     * av_frame_set_colorspace().     * - encoding: Set by user     * - decoding: Set by libavcodec     */    enum AVColorSpace colorspace;    /**     * MPEG vs JPEG YUV range.     * It must be accessed using av_frame_get_color_range() and     * av_frame_set_color_range().     * - encoding: Set by user     * - decoding: Set by libavcodec     */    enum AVColorRange color_range;    /**     * Not to be accessed directly from outside libavutil     */    AVBufferRef *qp_table_buf;} AVFrame;

通过对其内部的成员变量的研究可以看出,除了基本的储存像素的缓存之外,其成员大多还是与编解码相关的一些参数,如分辨率、帧类型、量化参数表、参考帧列表等。所以从大体上看,AVFrame就是一个容器类,同AVPacket不同的是所容纳的是原始的像素数据,相同点是都有很多编解码相关的参数作为补充数据。


原创粉丝点击