AVFrame和AVPicture

源地址: http://yul100887.blog.163.com/blog/static/200336135201211143525930/

struct  AVFrame
{
uint8_t * data[4];分别指向yuv三个位面及一个未知的位面或者是rgb模式下只有data[0]指向raw data
int  linesize[4];四个位面分别的内存块大小
}

AVFrame * avcodec_alloc_frame() //Allocates an AVFrame and sets its fields to default values
初始化的时候AVFrame中的元素data,linesize均为空。未指向任何内存数据

avcodec_decode_video()// Decodes a video frame from \p buf into \p picture.
* The avcodec_decode_video() function decodes a video frame from the input
* buffer \p buf of size \p buf_size.
对从文件中读取的包进行解码,将解码后的yuv数据填充在 AVFrame的 data及linesize的字段内。而且经过打印发现从始至终 AVFrame一直在两组数据中间1:1变动。说明 AVFrame始终指向一块内存数据,这块内存数据有可能由avcodec_decode_video()函数内部负责去申请,然后在解码结束之后自动释 放。

这也说明了为什么在yuv转rgb的时候需要自己去申请一块内存空间并将其绑定在AVFrame上,有可能因为
sws_scale()并不会自动帮用户去申请内存空间,所以为了获取转化之后的RGB数据则需要自动去申请内存使用。
sws_scale()负责图像数据的缩放及尺寸的变法
比如:  yuv420-->yuv444
CIF -> QCIF   QCIF-->CIF等
(zzcqh)


 AVPicture

对应AVPicture里面有data[4]和linesize[4]其中data是一个指向指针的指针(二级、二维指针),也就是指向视频数据缓冲区的首地址,而data[0]~data[3]是一级指针,可以用如下的图来表示:

data -->xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        ^                ^              ^
        |                |              |
         data[0]      data[1]         data[2]

比如说,当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).


源地址:http://yul100887.blog.163.com/blog/static/200336135201211143525930/

你可能感兴趣的:(Android流媒体)