mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-20 04:56:24 +00:00
composition: Start implementing seeking in a GSource
This commit is contained in:
parent
5faa417583
commit
bb7fa996b4
1 changed files with 87 additions and 60 deletions
|
@ -76,6 +76,12 @@ enum
|
||||||
|
|
||||||
typedef struct _GnlCompositionEntry GnlCompositionEntry;
|
typedef struct _GnlCompositionEntry GnlCompositionEntry;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GnlComposition *comp;
|
||||||
|
GstEvent *event;
|
||||||
|
} SeekData;
|
||||||
|
|
||||||
struct _GnlCompositionPrivate
|
struct _GnlCompositionPrivate
|
||||||
{
|
{
|
||||||
gboolean dispose_has_run;
|
gboolean dispose_has_run;
|
||||||
|
@ -214,6 +220,8 @@ static gboolean lock_child_state (GValue * item, GValue * ret,
|
||||||
gpointer udata G_GNUC_UNUSED);
|
gpointer udata G_GNUC_UNUSED);
|
||||||
static gboolean
|
static gboolean
|
||||||
set_child_caps (GValue * item, GValue * ret G_GNUC_UNUSED, GnlObject * comp);
|
set_child_caps (GValue * item, GValue * ret G_GNUC_UNUSED, GnlObject * comp);
|
||||||
|
static GstEvent *get_new_seek_event (GnlComposition * comp, gboolean initial,
|
||||||
|
gboolean updatestoponly);
|
||||||
|
|
||||||
|
|
||||||
/* COMP_REAL_START: actual position to start current playback at. */
|
/* COMP_REAL_START: actual position to start current playback at. */
|
||||||
|
@ -400,6 +408,66 @@ join_failed:
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_seek_pipeline_func (SeekData * seekd)
|
||||||
|
{
|
||||||
|
gdouble rate;
|
||||||
|
GstFormat format;
|
||||||
|
GstSeekFlags flags;
|
||||||
|
GstSeekType cur_type, stop_type;
|
||||||
|
gint64 cur, stop;
|
||||||
|
GnlCompositionPrivate *priv = seekd->comp->priv;
|
||||||
|
|
||||||
|
gst_event_parse_seek (seekd->event, &rate, &format, &flags,
|
||||||
|
&cur_type, &cur, &stop_type, &stop);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (seekd->comp,
|
||||||
|
"start:%" GST_TIME_FORMAT " -- stop:%" GST_TIME_FORMAT " flags:%d",
|
||||||
|
GST_TIME_ARGS (cur), GST_TIME_ARGS (stop), flags);
|
||||||
|
|
||||||
|
gst_segment_do_seek (priv->segment,
|
||||||
|
rate, format, flags, cur_type, cur, stop_type, stop, NULL);
|
||||||
|
gst_segment_do_seek (priv->outside_segment,
|
||||||
|
rate, format, flags, cur_type, cur, stop_type, stop, NULL);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (seekd->comp, "Segment now has flags:%d",
|
||||||
|
priv->segment->flags);
|
||||||
|
|
||||||
|
if (priv->segment->start >= GNL_OBJECT_STOP (seekd->comp)) {
|
||||||
|
GST_INFO_OBJECT (seekd->comp,
|
||||||
|
"Start %" GST_TIME_FORMAT " > comp->stop: %" GST_TIME_FORMAT
|
||||||
|
" Not seeking", GST_TIME_ARGS (priv->segment->start),
|
||||||
|
GST_TIME_ARGS (GNL_OBJECT_STOP (seekd->comp)));
|
||||||
|
GST_FIXME_OBJECT (seekd->comp, "HANDLE error async!");
|
||||||
|
goto beach;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* crop the segment start/stop values */
|
||||||
|
/* Only crop segment start value if we don't have a default object */
|
||||||
|
if (priv->expandables == NULL)
|
||||||
|
priv->segment->start =
|
||||||
|
MAX (priv->segment->start, GNL_OBJECT_START (seekd->comp));
|
||||||
|
priv->segment->stop =
|
||||||
|
MIN (priv->segment->stop, GNL_OBJECT_STOP (seekd->comp));
|
||||||
|
|
||||||
|
priv->next_base_time = 0;
|
||||||
|
|
||||||
|
seek_handling (seekd->comp, TRUE, FALSE);
|
||||||
|
|
||||||
|
priv->reset_time = TRUE;
|
||||||
|
priv->gnl_event_pad_func (GNL_OBJECT (seekd->comp)->srcpad,
|
||||||
|
GST_OBJECT (seekd->comp), get_new_seek_event (seekd->comp, FALSE, FALSE));
|
||||||
|
priv->reset_time = FALSE;
|
||||||
|
|
||||||
|
beach:
|
||||||
|
gst_event_unref (seekd->event);
|
||||||
|
g_slice_free (SeekData, seekd);
|
||||||
|
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_add_update_gsource (GnlComposition * comp)
|
_add_update_gsource (GnlComposition * comp)
|
||||||
{
|
{
|
||||||
|
@ -418,6 +486,21 @@ _add_commit_gsource (GnlComposition * comp)
|
||||||
MAIN_CONTEXT_UNLOCK (comp);
|
MAIN_CONTEXT_UNLOCK (comp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_add_seek_gsource (GnlComposition * comp, GstEvent * event)
|
||||||
|
{
|
||||||
|
SeekData *seekd = g_slice_new0 (SeekData);
|
||||||
|
|
||||||
|
seekd->comp = comp;
|
||||||
|
seekd->event = event;
|
||||||
|
|
||||||
|
MAIN_CONTEXT_LOCK (comp);
|
||||||
|
g_main_context_invoke (comp->priv->mcontext,
|
||||||
|
(GSourceFunc) _seek_pipeline_func, seekd);
|
||||||
|
MAIN_CONTEXT_UNLOCK (comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
_initialize_stack_func (GnlComposition * comp)
|
_initialize_stack_func (GnlComposition * comp)
|
||||||
{
|
{
|
||||||
|
@ -1316,50 +1399,6 @@ seek_handling (GnlComposition * comp, gboolean initial, gboolean update)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
handle_seek_event (GnlComposition * comp, GstEvent * event)
|
|
||||||
{
|
|
||||||
gdouble rate;
|
|
||||||
GstFormat format;
|
|
||||||
GstSeekFlags flags;
|
|
||||||
GstSeekType cur_type, stop_type;
|
|
||||||
gint64 cur, stop;
|
|
||||||
GnlCompositionPrivate *priv = comp->priv;
|
|
||||||
|
|
||||||
gst_event_parse_seek (event, &rate, &format, &flags,
|
|
||||||
&cur_type, &cur, &stop_type, &stop);
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (comp,
|
|
||||||
"start:%" GST_TIME_FORMAT " -- stop:%" GST_TIME_FORMAT " flags:%d",
|
|
||||||
GST_TIME_ARGS (cur), GST_TIME_ARGS (stop), flags);
|
|
||||||
|
|
||||||
gst_segment_do_seek (priv->segment,
|
|
||||||
rate, format, flags, cur_type, cur, stop_type, stop, NULL);
|
|
||||||
gst_segment_do_seek (priv->outside_segment,
|
|
||||||
rate, format, flags, cur_type, cur, stop_type, stop, NULL);
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (comp, "Segment now has flags:%d", priv->segment->flags);
|
|
||||||
|
|
||||||
if (priv->segment->start >= GNL_OBJECT_STOP (comp)) {
|
|
||||||
GST_INFO_OBJECT (comp,
|
|
||||||
"Start %" GST_TIME_FORMAT " > comp->stop: %" GST_TIME_FORMAT
|
|
||||||
" Not seeking", GST_TIME_ARGS (priv->segment->start),
|
|
||||||
GST_TIME_ARGS (GNL_OBJECT_STOP (comp)));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* crop the segment start/stop values */
|
|
||||||
/* Only crop segment start value if we don't have a default object */
|
|
||||||
if (priv->expandables == NULL)
|
|
||||||
priv->segment->start = MAX (priv->segment->start, GNL_OBJECT_START (comp));
|
|
||||||
priv->segment->stop = MIN (priv->segment->stop, GNL_OBJECT_STOP (comp));
|
|
||||||
|
|
||||||
comp->priv->next_base_time = 0;
|
|
||||||
|
|
||||||
seek_handling (comp, TRUE, FALSE);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gnl_composition_event_handler (GstPad * ghostpad, GstObject * parent,
|
gnl_composition_event_handler (GstPad * ghostpad, GstObject * parent,
|
||||||
GstEvent * event)
|
GstEvent * event)
|
||||||
|
@ -1373,23 +1412,11 @@ gnl_composition_event_handler (GstPad * ghostpad, GstObject * parent,
|
||||||
switch (GST_EVENT_TYPE (event)) {
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
case GST_EVENT_SEEK:
|
case GST_EVENT_SEEK:
|
||||||
{
|
{
|
||||||
GstEvent *nevent;
|
_add_seek_gsource (comp, event);
|
||||||
|
event = NULL;
|
||||||
|
GST_FIXME_OBJECT (comp, "HANDLE seeking errors!");
|
||||||
|
|
||||||
if ((res = handle_seek_event (comp, event)) == FALSE) {
|
return TRUE;
|
||||||
gst_event_unref (event);
|
|
||||||
event = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* the incoming event might not be quite correct, we get a new proper
|
|
||||||
* event to pass on to the children. */
|
|
||||||
COMP_OBJECTS_LOCK (comp);
|
|
||||||
nevent = get_new_seek_event (comp, FALSE, FALSE);
|
|
||||||
COMP_OBJECTS_UNLOCK (comp);
|
|
||||||
gst_event_unref (event);
|
|
||||||
event = nevent;
|
|
||||||
priv->reset_time = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case GST_EVENT_QOS:
|
case GST_EVENT_QOS:
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue