AVFrame关于视音频数据存储
在AVFrame中有2个很重要的数据成员,一个是data,一个是linesize。data中存储的是未编码的源始数据(不论视音频),linesize中存储的是每行data中数据大小。
data的定义如下:
uint8_t *data[AV_NUM_DATA_POINTERS];
linesize定义如下:
int linesize[AV_NUM_DATA_POINTERS];
注意:当为音频的时候linesize,只有linesize[0]才是有效值,因为左右一样大。
3、存储方式
1、视频
视频相对简单的多,以yuv420为例,图像数据在AVFrame中存储是这样的:
data[0]存储Y
data[1]存储U
data[2]存储V
而他们相对应的大小为:
linesize[0]为Y的大小
linesize[1]为U的大小
linesize[2]为V的大小
2、音频
音频数据则要复杂一些,在音频中分为平面和非平面数据类型,下面是音频数据类型的定义:
enum AVSampleFormat {
AV_SAMPLE_FMT_NONE = -1,
AV_SAMPLE_FMT_U8,
AV_SAMPLE_FMT_S16,
AV_SAMPLE_FMT_S32,
AV_SAMPLE_FMT_FLT,
AV_SAMPLE_FMT_DBL,
AV_SAMPLE_FMT_U8P,
AV_SAMPLE_FMT_S16P,
AV_SAMPLE_FMT_S32P,
AV_SAMPLE_FMT_FLTP,
AV_SAMPLE_FMT_DBLP,
AV_SAMPLE_FMT_NB
};
定义中最后带p的为平面数据类型,可以用av_sample_fmt_is_planar来判断此数据类型是否是平面数据类型。
先说非平面数据:
以一个双声道(左右)音频来说,存储格式可能就为LRLRLR.........(左声道在前还是右声道在前没有认真研究过),数据都装在data[0]中,而大小则为linesize[0]。
平面数据:
就有点像视频部分的YUV数据,同样对双声道音频PCM数据,以S16P为例,存储就可能是
plane 0: LLLLLLLLLLLLLLLLLLLLLLLLLL...
plane 1: RRRRRRRRRRRRRRRRRRRR....
对应的存储则为:
data[0]存储plane 0
data[1]存储plane 1
对应的大小则都为linesize[0],可以用av_get_bytes_per_sample(out_stream->codec->sample_fmt) * out_frame->nb_samples来算出plane的大小。