Fix cropping support to work like rest of GStreamer
VPU must decode video to buffers with sizes that are even multiples
of block size. For example, a 1080p h264 video is always encoded
1088 px high (68*16=1088), with cropping specified in the SPS.
There are also other HW imposed dimensional constraints.
NXPs cropping strategy has been to output the entire padded frame,
with garbage on the right/bottom, plus a VideoCropMeta rectangle.
There are multiple problems with this. Basically no standard
elements supports VideoCropMeta and the ones that do are only
display sinks. No filters like mixers and no support for GL
elements beyond the basic glimagesink. appsinks need to handle
cropping, GstDiscoverer is broken as it reports the padded and
wrong dimensions for source media.
NXP added flawed support in glupload to account for the crop
but that broke the standard rules of caps negotiation and with
that all GL filters. Instead of patching the
supposed-to-be-standard GStreamer framework let's fix this at
the source, the decoder.
The cropping rectangle is virtually never needed. As long as
the output frame is anchored at 0,0, or there's no crop at the
left/top, cropping is really just the same as modified stride
GstVideoDecoder supports different caps for output and allocation,
NXP used the same for both. We start by allocating the full padded
frame but we report the cropped dimensions in negotiations.
When a frame as been decoded into the padded buffer we change
the VideoMeta dimensions to the cropped ones before pushing.
The pushed buffer still has the strides and plane offsets of the
padded buffer, therefore standard functions like
gst_video_frame_map that's used in all sinks and other standard
elements work just fine.
In the event that cropping is done to the top/left we fall back to
the padded frame dimensions plus crop rectangle. I've never seen
a video file with left/top cropping, or an encoder that produces
1 file changed