summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Desmottes <guillaume.desmottes@collabora.com>2020-10-05 12:32:10 +0200
committerTim-Philipp Müller <tim@centricular.com>2020-10-10 14:00:56 +0100
commitfcd12e89cc72dda45998d3ef6d564a9a4d8f2a4a (patch)
treef964eec866a048d5ac851eadab30d64079d88019
parent211838428303fbff730179abb5b83c27a4c20e00 (diff)
downloadgst-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.c23
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) {