我想创建一个 python 脚本,解码 h264 1080p 视频并通过 Raspberry Pi 5 上的 SDL2 输出。Raspberry Pi 5 能够使用 VLC 毫无问题地播放 h264 1080p 视频。 VLC 的总 CPU 负载约为 10%。然而,使用 ffmpeg 解码并通过 SDL2 输出使用大约 70% 的 CPU 负载。由于我希望能够在两个输出视频之间无缝切换,因此我需要同时解码两个视频。因此,一个转码后的 1080p 视频的 70% CPU 负载是不可接受的。如何使代码更高效?为什么 VLC 如此高效?
这是我当前的Python脚本:
import numpy as np
import ffmpeg # ffmpeg-python
import sdl2.ext
in_file = ffmpeg.input('bbb1080_x264.mp4', re=None)
width = 1920
height = 1080
process1 = (
in_file
.output('pipe:', format='rawvideo', pix_fmt='bgra')
.run_async(pipe_stdout=True)
)
sdl2.ext.init()
window = sdl2.ext.Window("Hello World!", size=(width, height))
window.show()
windowsurface = sdl2.SDL_GetWindowSurface(window.window)
windowArray = sdl2.ext.pixels3d(windowsurface.contents)
sdl2.ext.mouse.hide_cursor()
while True:
in_bytes = process1.stdout.read(width * height * 4)
if not in_bytes:
break
in_frame = (
np
.frombuffer(in_bytes, np.uint8)
.reshape([height, width, 4])
.transpose(1, 0, 2)
)
for event in sdl2.ext.get_events():
if event.type == sdl2.SDL_QUIT:
exit()
windowArray[:] = in_frame
window.refresh()
process1.wait()
有趣的是,当我在 Raspberry Pi 5 上启动 VLC 时,这是终端上的输出
[00007fff78c1a550] avcodec decoder error: cannot start codec (h264_v4l2m2m)
Fontconfig warning: ignoring UTF-8: not a valid region tag
[00007fff68002d70] gles2 generic error: parent window not available
[00007fff68002d70] xcb generic error: window not available
[00007fff680013f0] mmal_xsplitter vout display: Try drm
[00007fff68002d70] drm_vout generic: <<< OpenDrmVout: Fmt=I420
[00007fff68002d70] drm_vout generic error: Failed to get xlease`
这表明VLC没有使用h264_v4l2m2m硬件加速。
我想出了如何减少处理器负载:
更改后的代码:
in_file = ffmpeg.input('bbb1080_hevc.mp4', hwaccel='auto')
width = 1920
height = 1080
process1 = (
in_file
.output('/dev/null', format='rawvideo')
.run_async(pipe_stdout=True)
)
但是这个代码现在当然无法使用了。我需要处理 python 中的格式转换并找出标准输出如此慢的原因。我改用 C,因为我应该从一开始就这样做,@qwr 已经在他的评论中建议了。