10bit YUV数据在内存中的存储格式

咱们知道为了得到更好的动态范围,除了常见的8bit yuv外,还有10bit,16bit这样的yuv数据。8bit的yuv数据还好理解,每个像素8bit,在内存中天然也就是一个字节一个字节的存储咯,16bit的也相似,每个像素对应两个字节,在内存中存起来也很是方便,那么10bit呢?web

在不作任何调查的状况下,咱们能够凭直觉猜测有两种存储方式:
1.每一个像素依然占用16bit两个字节,可是其中6个bit是padding,补0
2.每一个像素实打实地占用10bit,各个像素交织在一块儿,无法整齐地分布在字节中windows

第一种方式便于运算处理,可是有存储冗余,第二种方式则没有冗余,可是计算起来就很麻烦了。事实上,10bit是采用第一种方式存储在内存中的,也就是说,为了高动态范围,牺牲了一点压缩效率,但也得到了运算性能的加成,大概就是多媒体技术里无处不在的trade off了。ide

下面来详细说说是如何存储的,而且以实例进行验证。svg

参考这里的文档:
10-bit and 16-bit YUV Video Formats
能够得知10bit yuv数据在内存中的存储格式以下图所示
这里写图片描述性能

而8bit像素数据是如何转换为10bit像素数据的呢,根据SMPTE 274M标准,就是乘上一个系数2^(n-8),这里的n就是位深,也就是10或者16,因此若是要把8bit yuv数据转成10bit,就是乘4,即左移两位。.net

下面验证一下:
使用以下命令将8bit yuv转为10bitcode

ffmpeg -s 240x120 -i test.yuv -pix_fmt yuv420p10be test10.yuv

这里的yuv420p10be即10bit yuv420p 大端 格式。各类像素格式能够用以下命令列出orm

ffmpeg -pix_fmts

首先咱们发现的一件有意思的事情就是原来的test.yuv文件大小为1055KB,转出来的test10.yuv的大小正好是它的2倍,2110KB。验证了每像素16bit的说法。xml

再用UltraEdit看看每一个像素的2进制数据
在test.yuv中的第一个Y的2进制数据以下blog

1001 0010

在test10.yuv中对应的样点的2进制数据以下

0000 0010 0100 1000

能够看到,在原来的基础上左移两位,后面补上两个0,这是实际的10bit数据,前面再补上6个0,是padding位。

最后介绍一个能够播放10bit yuv流的播放器YUV Player

最后须要说明的是,以上都是软件解码时的状况,硬件解码时的状况可能有所不一样。

关注公众号,掌握更多多媒体领域知识与资讯
在这里插入图片描述

文章帮到你了?能够扫描以下二维码进行打赏,打赏多少您随意~
在这里插入图片描述