使用 pygame 叠加层显示 YUV420p 会导致图像顶部出现绿色条
Showing YUV420p using pygame overlay leads to green bar on top of image
代码如下。图像由 PyAV 库解码。在图片的顶部有一个水平的绿色条。大概 1 像素高度。你知道如何避免这种情况吗?我已经看到很多关于 VLC 播放器禁用硬件加速的建议。它已在 pygame 中被禁用。我在 Windows10 64 位工作。
import av
import pygame
import time
container = av.open('video.mp4') # libx264 en-/decoded, pixel format yuv420p
container.streams.video[0].thread_type = 'AUTO'
frameSequence = container.decode(video=0)
for _ in range(100):
image = next(frameSequence) #skip some frames
pygame.init()
trueResolution = pygame.display.list_modes()[0] # corresponds to video, as it FULL HD
#also tested with HD
pygame.display.set_mode(trueResolution)
ovl = pygame.Overlay(pygame.YV12_OVERLAY,trueResolution)
ovl.display((image.planes[0], image.planes[1], image.planes[2]))
time.sleep(10)
我也试过用其他线替换每个平面的第一行,以检查图像是否损坏。结果一样,所以图像似乎是正确的。
UPD1。 link转视频https://drive.google.com/file/d/1t6d5weBVeW4EWzGI1gytmUBwXF91dNC9/view?usp=sharing
图片上方有绿线的截图
您可以缩小到屏幕大小并更改叠加层的位置以隐藏绿色条。我知道这不是解决方法,但您可能会发现它足以让您进一步进步。
Overlay 的文档确实警告:
The Overlay objects represent lower level access to the display
hardware. To use the object you must understand the technical details
of video overlays.
因此,具有更多领域专业知识的人可能能够提供更好的解决方案。
pygame.display.set_mode((1280, 718), pygame.RESIZABLE)
ovl = pygame.Overlay(pygame.YV12_OVERLAY,trueResolution)
ovl.set_location(pygame.Rect(0,-2,1280, 720))
另请注意trueResolution
应根据源流而不是显卡支持的full screen modes来确定。
另外这里的image
是一个VideoFrame,你可以用它的.to_image()
方法转换成PIL类型的图片或者.to_rgb()
,可能是如果您不 want/need 使用叠加层,则更容易显示。
代码如下。图像由 PyAV 库解码。在图片的顶部有一个水平的绿色条。大概 1 像素高度。你知道如何避免这种情况吗?我已经看到很多关于 VLC 播放器禁用硬件加速的建议。它已在 pygame 中被禁用。我在 Windows10 64 位工作。
import av
import pygame
import time
container = av.open('video.mp4') # libx264 en-/decoded, pixel format yuv420p
container.streams.video[0].thread_type = 'AUTO'
frameSequence = container.decode(video=0)
for _ in range(100):
image = next(frameSequence) #skip some frames
pygame.init()
trueResolution = pygame.display.list_modes()[0] # corresponds to video, as it FULL HD
#also tested with HD
pygame.display.set_mode(trueResolution)
ovl = pygame.Overlay(pygame.YV12_OVERLAY,trueResolution)
ovl.display((image.planes[0], image.planes[1], image.planes[2]))
time.sleep(10)
我也试过用其他线替换每个平面的第一行,以检查图像是否损坏。结果一样,所以图像似乎是正确的。
UPD1。 link转视频https://drive.google.com/file/d/1t6d5weBVeW4EWzGI1gytmUBwXF91dNC9/view?usp=sharing
图片上方有绿线的截图
您可以缩小到屏幕大小并更改叠加层的位置以隐藏绿色条。我知道这不是解决方法,但您可能会发现它足以让您进一步进步。
Overlay 的文档确实警告:
The Overlay objects represent lower level access to the display hardware. To use the object you must understand the technical details of video overlays.
因此,具有更多领域专业知识的人可能能够提供更好的解决方案。
pygame.display.set_mode((1280, 718), pygame.RESIZABLE)
ovl = pygame.Overlay(pygame.YV12_OVERLAY,trueResolution)
ovl.set_location(pygame.Rect(0,-2,1280, 720))
另请注意trueResolution
应根据源流而不是显卡支持的full screen modes来确定。
另外这里的image
是一个VideoFrame,你可以用它的.to_image()
方法转换成PIL类型的图片或者.to_rgb()
,可能是如果您不 want/need 使用叠加层,则更容易显示。