mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 19:51:11 +00:00
uri-clip: match children by track
When the asset of a uri clip is reset, its core children are removed and replaced by the new core children. When replacing, the `set_asset` method attempts to copy children properties from the previous children to the new children. However, the children were matched by track-type only. This would not function as intended when a URI contains multiple audio or video streams. Instead, we now match children by the tracks themselves. This should work better, provided the user's select-tracks-for-object is well behaved. Also, fix a memory problem in `set_mute` for when a child is not in a track.
This commit is contained in:
parent
ba31a8d6a0
commit
46e6a074bb
1 changed files with 32 additions and 25 deletions
|
@ -233,7 +233,7 @@ extractable_set_asset (GESExtractable * self, GESAsset * asset)
|
|||
GESClip *clip = GES_CLIP (self);
|
||||
GESLayer *layer = ges_clip_get_layer (clip);
|
||||
GList *tmp, *children;
|
||||
GESTimelineElement *audio_source = NULL, *video_source = NULL;
|
||||
GHashTable *source_by_track;
|
||||
|
||||
g_return_val_if_fail (GES_IS_URI_CLIP_ASSET (asset), FALSE);
|
||||
|
||||
|
@ -270,19 +270,24 @@ extractable_set_asset (GESExtractable * self, GESAsset * asset)
|
|||
|
||||
GES_TIMELINE_ELEMENT (uriclip)->asset = asset;
|
||||
|
||||
source_by_track = g_hash_table_new_full (NULL, NULL,
|
||||
gst_object_unref, gst_object_unref);
|
||||
children = ges_container_get_children (GES_CONTAINER (self), TRUE);
|
||||
|
||||
for (tmp = children; tmp; tmp = tmp->next) {
|
||||
if (GES_IS_SOURCE (tmp->data)) {
|
||||
GESTrack *track = ges_track_element_get_track (tmp->data);
|
||||
GESTrackElement *child = tmp->data;
|
||||
GESTrack *track = ges_track_element_get_track (child);
|
||||
/* remove our core children */
|
||||
if (GES_TRACK_ELEMENT_IS_CORE (child)) {
|
||||
if (track)
|
||||
g_hash_table_insert (source_by_track, gst_object_ref (track),
|
||||
gst_object_ref (child));
|
||||
|
||||
if (track->type == GES_TRACK_TYPE_AUDIO)
|
||||
audio_source = gst_object_ref (tmp->data);
|
||||
else if (track->type == GES_TRACK_TYPE_VIDEO)
|
||||
video_source = gst_object_ref (tmp->data);
|
||||
|
||||
ges_track_remove_element (track, tmp->data);
|
||||
ges_container_remove (GES_CONTAINER (self), tmp->data);
|
||||
/* removing the track element from its clip whilst it is in a
|
||||
* timeline will remove it from its track */
|
||||
/* removing the core element will also empty its non-core siblings
|
||||
* from the same track */
|
||||
ges_container_remove (GES_CONTAINER (self), GES_TIMELINE_ELEMENT (child));
|
||||
}
|
||||
}
|
||||
g_list_free_full (children, g_object_unref);
|
||||
|
@ -293,29 +298,31 @@ extractable_set_asset (GESExtractable * self, GESAsset * asset)
|
|||
gst_object_ref (clip);
|
||||
|
||||
ges_layer_remove_clip (layer, clip);
|
||||
/* adding back to the layer will trigger the re-creation of the core
|
||||
* children */
|
||||
res = ges_layer_add_clip (layer, clip);
|
||||
|
||||
for (tmp = GES_CONTAINER_CHILDREN (self); tmp; tmp = tmp->next) {
|
||||
if (GES_IS_SOURCE (tmp->data)) {
|
||||
GESTrack *track = ges_track_element_get_track (tmp->data);
|
||||
/* NOTE: assume that core children in the same tracks correspond to
|
||||
* the same source! */
|
||||
for (tmp = GES_CONTAINER_CHILDREN (clip); tmp; tmp = tmp->next) {
|
||||
GESTrackElement *child = tmp->data;
|
||||
if (GES_TRACK_ELEMENT_IS_CORE (child)) {
|
||||
GESTrackElement *orig_source = g_hash_table_lookup (source_by_track,
|
||||
ges_track_element_get_track (child));
|
||||
contains_core = TRUE;
|
||||
|
||||
if (track->type == GES_TRACK_TYPE_AUDIO && audio_source) {
|
||||
ges_track_element_copy_properties (audio_source, tmp->data);
|
||||
ges_track_element_copy_bindings (GES_TRACK_ELEMENT (audio_source),
|
||||
tmp->data, GST_CLOCK_TIME_NONE);
|
||||
} else if (track->type == GES_TRACK_TYPE_VIDEO && video_source) {
|
||||
ges_track_element_copy_properties (video_source, tmp->data);
|
||||
ges_track_element_copy_bindings (GES_TRACK_ELEMENT (video_source),
|
||||
tmp->data, GST_CLOCK_TIME_NONE);
|
||||
if (orig_source) {
|
||||
ges_track_element_copy_properties (GES_TIMELINE_ELEMENT (orig_source),
|
||||
GES_TIMELINE_ELEMENT (child));
|
||||
ges_track_element_copy_bindings (orig_source, child,
|
||||
GST_CLOCK_TIME_NONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
gst_object_unref (clip);
|
||||
gst_object_unref (layer);
|
||||
}
|
||||
g_clear_object (&audio_source);
|
||||
g_clear_object (&video_source);
|
||||
g_hash_table_unref (source_by_track);
|
||||
|
||||
if (res) {
|
||||
g_free (uriclip->priv->uri);
|
||||
|
@ -370,9 +377,9 @@ ges_uri_clip_set_mute (GESUriClip * self, gboolean mute)
|
|||
/* Go over tracked objects, and update 'active' status on all audio objects */
|
||||
for (tmp = GES_CONTAINER_CHILDREN (self); tmp; tmp = g_list_next (tmp)) {
|
||||
GESTrackElement *trackelement = (GESTrackElement *) tmp->data;
|
||||
GESTrack *track = ges_track_element_get_track (trackelement);
|
||||
|
||||
if (ges_track_element_get_track (trackelement)->type ==
|
||||
GES_TRACK_TYPE_AUDIO)
|
||||
if (track && track->type == GES_TRACK_TYPE_AUDIO)
|
||||
ges_track_element_set_active (trackelement, !mute);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue