NDK(4-2)FFMPEG重要结构体源码注释

这几篇有点重复,不过想表达的不太一样,主要是为了自己理解。

AVPacket

只能分析源码了。索性都不太长,还算是比较容易
AVPacket:
比较重要的几个参数:
int size:data的大小
int64_t pts:显示时间戳
int64_t dts:解码时间戳
int stream_index:标识该AVPacket所属的视频/音频流

//用来存储压缩编码数据相关信息
//作为解码器的输入 或 编码器的输出
//当作为解码器的输入时,它由demuxer生成,然后传递给解码器 
 //当作为编码器的输出时,由编码器生成,然后传递给muxer 
//视频:最多包含一帧的内容,但是视频一帧的内容可能需要多个AVPacket,AVPacket < AVFrame 
//音频:包含多帧
//AVPacket 是ffmpeg中少数的几个公共ABI,它只能被libavcodec和libformat在栈上分配 

typedef struct AVPacket {
    /**
      *AVPacket 存储在“引用计数缓冲区”,,这个指针就指向一块引用计数缓冲区 
*可以为空,不算引用计数
     * A reference to the reference-counted buffer where the packet data is
     * stored.
     * May be NULL, then the packet data is not reference-counted.
     */
    AVBufferRef *buf;
    /**
    *显示时间戳 单位是 AVStream->time_base units 
     */
    int64_t pts;
   /**
   *解压时间戳,在这个时刻该包需要被解码 
     */ 
    int64_t dts;
    uint8_t *data;
    int   size;
//标识该AVPacket所属的视频/音频流。
    int   stream_index;
    /**
     * A combination of AV_PKT_FLAG values
     */
    int   flags;
    /**
     *存放额外的包信息 
     */
    AVPacketSideData *side_data;
    int side_data_elems;

    /**
   * 这个包的时间长度 in AVStream->time_base units, 设置0 表示未知.
     */
    int64_t duration;
 ///< 在数据流中的字节偏移量, -1 if unknown  
    int64_t pos;                            ///< byte position in stream, -1 if unknown

#if FF_API_CONVERGENCE_DURATION
    /**
     * @deprecated Same as the duration field, but as int64_t. This was required
     * for Matroska subtitles, whose duration values could overflow when the
     * duration field was still an int.
     */
    attribute_deprecated
    int64_t convergence_duration;
#endif
} AVPacket;

AVPicture

#define AV_NUM_DATA_POINTERS 8
typedef struct AVPicture {  
    uint8_t *data[AV_NUM_DATA_POINTERS];    ///< pointers to the image data planes  
    int linesize[AV_NUM_DATA_POINTERS];     ///< number of bytes per line  
}  

对应AVPicture里面有data[8]和linesize[8]其中data是一个指向指针的指针(二级、二维指针),也就是指向视频数据缓冲区的首地址,而data[0]~data[7]是一级指针,当pix_fmt=PIX_FMT_YUV420P时,data中的数据是按照YUV的格式存储的,也就是:
data -->YYYYYYYYYYYYYYUUUUUUUUUUUUUVVVVVVVVVVVV
--------- ^ ------------------- ^ ------------------------- ^
--------- | -------------------- | -------------------------- |
------- data[0] ------------ data[1] ------------------- data[2]

linesize是指对应于每一行的大小,为什么需要这个变量,是因为在 YUV格式和RGB格式时,每行的大小不一定等于图像的宽度,对于RGB格式输出时,只有一个通道(bgrbgrbgr......)可用,即 linesize[0],和data[0],so RGB24 : data[0] = packet rgb//bgrbgrbgr......

linesize[0] = width*3
其他的如data[1][2][3]与linesize[1][2][3]无任何意义.

而对于YUV格式输出时,有三个通道可用,即data[0][1][2],与linesize[0][1][2],而yuv格式对于运动估计时,需要填充padding(right, bottom),故:

linesize=width+padding size(16+16).

AVFrame

AVFrame结构体一般用于存储原始数据(即非压缩数据,例如对视频来说是YUV,RGB,对音频来说是PCM),此外还包含了一些相关的信息。比如说,解码的时候存储了宏块类型表,QP表,运动矢量表等数据。编码的时候也存储了相关的数据。因此在使用FFMPEG进行码流分析的时候,AVFrame是一个很重要的结构体。

