realmedia: Drop duplicate seek events.
authorDoug Nazar <nazard@nazar.ca>
Tue, 20 Apr 2021 22:48:38 +0000 (18:48 -0400)
committerDoug Nazar <nazard@nazar.ca>
Tue, 20 Apr 2021 23:32:29 +0000 (19:32 -0400)
Also use seek seqnum for flush & segment events/messages.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-ugly/-/merge_requests/81>

gst/realmedia/rmdemux.c
gst/realmedia/rmdemux.h

index f9b6bfa..1873cc1 100644 (file)
@@ -271,6 +271,7 @@ gst_rmdemux_init (GstRMDemux * rmdemux)
   rmdemux->have_group_id = FALSE;
   rmdemux->group_id = G_MAXUINT;
   rmdemux->flowcombiner = gst_flow_combiner_new ();
+  rmdemux->seek_seqnum = GST_SEQNUM_INVALID;
 
   gst_rm_utils_run_tests ();
 }
@@ -305,8 +306,18 @@ gst_rmdemux_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
     case GST_EVENT_SEEK:
     {
       gboolean running;
+      guint32 seqnum;
 
       GST_LOG_OBJECT (rmdemux, "Event on src: SEEK");
+
+      seqnum = gst_event_get_seqnum (event);
+      if (seqnum == rmdemux->seek_seqnum) {
+        GST_LOG_OBJECT (pad,
+            "Drop duplicated SEEK event seqnum %" G_GUINT32_FORMAT, seqnum);
+        gst_event_unref (event);
+        break;
+      }
+
       /* can't seek if we are not seekable, FIXME could pass the
        * seek query upstream after converting it to bytes using
        * the average bitrate of the stream. */
@@ -482,10 +493,13 @@ gst_rmdemux_perform_seek (GstRMDemux * rmdemux, GstEvent * event)
   GstSeekType cur_type, stop_type;
   gint64 cur, stop;
   gboolean update;
+  guint32 seqnum = GST_SEQNUM_INVALID;
+  GstEvent *fl_event;
 
   if (event) {
     GST_DEBUG_OBJECT (rmdemux, "seek with event");
 
+    seqnum = gst_event_get_seqnum (event);
     gst_event_parse_seek (event, &rate, &format, &flags,
         &cur_type, &cur, &stop_type, &stop);
 
@@ -514,8 +528,15 @@ gst_rmdemux_perform_seek (GstRMDemux * rmdemux, GstEvent * event)
   /* first step is to unlock the streaming thread if it is
    * blocked in a chain call, we do this by starting the flush. */
   if (flush) {
-    gst_pad_push_event (rmdemux->sinkpad, gst_event_new_flush_start ());
-    gst_rmdemux_send_event (rmdemux, gst_event_new_flush_start ());
+    fl_event = gst_event_new_flush_start ();
+    if (seqnum != GST_SEQNUM_INVALID)
+      gst_event_set_seqnum (fl_event, seqnum);
+    gst_pad_push_event (rmdemux->sinkpad, fl_event);
+
+    fl_event = gst_event_new_flush_start ();
+    if (seqnum != GST_SEQNUM_INVALID)
+      gst_event_set_seqnum (fl_event, seqnum);
+    gst_rmdemux_send_event (rmdemux, fl_event);
   } else {
     gst_pad_pause_task (rmdemux->sinkpad);
   }
@@ -535,6 +556,8 @@ gst_rmdemux_perform_seek (GstRMDemux * rmdemux, GstEvent * event)
       ret = FALSE;
       goto done;
     }
+
+    rmdemux->seek_seqnum = seqnum;
   }
 
   GST_DEBUG_OBJECT (rmdemux, "segment positions set to %" GST_TIME_FORMAT "-%"
@@ -543,7 +566,10 @@ gst_rmdemux_perform_seek (GstRMDemux * rmdemux, GstEvent * event)
 
   /* we need to stop flushing on the sinkpad as we're going to use it
    * next. We can do this as we have the STREAM lock now. */
-  gst_pad_push_event (rmdemux->sinkpad, gst_event_new_flush_stop (TRUE));
+  fl_event = gst_event_new_flush_stop (TRUE);
+  if (seqnum != GST_SEQNUM_INVALID)
+    gst_event_set_seqnum (fl_event, seqnum);
+  gst_pad_push_event (rmdemux->sinkpad, fl_event);
 
   GST_LOG_OBJECT (rmdemux, "Pushed FLUSH_STOP event");
 
@@ -581,17 +607,24 @@ gst_rmdemux_perform_seek (GstRMDemux * rmdemux, GstEvent * event)
     /* Reset the demuxer state */
     rmdemux->state = RMDEMUX_STATE_DATA_PACKET;
 
-    if (flush)
-      gst_rmdemux_send_event (rmdemux, gst_event_new_flush_stop (TRUE));
+    if (flush) {
+      fl_event = gst_event_new_flush_stop (TRUE);
+      if (seqnum != GST_SEQNUM_INVALID)
+        gst_event_set_seqnum (fl_event, seqnum);
+      gst_rmdemux_send_event (rmdemux, fl_event);
+    }
 
     /* must send newsegment event from streaming thread, so just set flag */
     rmdemux->need_newsegment = TRUE;
 
     /* notify start of new segment */
     if (rmdemux->segment.flags & GST_SEEK_FLAG_SEGMENT) {
-      gst_element_post_message (GST_ELEMENT_CAST (rmdemux),
+      GstMessage *msg =
           gst_message_new_segment_start (GST_OBJECT_CAST (rmdemux),
-              GST_FORMAT_TIME, rmdemux->segment.position));
+          GST_FORMAT_TIME, rmdemux->segment.position);
+      if (seqnum != GST_SEQNUM_INVALID)
+        gst_message_set_seqnum (msg, seqnum);
+      gst_element_post_message (GST_ELEMENT_CAST (rmdemux), msg);
     }
 
     /* restart our task since it might have been stopped when we did the 
@@ -734,6 +767,8 @@ gst_rmdemux_reset (GstRMDemux * rmdemux)
 
   rmdemux->have_group_id = FALSE;
   rmdemux->group_id = G_MAXUINT;
+
+  rmdemux->seek_seqnum = GST_SEQNUM_INVALID;
 }
 
 static GstStateChangeReturn
index 5c2fea2..40e1a0b 100644 (file)
@@ -103,6 +103,7 @@ struct _GstRMDemux {
 
   guint offset;
   gboolean seekable;
+  guint32 seek_seqnum;
 
   GstRMDemuxState state;
   GstRMDemuxLoopState loop_state;