rtsp-media: Make sure that sequence numbers are monotonic after pause
authorSrimanta Panda <srimanta@axis.com>
Mon, 8 Sep 2014 07:26:23 +0000 (09:26 +0200)
committerSebastian Dröge <sebastian@centricular.com>
Fri, 12 Sep 2014 14:29:30 +0000 (17:29 +0300)
The sequence number is not monotonic for RTP packets after pause. The
reason is basepayloader generates a randon sequence number when the
pipeline goes from ready to pause. With this fix generation of sequence
number will be monotonic when going from pause to play request.

https://bugzilla.gnome.org/show_bug.cgi?id=736017

gst/rtsp-server/rtsp-media.c
gst/rtsp-server/rtsp-stream.c
gst/rtsp-server/rtsp-stream.h

index 48868f5..6b81e25 100644 (file)
@@ -2713,6 +2713,14 @@ no_setup_sdp:
   }
 }
 
+static void
+do_set_seqnum (GstRTSPStream * stream)
+{
+  guint16 seq_num;
+  seq_num = gst_rtsp_stream_get_current_seqnum (stream);
+  gst_rtsp_stream_set_seqnum_offset (stream, seq_num + 1);
+}
+
 /* call with state_lock */
 gboolean
 default_suspend (GstRTSPMedia * media)
@@ -2735,6 +2743,12 @@ default_suspend (GstRTSPMedia * media)
       ret = set_target_state (media, GST_STATE_NULL, TRUE);
       if (ret == GST_STATE_CHANGE_FAILURE)
         goto state_failed;
+      /* Because payloader needs to set the sequence number as
+       * monotonic, we need to preserve the sequence number
+       * after pause. (otherwise going from pause to play,  which
+       * is actually from NULL to PLAY will create a new sequence
+       * number. */
+      g_ptr_array_foreach (priv->streams, (GFunc) do_set_seqnum, NULL);
       break;
     default:
       break;
index 68d7bec..456ddd9 100644 (file)
@@ -2577,6 +2577,48 @@ gst_rtsp_stream_get_rtcp_socket (GstRTSPStream * stream, GSocketFamily family)
 }
 
 /**
+ * gst_rtsp_stream_set_seqnum:
+ * @stream: a #GstRTSPStream
+ * @seqnum: a new sequence number
+ *
+ * Configure the sequence number in the payloader of @stream to @seqnum.
+ */
+void
+gst_rtsp_stream_set_seqnum_offset (GstRTSPStream * stream, guint16 seqnum)
+{
+  GstRTSPStreamPrivate *priv;
+
+  g_return_if_fail (GST_IS_RTSP_STREAM (stream));
+
+  priv = stream->priv;
+
+  g_object_set (G_OBJECT (priv->payloader), "seqnum-offset", seqnum, NULL);
+}
+
+/**
+ * gst_rtsp_stream_get_seqnum:
+ * @stream: a #GstRTSPStream
+ *
+ * Get the configured sequence number in the payloader of @stream.
+ *
+ * Returns: the sequence number of the payloader.
+ */
+guint16
+gst_rtsp_stream_get_current_seqnum (GstRTSPStream * stream)
+{
+  GstRTSPStreamPrivate *priv;
+  guint seqnum;
+
+  g_return_val_if_fail (GST_IS_RTSP_STREAM (stream), 0);
+
+  priv = stream->priv;
+
+  g_object_get (G_OBJECT (priv->payloader), "seqnum", &seqnum, NULL);
+
+  return seqnum;
+}
+
+/**
  * gst_rtsp_stream_transport_filter:
  * @stream: a #GstRTSPStream
  * @func: (scope call) (allow-none): a callback
index 1dbfdf3..135689e 100644 (file)
@@ -153,6 +153,9 @@ gboolean          gst_rtsp_stream_query_position   (GstRTSPStream * stream,
 gboolean          gst_rtsp_stream_query_stop       (GstRTSPStream * stream,
                                                     gint64 * stop);
 
+void              gst_rtsp_stream_set_seqnum_offset          (GstRTSPStream *stream, guint16 seqnum);
+guint16           gst_rtsp_stream_get_current_seqnum          (GstRTSPStream *stream);
+
 /**
  * GstRTSPStreamTransportFilterFunc:
  * @stream: a #GstRTSPStream object