diff --git a/ges/ges-layer.c b/ges/ges-layer.c index 31de793227..71eccde0e0 100644 --- a/ges/ges-layer.c +++ b/ges/ges-layer.c @@ -23,12 +23,26 @@ /** * SECTION:geslayer * @title: GESLayer - * @short_description: Non-overlapping sequence of GESClip + * @short_description: Non-overlapping sequence of #GESClip * - * Responsible for the ordering of the various contained Clip(s). A - * timeline layer has a "priority" property, which is used to manage the - * priorities of individual Clips. Two layers should not have the - * same priority within a given timeline. + * #GESLayer-s are responsible for collecting and ordering #GESClip-s. + * + * A layer within a timeline will have an associated priority, + * corresponding to their index within the timeline. A layer with the + * index/priority 0 will have the highest priority and the layer with the + * largest index will have the lowest priority (the order of priorities, + * in this sense, is the _reverse_ of the numerical ordering of the + * indices). ges_timeline_move_layer() should be used if you wish to + * change how layers are prioritised in a timeline. + * + * Layers with higher priorities will have their content priorities + * over content from lower priority layers, similar to how layers are + * used in image editing. For example, if two separate layers both + * display video content, then the layer with the higher priority will + * have its images shown first. The other layer will only have its image + * shown if the higher priority layer has no content at the given + * playtime, or is transparent in some way. Audio content in separate + * layers will simply play in addition. */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -162,11 +176,11 @@ ges_layer_class_init (GESLayerClass * klass) * GESLayer:priority: * * The priority of the layer in the #GESTimeline. 0 is the highest - * priority. Conceptually, a #GESTimeline is a stack of GESLayers, + * priority. Conceptually, a timeline is a stack of layers, * and the priority of the layer represents its position in the stack. Two * layers should not have the same priority within a given GESTimeline. * - * Note that the timeline needs to be commited (with #ges_timeline_commit) + * Note that the timeline needs to be committed (with #ges_timeline_commit) * for the change to be taken into account. * * Deprecated:1.16.0: use #ges_timeline_move_layer instead. This deprecation means @@ -180,7 +194,29 @@ ges_layer_class_init (GESLayerClass * klass) /** * GESLayer:auto-transition: * - * Sets whether transitions are added automagically when clips overlap. + * Whether to automatically create a #GESTransitionClip whenever two + * #GESClip-s overlap in the layer. Specifically, if this is set to + * %TRUE, then wherever two #GESSource-s (that belong to some clip in + * the layer) share the same #GESTrackElement:track and the end time of + * one source exceeds the #GESTimelineElement:start time of the other, + * there will exist a corresponding #GESTransitionClip in the same + * layer. These automatic transitions will be created and removed + * accordingly. Their temporal extent will cover the overlap of the + * two sources (their #GESTimelineElement:start will be set to the + * #GESTimelineElement:start of the later source, and their + * #GESTimelineElement:duration will be the difference between the + * #GESTimelineElement:start of the later source, and the end time of + * the earlier source). + * + * It may be difficult to use this feature if your timeline has multiple + * tracks of the same #GESTrack:track-type and you use the + * #GESTimeline::select-tracks-for-object signal. You will have to + * ensure that any #GESTransition that belongs to a newly created + * transition clip is able to arrive in the correct track. + * + * When a layer is added to a #GESTimeline, if this property is left as + * %FALSE, but the timeline's #GESTimeline:auto-transition is %TRUE, it + * will be set to %TRUE as well. */ g_object_class_install_property (object_class, PROP_AUTO_TRANSITION, g_param_spec_boolean ("auto-transition", "Auto-Transition", @@ -188,10 +224,10 @@ ges_layer_class_init (GESLayerClass * klass) /** * GESLayer::clip-added: - * @layer: the #GESLayer - * @clip: the #GESClip that was added. + * @layer: The #GESLayer + * @clip: The clip that was added * - * Will be emitted after the clip was added to the layer. + * Will be emitted after the clip is added to the layer. */ ges_layer_signals[OBJECT_ADDED] = g_signal_new ("clip-added", G_TYPE_FROM_CLASS (klass), @@ -200,10 +236,10 @@ ges_layer_class_init (GESLayerClass * klass) /** * GESLayer::clip-removed: - * @layer: the #GESLayer - * @clip: the #GESClip that was removed + * @layer: The #GESLayer + * @clip: The clip that was removed * - * Will be emitted after the clip was removed from the layer. + * Will be emitted after the clip is removed from the layer. */ ges_layer_signals[OBJECT_REMOVED] = g_signal_new ("clip-removed", G_TYPE_FROM_CLASS (klass), @@ -267,7 +303,7 @@ ges_layer_resync_priorities_by_type (GESLayer * layer, /** * ges_layer_resync_priorities: - * @layer: a #GESLayer + * @layer: The #GESLayer * * Resyncs the priorities of the clips controlled by @layer. */ @@ -356,12 +392,13 @@ new_asset_cb (GESAsset * source, GAsyncResult * res, NewAssetUData * udata) /** * ges_layer_get_duration: - * @layer: The #GESLayer to get the duration from + * @layer: The layer to get the duration from * - * Lets you retrieve the duration of the layer, which means - * the end time of the last clip inside it + * Retrieves the duration of the layer, which is the difference + * between the start of the layer (always time 0) and the end (which will + * be the end time of the final clip). * - * Returns: The duration of a layer + * Returns: The duration of @layer. */ GstClockTime ges_layer_get_duration (GESLayer * layer) @@ -420,16 +457,13 @@ ges_layer_remove_clip_internal (GESLayer * layer, GESClip * clip, /* Public methods */ /** * ges_layer_remove_clip: - * @layer: a #GESLayer - * @clip: the #GESClip to remove + * @layer: The #GESLayer + * @clip: The clip to remove * - * Removes the given @clip from the @layer and unparents it. - * Unparenting it means the reference owned by @layer on the @clip will be - * removed. If you wish to use the @clip after this function, make sure you - * call gst_object_ref() before removing it from the @layer. + * Removes the given clip from the layer. * - * Returns: %TRUE if the clip could be removed, %FALSE if the layer does - * not want to remove the clip. + * Returns: %TRUE if @clip was removed from @layer, or %FALSE if the + * operation failed. */ gboolean ges_layer_remove_clip (GESLayer * layer, GESClip * clip) @@ -442,11 +476,10 @@ ges_layer_remove_clip (GESLayer * layer, GESClip * clip) /** * ges_layer_set_priority: - * @layer: a #GESLayer - * @priority: the priority to set + * @layer: The #GESLayer + * @priority: The priority to set * - * Sets the layer to the given @priority. See the documentation of the - * priority property for more information. + * Sets the layer to the given priority. See #GESLayer:priority. * * Deprecated:1.16.0: use #ges_timeline_move_layer instead. This deprecation means * that you will not need to handle layer priorities at all yourself, GES @@ -464,12 +497,11 @@ ges_layer_set_priority (GESLayer * layer, guint priority) /** * ges_layer_get_auto_transition: - * @layer: a #GESLayer + * @layer: The #GESLayer * - * Gets whether transitions are automatically added when objects - * overlap or not. + * Gets the #GESLayer:auto-transition of the layer. * - * Returns: %TRUE if transitions are automatically added, else %FALSE. + * Returns: %TRUE if transitions are automatically added to @layer. */ gboolean ges_layer_get_auto_transition (GESLayer * layer) @@ -481,11 +513,16 @@ ges_layer_get_auto_transition (GESLayer * layer) /** * ges_layer_set_auto_transition: - * @layer: a #GESLayer - * @auto_transition: whether the auto_transition is active + * @layer: The #GESLayer + * @auto_transition: Whether transitions should be automatically added to + * the layer * - * Sets the layer to the given @auto_transition. See the documentation of the - * property auto_transition for more information. + * Sets #GESLayer:auto-transition for the layer. Use + * ges_timeline_set_auto_transition() if you want all layers within a + * #GESTimeline to have #GESLayer:auto-transition set to %TRUE. Use this + * method if you want different values for different layers (and make sure + * to keep #GESTimeline:auto-transition as %FALSE for the corresponding + * timeline). */ void ges_layer_set_auto_transition (GESLayer * layer, gboolean auto_transition) @@ -502,11 +539,12 @@ ges_layer_set_auto_transition (GESLayer * layer, gboolean auto_transition) /** * ges_layer_get_priority: - * @layer: a #GESLayer + * @layer: The #GESLayer * - * Get the priority of @layer within the timeline. + * Get the priority of the layer. When inside a timeline, this is its + * index in the timeline. See ges_timeline_move_layer(). * - * Returns: The priority of the @layer within the timeline. + * Returns: The priority of @layer within its timeline. */ guint ges_layer_get_priority (GESLayer * layer) @@ -518,13 +556,12 @@ ges_layer_get_priority (GESLayer * layer) /** * ges_layer_get_clips: - * @layer: a #GESLayer + * @layer: The #GESLayer * - * Get the clips this layer contains. + * Get the #GESClip-s contained in this layer. * - * Returns: (transfer full) (element-type GESClip): a #GList of - * clips. The user is responsible for - * unreffing the contained objects and freeing the list. + * Returns: (transfer full) (element-type GESClip): A list of clips in + * @layer. */ GList * @@ -549,11 +586,11 @@ ges_layer_get_clips (GESLayer * layer) * ges_layer_is_empty: * @layer: The #GESLayer to check * - * Convenience method to check if @layer is empty (doesn't contain any clip), - * or not. + * Convenience method to check if the layer is empty (doesn't contain + * any #GESClip), or not. * - * Returns: %TRUE if @layer is empty, %FALSE if it already contains at least - * one #GESClip + * Returns: %TRUE if @layer is empty, %FALSE if it contains at least + * one clip. */ gboolean ges_layer_is_empty (GESLayer * layer) @@ -565,21 +602,18 @@ ges_layer_is_empty (GESLayer * layer) /** * ges_layer_add_clip: - * @layer: a #GESLayer - * @clip: (transfer floating): the #GESClip to add. + * @layer: The #GESLayer + * @clip: (transfer floating): The clip to add * - * Adds the given clip to the layer. Sets the clip's parent, and thus - * takes ownership of the clip. + * Adds the given clip to the layer. If the method succeeds, the layer + * will take ownership of the clip. * - * An clip can only be added to one layer. + * This method will fail and return %FALSE if @clip already resides in + * some layer. It can also fail if the additional clip breaks some + * compositional rules (see #GESTimelineElement). * - * Calling this method will construct and properly set all the media related - * elements on @clip. If you need to know when those objects (actually #GESTrackElement) - * are constructed, you should connect to the container::child-added signal which - * is emited right after those elements are ready to be used. - * - * Returns: %TRUE if the clip was properly added to the layer, or %FALSE - * if the @layer refuses to add the clip. + * Returns: %TRUE if @clip was properly added to @layer, or %FALSE + * if @layer refused to add @clip. */ gboolean ges_layer_add_clip (GESLayer * layer, GESClip * clip) @@ -597,6 +631,8 @@ ges_layer_add_clip (GESLayer * layer, GESClip * clip) current_layer = ges_clip_get_layer (clip); if (G_UNLIKELY (current_layer)) { GST_WARNING ("Clip %p already belongs to another layer", clip); + /* FIXME: why are we reffing the clip if it belongs to another + * layer? */ gst_object_ref_sink (clip); gst_object_unref (current_layer); @@ -666,6 +702,15 @@ ges_layer_add_clip (GESLayer * layer, GESClip * clip) layer->timeline); /* emit 'clip-added' */ + /* FIXME: we are emitting the 'clip-added' signal even though we still + * might fail. This is because the timeline uses this signal to create + * the auto-transitions etc needed for timeline_tree_can_move_element + * below, which checks whether the added clip is in a legal position. + * However, we should have a way to check that adding a clip will be + * legal **before** we actually add it! + * A user connecting to 'clip-added' in such a case would receive a + * signal saying that the clip was added, but a return value that says + * something else! */ g_signal_emit (layer, ges_layer_signals[OBJECT_ADDED], 0, clip); if (!ELEMENT_FLAG_IS_SET (clip, GES_CLIP_IS_MOVING) && layer->timeline @@ -684,18 +729,22 @@ ges_layer_add_clip (GESLayer * layer, GESClip * clip) /** * ges_layer_add_asset: - * @layer: a #GESLayer - * @asset: The asset to add to - * @start: The start value to set on the new #GESClip, - * if @start == GST_CLOCK_TIME_NONE, it will be set to - * the current duration of @layer - * @inpoint: The inpoint value to set on the new #GESClip - * @duration: The duration value to set on the new #GESClip - * @track_types: The #GESTrackType to set on the the new #GESClip + * @layer: The #GESLayer + * @asset: The asset to extract the new clip from + * @start: The #GESTimelineElement:start value to set on the new clip + * If `start == #GST_CLOCK_TIME_NONE`, it will be added to the end + * of @layer, i.e. it will be set to @layer's duration + * @inpoint: The #GESTimelineElement:in-point value to set on the new + * clip + * @duration: The #GESTimelineElement:duration value to set on the new + * clip + * @track_types: The #GESClip:supported-formats to set on the the new + * clip, or #GES_TRACK_TYPE_UNKNOWN to use the default * - * Creates Clip from asset, adds it to layer and returns its pointer. + * Extracts a new clip from an asset and adds it to the layer with + * the given properties. * - * Returns: (transfer none): Created #GESClip + * Returns: (transfer none): The newly created clip. */ GESClip * ges_layer_add_asset (GESLayer * layer, @@ -744,9 +793,9 @@ ges_layer_add_asset (GESLayer * layer, /** * ges_layer_new: * - * Creates a new #GESLayer. + * Creates a new layer. * - * Returns: (transfer floating): A new #GESLayer + * Returns: (transfer floating): A new layer. */ GESLayer * ges_layer_new (void) @@ -756,12 +805,13 @@ ges_layer_new (void) /** * ges_layer_get_timeline: - * @layer: The #GESLayer to get the parent #GESTimeline from + * @layer: The #GESLayer * - * Get the #GESTimeline in which #GESLayer currently is. + * Gets the timeline that the layer is a part of. * - * Returns: (transfer none) (nullable): the #GESTimeline in which #GESLayer - * currently is or %NULL if not in any timeline yet. + * Returns: (transfer none) (nullable): The timeline that @layer + * is currently part of, or %NULL if it is not associated with any + * timeline. */ GESTimeline * ges_layer_get_timeline (GESLayer * layer) @@ -789,13 +839,14 @@ ges_layer_set_timeline (GESLayer * layer, GESTimeline * timeline) /** * ges_layer_get_clips_in_interval: - * @layer: a #GESLayer - * @start: start of the interval - * @end: end of the interval + * @layer: The #GESLayer + * @start: Start of the interval + * @end: End of the interval * - * Gets the clips which appear between @start and @end on @layer. + * Gets the clips within the layer that appear between @start and @end. * - * Returns: (transfer full) (element-type GESClip): a #GList of clips intersecting [@start, @end) interval on @layer. + * Returns: (transfer full) (element-type GESClip): A list of #GESClip-s + * that intersect the interval `[start, end)` in @layer. */ GList * ges_layer_get_clips_in_interval (GESLayer * layer, GstClockTime start, diff --git a/ges/ges-layer.h b/ges/ges-layer.h index fd97c7dac4..48109ba2ca 100644 --- a/ges/ges-layer.h +++ b/ges/ges-layer.h @@ -70,7 +70,7 @@ struct _GESLayer { * @get_objects: method to get the objects contained in the layer * * Subclasses can override the @get_objects if they can provide a more - * efficient way of providing the list of contained #GESClip(s). + * efficient way of providing the list of contained #GESClip-s. */ struct _GESLayerClass { /*< private >*/ diff --git a/ges/ges-timeline.c b/ges/ges-timeline.c index 797de8c7ae..569f640ce3 100644 --- a/ges/ges-timeline.c +++ b/ges/ges-timeline.c @@ -30,17 +30,51 @@ * * #GESTimeline is the central object for any multimedia timeline. * - * Contains a list of #GESLayer which users should use to arrange the - * various clips through time. + * A timeline is composed of a set of #GESTrack-s and a set of + * #GESLayer-s, which are added to the timeline using + * ges_timeline_add_track() and ges_timeline_append_layer(), respectively. * - * The output types are determined by the #GESTrack that are set on - * the #GESTimeline. + * The contained tracks define the supported types of the timeline + * and provide the media output. Essentially, each track provides an + * additional source #GstPad. * - * To save/load a timeline, you can use the ges_timeline_load_from_uri() and - * ges_timeline_save_to_uri() methods to use the default format. If you wish + * Most usage of a timeline will likely only need a single #GESAudioTrack + * and/or a single #GESVideoTrack. You can create such a timeline with + * ges_timeline_new_audio_video(). After this, you are unlikely to need to + * work with the tracks directly. * - * Note that any change you make in the timeline will not actually be taken - * into account until you call the #ges_timeline_commit method. + * A timeline's layers contain #GESClip-s, which in turn control the + * creation of #GESTrackElement-s, which are added to the timeline's + * tracks. See #GESTimeline::select-tracks-for-object if you wish to have + * more control over which track a clip's elements are added to. + * + * The layers are ordered, with higher priority layers having their + * content prioritised in the tracks. This ordering can be changed using + * ges_timeline_move_layer(). + * + * ## Saving + * + * To save/load a timeline, you can use the ges_timeline_load_from_uri() + * and ges_timeline_save_to_uri() methods that use the default format. + * + * ## Editing + * + * If you change the timing or ordering of a timeline's + * #GESTimelineElement-s, then these changes will not actually be taken + * into account in the timeline until the ges_timeline_commit() method is + * called. This allows you to move its elements around, say, in + * response to an end user's mouse dragging, with little expense before + * finalising their effect. + * + * ## Playing + * + * A timeline is a #GstBin with a source #GstPad for each of its + * tracks, which you can fetch with ges_timeline_get_pad_for_track(). You + * will likely want to link these to some compatible sink #GstElement-s to + * be able to play or capture the content of the timeline. + * + * You can use a #GESPipeline to easily preview/play the timeline's + * content, or render it to a file. */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -492,7 +526,9 @@ ges_timeline_class_init (GESTimelineClass * klass) /** * GESTimeline:duration: * - * Current duration (in nanoseconds) of the #GESTimeline + * The current duration (in nanoseconds) of the timeline. A timeline + * 'starts' at time 0, so this is the maximum end time of all of its + * #GESTimelineElement-s. */ properties[PROP_DURATION] = g_param_spec_uint64 ("duration", "Duration", @@ -504,7 +540,8 @@ ges_timeline_class_init (GESTimelineClass * klass) /** * GESTimeline:auto-transition: * - * Sets whether transitions are added automagically when clips overlap. + * Whether to automatically create a transition whenever two clips + * overlap in the timeline. See #GESLayer:auto-transition. */ g_object_class_install_property (object_class, PROP_AUTO_TRANSITION, g_param_spec_boolean ("auto-transition", "Auto-Transition", @@ -513,22 +550,29 @@ ges_timeline_class_init (GESTimelineClass * klass) /** * GESTimeline:snapping-distance: * - * Distance (in nanoseconds) from which a moving object will snap - * with it neighboors. 0 means no snapping. + * The distance (in nanoseconds) at which a #GESTimelineElement being + * moved within the timeline should snap to its neighbours. Note that + * such a neighbour includes any element in the timeline, including + * across separate layers. 0 means no snapping. */ properties[PROP_SNAPPING_DISTANCE] = g_param_spec_uint64 ("snapping-distance", "Snapping distance", - "Distance from which moving an object will snap with neighboors", 0, + "Distance from which moving an object will snap with neighbours", 0, G_MAXUINT64, 0, G_PARAM_READWRITE); g_object_class_install_property (object_class, PROP_SNAPPING_DISTANCE, properties[PROP_SNAPPING_DISTANCE]); /** * GESTimeline::track-added: - * @timeline: the #GESTimeline - * @track: the #GESTrack that was added to the timeline + * @timeline: The #GESTimeline + * @track: The track that was added to @timeline * - * Will be emitted after the track was added to the timeline. + * Will be emitted after the track is added to the timeline. + * + * Note that this should not be emitted whilst a timeline is being + * loaded from its #GESProject asset. You should connect to the + * project's #GESProject::loaded signal if you want to know which + * tracks were created for the timeline. */ ges_timeline_signals[TRACK_ADDED] = g_signal_new ("track-added", G_TYPE_FROM_CLASS (klass), @@ -537,10 +581,10 @@ ges_timeline_class_init (GESTimelineClass * klass) /** * GESTimeline::track-removed: - * @timeline: the #GESTimeline - * @track: the #GESTrack that was removed from the timeline + * @timeline: The #GESTimeline + * @track: The track that was removed from @timeline * - * Will be emitted after the track was removed from the timeline. + * Will be emitted after the track is removed from the timeline. */ ges_timeline_signals[TRACK_REMOVED] = g_signal_new ("track-removed", G_TYPE_FROM_CLASS (klass), @@ -549,10 +593,15 @@ ges_timeline_class_init (GESTimelineClass * klass) /** * GESTimeline::layer-added: - * @timeline: the #GESTimeline - * @layer: the #GESLayer that was added to the timeline + * @timeline: The #GESTimeline + * @layer: The layer that was added to @timeline * - * Will be emitted after a new layer is added to the timeline. + * Will be emitted after the layer is added to the timeline. + * + * Note that this should not be emitted whilst a timeline is being + * loaded from its #GESProject asset. You should connect to the + * project's #GESProject::loaded signal if you want to know which + * layers were created for the timeline. */ ges_timeline_signals[LAYER_ADDED] = g_signal_new ("layer-added", G_TYPE_FROM_CLASS (klass), @@ -561,10 +610,10 @@ ges_timeline_class_init (GESTimelineClass * klass) /** * GESTimeline::layer-removed: - * @timeline: the #GESTimeline - * @layer: the #GESLayer that was removed from the timeline + * @timeline: The #GESTimeline + * @layer: The layer that was removed from @timeline * - * Will be emitted after the layer was removed from the timeline. + * Will be emitted after the layer is removed from the timeline. */ ges_timeline_signals[LAYER_REMOVED] = g_signal_new ("layer-removed", G_TYPE_FROM_CLASS (klass), @@ -573,10 +622,17 @@ ges_timeline_class_init (GESTimelineClass * klass) /** * GESTimeline::group-added - * @timeline: the #GESTimeline - * @group: the #GESGroup + * @timeline: The #GESTimeline + * @group: The group that was added to @timeline * - * Will be emitted after a new group is added to to the timeline. + * Will be emitted after the group is added to to the timeline. This can + * happen when grouping with `ges_container_group`, or by adding + * containers to a newly created group. + * + * Note that this should not be emitted whilst a timeline is being + * loaded from its #GESProject asset. You should connect to the + * project's #GESProject::loaded signal if you want to know which groups + * were created for the timeline. */ ges_timeline_signals[GROUP_ADDED] = g_signal_new ("group-added", G_TYPE_FROM_CLASS (klass), @@ -585,11 +641,17 @@ ges_timeline_class_init (GESTimelineClass * klass) /** * GESTimeline::group-removed - * @timeline: the #GESTimeline - * @group: the #GESGroup - * @children: (element-type GES.Container) (transfer container): a list of #GESContainer + * @timeline: The #GESTimeline + * @group: The group that was removed from @timeline + * @children: (element-type GESContainer) (transfer none): A list + * of #GESContainer-s that _were_ the children of the removed @group * - * Will be emitted after a group has been removed from the timeline. + * Will be emitted after the group is removed from the timeline through + * `ges_container_ungroup`. Note that @group will no longer contain its + * former children, these are held in @children. + * + * Note that if a group is emptied, then it will no longer belong to the + * timeline, but this signal will **not** be emitted in such a case. */ ges_timeline_signals[GROUP_REMOVED] = g_signal_new ("group-removed", G_TYPE_FROM_CLASS (klass), @@ -598,12 +660,15 @@ ges_timeline_class_init (GESTimelineClass * klass) /** * GESTimeline::snapping-started: - * @timeline: the #GESTimeline - * @obj1: the first #GESTrackElement that was snapping. - * @obj2: the second #GESTrackElement that was snapping. - * @position: the position where the two objects finally snapping. + * @timeline: The #GESTimeline + * @obj1: The first element that is snapping + * @obj2: The second element that is snapping + * @position: The position where the two objects will snap to * - * Will be emitted when the 2 #GESTrackElement first snapped + * Will be emitted whenever an element's movement invokes a snapping + * event (usually by its controlling #GESClip being moved) because its + * start or end point lies within the #GESTimeline:snapping-distance of + * another element's start or end point. */ ges_timeline_signals[SNAPING_STARTED] = g_signal_new ("snapping-started", G_TYPE_FROM_CLASS (klass), @@ -613,12 +678,17 @@ ges_timeline_class_init (GESTimelineClass * klass) /** * GESTimeline::snapping-ended: - * @timeline: the #GESTimeline - * @obj1: the first #GESTrackElement that was snapping. - * @obj2: the second #GESTrackElement that was snapping. - * @position: the position where the two objects finally snapping. + * @timeline: The #GESTimeline + * @obj1: The first element that was snapping + * @obj2: The second element that was snapping + * @position: The position where the two objects were to be snapped to * - * Will be emitted when the 2 #GESTrackElement ended to snap + * Will be emitted whenever a snapping event ends. After a snap event + * has started (see #GESTimeline::snapping-started), it can end because + * the element whose movement created the snap event has since moved + * outside of the #GESTimeline:snapping-distance before its position was + * committed. It can also end because the element's movement was ended + * by a timeline being committed. */ ges_timeline_signals[SNAPING_ENDED] = g_signal_new ("snapping-ended", G_TYPE_FROM_CLASS (klass), @@ -628,11 +698,29 @@ ges_timeline_class_init (GESTimelineClass * klass) /** * GESTimeline::select-tracks-for-object: - * @timeline: the #GESTimeline - * @clip: The #GESClip on which @track_element will land - * @track_element: The #GESTrackElement for which to choose the tracks it should land into + * @timeline: The #GESTimeline + * @clip: The clip that @track_element is being added to + * @track_element: The element being added * - * Returns: (transfer full) (element-type GESTrack): a #GPtrArray of #GESTrack-s where that object should be added + * This will be emitted whenever a new track element is added to a + * clip within the timeline. + * + * Connect to this signal once if you wish to control which element + * should be added to which track. Doing so will overwrite the default + * behaviour, which adds @track_element to all tracks whose + * #GESTrack:track-type includes the @track_element's + * #GESTrackElement:track-type. + * + * If you wish to use this, you should add all necessary tracks to the + * timeline before adding any clips. In particular, this signal is + * **not** re-emitted for the existing clips when a new track is added + * to the timeline. + * + * Returns: (transfer full) (element-type GESTrack): An array of + * #GESTrack-s that @track_element should be added to. If this contains + * more than one track, a copy of @track_element will be added to the + * other tracks. If this is empty, @track_element will also be removed + * from @clip. */ ges_timeline_signals[SELECT_TRACKS_FOR_OBJECT] = g_signal_new ("select-tracks-for-object", G_TYPE_FROM_CLASS (klass), @@ -641,11 +729,12 @@ ges_timeline_class_init (GESTimelineClass * klass) /** * GESTimeline::commited: - * @timeline: the #GESTimeline + * @timeline: The #GESTimeline * - * This signal will be emitted once the changes initiated by #ges_timeline_commit - * have been executed in the backend. Use #ges_timeline_commit_sync if you - * don't need to do anything in the meantime. + * This signal will be emitted once the changes initiated by + * ges_timeline_commit() have been executed in the backend. Use + * ges_timeline_commit_sync() if you do not want to have to connect + * to this signal. */ ges_timeline_signals[COMMITED] = g_signal_new ("commited", G_TYPE_FROM_CLASS (klass), @@ -1121,7 +1210,7 @@ timeline_update_transition (GESTimeline * timeline) /** * timeline_emit_group_added: - * @timeline: a #GESTimeline + * @timeline: The #GESTimeline * @group: group that was added * * Emit group-added signal. @@ -1134,7 +1223,7 @@ timeline_emit_group_added (GESTimeline * timeline, GESGroup * group) /** * timeline_emit_group_removed: - * @timeline: a #GESTimeline + * @timeline: The #GESTimeline * @group: group that was removed * * Emit group-removed signal. @@ -1201,7 +1290,7 @@ add_object_to_tracks (GESTimeline * timeline, GESClip * clip, GESTrack * track) LOCK_DYN (timeline); for (i = 0, tmp = timeline->tracks; tmp; tmp = tmp->next, i++) { GESTrack *track = GES_TRACK (tmp->data); - + /* FIXME: visited_type is essentially unused */ if (((track->type & types) == 0 || (track->type & visited_type))) continue; @@ -1272,6 +1361,9 @@ clip_track_element_added_cb (GESClip * clip, g_signal_emit (G_OBJECT (timeline), ges_timeline_signals[SELECT_TRACKS_FOR_OBJECT], 0, clip, track_element, &tracks); + /* FIXME: make sure each track in the list is unique */ + /* FIXME: make sure each track is part of the same timeline as the clip, + * and warn and ignore the track if it isn't */ if (!tracks || tracks->len == 0) { GST_WARNING_OBJECT (timeline, "Got no Track to add %p (type %s), removing" @@ -1301,6 +1393,7 @@ clip_track_element_added_cb (GESClip * clip, GST_WARNING_OBJECT (clip, "Failed to add track element to track"); ges_container_remove (GES_CONTAINER (clip), GES_TIMELINE_ELEMENT (track_element)); + /* FIXME: unref all the individual track in tracks */ g_ptr_array_unref (tracks); return; } @@ -1328,6 +1421,7 @@ clip_track_element_added_cb (GESClip * clip, ges_container_remove (GES_CONTAINER (clip), GES_TIMELINE_ELEMENT (track_element)); gst_object_unref (track); + /* FIXME: tracks is needed for the next loop after continue */ g_ptr_array_unref (tracks); continue; } else { @@ -1338,6 +1432,7 @@ clip_track_element_added_cb (GESClip * clip, ges_container_remove (GES_CONTAINER (clip), GES_TIMELINE_ELEMENT (track_element)); } + /* FIXME: in both cases track_element is removed from the clip! */ g_clear_object (&existing_src); track_element_copy = @@ -1351,6 +1446,7 @@ clip_track_element_added_cb (GESClip * clip, GES_TIMELINE_ELEMENT (track_element_copy))) { GST_WARNING_OBJECT (clip, "Failed to add track element to clip"); gst_object_unref (track_element_copy); + /* FIXME: unref **all** the individual track in tracks */ g_ptr_array_unref (tracks); return; } @@ -1359,7 +1455,10 @@ clip_track_element_added_cb (GESClip * clip, GST_WARNING_OBJECT (clip, "Failed to add track element to track"); ges_container_remove (GES_CONTAINER (clip), GES_TIMELINE_ELEMENT (track_element_copy)); + /* FIXME: should we also stop the child-added and child-removed + * emissions? */ gst_object_unref (track_element_copy); + /* FIXME: unref **all** the individual track in tracks */ g_ptr_array_unref (tracks); return; } @@ -1613,6 +1712,7 @@ _ghost_track_srcpad (TrackPrivate * tr_priv) gboolean timeline_add_element (GESTimeline * timeline, GESTimelineElement * element) { + /* FIXME: handle NULL element->name */ GESTimelineElement *same_name = g_hash_table_lookup (timeline->priv->all_elements, element->name); @@ -1624,6 +1724,11 @@ timeline_add_element (GESTimeline * timeline, GESTimelineElement * element) return FALSE; } + /* FIXME: why is the hash table using the name of the element, rather than + * the pointer to the element itself as the key? This makes it awkward + * to change the name of an element after it has been added. See + * ges_timeline_element_set_name. It means we have to remove and then + * re-add the element. */ g_hash_table_insert (timeline->priv->all_elements, ges_timeline_element_get_name (element), gst_object_ref (element)); @@ -1666,7 +1771,7 @@ timeline_get_tree (GESTimeline * timeline) /** * ges_timeline_new: * - * Creates a new empty #GESTimeline. + * Creates a new empty timeline. * * Returns: (transfer floating): The new timeline. */ @@ -1685,8 +1790,9 @@ ges_timeline_new (void) /** * ges_timeline_new_from_uri: - * @uri: the URI to load from - * @error: (out) (allow-none): An error to be set in case something wrong happens or %NULL + * @uri: The URI to load from + * @error: (out) (allow-none): An error to be set if loading fails, or + * %NULL to ignore * * Creates a timeline from the given URI. * @@ -1707,14 +1813,14 @@ ges_timeline_new_from_uri (const gchar * uri, GError ** error) /** * ges_timeline_load_from_uri: - * @timeline: an empty #GESTimeline into which to load the formatter + * @timeline: An empty #GESTimeline into which to load the formatter * @uri: The URI to load from - * @error: (out) (allow-none): An error to be set in case something wrong happens or %NULL + * @error: (out) (allow-none): An error to be set if loading fails, or + * %NULL to ignore * - * Loads the contents of URI into the given timeline. + * Loads the contents of URI into the timeline. * - * Returns: %TRUE if the timeline was loaded successfully, or %FALSE if the uri - * could not be loaded. + * Returns: %TRUE if the timeline was loaded successfully from @uri. */ gboolean ges_timeline_load_from_uri (GESTimeline * timeline, const gchar * uri, @@ -1736,18 +1842,18 @@ ges_timeline_load_from_uri (GESTimeline * timeline, const gchar * uri, /** * ges_timeline_save_to_uri: - * @timeline: a #GESTimeline + * @timeline: The #GESTimeline * @uri: The location to save to - * @formatter_asset: (allow-none): The formatter asset to use or %NULL. If %NULL, - * will try to save in the same format as the one from which the timeline as been loaded - * or default to the formatter with highest rank + * @formatter_asset: (allow-none): The formatter asset to use, or %NULL * @overwrite: %TRUE to overwrite file if it exists - * @error: (out) (allow-none): An error to be set in case something wrong happens or %NULL + * @error: (out) (allow-none): An error to be set if saving fails, or + * %NULL to ignore * - * Saves the timeline to the given location + * Saves the timeline to the given location. If @formatter_asset is %NULL, + * the method will attempt to save in the same format the timeline was + * loaded from, before defaulting to the formatter with highest rank. * - * Returns: %TRUE if the timeline was successfully saved to the given location, - * else %FALSE. + * Returns: %TRUE if @timeline was successfully saved to @uri. */ gboolean ges_timeline_save_to_uri (GESTimeline * timeline, const gchar * uri, @@ -1777,12 +1883,12 @@ ges_timeline_save_to_uri (GESTimeline * timeline, const gchar * uri, /** * ges_timeline_get_groups: - * @timeline: a #GESTimeline + * @timeline: The #GESTimeline * - * Get the list of #GESGroup present in the Timeline. + * Get the list of #GESGroup-s present in the timeline. * - * Returns: (transfer none) (element-type GESGroup): the list of - * #GESGroup that contain clips present in the timeline's layers. + * Returns: (transfer none) (element-type GESGroup): The list of + * groups that contain clips present in @timeline's layers. * Must not be changed. */ GList * @@ -1796,13 +1902,12 @@ ges_timeline_get_groups (GESTimeline * timeline) /** * ges_timeline_append_layer: - * @timeline: a #GESTimeline + * @timeline: The #GESTimeline * - * Append a newly created #GESLayer to @timeline - * Note that you do not own any reference to the returned layer. + * Append a newly created layer to the timeline. The layer will + * be added at the lowest #GESLayer:priority (numerically, the highest). * - * Returns: (transfer none): The newly created #GESLayer, or the last (empty) - * #GESLayer of @timeline. + * Returns: (transfer none): The newly created layer. */ GESLayer * ges_timeline_append_layer (GESTimeline * timeline) @@ -1815,6 +1920,8 @@ ges_timeline_append_layer (GESTimeline * timeline) layer = ges_layer_new (); priority = g_list_length (timeline->layers); + /* FIXME: if a timeline contains 2 layers with priority 0 and 2, then + * this will set the layer priority of the new layer to 2 as well! */ ges_layer_set_priority (layer, priority); ges_timeline_add_layer (timeline, layer); @@ -1824,13 +1931,16 @@ ges_timeline_append_layer (GESTimeline * timeline) /** * ges_timeline_add_layer: - * @timeline: a #GESTimeline - * @layer: (transfer floating): the #GESLayer to add + * @timeline: The #GESTimeline + * @layer: (transfer floating): The layer to add * - * Add the layer to the timeline. The reference to the @layer will be stolen - * by the @timeline. + * Add a layer to the timeline. * - * Returns: %TRUE if the layer was properly added, else %FALSE. + * Deprecated: 1.18: This method requires you to ensure the layer's + * #GESLayer:priority will be unique to the timeline. Use + * ges_timeline_append_layer() and ges_timeline_move_layer() instead. + * + * Returns: %TRUE if @layer was properly added. */ gboolean ges_timeline_add_layer (GESTimeline * timeline, GESLayer * layer) @@ -1860,6 +1970,10 @@ ges_timeline_add_layer (GESTimeline * timeline, GESLayer * layer) return FALSE; } + /* FIXME: ensure the layer->priority does not conflict with an existing + * layer in the timeline. Currently can add several layers with equal + * layer priorities */ + auto_transition = ges_layer_get_auto_transition (layer); /* If the user doesn't explicitely set layer auto_transition, then set our */ @@ -1902,14 +2016,12 @@ ges_timeline_add_layer (GESTimeline * timeline, GESLayer * layer) /** * ges_timeline_remove_layer: - * @timeline: a #GESTimeline - * @layer: the #GESLayer to remove + * @timeline: The #GESTimeline + * @layer: The layer to remove * - * Removes the layer from the timeline. The reference that the @timeline holds on - * the layer will be dropped. If you wish to use the @layer after calling this - * method, you need to take a reference before calling. + * Removes a layer from the timeline. * - * Returns: %TRUE if the layer was properly removed, else %FALSE. + * Returns: %TRUE if @layer was properly removed. */ gboolean @@ -1950,6 +2062,7 @@ ges_timeline_remove_layer (GESTimeline * timeline, GESLayer * layer) timeline->layers = g_list_remove (timeline->layers, layer); ges_layer_set_timeline (layer, NULL); + /* FIXME: we should resync the layer priorities */ g_signal_emit (timeline, ges_timeline_signals[LAYER_REMOVED], 0, layer); @@ -1960,13 +2073,13 @@ ges_timeline_remove_layer (GESTimeline * timeline, GESLayer * layer) /** * ges_timeline_add_track: - * @timeline: a #GESTimeline - * @track: (transfer full): the #GESTrack to add + * @timeline: The #GESTimeline + * @track: (transfer full): The track to add * - * Add a track to the timeline. The reference to the track will be stolen by the - * pipeline. + * Add a track to the timeline. Existing #GESClip-s in the timeline will, + * where appropriate, add their controlled elements to the new track. * - * Returns: %TRUE if the track was properly added, else %FALSE. + * Returns: %TRUE if @track was properly added. */ /* FIXME: create track elements for clips which have already been @@ -2056,14 +2169,12 @@ ges_timeline_add_track (GESTimeline * timeline, GESTrack * track) /** * ges_timeline_remove_track: - * @timeline: a #GESTimeline - * @track: the #GESTrack to remove + * @timeline: The #GESTimeline + * @track: The track to remove * - * Remove the @track from the @timeline. The reference stolen when adding the - * @track will be removed. If you wish to use the @track after calling this - * function you must ensure that you have a reference to it. + * Remove a track from the timeline. * - * Returns: %TRUE if the @track was properly removed, else %FALSE. + * Returns: %TRUE if @track was properly removed. */ /* FIXME: release any track elements associated with this layer. currenly this @@ -2138,12 +2249,12 @@ ges_timeline_remove_track (GESTimeline * timeline, GESTrack * track) /** * ges_timeline_get_track_for_pad: * @timeline: The #GESTimeline - * @pad: The #GstPad + * @pad: A pad * - * Search the #GESTrack corresponding to the given @timeline's @pad. + * Search for the #GESTrack corresponding to the given timeline's pad. * - * Returns: (transfer none) (nullable): The corresponding #GESTrack if it is - * found, or %NULL if there is an error. + * Returns: (transfer none) (nullable): The track corresponding to @pad, + * or %NULL if there is an error. */ GESTrack * @@ -2169,12 +2280,13 @@ ges_timeline_get_track_for_pad (GESTimeline * timeline, GstPad * pad) /** * ges_timeline_get_pad_for_track: * @timeline: The #GESTimeline - * @track: The #GESTrack + * @track: A track * - * Search the #GstPad corresponding to the given @timeline's @track. + * Search for the #GstPad corresponding to the given timeline's track. + * You can link to this pad to receive the output data of the given track. * - * Returns: (transfer none) (nullable): The corresponding #GstPad if it is - * found, or %NULL if there is an error. + * Returns: (transfer none) (nullable): The pad corresponding to @track, + * or %NULL if there is an error. */ GstPad * @@ -2201,12 +2313,12 @@ ges_timeline_get_pad_for_track (GESTimeline * timeline, GESTrack * track) /** * ges_timeline_get_tracks: - * @timeline: a #GESTimeline + * @timeline: The #GESTimeline * - * Returns the list of #GESTrack used by the Timeline. + * Get the list of #GESTrack-s used by the timeline. * - * Returns: (transfer full) (element-type GESTrack): A list of #GESTrack. - * The caller should unref each track once he is done with them. + * Returns: (transfer full) (element-type GESTrack): The list of tracks + * used by @timeline. */ GList * ges_timeline_get_tracks (GESTimeline * timeline) @@ -2223,13 +2335,12 @@ ges_timeline_get_tracks (GESTimeline * timeline) /** * ges_timeline_get_layers: - * @timeline: a #GESTimeline + * @timeline: The #GESTimeline * - * Get the list of #GESLayer present in the Timeline. + * Get the list of #GESLayer-s present in the timeline. * - * Returns: (transfer full) (element-type GESLayer): the list of - * #GESLayer present in the Timeline sorted by priority. - * The caller should unref each Layer once he is done with them. + * Returns: (transfer full) (element-type GESLayer): The list of + * layers present in @timeline sorted by priority. */ GList * ges_timeline_get_layers (GESTimeline * timeline) @@ -2314,32 +2425,30 @@ ges_timeline_commit_unlocked (GESTimeline * timeline) /** * ges_timeline_commit: - * @timeline: a #GESTimeline + * @timeline: A #GESTimeline * * Commit all the pending changes of the clips contained in the - * @timeline. + * timeline. * - * When changes happen in a timeline, they are not - * directly executed in the non-linear engine. Call this method once you are - * done with a set of changes and want it to be executed. - * - * The #GESTimeline::commited signal will be emitted when the (possibly updated) - * #GstPipeline is ready to output data again, except if the state of the - * timeline was #GST_STATE_READY or #GST_STATE_NULL. - * - * Note that all the pending changes will automatically be executed when the - * timeline goes from #GST_STATE_READY to #GST_STATE_PAUSED, which usually is - * triggered by corresponding state changes in a containing #GESPipeline. + * When changes happen in a timeline, they are not immediately executed + * internally, in a way that effects the output data of the timeline. You + * should call this method when you are done with a set of changes and you + * want them to be executed. * + * Any pending changes will be executed in the backend. The + * #GESTimeline::commited signal will be emitted once this has completed. * You should not try to change the state of the timeline, seek it or add - * tracks to it during a commit operation, that is between a call to this - * function and after receiving the #GESTimeline::commited signal. + * tracks to it before receiving this signal. You can use + * ges_timeline_commit_sync() if you do not want to perform other tasks in + * the mean time. * - * See #ges_timeline_commit_sync if you don't want to bother with waiting - * for the signal. + * Note that all the pending changes will automatically be executed when + * the timeline goes from #GST_STATE_READY to #GST_STATE_PAUSED, which is + * usually triggered by a corresponding state changes in a containing + * #GESPipeline. * - * Returns: %TRUE if pending changes were commited or %FALSE if nothing needed - * to be commited + * Returns: %TRUE if pending changes were committed, or %FALSE if nothing + * needed to be committed. */ gboolean ges_timeline_commit (GESTimeline * timeline) @@ -2373,24 +2482,15 @@ commited_cb (GESTimeline * timeline) /** * ges_timeline_commit_sync: - * @timeline: a #GESTimeline + * @timeline: A #GESTimeline * - * Commit all the pending changes of the #GESClips contained in the - * @timeline. + * Commit all the pending changes of the clips contained in the + * timeline and wait for the changes to complete. * - * Will return once the update is complete, that is when the - * (possibly updated) #GstPipeline is ready to output data again, or if the - * state of the timeline was #GST_STATE_READY or #GST_STATE_NULL. + * See ges_timeline_commit(). * - * This function will wait for any pending state change of the timeline by - * calling #gst_element_get_state with a #GST_CLOCK_TIME_NONE timeout, you - * should not try to change the state from another thread before this function - * has returned. - * - * See #ges_timeline_commit for more information. - * - * Returns: %TRUE if pending changes were commited or %FALSE if nothing needed - * to be commited + * Returns: %TRUE if pending changes were committed, or %FALSE if nothing + * needed to be committed. */ gboolean ges_timeline_commit_sync (GESTimeline * timeline) @@ -2431,11 +2531,11 @@ ges_timeline_commit_sync (GESTimeline * timeline) /** * ges_timeline_get_duration: - * @timeline: a #GESTimeline + * @timeline: The #GESTimeline * - * Get the current duration of @timeline + * Get the current #GESTimeline:duration of the timeline * - * Returns: The current duration of @timeline + * Returns: The current duration of @timeline. */ GstClockTime ges_timeline_get_duration (GESTimeline * timeline) @@ -2448,12 +2548,11 @@ ges_timeline_get_duration (GESTimeline * timeline) /** * ges_timeline_get_auto_transition: - * @timeline: a #GESTimeline + * @timeline: The #GESTimeline * - * Gets whether transitions are automatically added when objects - * overlap or not. + * Gets #GESTimeline:auto-transition for the timeline. * - * Returns: %TRUE if transitions are automatically added, else %FALSE. + * Returns: The auto-transition of @self. */ gboolean ges_timeline_get_auto_transition (GESTimeline * timeline) @@ -2466,11 +2565,14 @@ ges_timeline_get_auto_transition (GESTimeline * timeline) /** * ges_timeline_set_auto_transition: - * @timeline: a #GESLayer - * @auto_transition: whether the auto_transition is active + * @timeline: The #GESTimeline + * @auto_transition: Whether transitions should be automatically added + * to @timeline's layers * - * Sets the layer to the given @auto_transition. See the documentation of the - * property auto_transition for more information. + * Sets #GESTimeline:auto-transition for the timeline. This will also set + * the corresponding #GESLayer:auto-transition for all of the timeline's + * layers to the same value. See ges_layer_set_auto_transition() if you + * wish to set the layer's #GESLayer:auto-transition individually. */ void ges_timeline_set_auto_transition (GESTimeline * timeline, @@ -2494,13 +2596,11 @@ ges_timeline_set_auto_transition (GESTimeline * timeline, /** * ges_timeline_get_snapping_distance: - * @timeline: a #GESTimeline + * @timeline: The #GESTimeline * - * Gets the configured snapping distance of the timeline. See - * the documentation of the property snapping_distance for more - * information. + * Gets the #GESTimeline:snapping-distance for the timeline. * - * Returns: The @snapping_distance property of the timeline + * Returns: The snapping distance (in nanoseconds) of @timeline. */ GstClockTime ges_timeline_get_snapping_distance (GESTimeline * timeline) @@ -2514,11 +2614,12 @@ ges_timeline_get_snapping_distance (GESTimeline * timeline) /** * ges_timeline_set_snapping_distance: - * @timeline: a #GESLayer - * @snapping_distance: whether the snapping_distance is active + * @timeline: The #GESTimeline + * @snapping_distance: The snapping distance to use (in nanoseconds) * - * Sets the @snapping_distance of the timeline. See the documentation of the - * property snapping_distance for more information. + * Sets #GESTimeline:snapping-distance for the timeline. This new value + * will only effect future snappings and will not be used to snap the + * current element positions within the timeline. */ void ges_timeline_set_snapping_distance (GESTimeline * timeline, @@ -2532,12 +2633,13 @@ ges_timeline_set_snapping_distance (GESTimeline * timeline, /** * ges_timeline_get_element: - * @timeline: a #GESTimeline + * @timeline: The #GESTimeline + * @name: The name of the element to find * - * Gets a #GESTimelineElement contained in the timeline + * Gets the element contained in the timeline with the given name. * - * Returns: (transfer full) (nullable): The #GESTimelineElement or %NULL if - * not found. + * Returns: (transfer full) (nullable): The timeline element in @timeline + * with the given @name, or %NULL if it was not found. */ GESTimelineElement * ges_timeline_get_element (GESTimeline * timeline, const gchar * name) @@ -2547,6 +2649,7 @@ ges_timeline_get_element (GESTimeline * timeline, const gchar * name) g_return_val_if_fail (GES_IS_TIMELINE (timeline), NULL); CHECK_THREAD (timeline); + /* FIXME: handle NULL name */ ret = g_hash_table_lookup (timeline->priv->all_elements, name); if (ret) @@ -2571,11 +2674,11 @@ ges_timeline_get_element (GESTimeline * timeline, const gchar * name) /** * ges_timeline_is_empty: - * @timeline: a #GESTimeline + * @timeline: The #GESTimeline * - * Check whether a #GESTimeline is empty or not + * Check whether the timeline is empty or not. * - * Returns: %TRUE if the timeline is empty %FALSE otherwize + * Returns: %TRUE if @timeline is empty. */ gboolean ges_timeline_is_empty (GESTimeline * timeline) @@ -2601,13 +2704,14 @@ ges_timeline_is_empty (GESTimeline * timeline) /** * ges_timeline_get_layer: - * @timeline: The #GESTimeline to retrive a layer from - * @priority: The priority of the layer to find + * @timeline: The #GESTimeline to retrieve a layer from + * @priority: The priority/index of the layer to find * - * Retrieve the layer with @priority as a priority + * Retrieve the layer whose index in the timeline matches the given + * priority. * - * Returns: (transfer full) (nullable): A #GESLayer or %NULL if no layer with - * @priority was found + * Returns: (transfer full) (nullable): The layer with the given + * @priority, or %NULL if none was found. * * Since 1.6 */ @@ -2636,18 +2740,32 @@ ges_timeline_get_layer (GESTimeline * timeline, guint priority) /** * ges_timeline_paste_element: - * @timeline: The #GESTimeline onto which the #GESTimelineElement should be pasted - * @element: The #GESTimelineElement to paste - * @position: The position in the timeline the element should - * be pasted to, meaning it will become the start of @element - * @layer_priority: The #GESLayer to which the element should be pasted to. - * -1 means paste to the same layer from which the @element has been copied from. + * @timeline: The #GESTimeline onto which @element should be pasted + * @element: The element to paste + * @position: The position in the timeline @element should be pasted to, + * i.e. the #GESTimelineElement:start value for the pasted element. + * @layer_priority: The layer into which the element should be pasted. + * -1 means paste to the same layer from which @element has been copied from * - * Paste @element inside the timeline. @element must have been - * created using ges_timeline_element_copy with deep=TRUE set, - * i.e. it must be a deep copy, otherwise it will fail. + * Paste an element inside the timeline. @element **must** be the return of + * ges_timeline_element_copy() with `deep=TRUE`, + * and it should not be changed before pasting. @element itself is not + * placed in the timeline, instead a new element is created, alike to the + * originally copied element. Note that the originally copied element must + * also lie within @timeline, at both the point of copying and pasting. * - * Returns: (transfer none): Shallow copy of the @element pasted + * Pasting may fail if it would place the timeline in an unsupported + * configuration. + * + * After calling this function @element should not be used. In particular, + * @element can **not** be pasted again. Instead, you can copy the + * returned element and paste that copy (although, this is only possible + * if the paste was successful). + * + * See also ges_timeline_element_paste(). + * + * Returns: (transfer full) (nullable): The newly created element, or + * %NULL if pasting fails. */ GESTimelineElement * ges_timeline_paste_element (GESTimeline * timeline, @@ -2693,15 +2811,15 @@ ges_timeline_paste_element (GESTimeline * timeline, /** * ges_timeline_move_layer: - * @timeline: The timeline in which @layer must be - * @layer: The layer to move at @new_layer_priority - * @new_layer_priority: The index at which @layer should land + * @timeline: A #GESTimeline + * @layer: A layer within @timeline, whose priority should be changed + * @new_layer_priority: The new index for @layer * - * Moves @layer at @new_layer_priority meaning that @layer - * we land at that position in the stack of layers inside - * the timeline. If @new_layer_priority is superior than the number - * of layers present in the time, it will move to the end of the - * stack of layers. + * Moves a layer within the timeline to the index given by + * @new_layer_priority. + * An index of 0 corresponds to the layer with the highest priority in a + * timeline. If @new_layer_priority is greater than the number of layers + * present in the timeline, it will become the lowest priority layer. * * Since: 1.16 */ diff --git a/ges/ges-timeline.h b/ges/ges-timeline.h index 7ebe3f0df0..ac07ae95f3 100644 --- a/ges/ges-timeline.h +++ b/ges/ges-timeline.h @@ -52,7 +52,7 @@ G_BEGIN_DECLS * ges_timeline_get_project: * @obj: The #GESTimeline from which to retrieve the project * - * Helper macro to retrieve the project from which a #GESTimeline as been extracted + * Helper macro to retrieve the project from which @obj was extracted */ #define ges_timeline_get_project(obj) (GES_PROJECT (ges_extractable_get_asset (GES_EXTRACTABLE(obj)))) @@ -60,9 +60,10 @@ typedef struct _GESTimelinePrivate GESTimelinePrivate; /** * GESTimeline: - * @layers: (element-type GES.Layer): A list of #GESLayer sorted by priority NOTE: Do not modify. - * @tracks: Deprecated:1.10: (element-type GES.Track): This is not thread safe, use - * #ges_timeline_get_tracks instead. + * @layers: (element-type GES.Layer): A list of #GESLayer-s sorted by + * priority. NOTE: Do not modify. + * @tracks: Deprecated:1.10: (element-type GES.Track): This is not thread + * safe, use #ges_timeline_get_tracks instead. */ struct _GESTimeline { GstBin parent; diff --git a/ges/ges-utils.c b/ges/ges-utils.c index 654039b850..fcfcd0f661 100644 --- a/ges/ges-utils.c +++ b/ges/ges-utils.c @@ -40,10 +40,11 @@ static GstElementFactory *compositor_factory = NULL; /** * ges_timeline_new_audio_video: * - * Creates a new #GESTimeline containing a raw audio and a - * raw video track. + * Creates a new timeline containing a single #GESAudioTrack and a + * single #GESVideoTrack. * - * Returns: (transfer floating): The newly created #GESTimeline. + * Returns: (transfer floating): The new timeline, or %NULL if the tracks + * could not be created and added. */ GESTimeline *