mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 02:01:12 +00:00
ges: Implement the ges_timeline_layer_add_asset method
+ Remove GstDiscoverer related code in GESTimeline as we do not need it anymore + Refactor the ges_timeline_layer_add_object method to make sure it is still working as intended API: ges_timeline_layer_add_asset
This commit is contained in:
parent
c7cefd0f37
commit
a7280fb59d
3 changed files with 140 additions and 306 deletions
|
@ -59,6 +59,12 @@ struct _GESTimelineLayerPrivate
|
||||||
gboolean auto_transition;
|
gboolean auto_transition;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GESTimelineObject *object;
|
||||||
|
GESTimelineLayer *layer;
|
||||||
|
} NewAssetUData;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
|
@ -695,6 +701,26 @@ start_calculating_transitions (GESTimelineLayer * layer)
|
||||||
/* FIXME calculate all the transitions at that time */
|
/* FIXME calculate all the transitions at that time */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
new_asset_cb (GESAsset * source, GAsyncResult * res, NewAssetUData * udata)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
GESAsset *asset = ges_asset_request_finish (res, &error);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (udata->layer, "%" GST_PTR_FORMAT " Asset loaded, "
|
||||||
|
"setting its asset", udata->object);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
GST_ERROR ("Asset could not be created for uri");
|
||||||
|
} else {
|
||||||
|
ges_timeline_layer_add_object (udata->layer, udata->object);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_unref (asset);
|
||||||
|
g_slice_free (NewAssetUData, udata);
|
||||||
|
}
|
||||||
|
|
||||||
/* Public methods */
|
/* Public methods */
|
||||||
/**
|
/**
|
||||||
* ges_timeline_layer_remove_object:
|
* ges_timeline_layer_remove_object:
|
||||||
|
@ -713,7 +739,7 @@ gboolean
|
||||||
ges_timeline_layer_remove_object (GESTimelineLayer * layer,
|
ges_timeline_layer_remove_object (GESTimelineLayer * layer,
|
||||||
GESTimelineObject * object)
|
GESTimelineObject * object)
|
||||||
{
|
{
|
||||||
GESTimelineLayer *tl_obj_layer;
|
GESTimelineLayer *current_layer;
|
||||||
GList *trackobjects, *tmp;
|
GList *trackobjects, *tmp;
|
||||||
|
|
||||||
g_return_val_if_fail (GES_IS_TIMELINE_LAYER (layer), FALSE);
|
g_return_val_if_fail (GES_IS_TIMELINE_LAYER (layer), FALSE);
|
||||||
|
@ -721,16 +747,16 @@ ges_timeline_layer_remove_object (GESTimelineLayer * layer,
|
||||||
|
|
||||||
GST_DEBUG ("layer:%p, object:%p", layer, object);
|
GST_DEBUG ("layer:%p, object:%p", layer, object);
|
||||||
|
|
||||||
tl_obj_layer = ges_timeline_object_get_layer (object);
|
current_layer = ges_timeline_object_get_layer (object);
|
||||||
if (G_UNLIKELY (tl_obj_layer != layer)) {
|
if (G_UNLIKELY (current_layer != layer)) {
|
||||||
GST_WARNING ("TimelineObject doesn't belong to this layer");
|
GST_WARNING ("TimelineObject doesn't belong to this layer");
|
||||||
|
|
||||||
if (tl_obj_layer != NULL)
|
if (current_layer != NULL)
|
||||||
g_object_unref (tl_obj_layer);
|
g_object_unref (current_layer);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
g_object_unref (tl_obj_layer);
|
g_object_unref (current_layer);
|
||||||
|
|
||||||
if (layer->priv->auto_transition && GES_IS_TIMELINE_SOURCE (object)) {
|
if (layer->priv->auto_transition && GES_IS_TIMELINE_SOURCE (object)) {
|
||||||
trackobjects = ges_timeline_object_get_track_objects (object);
|
trackobjects = ges_timeline_object_get_track_objects (object);
|
||||||
|
@ -912,24 +938,60 @@ gboolean
|
||||||
ges_timeline_layer_add_object (GESTimelineLayer * layer,
|
ges_timeline_layer_add_object (GESTimelineLayer * layer,
|
||||||
GESTimelineObject * object)
|
GESTimelineObject * object)
|
||||||
{
|
{
|
||||||
GESTimelineLayer *tl_obj_layer;
|
GESAsset *asset;
|
||||||
|
GESTimelineLayer *current_layer;
|
||||||
guint32 maxprio, minprio, prio;
|
guint32 maxprio, minprio, prio;
|
||||||
|
|
||||||
GST_DEBUG ("layer:%p, object:%p", layer, object);
|
GESTimelineLayerPrivate *priv;
|
||||||
|
|
||||||
tl_obj_layer = ges_timeline_object_get_layer (object);
|
g_return_val_if_fail (GES_IS_TIMELINE_LAYER (layer), FALSE);
|
||||||
|
g_return_val_if_fail (GES_IS_TIMELINE_OBJECT (object), FALSE);
|
||||||
|
|
||||||
if (G_UNLIKELY (tl_obj_layer)) {
|
GST_DEBUG_OBJECT (layer, "adding object:%p", object);
|
||||||
|
|
||||||
|
priv = layer->priv;
|
||||||
|
current_layer = ges_timeline_object_get_layer (object);
|
||||||
|
|
||||||
|
if (G_UNLIKELY (current_layer)) {
|
||||||
GST_WARNING ("TimelineObject %p already belongs to another layer", object);
|
GST_WARNING ("TimelineObject %p already belongs to another layer", object);
|
||||||
g_object_unref (tl_obj_layer);
|
g_object_unref (current_layer);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
asset = ges_extractable_get_asset (GES_EXTRACTABLE (object));
|
||||||
|
if (asset == NULL) {
|
||||||
|
gchar *id;
|
||||||
|
NewAssetUData *mudata = g_slice_new (NewAssetUData);
|
||||||
|
|
||||||
|
mudata->object = object;
|
||||||
|
mudata->layer = layer;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (layer, "%" GST_PTR_FORMAT " as no reference to any "
|
||||||
|
"assets creating a asset... trying sync", object);
|
||||||
|
|
||||||
|
id = ges_extractable_get_id (GES_EXTRACTABLE (object));
|
||||||
|
asset = ges_asset_request (G_OBJECT_TYPE (object), id, NULL);
|
||||||
|
if (asset == NULL) {
|
||||||
|
ges_asset_request_async (G_OBJECT_TYPE (object),
|
||||||
|
id, NULL, (GAsyncReadyCallback) new_asset_cb, mudata);
|
||||||
|
g_free (id);
|
||||||
|
|
||||||
|
GST_LOG_OBJECT (layer, "Object added async");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
g_free (id);
|
||||||
|
|
||||||
|
ges_extractable_set_asset (GES_EXTRACTABLE (object), asset);
|
||||||
|
|
||||||
|
g_slice_free (NewAssetUData, mudata);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
g_object_ref_sink (object);
|
g_object_ref_sink (object);
|
||||||
|
|
||||||
/* Take a reference to the object and store it stored by start/priority */
|
/* Take a reference to the object and store it stored by start/priority */
|
||||||
layer->priv->objects_start =
|
priv->objects_start = g_list_insert_sorted (priv->objects_start, object,
|
||||||
g_list_insert_sorted (layer->priv->objects_start, object,
|
|
||||||
(GCompareFunc) objects_start_compare);
|
(GCompareFunc) objects_start_compare);
|
||||||
|
|
||||||
/* Inform the object it's now in this layer */
|
/* Inform the object it's now in this layer */
|
||||||
|
@ -943,15 +1005,17 @@ ges_timeline_layer_add_object (GESTimelineLayer * layer,
|
||||||
maxprio = layer->max_gnl_priority;
|
maxprio = layer->max_gnl_priority;
|
||||||
minprio = layer->min_gnl_priority;
|
minprio = layer->min_gnl_priority;
|
||||||
prio = GES_TIMELINE_OBJECT_PRIORITY (object);
|
prio = GES_TIMELINE_OBJECT_PRIORITY (object);
|
||||||
|
|
||||||
if (minprio + prio > (maxprio)) {
|
if (minprio + prio > (maxprio)) {
|
||||||
GST_WARNING ("%p is out of the layer %p space, setting its priority to "
|
GST_WARNING_OBJECT (layer,
|
||||||
"setting its priority %d to failthe maximum priority of the layer %d",
|
"%p is out of the layer space, setting its priority to "
|
||||||
object, layer, prio, maxprio - minprio);
|
"%d, setting it to the maximum priority of the layer: %d", object, prio,
|
||||||
|
maxprio - minprio);
|
||||||
ges_timeline_object_set_priority (object, LAYER_HEIGHT - 1);
|
ges_timeline_object_set_priority (object, LAYER_HEIGHT - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the object has an acceptable priority, we just let it with its current
|
/* If the object has an acceptable priority, we just let it with its current
|
||||||
* priority */
|
* priority */
|
||||||
|
|
||||||
ges_timeline_layer_resync_priorities (layer);
|
ges_timeline_layer_resync_priorities (layer);
|
||||||
|
|
||||||
/* emit 'object-added' */
|
/* emit 'object-added' */
|
||||||
|
@ -960,6 +1024,54 @@ ges_timeline_layer_add_object (GESTimelineLayer * layer,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ges_timeline_layer_add_asset:
|
||||||
|
* @layer: a #GESTimelineLayer
|
||||||
|
* @asset: The asset to add to
|
||||||
|
* @start: The start value to set on the new #GESTimelineObject
|
||||||
|
* @inpoint: The inpoint value to set on the new #GESTimelineObject
|
||||||
|
* @duration: The duration value to set on the new #GESTimelineObject
|
||||||
|
* @rate: The rate value to set on the new #GESTimelineObject
|
||||||
|
* @track_types: The #GESTrackType to set on the the new #GESTimelineObject
|
||||||
|
*
|
||||||
|
* Creates TimelineObject from asset, adds it to layer and
|
||||||
|
* returns a reference to it.
|
||||||
|
*
|
||||||
|
* Returns: (transfer floating): Created #GESTimelineObject
|
||||||
|
*/
|
||||||
|
GESTimelineObject *
|
||||||
|
ges_timeline_layer_add_asset (GESTimelineLayer * layer,
|
||||||
|
GESAsset * asset, GstClockTime start, GstClockTime inpoint,
|
||||||
|
GstClockTime duration, gdouble rate, GESTrackType track_types)
|
||||||
|
{
|
||||||
|
GESTimelineObject *tlobj;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GES_IS_TIMELINE_LAYER (layer), NULL);
|
||||||
|
g_return_val_if_fail (GES_IS_ASSET (asset), NULL);
|
||||||
|
g_return_val_if_fail (g_type_is_a (ges_asset_get_extractable_type
|
||||||
|
(asset), GES_TYPE_TIMELINE_OBJECT), NULL);
|
||||||
|
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (layer, "Adding asset: %s", ges_asset_get_id (asset));
|
||||||
|
tlobj = GES_TIMELINE_OBJECT (ges_asset_extract (asset, NULL));
|
||||||
|
ges_timeline_object_set_start (tlobj, start);
|
||||||
|
ges_timeline_object_set_inpoint (tlobj, inpoint);
|
||||||
|
if (track_types != GES_TRACK_TYPE_UNKNOWN)
|
||||||
|
ges_timeline_object_set_supported_formats (tlobj, track_types);
|
||||||
|
|
||||||
|
if (GST_CLOCK_TIME_IS_VALID (duration)) {
|
||||||
|
ges_timeline_object_set_duration (tlobj, duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ges_timeline_layer_add_object (layer, tlobj)) {
|
||||||
|
gst_object_unref (tlobj);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tlobj;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ges_timeline_layer_new:
|
* ges_timeline_layer_new:
|
||||||
*
|
*
|
||||||
|
|
|
@ -50,7 +50,7 @@ typedef struct _GESTimelineLayerPrivate GESTimelineLayerPrivate;
|
||||||
* @timeline: the #GESTimeline where this layer is being used.
|
* @timeline: the #GESTimeline where this layer is being used.
|
||||||
*/
|
*/
|
||||||
struct _GESTimelineLayer {
|
struct _GESTimelineLayer {
|
||||||
GInitiallyUnowned parent;
|
GInitiallyUnowned parent;
|
||||||
|
|
||||||
/*< public >*/
|
/*< public >*/
|
||||||
|
|
||||||
|
@ -102,6 +102,14 @@ ges_timeline_layer_get_timeline (GESTimelineLayer * layer);
|
||||||
gboolean ges_timeline_layer_add_object (GESTimelineLayer * layer,
|
gboolean ges_timeline_layer_add_object (GESTimelineLayer * layer,
|
||||||
|
|
||||||
GESTimelineObject * object);
|
GESTimelineObject * object);
|
||||||
|
GESTimelineObject * ges_timeline_layer_add_asset (GESTimelineLayer *layer,
|
||||||
|
GESAsset *asset,
|
||||||
|
GstClockTime start,
|
||||||
|
GstClockTime inpoint,
|
||||||
|
GstClockTime duration,
|
||||||
|
gdouble rate,
|
||||||
|
GESTrackType track_types);
|
||||||
|
|
||||||
gboolean ges_timeline_layer_remove_object (GESTimelineLayer * layer,
|
gboolean ges_timeline_layer_remove_object (GESTimelineLayer * layer,
|
||||||
GESTimelineObject * object);
|
GESTimelineObject * object);
|
||||||
|
|
||||||
|
|
|
@ -117,15 +117,6 @@ struct _GESTimelinePrivate
|
||||||
/* The duration of the timeline */
|
/* The duration of the timeline */
|
||||||
gint64 duration;
|
gint64 duration;
|
||||||
|
|
||||||
/* discoverer used for virgin sources */
|
|
||||||
GstDiscoverer *discoverer;
|
|
||||||
GList *pendingobjects;
|
|
||||||
/* lock to avoid discovery of objects that will be removed */
|
|
||||||
GMutex pendingobjects_lock;
|
|
||||||
|
|
||||||
/* Whether we are changing state asynchronously or not */
|
|
||||||
gboolean async_pending;
|
|
||||||
|
|
||||||
/* Timeline edition modes and snapping management */
|
/* Timeline edition modes and snapping management */
|
||||||
guint64 snapping_distance;
|
guint64 snapping_distance;
|
||||||
|
|
||||||
|
@ -183,13 +174,6 @@ static GstBinClass *parent_class;
|
||||||
static guint ges_timeline_signals[LAST_SIGNAL] = { 0 };
|
static guint ges_timeline_signals[LAST_SIGNAL] = { 0 };
|
||||||
|
|
||||||
static gint custom_find_track (TrackPrivate * tr_priv, GESTrack * track);
|
static gint custom_find_track (TrackPrivate * tr_priv, GESTrack * track);
|
||||||
static GstStateChangeReturn
|
|
||||||
ges_timeline_change_state (GstElement * element, GstStateChange transition);
|
|
||||||
static void
|
|
||||||
discoverer_finished_cb (GstDiscoverer * discoverer, GESTimeline * timeline);
|
|
||||||
static void
|
|
||||||
discoverer_discovered_cb (GstDiscoverer * discoverer,
|
|
||||||
GstDiscovererInfo * info, GError * err, GESTimeline * timeline);
|
|
||||||
|
|
||||||
/* Internal methods */
|
/* Internal methods */
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -257,12 +241,6 @@ ges_timeline_dispose (GObject * object)
|
||||||
{
|
{
|
||||||
GESTimelinePrivate *priv = GES_TIMELINE (object)->priv;
|
GESTimelinePrivate *priv = GES_TIMELINE (object)->priv;
|
||||||
|
|
||||||
if (priv->discoverer) {
|
|
||||||
gst_discoverer_stop (priv->discoverer);
|
|
||||||
g_object_unref (priv->discoverer);
|
|
||||||
priv->discoverer = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (priv->layers) {
|
while (priv->layers) {
|
||||||
GESTimelineLayer *layer = (GESTimelineLayer *) priv->layers->data;
|
GESTimelineLayer *layer = (GESTimelineLayer *) priv->layers->data;
|
||||||
ges_timeline_remove_layer (GES_TIMELINE (object), layer);
|
ges_timeline_remove_layer (GES_TIMELINE (object), layer);
|
||||||
|
@ -293,10 +271,6 @@ ges_timeline_dispose (GObject * object)
|
||||||
static void
|
static void
|
||||||
ges_timeline_finalize (GObject * object)
|
ges_timeline_finalize (GObject * object)
|
||||||
{
|
{
|
||||||
GESTimeline *timeline = GES_TIMELINE (object);
|
|
||||||
|
|
||||||
g_mutex_clear (&timeline->priv->pendingobjects_lock);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (ges_timeline_parent_class)->finalize (object);
|
G_OBJECT_CLASS (ges_timeline_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,14 +278,11 @@ static void
|
||||||
ges_timeline_class_init (GESTimelineClass * klass)
|
ges_timeline_class_init (GESTimelineClass * klass)
|
||||||
{
|
{
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
|
||||||
|
|
||||||
g_type_class_add_private (klass, sizeof (GESTimelinePrivate));
|
g_type_class_add_private (klass, sizeof (GESTimelinePrivate));
|
||||||
|
|
||||||
parent_class = g_type_class_peek_parent (klass);
|
parent_class = g_type_class_peek_parent (klass);
|
||||||
|
|
||||||
element_class->change_state = ges_timeline_change_state;
|
|
||||||
|
|
||||||
object_class->get_property = ges_timeline_get_property;
|
object_class->get_property = ges_timeline_get_property;
|
||||||
object_class->set_property = ges_timeline_set_property;
|
object_class->set_property = ges_timeline_set_property;
|
||||||
object_class->dispose = ges_timeline_dispose;
|
object_class->dispose = ges_timeline_dispose;
|
||||||
|
@ -489,15 +460,6 @@ ges_timeline_init (GESTimeline * self)
|
||||||
(GDestroyNotify) _destroy_obj_iters);
|
(GDestroyNotify) _destroy_obj_iters);
|
||||||
priv->starts_ends = g_sequence_new (g_free);
|
priv->starts_ends = g_sequence_new (g_free);
|
||||||
priv->tracksources = g_sequence_new (g_object_unref);
|
priv->tracksources = g_sequence_new (g_object_unref);
|
||||||
|
|
||||||
g_mutex_init (&priv->pendingobjects_lock);
|
|
||||||
/* New discoverer with a 15s timeout */
|
|
||||||
priv->discoverer = gst_discoverer_new (15 * GST_SECOND, NULL);
|
|
||||||
g_signal_connect (priv->discoverer, "finished",
|
|
||||||
G_CALLBACK (discoverer_finished_cb), self);
|
|
||||||
g_signal_connect (priv->discoverer, "discovered",
|
|
||||||
G_CALLBACK (discoverer_discovered_cb), self);
|
|
||||||
gst_discoverer_start (priv->discoverer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Private methods */
|
/* Private methods */
|
||||||
|
@ -1441,169 +1403,6 @@ add_object_to_tracks (GESTimeline * timeline, GESTimelineObject * object)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
do_async_start (GESTimeline * timeline)
|
|
||||||
{
|
|
||||||
GstMessage *message;
|
|
||||||
GList *tmp;
|
|
||||||
|
|
||||||
timeline->priv->async_pending = TRUE;
|
|
||||||
|
|
||||||
/* Freeze state of tracks */
|
|
||||||
for (tmp = timeline->priv->tracks; tmp; tmp = tmp->next) {
|
|
||||||
TrackPrivate *tr_priv = (TrackPrivate *) tmp->data;
|
|
||||||
gst_element_set_locked_state ((GstElement *) tr_priv->track, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
message = gst_message_new_async_start (GST_OBJECT_CAST (timeline));
|
|
||||||
parent_class->handle_message (GST_BIN_CAST (timeline), message);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
do_async_done (GESTimeline * timeline)
|
|
||||||
{
|
|
||||||
GstMessage *message;
|
|
||||||
|
|
||||||
if (timeline->priv->async_pending) {
|
|
||||||
GList *tmp;
|
|
||||||
/* Unfreeze state of tracks */
|
|
||||||
for (tmp = timeline->priv->tracks; tmp; tmp = tmp->next) {
|
|
||||||
TrackPrivate *tr_priv = (TrackPrivate *) tmp->data;
|
|
||||||
gst_element_set_locked_state ((GstElement *) tr_priv->track, FALSE);
|
|
||||||
gst_element_sync_state_with_parent ((GstElement *) tr_priv->track);
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (timeline, "Emitting async-done");
|
|
||||||
message = gst_message_new_async_done (GST_OBJECT_CAST (timeline), FALSE);
|
|
||||||
parent_class->handle_message (GST_BIN_CAST (timeline), message);
|
|
||||||
|
|
||||||
timeline->priv->async_pending = FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Callbacks */
|
|
||||||
static void
|
|
||||||
discoverer_finished_cb (GstDiscoverer * discoverer, GESTimeline * timeline)
|
|
||||||
{
|
|
||||||
do_async_done (timeline);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
discoverer_discovered_cb (GstDiscoverer * discoverer,
|
|
||||||
GstDiscovererInfo * info, GError * err, GESTimeline * timeline)
|
|
||||||
{
|
|
||||||
GList *tmp;
|
|
||||||
GList *stream_list;
|
|
||||||
GESTimelineObject *tlobj;
|
|
||||||
GESTrackType tfs_supportedformats;
|
|
||||||
|
|
||||||
gboolean found = FALSE;
|
|
||||||
gboolean is_image = FALSE;
|
|
||||||
GESTimelineFileSource *tfs = NULL;
|
|
||||||
GESTimelinePrivate *priv = timeline->priv;
|
|
||||||
const gchar *uri = gst_discoverer_info_get_uri (info);
|
|
||||||
|
|
||||||
GES_TIMELINE_PENDINGOBJS_LOCK (timeline);
|
|
||||||
|
|
||||||
/* Find corresponding TimelineFileSource in the sources */
|
|
||||||
for (tmp = priv->pendingobjects; tmp; tmp = tmp->next) {
|
|
||||||
tfs = (GESTimelineFileSource *) tmp->data;
|
|
||||||
|
|
||||||
if (!g_strcmp0 (ges_timeline_filesource_get_uri (tfs), uri)) {
|
|
||||||
found = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found) {
|
|
||||||
GST_WARNING ("Discovered %s, that seems not to be in the list of sources"
|
|
||||||
"to discover", uri);
|
|
||||||
GES_TIMELINE_PENDINGOBJS_UNLOCK (timeline);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err) {
|
|
||||||
GError *propagate_error = NULL;
|
|
||||||
|
|
||||||
priv->pendingobjects = g_list_delete_link (priv->pendingobjects, tmp);
|
|
||||||
GES_TIMELINE_PENDINGOBJS_UNLOCK (timeline);
|
|
||||||
GST_WARNING ("Error while discovering %s: %s", uri, err->message);
|
|
||||||
|
|
||||||
g_propagate_error (&propagate_error, err);
|
|
||||||
g_signal_emit (timeline, ges_timeline_signals[DISCOVERY_ERROR], 0, tfs,
|
|
||||||
propagate_error);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Everything went fine... let's do our job! */
|
|
||||||
GST_DEBUG ("Discovered uri %s", uri);
|
|
||||||
|
|
||||||
/* The timeline file source will be updated with discovered information
|
|
||||||
* so it needs to not be finalized during this process */
|
|
||||||
g_object_ref (tfs);
|
|
||||||
|
|
||||||
/* Remove object from list */
|
|
||||||
priv->pendingobjects = g_list_delete_link (priv->pendingobjects, tmp);
|
|
||||||
GES_TIMELINE_PENDINGOBJS_UNLOCK (timeline);
|
|
||||||
|
|
||||||
/* FIXME : Handle errors in discovery */
|
|
||||||
stream_list = gst_discoverer_info_get_stream_list (info);
|
|
||||||
|
|
||||||
tfs_supportedformats = ges_timeline_filesource_get_supported_formats (tfs);
|
|
||||||
if (tfs_supportedformats != GES_TRACK_TYPE_UNKNOWN)
|
|
||||||
goto check_image;
|
|
||||||
|
|
||||||
/* Update timelinefilesource properties based on info */
|
|
||||||
for (tmp = stream_list; tmp; tmp = tmp->next) {
|
|
||||||
GstDiscovererStreamInfo *sinf = (GstDiscovererStreamInfo *) tmp->data;
|
|
||||||
|
|
||||||
if (GST_IS_DISCOVERER_AUDIO_INFO (sinf)) {
|
|
||||||
tfs_supportedformats |= GES_TRACK_TYPE_AUDIO;
|
|
||||||
ges_timeline_filesource_set_supported_formats (tfs, tfs_supportedformats);
|
|
||||||
} else if (GST_IS_DISCOVERER_VIDEO_INFO (sinf)) {
|
|
||||||
tfs_supportedformats |= GES_TRACK_TYPE_VIDEO;
|
|
||||||
ges_timeline_filesource_set_supported_formats (tfs, tfs_supportedformats);
|
|
||||||
if (gst_discoverer_video_info_is_image ((GstDiscovererVideoInfo *)
|
|
||||||
sinf)) {
|
|
||||||
tfs_supportedformats |= GES_TRACK_TYPE_AUDIO;
|
|
||||||
ges_timeline_filesource_set_supported_formats (tfs,
|
|
||||||
tfs_supportedformats);
|
|
||||||
is_image = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stream_list)
|
|
||||||
gst_discoverer_stream_info_list_free (stream_list);
|
|
||||||
|
|
||||||
check_image:
|
|
||||||
|
|
||||||
tlobj = GES_TIMELINE_OBJECT (tfs);
|
|
||||||
if (is_image) {
|
|
||||||
/* don't set max-duration on still images */
|
|
||||||
g_object_set (tfs, "is_image", (gboolean) TRUE, NULL);
|
|
||||||
} else {
|
|
||||||
GstClockTime file_duration, tlobj_max_duration;
|
|
||||||
|
|
||||||
/* Properly set duration informations from the discovery */
|
|
||||||
file_duration = gst_discoverer_info_get_duration (info);
|
|
||||||
tlobj_max_duration = ges_timeline_object_get_max_duration (tlobj);
|
|
||||||
|
|
||||||
if (tlobj_max_duration == G_MAXUINT64)
|
|
||||||
ges_timeline_object_set_max_duration (tlobj, file_duration);
|
|
||||||
|
|
||||||
if (GST_CLOCK_TIME_IS_VALID (tlobj->duration) == FALSE)
|
|
||||||
ges_timeline_object_set_duration (tlobj, file_duration);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Continue the processing on tfs */
|
|
||||||
add_object_to_tracks (timeline, tlobj);
|
|
||||||
|
|
||||||
/* Remove the ref as the timeline file source is no longer needed here */
|
|
||||||
g_object_unref (tfs);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
layer_object_added_cb (GESTimelineLayer * layer, GESTimelineObject * object,
|
layer_object_added_cb (GESTimelineLayer * layer, GESTimelineObject * object,
|
||||||
GESTimeline * timeline)
|
GESTimeline * timeline)
|
||||||
|
@ -1616,37 +1415,8 @@ layer_object_added_cb (GESTimelineLayer * layer, GESTimelineObject * object,
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_DEBUG ("New TimelineObject %p added to layer %p", object, layer);
|
GST_DEBUG ("New TimelineObject %p added to layer %p", object, layer);
|
||||||
|
add_object_to_tracks (timeline, object);
|
||||||
if (GES_IS_TIMELINE_FILE_SOURCE (object)) {
|
GST_DEBUG ("Done");
|
||||||
GESTimelineFileSource *tfs = GES_TIMELINE_FILE_SOURCE (object);
|
|
||||||
GESTrackType tfs_supportedformats =
|
|
||||||
ges_timeline_filesource_get_supported_formats (tfs);
|
|
||||||
guint64 tfs_maxdur = ges_timeline_filesource_get_max_duration (tfs);
|
|
||||||
const gchar *tfs_uri;
|
|
||||||
|
|
||||||
/* Send the filesource to the discoverer if:
|
|
||||||
* * it doesn't have specified supported formats
|
|
||||||
* * OR it doesn't have a specified max-duration
|
|
||||||
* * OR it doesn't have a valid duration */
|
|
||||||
|
|
||||||
if (tfs_supportedformats == GES_TRACK_TYPE_UNKNOWN ||
|
|
||||||
tfs_maxdur == GST_CLOCK_TIME_NONE || object->duration == 0) {
|
|
||||||
GST_LOG ("Incomplete TimelineFileSource, discovering it");
|
|
||||||
tfs_uri = ges_timeline_filesource_get_uri (tfs);
|
|
||||||
|
|
||||||
GES_TIMELINE_PENDINGOBJS_LOCK (timeline);
|
|
||||||
timeline->priv->pendingobjects =
|
|
||||||
g_list_append (timeline->priv->pendingobjects, object);
|
|
||||||
GES_TIMELINE_PENDINGOBJS_UNLOCK (timeline);
|
|
||||||
|
|
||||||
gst_discoverer_discover_uri_async (timeline->priv->discoverer, tfs_uri);
|
|
||||||
} else
|
|
||||||
add_object_to_tracks (timeline, object);
|
|
||||||
} else {
|
|
||||||
add_object_to_tracks (timeline, object);
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_DEBUG ("done");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1693,16 +1463,6 @@ layer_object_removed_cb (GESTimelineLayer * layer, GESTimelineObject * object,
|
||||||
|
|
||||||
g_list_free (trackobjects);
|
g_list_free (trackobjects);
|
||||||
|
|
||||||
/* if the object is a timeline file source that has not yet been discovered,
|
|
||||||
* it no longer needs to be discovered so remove it from the pendingobjects
|
|
||||||
* list if it belongs to this layer */
|
|
||||||
if (GES_IS_TIMELINE_FILE_SOURCE (object)) {
|
|
||||||
GES_TIMELINE_PENDINGOBJS_LOCK (timeline);
|
|
||||||
timeline->priv->pendingobjects =
|
|
||||||
g_list_remove_all (timeline->priv->pendingobjects, object);
|
|
||||||
GES_TIMELINE_PENDINGOBJS_UNLOCK (timeline);
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_DEBUG ("Done");
|
GST_DEBUG ("Done");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1835,51 +1595,6 @@ pad_removed_cb (GESTrack * track, GstPad * pad, TrackPrivate * tr_priv)
|
||||||
tr_priv->pad = NULL;
|
tr_priv->pad = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* GstElement Virtual methods */
|
|
||||||
static GstStateChangeReturn
|
|
||||||
ges_timeline_change_state (GstElement * element, GstStateChange transition)
|
|
||||||
{
|
|
||||||
GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
|
|
||||||
GESTimeline *timeline = GES_TIMELINE (element);
|
|
||||||
|
|
||||||
switch (transition) {
|
|
||||||
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
|
||||||
GES_TIMELINE_PENDINGOBJS_LOCK (timeline);
|
|
||||||
if (timeline->priv->pendingobjects) {
|
|
||||||
GES_TIMELINE_PENDINGOBJS_UNLOCK (timeline);
|
|
||||||
do_async_start (timeline);
|
|
||||||
ret = GST_STATE_CHANGE_ASYNC;
|
|
||||||
} else {
|
|
||||||
GES_TIMELINE_PENDINGOBJS_UNLOCK (timeline);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
GstStateChangeReturn bret;
|
|
||||||
|
|
||||||
bret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
|
|
||||||
if (G_UNLIKELY (bret == GST_STATE_CHANGE_NO_PREROLL)) {
|
|
||||||
do_async_done (timeline);
|
|
||||||
ret = bret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (transition) {
|
|
||||||
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
|
||||||
do_async_done (timeline);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**** API *****/
|
/**** API *****/
|
||||||
/**
|
/**
|
||||||
* ges_timeline_new:
|
* ges_timeline_new:
|
||||||
|
@ -2247,7 +1962,6 @@ ges_timeline_remove_track (GESTimeline * timeline, GESTrack * track)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set track state to NULL */
|
/* set track state to NULL */
|
||||||
|
|
||||||
gst_element_set_state (GST_ELEMENT (track), GST_STATE_NULL);
|
gst_element_set_state (GST_ELEMENT (track), GST_STATE_NULL);
|
||||||
|
|
||||||
gst_object_unref (track);
|
gst_object_unref (track);
|
||||||
|
|
Loading…
Reference in a new issue