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

在不做任何调查的情况下,我们可以凭直觉猜想有两种存储方式:
1.每个像素依然占用16bit两个字节,但是其中6个bit是padding,补0
2.每个像素实打实地占用10bit,各个像素交织在一起,没法整齐地分布在字节中

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

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

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

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

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

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

这里的yuv420p10be即10bit yuv420p 大端 格式。各种像素格式可以用如下命令列出

ffmpeg -pix_fmts

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

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

1001 0010

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

0000 0010 0100 1000

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

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

最后需要说明的是,以上都是软件解码时的情况,硬件解码时的情况可能有所不同。

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

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

我们知道为了获得更好的动态范围,除了常见的8bit yuv外,还有10bit,16bit这样的yuv数据。8bit的yuv数据还好理解,每一个像素8bit,在内存中自然也就是一个字节一个字节的存储咯,16bit的也类似,每一个像素对应两个字节,在内存中存起来也非常方便,那么10bit呢?在不做任何调查的情况下,我们可以凭直觉猜想有两种存储方式: 1.每个像素依然占用16bit两个字节,但是其中6个
ffmepg处理yuv视频的系列之三 最近发现数据集里的yuv大部分是8bit,但是有一部分是10bit或者16bit的,默认的yuv播放器打不开,也不利于数据集制作。所以就想用ffmpeg进行处理,记录一下方法。10bit能够容纳更多的色彩,获得更好的动态范围。 ffmpeg里面yuv格式定义了很多种,比如下面: PIX_FMT_YUV420P9BE,///<planar YU...
引用自GitHub:https://github.com/oswystan/raw_unpack ************************************************************************************** * Filename: unpack.c * Description: source file * Version: ...
Mat src16,tmp; Mat dst8 = Mat::zeros(src16.size(), CV_8U); normalize(src16, tmp, 0, 255, NORM_MINMAX); convertScaleAbs(tmp, dst8); 二、自己代码实现 Mat src16; Mat dst8 = Mat::zeros(src16.size(), CV_8U); double mymin, mymax; cv::minMaxIdx(s
文章版权由作者柯O德尔和博客园共有,请尊重并支持原创,若转载请于明显处标明出处:http://www.cnblogs.com/koder/ 最近因为工作需要,要进行265 10bit编码,于是从ffmpeg官网下载了最新版的32位的ffmpeg可执行程序,使用如下命令进行编码: ffmpeg.exe -i input.ts -vcodec libx265 -pix_fmt yuv42...
注:本文所指的YUV均为YUV420的I420格式(最常见的一种),其他格式不能用以下的代码。 位深为8bit时,每个像素占用1字节,对应文件指针的fp.read(1); 位深为10bit时,每个像素占用2字节,对应文件指针的fp.read(2); 然后使用 int.from_bytes() 方法将二进制转换为int型数字。 以下程序可以读8bit10bit位深的YUV,需要指定从第几帧开始读、一共读多少帧。 它返回三个数组,其shape分别为:Y [frame,W,H] U [frame,W/2,H/2] V [frame,W/2,H/2] 当只读1帧时它返回:Y [W,H] U [W/
ffmepg处理yuv视频的系列之三 最近发现数据集里的yuv大部分是8bit,但是有一部分是10bit或者16bit的,默认的yuv播放器打不开,也不利于数据集制作。所以就想用ffmpeg进行处理,记录一下方法。10bit能够容纳更多的色彩,获得更好的动态范围。 ffmpeg里面yuv格式定义了很多种,比如下面: PIX_FMT_YUV420P9BE, ///&lt; planar YU...
YUV 4:4:4采样,每一个Y对应一组UV分量。YUV 4:2:2采样,每两个Y共用一组UV分量。YUV 4:2:0采样,每四个Y共用一组UV分量。 Y占一个字节,U占一个字节,V占一个字节。YUV 4:4:4采样,每一个Y对应一组UV分量,也就是说1个像素点占1个Y和一组UV,也就是3个字节。 经上分析可以得出以下结论: YUV 420(NV12 NV21) 每个像素:1.5个字...