mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 20:21:24 +00:00
media: make media_prepare virtual
Fixes https://bugzilla.gnome.org/show_bug.cgi?id=728029
This commit is contained in:
parent
da19a3c21a
commit
80474e9e5e
2 changed files with 98 additions and 59 deletions
|
@ -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:
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue