1

我用ffmpeg做HDR测试视频,我的做法是写一张图片,把图片转成yuv420p,然后用ffmpeg做HDR测试视频。

但是我发现从 mp4 读取的 yuv 数据与原始输入不同。我在这里停留了一段时间,有人知道如何从 mp4 读取正确的 yuv 数据吗?

#ffmpeg encode command
ffmpeg_encode_mp4 = \
"ffmpeg -y -s 100*100 -pix_fmt yuv420p -threads 4 -r 1 -stream_loop -1 -f rawvideo -i write_yuv.yuv -vf \
scale=out_h_chr_pos=0:out_v_chr_pos=0,format=yuv420p10le \
-c:v libx265 -tag:v hvc1 -t 10 -pix_fmt yuv420p10le -preset medium -x265-params \
crf=12:colorprim=bt2020:transfer=smpte2084:colormatrix=bt2020nc:master-display=\"G(13250,34500)B(7500,3000)R(34000,16000)WP(15635,16450)L(10000000,1)\":max-cll=\"1000,400\" \
-an test.mp4"

#ffmpeg read yuv from mp4 command
ffmpeg_extract_yuv = "ffmpeg -i test.mp4 -vframes 1 -c:v rawvideo -pix_fmt yuv420p read_yuv.yuv"


#make 100*100 yuv raw
w, h = 100, 100
test_gray = 255
test = np.full((100, 100, 3), test_gray, dtype=np.uint8)
yuv_cv = cv.cvtColor(test, cv.COLOR_RGB2YUV_I420)
yuv_cv.tofile("write_yuv.yuv")

#encode yuv raw to mp4 with HDR metadata
print(ffmpeg_encode_mp4)
result = subprocess.check_output(ffmpeg_encode_mp4, shell = True)
print(result)
sleep(0.5)

#extract yuv from mp4
kill_existing_file("read_yuv.yuv")
print(ffmpeg_extract_yuv)
result = subprocess.check_output(ffmpeg_extract_yuv, shell = True)
print(result)
sleep(0.5)

write_yuv = np.fromfile("write_yuv.yuv",dtype='uint8')
read_yuv = np.fromfile("read_yuv.yuv",dtype='uint8')

print("input gray:", test_gray)
print("write_yuv", write_yuv[:10])
print("read_yuv", read_yuv[:10])

reader = imageio.get_reader("test.mp4")
img = reader.get_data(0)
print("imgeio read:", img[50, 50])

'''
ouput result:
input gray: 255
write_yuv [235 235 235 235 235 235 235 235 235 235]
read_yuv [234 235 234 235 234 235 234 235 234 235]
imgeio read: [253 253 253]
'''

我不知道如何验证我制作的视频是否正确任何反馈将不胜感激!

4

1 回答 1

0

当然。使用 ffplay -vf extractplanes=y (也可以使用 u, v, r, g, b, a)。

对于 10 位请使用 ffmpeg -vf extractplanes=y to png 和 GIMP 中的 16 位颜色选择器,因为 ffplay 中存在一些问题。

于 2021-05-09T10:25:58.070 回答