summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Desmottes <guillaume.desmottes@collabora.com>2020-10-05 12:07:22 +0200
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>2020-10-12 13:17:53 +0000
commit4b0a139714e9ac85ead7b7f8e491f6e705cf62a1 (patch)
treebfd10e92d12ae39e785ab5f58fee07bd9be008ab
parent3efdc3f12b419234da8b74c59c705ec5b48e66fd (diff)
downloadgstreamer-plugins-base-4b0a139714e9ac85ead7b7f8e491f6e705cf62a1.tar.gz
videodecoder: fix output state interlace-mode
When user is passing the actual interlace-mode when calling gst_video_decoder_set_interlaced_output_state() it should not be overidden by the input interlace-mode. Needed to fix #825 as we want to keep interlace-mode=interleaved from parsers and have the OMX decoder producing interlace-mode=alternate. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/862>
-rw-r--r--gst-libs/gst/video/gstvideodecoder.c104
1 files changed, 61 insertions, 43 deletions
diff --git a/gst-libs/gst/video/gstvideodecoder.c b/gst-libs/gst/video/gstvideodecoder.c
index 7e8f37579..9a750b7c9 100644
--- a/gst-libs/gst/video/gstvideodecoder.c
+++ b/gst-libs/gst/video/gstvideodecoder.c
@@ -619,16 +619,17 @@ parse_fail:
}
static GstVideoCodecState *
-_new_output_state (GstVideoFormat fmt, GstVideoInterlaceMode mode, guint width,
- guint height, GstVideoCodecState * reference)
+_new_output_state (GstVideoFormat fmt, GstVideoInterlaceMode interlace_mode,
+ guint width, guint height, GstVideoCodecState * reference,
+ gboolean copy_interlace_mode)
{
GstVideoCodecState *state;
state = g_slice_new0 (GstVideoCodecState);
state->ref_count = 1;
gst_video_info_init (&state->info);
- if (!gst_video_info_set_interlaced_format (&state->info, fmt, mode, width,
- height)) {
+ if (!gst_video_info_set_interlaced_format (&state->info, fmt, interlace_mode,
+ width, height)) {
g_slice_free (GstVideoCodecState, state);
return NULL;
}
@@ -640,7 +641,8 @@ _new_output_state (GstVideoFormat fmt, GstVideoInterlaceMode mode, guint width,
ref = &reference->info;
/* Copy over extra fields from reference state */
- tgt->interlace_mode = ref->interlace_mode;
+ if (copy_interlace_mode)
+ tgt->interlace_mode = ref->interlace_mode;
tgt->flags = ref->flags;
/* only copy values that are not unknown so that we don't override the
* defaults. subclasses should really fill these in when they know. */
@@ -3430,6 +3432,53 @@ gst_video_decoder_get_output_state (GstVideoDecoder * decoder)
return state;
}
+static GstVideoCodecState *
+_set_interlaced_output_state (GstVideoDecoder * decoder,
+ GstVideoFormat fmt, GstVideoInterlaceMode interlace_mode, guint width,
+ guint height, GstVideoCodecState * reference, gboolean copy_interlace_mode)
+{
+ GstVideoDecoderPrivate *priv = decoder->priv;
+ GstVideoCodecState *state;
+
+ g_assert ((copy_interlace_mode
+ && interlace_mode == GST_VIDEO_INTERLACE_MODE_PROGRESSIVE)
+ || !copy_interlace_mode);
+
+ GST_DEBUG_OBJECT (decoder,
+ "fmt:%d, width:%d, height:%d, interlace-mode: %s, reference:%p", fmt,
+ width, height, gst_video_interlace_mode_to_string (interlace_mode),
+ reference);
+
+ /* Create the new output state */
+ state =
+ _new_output_state (fmt, interlace_mode, width, height, reference,
+ copy_interlace_mode);
+ if (!state)
+ return NULL;
+
+ GST_VIDEO_DECODER_STREAM_LOCK (decoder);
+
+ GST_OBJECT_LOCK (decoder);
+ /* Replace existing output state by new one */
+ if (priv->output_state)
+ gst_video_codec_state_unref (priv->output_state);
+ priv->output_state = gst_video_codec_state_ref (state);
+
+ if (priv->output_state != NULL && priv->output_state->info.fps_n > 0) {
+ priv->qos_frame_duration =
+ gst_util_uint64_scale (GST_SECOND, priv->output_state->info.fps_d,
+ priv->output_state->info.fps_n);
+ } else {
+ priv->qos_frame_duration = 0;
+ }
+ priv->output_state_changed = TRUE;
+ GST_OBJECT_UNLOCK (decoder);
+
+ GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
+
+ return state;
+}
+
/**
* gst_video_decoder_set_output_state:
* @decoder: a #GstVideoDecoder
@@ -3460,8 +3509,8 @@ gst_video_decoder_set_output_state (GstVideoDecoder * decoder,
GstVideoFormat fmt, guint width, guint height,
GstVideoCodecState * reference)
{
- return gst_video_decoder_set_interlaced_output_state (decoder, fmt,
- GST_VIDEO_INTERLACE_MODE_PROGRESSIVE, width, height, reference);
+ return _set_interlaced_output_state (decoder, fmt,
+ GST_VIDEO_INTERLACE_MODE_PROGRESSIVE, width, height, reference, TRUE);
}
/**
@@ -3470,7 +3519,7 @@ gst_video_decoder_set_output_state (GstVideoDecoder * decoder,
* @fmt: a #GstVideoFormat
* @width: The width in pixels
* @height: The height in pixels
- * @mode: A #GstVideoInterlaceMode
+ * @interlace_mode: A #GstVideoInterlaceMode
* @reference: (allow-none) (transfer none): An optional reference #GstVideoCodecState
*
* Same as #gst_video_decoder_set_output_state() but also allows you to also set
@@ -3482,42 +3531,11 @@ gst_video_decoder_set_output_state (GstVideoDecoder * decoder,
*/
GstVideoCodecState *
gst_video_decoder_set_interlaced_output_state (GstVideoDecoder * decoder,
- GstVideoFormat fmt, GstVideoInterlaceMode mode, guint width, guint height,
- GstVideoCodecState * reference)
+ GstVideoFormat fmt, GstVideoInterlaceMode interlace_mode, guint width,
+ guint height, GstVideoCodecState * reference)
{
- GstVideoDecoderPrivate *priv = decoder->priv;
- GstVideoCodecState *state;
-
- GST_DEBUG_OBJECT (decoder,
- "fmt:%d, width:%d, height:%d, interlace-mode: %s, reference:%p", fmt,
- width, height, gst_video_interlace_mode_to_string (mode), reference);
-
- /* Create the new output state */
- state = _new_output_state (fmt, mode, width, height, reference);
- if (!state)
- return NULL;
-
- GST_VIDEO_DECODER_STREAM_LOCK (decoder);
-
- GST_OBJECT_LOCK (decoder);
- /* Replace existing output state by new one */
- if (priv->output_state)
- gst_video_codec_state_unref (priv->output_state);
- priv->output_state = gst_video_codec_state_ref (state);
-
- if (priv->output_state != NULL && priv->output_state->info.fps_n > 0) {
- priv->qos_frame_duration =
- gst_util_uint64_scale (GST_SECOND, priv->output_state->info.fps_d,
- priv->output_state->info.fps_n);
- } else {
- priv->qos_frame_duration = 0;
- }
- priv->output_state_changed = TRUE;
- GST_OBJECT_UNLOCK (decoder);
-
- GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
-
- return state;
+ return _set_interlaced_output_state (decoder, fmt, interlace_mode, width,
+ height, reference, FALSE);
}