Replies: 5 comments
-
I'm attaching the sample video: RGB.video.mov |
Beta Was this translation helpful? Give feedback.
-
Is anything expected from the maintainers here or is this just for future reference from users? |
Beta Was this translation helpful? Give feedback.
-
I was hoping that a maintainer or someone experienced with PyAV/ffmpeg would be willing to help as to how to go about trimming padding off of frames. It seems that Now, I could be doing this all wrong in the first place, hence the request for help. But if I'm not, then it may be a bug in PyAV which may be worth looking into. |
Beta Was this translation helpful? Give feedback.
-
OK I've just enabled the "discussions" feature, this seems like a good place to engage with community members. |
Beta Was this translation helpful? Give feedback.
-
Yep alignment problems are a pain to debug if you are unfamiliar with numpy internals. Try this and see if it solves the problem: def _remove_padding(self, plane):
"""Remove padding from a video plane.
Args:
plane (av.video.plane.VideoPlane): the plane to remove padding from
Returns:
numpy.array: an array with proper memory aligned width
"""
buf_width = plane.line_size
bytes_per_pixel = 1
frame_width = plane.width * bytes_per_pixel
arr = np.frombuffer(plane, np.uint8)
if buf_width != frame_width:
arr = arr.reshape(-1, buf_width)[:, :frame_width]
return np.ascontiguousarray(arr.reshape(-1, frame_width)) # I changed this line Regarding the approach of using def frame_to_ycbcr(self, frame):
frame_data = frame.to_ndarray() # no need to pass the format explicitly
start_offset = 0
end_offset = frame.height
y_data = frame_data[start_offset:end_offset, :] # y-plane gets reconstructed correctly
start_offset = end_offset
end_offset = (5 * frame.height) // 4 # this is weird, try:
end_offset = (frame.height // 4) // 2
cb_data = frame_data[start_offset:end_offset, :].reshape(-1, frame.width // 2)
start_offset = end_offset
end_offset = None
cr_data = frame_data[start_offset:, :].reshape(-1, frame.width // 2)
return y_data, cb_data, cr_data I didn't test this though, so take it with some salt. The logic is that chroma is subsampled by a factor of 4 in height (hence we can reconstruct the plane's height via Edit You could sidestep all of this by promoting your frames to YUV444p: |
Beta Was this translation helpful? Give feedback.
-
Overview
I'm trying to render a yuvj420p frame as an OpenGL texture. In my testing, frames that do not have padding work great. However, frames with padding are a mess. To prepare data for texture, I'm using the following function which is mostly the same as
useful_array
function inav/video/frame.pyx
.With frames that have padding, the above function does not work properly.
Expected behavior
The given function should be able to remove any padding from the frame and be rendered as a texture properly.
Actual behavior
The output frame is completely messed up:
Traceback:
Investigation
I felt that the above behavior may be a result of
plane.width
being off by some pixels. In my case, the width is 1198 px for which 16 pixel alignment would be 1200 px. So, I adjusted the above function to align the width value:Now at least Y plane seems to be aligned properly, but chroma planes still are not. In my case, the chroma width is 599 which when adjusted by the above function comes out to be 608.
If I adjust chroma planes' width manually to 600, it seems to work:
Research
I have done the following:
Additional context
frame.to_ndarray()
directly with same results.Beta Was this translation helpful? Give feedback.
All reactions