1.资源文件
https://download.csdn.net/download/twicave/89579327
上面是.264 .265和原始的YUV420文件,各自的大小。
2.转换工具:
2.1 .h264 .h265互转
可以使用ffmpeg工具:Builds - CODEX FFMPEG @ gyan.dev
命令行参数:
ffmpeg -i Tennis1080p.h264 -c:v libx265 -preset medium -crf 28 Tennis1080p.h265
2.2 .h264 转 yuv
我因为要测试rk3588上一个硬件解码器,使用的是一个.c代码:
2.3 yuv file reader
这个可以使用python直接处理,2.2代码里存储的YUV420SP格式我没有完全解出来,色彩不正:
import cv2
import numpy as np
yuv_frame_pack_file = "Tennis1080p.yuv"
def yuv420sp_to_rgb(yuv420sp_frame, width, height, format='NV21'):
y_size = width * height
uv_size = (width * height) // 2
# 分离 Y 分量
y = yuv420sp_frame[:y_size].reshape((height, width))
# 分离 UV 分量
uv = yuv420sp_frame[y_size:y_size + uv_size]
uv = uv.reshape((height // 2, width)) # UV 分量的宽度为原图的宽度,但高度为一半
if format == 'NV12':
u = uv[0::2, :] # U分量
v = uv[1::2, :] # V分量
elif format == 'NV21':
v = uv[0::2, :] # V分量
u = uv[1::2, :] # U分量
else:
raise ValueError("Unsupported format. Use 'NV12' or 'NV21'.")
# 将U和V分量上采样到Y的分辨率
u_upscaled = cv2.resize(u, (width, height), interpolation=cv2.INTER_LINEAR)
v_upscaled = cv2.resize(v, (width, height), interpolation=cv2.INTER_LINEAR)
# 合并Y, U, V分量为一个3通道的图像
yuv_image = np.zeros((height + height // 2, width), dtype=np.uint8)
yuv_image[:height, :] = y
yuv_image[height:height + height // 4, :] = u_upscaled[:height // 4, :]
yuv_image[height + height // 4:, :] = v_upscaled[:height // 4, :]
# 转换到RGB
rgb_image = cv2.cvtColor(yuv_image, cv2.COLOR_YUV2RGB_I420)
return rgb_image
# 设置图像的宽度和高度
width, height = 1920, 1080
# 设置图像的宽度和高度
width, height = 1920, 1080
# 读取一帧YUV420数据
cnt = 23 #控制跳过几帧。视频总帧数可以按照通过文件尺寸测算,YUV420系列一帧是1920*1080*1.5 Bytes.
with open(yuv_frame_pack_file , 'rb') as file:
while(cnt>0):
cnt -=1
yuv420_frame = file.read(width * height * 3 // 2) # YUV420格式,每帧大小为width * height * 3 / 2
continue
yuv420_frame = file.read(width * height * 3 // 2) # YUV420格式,每帧大小为width * height * 3 / 2
yuv420_frame = np.frombuffer(yuv420_frame, dtype=np.uint8)
rgb_frame = yuv420sp_to_rgb(yuv420_frame, width, height)
cv2.imshow('RGB Image', rgb_frame)
cv2.waitKey(0)
cv2.destroyAllWindows()