diff options
author | Guillaume Desmottes <guillaume.desmottes@collabora.com> | 2020-10-05 12:32:10 +0200 |
---|---|---|
committer | Tim-Philipp Müller <tim@centricular.com> | 2020-10-10 14:00:56 +0100 |
commit | fcd12e89cc72dda45998d3ef6d564a9a4d8f2a4a (patch) | |
tree | f964eec866a048d5ac851eadab30d64079d88019 | |
parent | 211838428303fbff730179abb5b83c27a4c20e00 (diff) | |
download | gst-omx-fcd12e89cc72dda45998d3ef6d564a9a4d8f2a4a.tar.gz |
omxvideodec: support interlace-mode=interleaved input
interlace-mode=alternate is a special case of interlace-mode=interleaved
where the fields are split using two different buffers.
The Zynq decoder always produces alternate content and we
used to assume that upstream will set interlace-mode=alternate in its
caps as well.
This is no longer the case as h265parse is now setting
alternate-mode=interleaved on alternate content to not break compat with
elements not supporting alternate.
As a result the decoder now accept both 'interleaved' and 'alternate' on
its input and ensures that its ouput has interlace-mode=alternate.
Needed to fix https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/issues/825
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-omx/-/merge_requests/73>
-rw-r--r-- | omx/gstomxvideodec.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/omx/gstomxvideodec.c b/omx/gstomxvideodec.c index 9e172a4..4f4b13a 100644 --- a/omx/gstomxvideodec.c +++ b/omx/gstomxvideodec.c @@ -1348,8 +1348,12 @@ gst_omx_video_dec_reconfigure_output_port (GstOMXVideoDec * self) frame_height = port_def.format.video.nFrameHeight; /* OMX's frame height is actually the field height in alternate mode * while it's always the full frame height in gst. */ - if (interlace_mode == GST_VIDEO_INTERLACE_MODE_ALTERNATE) + if (interlace_mode == GST_VIDEO_INTERLACE_MODE_ALTERNATE || + interlace_mode == GST_VIDEO_INTERLACE_MODE_INTERLEAVED) { frame_height *= 2; + /* Decoder outputs interlaced content using the alternate mode */ + interlace_mode = GST_VIDEO_INTERLACE_MODE_ALTERNATE; + } state = gst_video_decoder_set_interlaced_output_state (GST_VIDEO_DECODER @@ -1550,8 +1554,12 @@ gst_omx_video_dec_reconfigure_output_port (GstOMXVideoDec * self) frame_height = port_def.format.video.nFrameHeight; /* OMX's frame height is actually the field height in alternate mode * while it's always the full frame height in gst. */ - if (interlace_mode == GST_VIDEO_INTERLACE_MODE_ALTERNATE) + if (interlace_mode == GST_VIDEO_INTERLACE_MODE_ALTERNATE || + interlace_mode == GST_VIDEO_INTERLACE_MODE_INTERLEAVED) { frame_height *= 2; + /* Decoder outputs interlaced content using the alternate mode */ + interlace_mode = GST_VIDEO_INTERLACE_MODE_ALTERNATE; + } GST_DEBUG_OBJECT (self, "Setting output state: format %s (%d), width %u, height %u", @@ -2685,7 +2693,8 @@ gst_omx_video_dec_set_interlacing_parameters (GstOMXVideoDec * self, return FALSE; } - if (info->interlace_mode == GST_VIDEO_INTERLACE_MODE_ALTERNATE) + if (info->interlace_mode == GST_VIDEO_INTERLACE_MODE_ALTERNATE || + info->interlace_mode == GST_VIDEO_INTERLACE_MODE_INTERLEAVED) seq_pic_mode.eMode = OMX_ALG_SEQUENCE_PICTURE_FIELD; else if (info->interlace_mode == GST_VIDEO_INTERLACE_MODE_PROGRESSIVE) seq_pic_mode.eMode = OMX_ALG_SEQUENCE_PICTURE_FRAME; @@ -2789,7 +2798,13 @@ gst_omx_video_dec_set_format (GstVideoDecoder * decoder, } port_def.format.video.nFrameWidth = info->width; - port_def.format.video.nFrameHeight = GST_VIDEO_INFO_FIELD_HEIGHT (info); + port_def.format.video.nFrameHeight = GST_VIDEO_INFO_HEIGHT (info); + /*We cannot use GST_VIDEO_INFO_FIELD_HEIGHT() as encoded content may use either + * interlace-mode=interleaved or alternate. In both case we'll output alternate + * so the OMX frame height needs to be halfed. */ + if (GST_VIDEO_INFO_IS_INTERLACED (info)) + port_def.format.video.nFrameHeight = + GST_ROUND_UP_2 (port_def.format.video.nFrameHeight / 2); port_def.format.video.xFramerate = framerate_q16; if (klass->cdata.hacks & GST_OMX_HACK_PASS_COLOR_FORMAT_TO_DECODER) { |