rtsp-media: Make sure that sequence numbers are monotonic after pause

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
This commit is contained in:
Srimanta Panda 2014-09-08 09:26:23 +02:00 committed by Sebastian Dröge
parent 09bf2025f8
commit 376488d8c7
3 changed files with 59 additions and 0 deletions

View 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 */ /* call with state_lock */
gboolean gboolean
default_suspend (GstRTSPMedia * media) default_suspend (GstRTSPMedia * media)
@ -2735,6 +2743,12 @@ default_suspend (GstRTSPMedia * media)
ret = set_target_state (media, GST_STATE_NULL, TRUE); ret = set_target_state (media, GST_STATE_NULL, TRUE);
if (ret == GST_STATE_CHANGE_FAILURE) if (ret == GST_STATE_CHANGE_FAILURE)
goto state_failed; 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; break;
default: default:
break; break;

View file

@ -2576,6 +2576,48 @@ gst_rtsp_stream_get_rtcp_socket (GstRTSPStream * stream, GSocketFamily family)
return socket; return socket;
} }
/**
* 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: * gst_rtsp_stream_transport_filter:
* @stream: a #GstRTSPStream * @stream: a #GstRTSPStream

View file

@ -153,6 +153,9 @@ gboolean gst_rtsp_stream_query_position (GstRTSPStream * stream,
gboolean gst_rtsp_stream_query_stop (GstRTSPStream * stream, gboolean gst_rtsp_stream_query_stop (GstRTSPStream * stream,
gint64 * stop); gint64 * stop);
void gst_rtsp_stream_set_seqnum_offset (GstRTSPStream *stream, guint16 seqnum);
guint16 gst_rtsp_stream_get_current_seqnum (GstRTSPStream *stream);
/** /**
* GstRTSPStreamTransportFilterFunc: * GstRTSPStreamTransportFilterFunc:
* @stream: a #GstRTSPStream object * @stream: a #GstRTSPStream object