在有些场景中,我们经常会使用到YUV 8 bit转10bit的场景。
比如YUV420p 8bit 转 P010,P010le,YUV420p10le。
首先说ffmpeg 8 bit 转 10bit.
对于ffmpeg的P010le 和P010be 分别代表小端和大端,那么它转化的时候非常简单,就是8 bit再增加 8bit,后面的8bit全为0.
比如:
这是最简单的一种办法,所以如果你有一个转换后的10bitYUV,那么只要简单的去掉这个全为0的byte就可以了。
补充说明:
P010le和P010be 排列方式和NV12一样,是YYYY… UVUVUVUVUVU…
下面是一个简单python代码,将10bit P010le转换为nv12:
import cv2 as cv
import numpy as np
import os
W = 1920
H = 1080
num=5
Y_planar = W*H*2
UV_planar = W*H
# p010 2 nv12
root = os.path.split(os.path.realpath(__file__))[0]
name = root + "\\dev-0-session-0-test10-p010le.yuv"
fp = open(name, "rb")
fp2 = open(name+"-out-nv12.yuv","wb+")
y1 = np.zeros(shape=(H, W), dtype=np.uint8, order='C')
u1 = np.zeros(shape=(int(H/2), int(W/2)), dtype=np.uint8, order='C')
v1 = np.zeros(shape=(int(H/2), int(W/2)), dtype=np.uint8, order='C')
for i in range(num):
for m in range(H):
for n in range(W):
msb = (ord(fp.read(1))>>2)
lsb = (ord(fp.read(1))<<6)
y1[m,n] = msb | lsb
for m in range(int(H/2)):
for n in range(int(W/2)):
msb = (ord(fp.read(1))>>2)
lsb = (ord(fp.read(1))<<6)
u1[m,n] = msb | lsb
msb = (ord(fp.read(1))>>2)
lsb = (ord(fp.read(1))<<6)
v1[m,n] = msb | lsb
fp2.write(bytes(y1))
fp2.write(bytes(u1))
fp2.write(bytes(v1))
fp.close()
fp2.close()
除了这种简单的增加一个字节的方式外,其实还有另外一种方式:
ffmpeg中的yuv420p10le就是这种方式。
燧远的y10,P010le就是这种方式。
下面一个脚本,可以将P010le的转为YUV420 8bit
import cv2 as cv
import numpy as np
import os
W = 1920
H = 1080
num=5
Y_planar = W*H*2
UV_planar = W*H
# p010 2 nv12
root = os.path.split(os.path.realpath(__file__))[0]
name = root + "\\dev-0-session-0-test10-p010le.yuv"
fp = open(name, "rb")
fp2 = open(name+"-out-yuv420p8bit.yuv","wb+")
y1 = np.zeros(shape=(H, W), dtype=np.uint8, order='C')
u1 = np.zeros(shape=(int(H/2), int(W/2)), dtype=np.uint8, order='C')
v1 = np.zeros(shape=(int(H/2), int(W/2)), dtype=np.uint8, order='C')
for i in range(num):
for m in range(H):
for n in range(W):
msb = (ord(fp.read(1))>>2)
lsb = (ord(fp.read(1))<<6)
y1[m,n] = msb | lsb
for m in range(int(H/2)):
for n in range(int(W/2)):
msb = (ord(fp.read(1))>>2)
lsb = (ord(fp.read(1))<<6)
u1[m,n] = msb | lsb
msb = (ord(fp.read(1))>>2)
lsb = (ord(fp.read(1))<<6)
v1[m,n] = msb | lsb
fp2.write(bytes(y1))
fp2.write(bytes(u1))
fp2.write(bytes(v1))
fp.close()
fp2.close()