Commit 0fb7922e authored by Ognyan Tonchev's avatar Ognyan Tonchev Committed by Wim Taymans

media: Make suspend()/unsuspend() virtual

Fixes https://bugzilla.gnome.org/show_bug.cgi?id=730109
parent d01beef7
......@@ -176,6 +176,8 @@ static gboolean default_handle_message (GstRTSPMedia * media,
static void finish_unprepare (GstRTSPMedia * media);
static gboolean default_prepare (GstRTSPMedia * media, GstRTSPThread * thread);
static gboolean default_unprepare (GstRTSPMedia * media);
static gboolean default_suspend (GstRTSPMedia * media);
static gboolean default_unsuspend (GstRTSPMedia * media);
static gboolean default_convert_range (GstRTSPMedia * media,
GstRTSPTimeRange * range, GstRTSPRangeUnit unit);
static gboolean default_query_position (GstRTSPMedia * media,
......@@ -308,6 +310,8 @@ gst_rtsp_media_class_init (GstRTSPMediaClass * klass)
klass->handle_message = default_handle_message;
klass->prepare = default_prepare;
klass->unprepare = default_unprepare;
klass->suspend = default_suspend;
klass->unsuspend = default_unsuspend;
klass->convert_range = default_convert_range;
klass->query_position = default_query_position;
klass->query_stop = default_query_stop;
......@@ -2661,6 +2665,46 @@ no_setup_sdp:
}
}
/* call with state_lock */
gboolean
default_suspend (GstRTSPMedia * media)
{
GstRTSPMediaPrivate *priv = media->priv;
GstStateChangeReturn ret;
switch (priv->suspend_mode) {
case GST_RTSP_SUSPEND_MODE_NONE:
GST_DEBUG ("media %p no suspend", media);
break;
case GST_RTSP_SUSPEND_MODE_PAUSE:
GST_DEBUG ("media %p suspend to PAUSED", media);
ret = set_target_state (media, GST_STATE_PAUSED, TRUE);
if (ret == GST_STATE_CHANGE_FAILURE)
goto state_failed;
break;
case GST_RTSP_SUSPEND_MODE_RESET:
GST_DEBUG ("media %p suspend to NULL", media);
ret = set_target_state (media, GST_STATE_NULL, TRUE);
if (ret == GST_STATE_CHANGE_FAILURE)
goto state_failed;
break;
default:
break;
}
/* let the streams do the state changes freely, if any */
media_streams_set_blocked (media, FALSE);
return TRUE;
/* ERRORS */
state_failed:
{
GST_WARNING ("failed changing pipeline's state for media %p", media);
return FALSE;
}
}
/**
* gst_rtsp_media_suspend:
* @media: a #GstRTSPMedia
......@@ -2677,7 +2721,7 @@ gboolean
gst_rtsp_media_suspend (GstRTSPMedia * media)
{
GstRTSPMediaPrivate *priv = media->priv;
GstStateChangeReturn ret;
GstRTSPMediaClass *klass;
g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), FALSE);
......@@ -2691,27 +2735,12 @@ gst_rtsp_media_suspend (GstRTSPMedia * media)
if (priv->n_active > 0)
goto done;
switch (priv->suspend_mode) {
case GST_RTSP_SUSPEND_MODE_NONE:
GST_DEBUG ("media %p no suspend", media);
break;
case GST_RTSP_SUSPEND_MODE_PAUSE:
GST_DEBUG ("media %p suspend to PAUSED", media);
ret = set_target_state (media, GST_STATE_PAUSED, TRUE);
if (ret == GST_STATE_CHANGE_FAILURE)
goto state_failed;
break;
case GST_RTSP_SUSPEND_MODE_RESET:
GST_DEBUG ("media %p suspend to NULL", media);
ret = set_target_state (media, GST_STATE_NULL, TRUE);
if (ret == GST_STATE_CHANGE_FAILURE)
goto state_failed;
break;
default:
break;
klass = GST_RTSP_MEDIA_GET_CLASS (media);
if (klass->suspend) {
if (!klass->suspend (media))
goto suspend_failed;
}
/* let the streams do the state changes freely, if any */
media_streams_set_blocked (media, FALSE);
gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_SUSPENDED);
done:
g_rec_mutex_unlock (&priv->state_lock);
......@@ -2725,35 +2754,21 @@ not_prepared:
GST_WARNING ("media %p was not prepared", media);
return FALSE;
}
state_failed:
suspend_failed:
{
g_rec_mutex_unlock (&priv->state_lock);
gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_ERROR);
GST_WARNING ("failed changing pipeline's state for media %p", media);
GST_WARNING ("failed to suspend media %p", media);
return FALSE;
}
}
/**
* gst_rtsp_media_unsuspend:
* @media: a #GstRTSPMedia
*
* Unsuspend @media if it was in a suspended state. This method does nothing
* when the media was not in the suspended state.
*
* Returns: %TRUE on success.
*/
/* call with state_lock */
gboolean
gst_rtsp_media_unsuspend (GstRTSPMedia * media)
default_unsuspend (GstRTSPMedia * media)
{
GstRTSPMediaPrivate *priv = media->priv;
g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), FALSE);
g_rec_mutex_lock (&priv->state_lock);
if (priv->status != GST_RTSP_MEDIA_STATUS_SUSPENDED)
goto done;
switch (priv->suspend_mode) {
case GST_RTSP_SUSPEND_MODE_NONE:
gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_PREPARED);
......@@ -2776,17 +2791,13 @@ gst_rtsp_media_unsuspend (GstRTSPMedia * media)
default:
break;
}
done:
g_rec_mutex_unlock (&priv->state_lock);
return TRUE;
/* ERRORS */
start_failed:
{
g_rec_mutex_unlock (&priv->state_lock);
GST_WARNING ("failed to preroll pipeline");
gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_ERROR);
return FALSE;
}
preroll_failed:
......@@ -2796,6 +2807,48 @@ preroll_failed:
}
}
/**
* gst_rtsp_media_unsuspend:
* @media: a #GstRTSPMedia
*
* Unsuspend @media if it was in a suspended state. This method does nothing
* when the media was not in the suspended state.
*
* Returns: %TRUE on success.
*/
gboolean
gst_rtsp_media_unsuspend (GstRTSPMedia * media)
{
GstRTSPMediaPrivate *priv = media->priv;
GstRTSPMediaClass *klass;
g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), FALSE);
g_rec_mutex_lock (&priv->state_lock);
if (priv->status != GST_RTSP_MEDIA_STATUS_SUSPENDED)
goto done;
klass = GST_RTSP_MEDIA_GET_CLASS (media);
if (klass->unsuspend) {
if (!klass->unsuspend (media))
goto unsuspend_failed;
}
done:
g_rec_mutex_unlock (&priv->state_lock);
return TRUE;
/* ERRORS */
unsuspend_failed:
{
g_rec_mutex_unlock (&priv->state_lock);
GST_WARNING ("failed to unsuspend media %p", media);
gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_ERROR);
return FALSE;
}
}
/* must be called with state-lock */
static void
media_set_pipeline_state_locked (GstRTSPMedia * media, GstState state)
......
......@@ -110,6 +110,12 @@ struct _GstRTSPMedia {
* in case of NO_PREROLL elements).
* @unprepare: the default implementation sets the pipeline's state
* to GST_STATE_NULL and removes all elements.
* @suspend: the default implementation sets the pipeline's state to
* GST_STATE_NULL GST_STATE_PAUSED depending on the selected
* suspend mode.
* @unsuspend: the default implementation reverts the suspend operation.
* The pipeline will be prerolled again if it's state was
* set to GST_STATE_NULL in suspend.
* @convert_range: convert a range to the given unit
* @query_position: query the current posision in the pipeline
* @query_stop: query when playback will stop
......@@ -123,6 +129,8 @@ struct _GstRTSPMediaClass {
gboolean (*handle_message) (GstRTSPMedia *media, GstMessage *message);
gboolean (*prepare) (GstRTSPMedia *media, GstRTSPThread *thread);
gboolean (*unprepare) (GstRTSPMedia *media);
gboolean (*suspend) (GstRTSPMedia *media);
gboolean (*unsuspend) (GstRTSPMedia *media);
gboolean (*convert_range) (GstRTSPMedia *media, GstRTSPTimeRange *range,
GstRTSPRangeUnit unit);
gboolean (*query_position) (GstRTSPMedia *media, gint64 *position);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment