media: make media_prepare virtual

Fixes https://bugzilla.gnome.org/show_bug.cgi?id=728029
This commit is contained in:
Ognyan Tonchev 2014-04-09 16:44:21 +02:00 committed by Wim Taymans
parent da19a3c21a
commit 80474e9e5e
2 changed files with 98 additions and 59 deletions

View file

@ -174,6 +174,7 @@ static void gst_rtsp_media_finalize (GObject * obj);
static gboolean default_handle_message (GstRTSPMedia * media, static gboolean default_handle_message (GstRTSPMedia * media,
GstMessage * message); GstMessage * message);
static void finish_unprepare (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_unprepare (GstRTSPMedia * media);
static gboolean default_convert_range (GstRTSPMedia * media, static gboolean default_convert_range (GstRTSPMedia * media,
GstRTSPTimeRange * range, GstRTSPRangeUnit unit); GstRTSPTimeRange * range, GstRTSPRangeUnit unit);
@ -305,6 +306,7 @@ gst_rtsp_media_class_init (GstRTSPMediaClass * klass)
GST_DEBUG_CATEGORY_INIT (rtsp_media_debug, "rtspmedia", 0, "GstRTSPMedia"); GST_DEBUG_CATEGORY_INIT (rtsp_media_debug, "rtspmedia", 0, "GstRTSPMedia");
klass->handle_message = default_handle_message; klass->handle_message = default_handle_message;
klass->prepare = default_prepare;
klass->unprepare = default_unprepare; klass->unprepare = default_unprepare;
klass->convert_range = default_convert_range; klass->convert_range = default_convert_range;
klass->query_position = default_query_position; klass->query_position = default_query_position;
@ -2136,49 +2138,17 @@ preroll_failed:
} }
} }
/** static gboolean
* gst_rtsp_media_prepare: default_prepare (GstRTSPMedia * media, GstRTSPThread * thread)
* @media: a #GstRTSPMedia
* @thread: (transfer full): a #GstRTSPThread to run the bus handler or %NULL
*
* Prepare @media for streaming. This function will create the objects
* to manage the streaming. A pipeline must have been set on @media with
* gst_rtsp_media_take_pipeline().
*
* It will preroll the pipeline and collect vital information about the streams
* such as the duration.
*
* Returns: %TRUE on success.
*/
gboolean
gst_rtsp_media_prepare (GstRTSPMedia * media, GstRTSPThread * thread)
{ {
GstRTSPMediaPrivate *priv; GstRTSPMediaPrivate *priv;
GstBus *bus;
GSource *source;
GstRTSPMediaClass *klass; GstRTSPMediaClass *klass;
GstBus *bus;
GMainContext *context; GMainContext *context;
GSource *source;
g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), FALSE);
priv = media->priv; priv = media->priv;
g_rec_mutex_lock (&priv->state_lock);
priv->prepare_count++;
if (priv->status == GST_RTSP_MEDIA_STATUS_PREPARED ||
priv->status == GST_RTSP_MEDIA_STATUS_SUSPENDED)
goto was_prepared;
if (priv->status == GST_RTSP_MEDIA_STATUS_PREPARING)
goto wait_status;
if (priv->status != GST_RTSP_MEDIA_STATUS_UNPREPARED)
goto not_unprepared;
if (!priv->reusable && priv->reused)
goto is_reused;
klass = GST_RTSP_MEDIA_GET_CLASS (media); klass = GST_RTSP_MEDIA_GET_CLASS (media);
if (!klass->create_rtpbin) if (!klass->create_rtpbin)
@ -2199,18 +2169,9 @@ gst_rtsp_media_prepare (GstRTSPMedia * media, GstRTSPThread * thread)
if (priv->rtpbin == NULL) if (priv->rtpbin == NULL)
goto no_rtpbin; goto no_rtpbin;
GST_INFO ("preparing media %p", media);
/* reset some variables */
priv->is_live = FALSE;
priv->seekable = FALSE;
priv->buffering = FALSE;
priv->thread = thread; priv->thread = thread;
context = (thread != NULL) ? (thread->context) : NULL; context = (thread != NULL) ? (thread->context) : NULL;
/* we're preparing now */
gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_PREPARING);
bus = gst_pipeline_get_bus (GST_PIPELINE_CAST (priv->pipeline)); bus = gst_pipeline_get_bus (GST_PIPELINE_CAST (priv->pipeline));
/* add the pipeline bus to our custom mainloop */ /* add the pipeline bus to our custom mainloop */
@ -2231,6 +2192,85 @@ gst_rtsp_media_prepare (GstRTSPMedia * media, GstRTSPThread * thread)
g_source_attach (source, context); g_source_attach (source, context);
g_source_unref (source); g_source_unref (source);
return TRUE;
/* ERRORS */
no_create_rtpbin:
{
/* we are not going to use the giving thread, so stop it. */
if (thread)
gst_rtsp_thread_stop (thread);
GST_ERROR ("no create_rtpbin function");
g_critical ("no create_rtpbin vmethod function set");
return FALSE;
}
no_rtpbin:
{
/* we are not going to use the giving thread, so stop it. */
if (thread)
gst_rtsp_thread_stop (thread);
GST_WARNING ("no rtpbin element");
g_warning ("failed to create element 'rtpbin', check your installation");
return FALSE;
}
}
/**
* gst_rtsp_media_prepare:
* @media: a #GstRTSPMedia
* @thread: (transfer full): a #GstRTSPThread to run the bus handler or %NULL
*
* Prepare @media for streaming. This function will create the objects
* to manage the streaming. A pipeline must have been set on @media with
* gst_rtsp_media_take_pipeline().
*
* It will preroll the pipeline and collect vital information about the streams
* such as the duration.
*
* Returns: %TRUE on success.
*/
gboolean
gst_rtsp_media_prepare (GstRTSPMedia * media, GstRTSPThread * thread)
{
GstRTSPMediaPrivate *priv;
GstRTSPMediaClass *klass;
g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), FALSE);
priv = media->priv;
g_rec_mutex_lock (&priv->state_lock);
priv->prepare_count++;
if (priv->status == GST_RTSP_MEDIA_STATUS_PREPARED ||
priv->status == GST_RTSP_MEDIA_STATUS_SUSPENDED)
goto was_prepared;
if (priv->status == GST_RTSP_MEDIA_STATUS_PREPARING)
goto is_preparing;
if (priv->status != GST_RTSP_MEDIA_STATUS_UNPREPARED)
goto not_unprepared;
if (!priv->reusable && priv->reused)
goto is_reused;
GST_INFO ("preparing media %p", media);
/* reset some variables */
priv->is_live = FALSE;
priv->seekable = FALSE;
priv->buffering = FALSE;
/* we're preparing now */
gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_PREPARING);
klass = GST_RTSP_MEDIA_GET_CLASS (media);
if (klass->prepare) {
if (!klass->prepare (media, thread))
goto prepare_failed;
}
wait_status: wait_status:
g_rec_mutex_unlock (&priv->state_lock); g_rec_mutex_unlock (&priv->state_lock);
@ -2246,6 +2286,13 @@ wait_status:
return TRUE; return TRUE;
/* OK */ /* OK */
is_preparing:
{
/* we are not going to use the giving thread, so stop it. */
if (thread)
gst_rtsp_thread_stop (thread);
goto wait_status;
}
was_prepared: was_prepared:
{ {
GST_LOG ("media %p was prepared", media); GST_LOG ("media %p was prepared", media);
@ -2276,26 +2323,14 @@ is_reused:
GST_WARNING ("can not reuse media %p", media); GST_WARNING ("can not reuse media %p", media);
return FALSE; return FALSE;
} }
no_create_rtpbin: prepare_failed:
{ {
/* we are not going to use the giving thread, so stop it. */ /* we are not going to use the giving thread, so stop it. */
if (thread) if (thread)
gst_rtsp_thread_stop (thread); gst_rtsp_thread_stop (thread);
priv->prepare_count--; priv->prepare_count--;
g_rec_mutex_unlock (&priv->state_lock); g_rec_mutex_unlock (&priv->state_lock);
GST_ERROR ("no create_rtpbin function"); GST_ERROR ("failed to prepare media");
g_critical ("no create_rtpbin vmethod function set");
return FALSE;
}
no_rtpbin:
{
/* we are not going to use the giving thread, so stop it. */
if (thread)
gst_rtsp_thread_stop (thread);
priv->prepare_count--;
g_rec_mutex_unlock (&priv->state_lock);
GST_WARNING ("no rtpbin element");
g_warning ("failed to create element 'rtpbin', check your installation");
return FALSE; return FALSE;
} }
preroll_failed: preroll_failed:

