我们知道为了获得更好的动态范围,除了常见的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型数字。
以下程序可以读8bit或10bit位深的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, ///< 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个字...