videodecoder: Handle instant-rate-change event
authorJan Schmidt <jan@centricular.com>
Fri, 30 Nov 2018 11:56:11 +0000 (22:56 +1100)
committerSebastian Dröge <slomo@coaxion.net>
Wed, 1 Apr 2020 21:01:38 +0000 (21:01 +0000)
When receiving an instant-rate-change event, store the updated
seek flags and replace the flags in any input segments with them
to allow for instant switching between trickmodes and not.

gst-libs/gst/video/gstvideodecoder.c

index ed74d48..22b9e7c 100644 (file)
@@ -327,6 +327,10 @@ struct _GstVideoDecoderPrivate
   /* input_segment are output_segment identical */
   gboolean in_out_segment_sync;
 
+  /* TRUE if we have an active set of instant rate flags */
+  gboolean decode_flags_override;
+  GstSegmentFlags decode_flags;
+
   /* ... being tracked here;
    * only available during parsing */
   GstVideoCodecFrame *current_frame;
@@ -1328,13 +1332,43 @@ gst_video_decoder_sink_event_default (GstVideoDecoder * decoder,
 
       GST_VIDEO_DECODER_STREAM_LOCK (decoder);
 
+      /* Update the decode flags in the segment if we have an instant-rate
+       * override active */
+      GST_OBJECT_LOCK (decoder);
+      if (!priv->decode_flags_override)
+        priv->decode_flags = segment.flags;
+      else {
+        segment.flags &= ~GST_SEGMENT_INSTANT_FLAGS;
+        segment.flags |= priv->decode_flags & GST_SEGMENT_INSTANT_FLAGS;
+      }
+
       priv->base_timestamp = GST_CLOCK_TIME_NONE;
       priv->base_picture_number = 0;
 
       decoder->input_segment = segment;
       decoder->priv->in_out_segment_sync = FALSE;
 
+      GST_OBJECT_UNLOCK (decoder);
       GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
+
+      break;
+    }
+    case GST_EVENT_INSTANT_RATE_CHANGE:
+    {
+      GstSegmentFlags flags;
+      GstSegment *seg;
+
+      gst_event_parse_instant_rate_change (event, NULL, &flags);
+
+      GST_OBJECT_LOCK (decoder);
+      priv->decode_flags_override = TRUE;
+      priv->decode_flags = flags;
+
+      /* Update the input segment flags */
+      seg = &decoder->input_segment;
+      seg->flags &= ~GST_SEGMENT_INSTANT_FLAGS;
+      seg->flags |= priv->decode_flags & GST_SEGMENT_INSTANT_FLAGS;
+      GST_OBJECT_UNLOCK (decoder);
       break;
     }
     case GST_EVENT_FLUSH_STOP:
@@ -2072,6 +2106,7 @@ gst_video_decoder_reset (GstVideoDecoder * decoder, gboolean full,
     GST_OBJECT_LOCK (decoder);
     priv->earliest_time = GST_CLOCK_TIME_NONE;
     priv->proportion = 0.5;
+    priv->decode_flags_override = FALSE;
     GST_OBJECT_UNLOCK (decoder);
   }