View file

@ -105,6 +105,9 @@ struct _GstRTSPMedia {
/** /**
* GstRTSPMediaClass: * GstRTSPMediaClass:
* @handle_message: handle a message * @handle_message: handle a message
* @prepare: the default implementation adds all elements and sets the
* pipeline's state to GST_STATE_PAUSED (or GST_STATE_PLAYING
* in case of NO_PREROLL elements).
* @unprepare: the default implementation sets the pipeline's state * @unprepare: the default implementation sets the pipeline's state
* to GST_STATE_NULL and removes all elements. * to GST_STATE_NULL and removes all elements.
* @convert_range: convert a range to the given unit * @convert_range: convert a range to the given unit
@ -118,6 +121,7 @@ struct _GstRTSPMediaClass {
/* vmethods */ /* vmethods */
gboolean (*handle_message) (GstRTSPMedia *media, GstMessage *message); gboolean (*handle_message) (GstRTSPMedia *media, GstMessage *message);
gboolean (*prepare) (GstRTSPMedia *media, GstRTSPThread *thread);
gboolean (*unprepare) (GstRTSPMedia *media); gboolean (*unprepare) (GstRTSPMedia *media);
gboolean (*convert_range) (GstRTSPMedia *media, GstRTSPTimeRange *range, gboolean (*convert_range) (GstRTSPMedia *media, GstRTSPTimeRange *range,
GstRTSPRangeUnit unit); GstRTSPRangeUnit unit);