uint8_t *data[AV_NUM_DATA_POINTERS]:解码后原始数据(对视频来说是YUV,RGB,对音频来说是PCM)
int linesize[AV_NUM_DATA_POINTERS]:data中“一行”数据的大小。注意:未必等于图像的宽,一般大于图像的宽。
int width, height:视频帧宽和高(1920x1080,1280x720...)
int nb_samples:音频的一个AVFrame中可能包含多个音频帧,在此标记包含了几个
int format:解码后原始数据类型(YUV420,YUV422,RGB24...)
int key_frame:是否是关键帧
enum AVPictureType pict_type:帧类型(I,B,P...)
AVRational sample_aspect_ratio:宽高比(16:9,4:3...)
int64_t pts:显示时间戳
int coded_picture_number:编码帧序号
int display_picture_number:显示帧序号
int8_t *qscale_table:QP表
uint8_t mbskip_table:跳过宏块表
int16_t (
motion_val[2])[2]:运动矢量表
uint32_t *mb_type:宏块类型表
short*dct_coeff:DCT系数,这个没有提取过
int8_t *ref_index[2]:运动估计参考帧列表(貌似H.264这种比较新的标准才会涉及到多参考帧)
int interlaced_frame:是否是隔行扫描
uint8_t motion_subsample_log2:一个宏块中的运动矢量采样个数,取log的


/**
 * AVFrame表示解码过后的一个数据帧
 *
 * AVFrame 通过使用 av_frame_alloc()来创建. 这个函数只是创建了AVFrame结构本身,在结构
 * 中定义的指向其他内存块的缓冲区指针要用其他方法来分配
 * 使用 av_frame_free()来释放AVFrame.
 *
 */
typedef struct AVFrame {
#define AV_NUM_DATA_POINTERS 8
    /**
*指向图片/通道 平面 的指针
     * pointer to the picture/channel planes.
     */
    uint8_t *data[AV_NUM_DATA_POINTERS];

    /**
     * For video, size in bytes of each picture line.
     * For audio, size in bytes of each plane.
     */
    int linesize[AV_NUM_DATA_POINTERS];

    /**
     * pointers to the data planes/channels.
     */
    uint8_t **extended_data;

    /**
     * width and height of the video frame
     */
    int width, height;

    /**
     * 此帧描述的音频样本数(每个通道)
     */
    int nb_samples;

    /**
     * format of the frame, -1 if unknown or unset
     */
    int format;

    /**
     * 1 -> keyframe, 0-> not
     */
    int key_frame;

    /**
     * Picture type of the frame.
     */
    enum AVPictureType pict_type;

    /**
     * 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;

    /**
     * for some private data of the user
     */
    void *opaque;

    /**
     * error
     */
    uint64_t error[AV_NUM_DATA_POINTERS];

    /**
     * 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;

    /**
     * Sample rate of the audio data.
     */
    int sample_rate;

    /**
     * Channel layout of the audio data.
     */
    uint64_t channel_layout;

    /**
     * 指向这个帧要用到的AVBuffer中的数据缓冲区.
     *
     * 一般每个图像位面(就时data[0],data[1] data[2])只有一个指向AVBuffer的缓冲区, 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.
     */
    AVBufferRef **extended_buf;
    /**
     * Number of elements in extended_buf.
     */
    int        nb_extended_buf;

    AVFrameSideData **side_data;
    int            nb_side_data;

/**
 * 可能因为解码错误,数据帧Frame会成为无效的帧,下面的结构就是当数据帧无效时使用的
 */
#define AV_FRAME_FLAG_CORRUPT       (1 << 0)

    /**
     * Frame flags, a combination of AV_FRAME_FLAG_*
     */
    int flags;

    
    int64_t best_effort_timestamp;

   
    int64_t pkt_pos;

    
    int64_t pkt_duration;

   
    AVDictionary *metadata;

    
    int decode_error_flags;
#define FF_DECODE_ERROR_INVALID_BITSTREAM   1
#define FF_DECODE_ERROR_MISSING_REFERENCE   2

   
    int channels;

    
    int pkt_size;

    
    enum AVColorSpace colorspace;

   
    enum AVColorRange color_range;


    /**
     * Not to be accessed directly from outside libavutil
     */
    AVBufferRef *qp_table_buf;
} AVFrame;
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容