mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-02 05:28:48 +00:00
media: refactor starting and waiting for preroll
Based on patches from Ognyan Tonchev <ognyan@axis.com> See https://bugzilla.gnome.org/show_bug.cgi?id=711257
This commit is contained in:
parent
bdef631218
commit
6ce48c51a2
1 changed files with 85 additions and 38 deletions
|
@ -173,6 +173,8 @@ static gboolean default_query_position (GstRTSPMedia * media,
|
||||||
gint64 * position);
|
gint64 * position);
|
||||||
static gboolean default_query_stop (GstRTSPMedia * media, gint64 * stop);
|
static gboolean default_query_stop (GstRTSPMedia * media, gint64 * stop);
|
||||||
|
|
||||||
|
static gboolean wait_preroll (GstRTSPMedia * media);
|
||||||
|
|
||||||
static guint gst_rtsp_media_signals[SIGNAL_LAST] = { 0 };
|
static guint gst_rtsp_media_signals[SIGNAL_LAST] = { 0 };
|
||||||
|
|
||||||
G_DEFINE_TYPE (GstRTSPMedia, gst_rtsp_media, G_TYPE_OBJECT);
|
G_DEFINE_TYPE (GstRTSPMedia, gst_rtsp_media, G_TYPE_OBJECT);
|
||||||
|
@ -1345,10 +1347,14 @@ gst_rtsp_media_seek (GstRTSPMedia * media, GstRTSPTimeRange * range)
|
||||||
|
|
||||||
/* and block for the seek to complete */
|
/* and block for the seek to complete */
|
||||||
GST_INFO ("done seeking %d", res);
|
GST_INFO ("done seeking %d", res);
|
||||||
gst_element_get_state (priv->pipeline, NULL, NULL, -1);
|
g_rec_mutex_unlock (&priv->state_lock);
|
||||||
GST_INFO ("prerolled again");
|
|
||||||
|
|
||||||
collect_media_stats (media);
|
/* wait until pipeline is prerolled again, this will also collect stats */
|
||||||
|
if (!wait_preroll (media))
|
||||||
|
goto preroll_failed;
|
||||||
|
|
||||||
|
g_rec_mutex_lock (&priv->state_lock);
|
||||||
|
GST_INFO ("prerolled again");
|
||||||
} else {
|
} else {
|
||||||
GST_INFO ("no seek needed");
|
GST_INFO ("no seek needed");
|
||||||
res = TRUE;
|
res = TRUE;
|
||||||
|
@ -1376,6 +1382,11 @@ not_supported:
|
||||||
GST_WARNING ("conversion to npt not supported");
|
GST_WARNING ("conversion to npt not supported");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
preroll_failed:
|
||||||
|
{
|
||||||
|
GST_WARNING ("failed to preroll after seek");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1684,10 +1695,74 @@ struct _DynPaySignalHandlers
|
||||||
};
|
};
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
start_prepare (GstRTSPMedia * media)
|
start_preroll (GstRTSPMedia * media)
|
||||||
{
|
{
|
||||||
GstRTSPMediaPrivate *priv = media->priv;
|
GstRTSPMediaPrivate *priv = media->priv;
|
||||||
GstStateChangeReturn ret;
|
GstStateChangeReturn ret;
|
||||||
|
|
||||||
|
GST_INFO ("setting pipeline to PAUSED for media %p", media);
|
||||||
|
/* first go to PAUSED */
|
||||||
|
ret = gst_element_set_state (priv->pipeline, GST_STATE_PAUSED);
|
||||||
|
priv->target_state = GST_STATE_PAUSED;
|
||||||
|
|
||||||
|
switch (ret) {
|
||||||
|
case GST_STATE_CHANGE_SUCCESS:
|
||||||
|
GST_INFO ("SUCCESS state change for media %p", media);
|
||||||
|
priv->seekable = TRUE;
|
||||||
|
break;
|
||||||
|
case GST_STATE_CHANGE_ASYNC:
|
||||||
|
GST_INFO ("ASYNC state change for media %p", media);
|
||||||
|
priv->seekable = TRUE;
|
||||||
|
break;
|
||||||
|
case GST_STATE_CHANGE_NO_PREROLL:
|
||||||
|
/* we need to go to PLAYING */
|
||||||
|
GST_INFO ("NO_PREROLL state change: live media %p", media);
|
||||||
|
/* FIXME we disable seeking for live streams for now. We should perform a
|
||||||
|
* seeking query in preroll instead */
|
||||||
|
priv->seekable = FALSE;
|
||||||
|
priv->is_live = TRUE;
|
||||||
|
ret = gst_element_set_state (priv->pipeline, GST_STATE_PLAYING);
|
||||||
|
if (ret == GST_STATE_CHANGE_FAILURE)
|
||||||
|
goto state_failed;
|
||||||
|
break;
|
||||||
|
case GST_STATE_CHANGE_FAILURE:
|
||||||
|
goto state_failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
state_failed:
|
||||||
|
{
|
||||||
|
GST_WARNING ("failed to preroll pipeline");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
wait_preroll (GstRTSPMedia * media)
|
||||||
|
{
|
||||||
|
GstRTSPMediaStatus status;
|
||||||
|
|
||||||
|
GST_DEBUG ("wait to preroll pipeline");
|
||||||
|
|
||||||
|
/* wait until pipeline is prerolled */
|
||||||
|
status = gst_rtsp_media_get_status (media);
|
||||||
|
if (status == GST_RTSP_MEDIA_STATUS_ERROR)
|
||||||
|
goto preroll_failed;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
preroll_failed:
|
||||||
|
{
|
||||||
|
GST_WARNING ("failed to preroll pipeline");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
start_prepare (GstRTSPMedia * media)
|
||||||
|
{
|
||||||
|
GstRTSPMediaPrivate *priv = media->priv;
|
||||||
guint i;
|
guint i;
|
||||||
GList *walk;
|
GList *walk;
|
||||||
|
|
||||||
|
@ -1723,38 +1798,12 @@ start_prepare (GstRTSPMedia * media)
|
||||||
gst_bin_add (GST_BIN (priv->pipeline), priv->fakesink);
|
gst_bin_add (GST_BIN (priv->pipeline), priv->fakesink);
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_INFO ("setting pipeline to PAUSED for media %p", media);
|
if (!start_preroll (media))
|
||||||
/* first go to PAUSED */
|
goto preroll_failed;
|
||||||
ret = gst_element_set_state (priv->pipeline, GST_STATE_PAUSED);
|
|
||||||
priv->target_state = GST_STATE_PAUSED;
|
|
||||||
|
|
||||||
switch (ret) {
|
|
||||||
case GST_STATE_CHANGE_SUCCESS:
|
|
||||||
GST_INFO ("SUCCESS state change for media %p", media);
|
|
||||||
priv->seekable = TRUE;
|
|
||||||
break;
|
|
||||||
case GST_STATE_CHANGE_ASYNC:
|
|
||||||
GST_INFO ("ASYNC state change for media %p", media);
|
|
||||||
priv->seekable = TRUE;
|
|
||||||
break;
|
|
||||||
case GST_STATE_CHANGE_NO_PREROLL:
|
|
||||||
/* we need to go to PLAYING */
|
|
||||||
GST_INFO ("NO_PREROLL state change: live media %p", media);
|
|
||||||
/* FIXME we disable seeking for live streams for now. We should perform a
|
|
||||||
* seeking query in preroll instead */
|
|
||||||
priv->seekable = FALSE;
|
|
||||||
priv->is_live = TRUE;
|
|
||||||
ret = gst_element_set_state (priv->pipeline, GST_STATE_PLAYING);
|
|
||||||
if (ret == GST_STATE_CHANGE_FAILURE)
|
|
||||||
goto state_failed;
|
|
||||||
break;
|
|
||||||
case GST_STATE_CHANGE_FAILURE:
|
|
||||||
goto state_failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
state_failed:
|
preroll_failed:
|
||||||
{
|
{
|
||||||
GST_WARNING ("failed to preroll pipeline");
|
GST_WARNING ("failed to preroll pipeline");
|
||||||
gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_ERROR);
|
gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_ERROR);
|
||||||
|
@ -1780,7 +1829,6 @@ gboolean
|
||||||
gst_rtsp_media_prepare (GstRTSPMedia * media, GstRTSPThread * thread)
|
gst_rtsp_media_prepare (GstRTSPMedia * media, GstRTSPThread * thread)
|
||||||
{
|
{
|
||||||
GstRTSPMediaPrivate *priv;
|
GstRTSPMediaPrivate *priv;
|
||||||
GstRTSPMediaStatus status;
|
|
||||||
GstBus *bus;
|
GstBus *bus;
|
||||||
GSource *source;
|
GSource *source;
|
||||||
|
|
||||||
|
@ -1856,9 +1904,8 @@ wait_status:
|
||||||
|
|
||||||
/* now wait for all pads to be prerolled, FIXME, we should somehow be
|
/* now wait for all pads to be prerolled, FIXME, we should somehow be
|
||||||
* able to do this async so that we don't block the server thread. */
|
* able to do this async so that we don't block the server thread. */
|
||||||
status = gst_rtsp_media_get_status (media);
|
if (!wait_preroll (media))
|
||||||
if (status == GST_RTSP_MEDIA_STATUS_ERROR)
|
goto preroll_failed;
|
||||||
goto state_failed;
|
|
||||||
|
|
||||||
g_signal_emit (media, gst_rtsp_media_signals[SIGNAL_PREPARED], 0, NULL);
|
g_signal_emit (media, gst_rtsp_media_signals[SIGNAL_PREPARED], 0, NULL);
|
||||||
|
|
||||||
|
@ -1896,7 +1943,7 @@ no_rtpbin:
|
||||||
g_warning ("failed to create element 'rtpbin', check your installation");
|
g_warning ("failed to create element 'rtpbin', check your installation");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
state_failed:
|
preroll_failed:
|
||||||
{
|
{
|
||||||
GST_WARNING ("failed to preroll pipeline");
|
GST_WARNING ("failed to preroll pipeline");
|
||||||
gst_rtsp_media_unprepare (media);
|
gst_rtsp_media_unprepare (media);
|
||||||
|
|
Loading…
Reference in a new issue