mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 04:36:20 +00:00
ges: Add an internal GstStructure based interface
To be use by GstValidate action and ges-launch Reviewers: Mathieu_Du, thiblahute Differential Revision: http://phabricator.freedesktop.org/D42
This commit is contained in:
parent
7d0015b973
commit
3105797913
4 changed files with 435 additions and 268 deletions
|
@ -75,6 +75,7 @@ libges_@GST_API_VERSION@_la_SOURCES = \
|
||||||
ges-utils.c \
|
ges-utils.c \
|
||||||
ges-group.c \
|
ges-group.c \
|
||||||
ges-validate.c \
|
ges-validate.c \
|
||||||
|
ges-structured-interface.c \
|
||||||
gstframepositionner.c
|
gstframepositionner.c
|
||||||
|
|
||||||
libges_@GST_API_VERSION@includedir = $(includedir)/gstreamer-@GST_API_VERSION@/ges/
|
libges_@GST_API_VERSION@includedir = $(includedir)/gstreamer-@GST_API_VERSION@/ges/
|
||||||
|
@ -153,6 +154,7 @@ noinst_HEADERS = \
|
||||||
nle/nleurisource.h \
|
nle/nleurisource.h \
|
||||||
ges-internal.h \
|
ges-internal.h \
|
||||||
ges-auto-transition.h \
|
ges-auto-transition.h \
|
||||||
|
ges-structured-interface.h \
|
||||||
gstframepositionner.h
|
gstframepositionner.h
|
||||||
|
|
||||||
libges_@GST_API_VERSION@_la_CFLAGS = -I$(top_srcdir) $(GST_PBUTILS_CFLAGS) \
|
libges_@GST_API_VERSION@_la_CFLAGS = -I$(top_srcdir) $(GST_PBUTILS_CFLAGS) \
|
||||||
|
|
344
ges/ges-structured-interface.c
Normal file
344
ges/ges-structured-interface.c
Normal file
|
@ -0,0 +1,344 @@
|
||||||
|
/* GStreamer Editing Services
|
||||||
|
*
|
||||||
|
* Copyright (C) <2015> Thibault Saunier <tsaunier@gnome.org>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
#include "ges-structured-interface.h"
|
||||||
|
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_ges_add_remove_keyframe_from_struct (GESTimeline * timeline,
|
||||||
|
GstStructure * structure, GError ** error)
|
||||||
|
{
|
||||||
|
GESTrackElement *element;
|
||||||
|
|
||||||
|
gdouble value;
|
||||||
|
GstClockTime timestamp;
|
||||||
|
GstControlBinding *binding = NULL;
|
||||||
|
GstTimedValueControlSource *source = NULL;
|
||||||
|
gchar *element_name = NULL, *property_name = NULL;
|
||||||
|
|
||||||
|
gboolean ret = FALSE;
|
||||||
|
|
||||||
|
|
||||||
|
if (!gst_structure_get (structure,
|
||||||
|
"element-name", G_TYPE_STRING, &element_name,
|
||||||
|
"property-name", G_TYPE_STRING, &property_name,
|
||||||
|
"value", G_TYPE_DOUBLE, &value,
|
||||||
|
"timestamp", GST_TYPE_CLOCK_TIME, ×tamp, NULL)) {
|
||||||
|
*error = g_error_new (GES_ERROR, 0, "Could not get one of the mandatory"
|
||||||
|
" fields in %s", gst_structure_get_name (structure));
|
||||||
|
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
element =
|
||||||
|
GES_TRACK_ELEMENT (ges_timeline_get_element (timeline, element_name));
|
||||||
|
|
||||||
|
if (!GES_IS_TRACK_ELEMENT (element)) {
|
||||||
|
*error =
|
||||||
|
g_error_new (GES_ERROR, 0, "Could not find TrackElement %s",
|
||||||
|
element_name);
|
||||||
|
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
binding = ges_track_element_get_control_binding (element, property_name);
|
||||||
|
if (binding == NULL) {
|
||||||
|
*error = g_error_new (GES_ERROR, 0, "No control binding found for %s:%s"
|
||||||
|
" you should first set-control-binding on it",
|
||||||
|
element_name, property_name);
|
||||||
|
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_get (binding, "control-source", &source, NULL);
|
||||||
|
|
||||||
|
if (source == NULL) {
|
||||||
|
*error = g_error_new (GES_ERROR, 0, "No control source found for %s:%s"
|
||||||
|
" you should first set-control-binding on it",
|
||||||
|
element_name, property_name);
|
||||||
|
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GST_IS_TIMED_VALUE_CONTROL_SOURCE (source)) {
|
||||||
|
*error = g_error_new (GES_ERROR, 0, "You can use add-keyframe"
|
||||||
|
" only on GstTimedValueControlSource not %s",
|
||||||
|
G_OBJECT_TYPE_NAME (source));
|
||||||
|
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!g_strcmp0 (gst_structure_get_name (structure), "add-keyframe"))
|
||||||
|
ret = gst_timed_value_control_source_set (source, timestamp, value);
|
||||||
|
else {
|
||||||
|
ret = gst_timed_value_control_source_unset (source, timestamp);
|
||||||
|
|
||||||
|
if (!ret) {
|
||||||
|
*error =
|
||||||
|
g_error_new (GES_ERROR, 0,
|
||||||
|
"Could not unset value for timestamp: %" GST_TIME_FORMAT,
|
||||||
|
GST_TIME_ARGS (timestamp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (source)
|
||||||
|
gst_object_unref (source);
|
||||||
|
g_free (element_name);
|
||||||
|
g_free (property_name);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
GESAsset *
|
||||||
|
_ges_get_asset_from_timeline (GESTimeline * timeline, GType type,
|
||||||
|
const gchar * id)
|
||||||
|
{
|
||||||
|
GESAsset *asset;
|
||||||
|
GError *error = NULL;
|
||||||
|
GESProject *project = ges_timeline_get_project (timeline);
|
||||||
|
|
||||||
|
asset = ges_project_create_asset_sync (project, id, type, &error);
|
||||||
|
if (!asset || error) {
|
||||||
|
GST_ERROR
|
||||||
|
("There was an error requesting the asset with id %s and type %s (%s)",
|
||||||
|
id, g_type_name (type), error ? error->message : "unknown");
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return asset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unref after usage */
|
||||||
|
GESLayer *
|
||||||
|
_ges_get_layer_by_priority (GESTimeline * timeline, gint priority)
|
||||||
|
{
|
||||||
|
GList *layers, *tmp;
|
||||||
|
GESLayer *layer = NULL;
|
||||||
|
|
||||||
|
layers = ges_timeline_get_layers (timeline);
|
||||||
|
if (priority == (gint) g_list_length (layers)) {
|
||||||
|
layer = gst_object_ref (ges_timeline_append_layer (timeline));
|
||||||
|
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (tmp = layers; tmp; tmp = tmp->next) {
|
||||||
|
GESLayer *tmp_layer = GES_LAYER (tmp->data);
|
||||||
|
guint tmp_priority;
|
||||||
|
|
||||||
|
g_object_get (tmp_layer, "priority", &tmp_priority, NULL);
|
||||||
|
if ((gint) tmp_priority == priority) {
|
||||||
|
layer = gst_object_ref (tmp_layer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
g_list_free_full (layers, gst_object_unref);
|
||||||
|
|
||||||
|
return layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GET_AND_CHECK(name,type,var) G_STMT_START {\
|
||||||
|
if (!gst_structure_get (structure, name, type, var, NULL)) {\
|
||||||
|
*error = g_error_new (GES_ERROR, 0, "Could not get mandatory field: %s in %s",\
|
||||||
|
name, gst_structure_get_name (structure)); \
|
||||||
|
goto beach;\
|
||||||
|
} \
|
||||||
|
} G_STMT_END
|
||||||
|
|
||||||
|
#define TRY_GET(name,type,var,def) G_STMT_START {\
|
||||||
|
if (!gst_structure_get (structure, name, type, var, NULL)) {\
|
||||||
|
*var = def; \
|
||||||
|
} \
|
||||||
|
} G_STMT_END
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_ges_add_clip_from_struct (GESTimeline * timeline, GstStructure * structure,
|
||||||
|
GError ** error)
|
||||||
|
{
|
||||||
|
GESAsset *asset;
|
||||||
|
GESLayer *layer;
|
||||||
|
GESClip *clip;
|
||||||
|
gint layer_priority;
|
||||||
|
const gchar *name;
|
||||||
|
const gchar *asset_id;
|
||||||
|
const gchar *type_string;
|
||||||
|
GType type;
|
||||||
|
gboolean res = FALSE;
|
||||||
|
GstClockTime duration = 1 * GST_SECOND, inpoint = 0, start =
|
||||||
|
GST_CLOCK_TIME_NONE;
|
||||||
|
|
||||||
|
GET_AND_CHECK ("asset-id", G_TYPE_STRING, &asset_id);
|
||||||
|
|
||||||
|
TRY_GET ("name", G_TYPE_STRING, &name, NULL);
|
||||||
|
TRY_GET ("layer-priority", G_TYPE_INT, &layer_priority,
|
||||||
|
g_list_length (timeline->layers));
|
||||||
|
TRY_GET ("type", G_TYPE_STRING, &type_string, "GESUriClip");
|
||||||
|
TRY_GET ("start", GST_TYPE_CLOCK_TIME, &start, 0);
|
||||||
|
TRY_GET ("inpoint", GST_TYPE_CLOCK_TIME, &inpoint, 0);
|
||||||
|
TRY_GET ("duration", GST_TYPE_CLOCK_TIME, &duration, GST_CLOCK_TIME_NONE);
|
||||||
|
|
||||||
|
if (!(type = g_type_from_name (type_string))) {
|
||||||
|
*error = g_error_new (GES_ERROR, 0, "This type doesn't exist : %s",
|
||||||
|
type_string);
|
||||||
|
|
||||||
|
goto beach;
|
||||||
|
}
|
||||||
|
|
||||||
|
asset = _ges_get_asset_from_timeline (timeline, type, asset_id);
|
||||||
|
if (!asset) {
|
||||||
|
res = FALSE;
|
||||||
|
|
||||||
|
goto beach;
|
||||||
|
}
|
||||||
|
|
||||||
|
layer = _ges_get_layer_by_priority (timeline, layer_priority);
|
||||||
|
|
||||||
|
if (!layer) {
|
||||||
|
g_error_new (GES_ERROR, 0, "No layer with priority %d", layer_priority);
|
||||||
|
goto beach;
|
||||||
|
}
|
||||||
|
|
||||||
|
clip = ges_layer_add_asset (layer, asset, start, inpoint, duration,
|
||||||
|
GES_TRACK_TYPE_UNKNOWN);
|
||||||
|
|
||||||
|
if (clip) {
|
||||||
|
res = TRUE;
|
||||||
|
if (name
|
||||||
|
&& !ges_timeline_element_set_name (GES_TIMELINE_ELEMENT (clip), name)) {
|
||||||
|
res = FALSE;
|
||||||
|
g_error_new (GES_ERROR, 0, "couldn't set name %s on clip with id %s",
|
||||||
|
name, asset_id);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
g_error_new (GES_ERROR, 0,
|
||||||
|
"Couldn't add clip with id %s to layer with priority %d", asset_id,
|
||||||
|
layer_priority);
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_object_unref (layer);
|
||||||
|
|
||||||
|
beach:
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef GET_AND_CHECK
|
||||||
|
#undef TRY_GET
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_ges_container_add_child_from_struct (GESTimeline * timeline,
|
||||||
|
GstStructure * structure, GError ** error)
|
||||||
|
{
|
||||||
|
GESAsset *asset;
|
||||||
|
GESContainer *container;
|
||||||
|
GESTimelineElement *child = NULL;
|
||||||
|
const gchar *container_name, *child_name, *child_type, *id;
|
||||||
|
|
||||||
|
gboolean res = TRUE;
|
||||||
|
|
||||||
|
container_name = gst_structure_get_string (structure, "container-name");
|
||||||
|
container =
|
||||||
|
GES_CONTAINER (ges_timeline_get_element (timeline, container_name));
|
||||||
|
g_return_val_if_fail (GES_IS_CONTAINER (container), FALSE);
|
||||||
|
|
||||||
|
id = gst_structure_get_string (structure, "asset-id");
|
||||||
|
child_type = gst_structure_get_string (structure, "child-type");
|
||||||
|
|
||||||
|
if (id && child_type) {
|
||||||
|
asset =
|
||||||
|
_ges_get_asset_from_timeline (timeline, g_type_from_name (child_type),
|
||||||
|
id);
|
||||||
|
|
||||||
|
if (asset == NULL) {
|
||||||
|
res = FALSE;
|
||||||
|
g_error_new (GES_ERROR, 0, "Could not find asset: %s", id);
|
||||||
|
goto beach;
|
||||||
|
}
|
||||||
|
|
||||||
|
child = GES_TIMELINE_ELEMENT (ges_asset_extract (asset, NULL));
|
||||||
|
if (!GES_IS_TIMELINE_ELEMENT (child)) {
|
||||||
|
g_error_new (GES_ERROR, 0, "Could not extract child element");
|
||||||
|
|
||||||
|
goto beach;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
child_name = gst_structure_get_string (structure, "child-name");
|
||||||
|
if (!child && child_name) {
|
||||||
|
child = ges_timeline_get_element (timeline, child_name);
|
||||||
|
if (!GES_IS_TIMELINE_ELEMENT (child)) {
|
||||||
|
g_error_new (GES_ERROR, 0, "Could not find child element");
|
||||||
|
|
||||||
|
goto beach;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!child) {
|
||||||
|
g_error_new (GES_ERROR, 0, "Wong parametters, could not get a child");
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (child_name)
|
||||||
|
ges_timeline_element_set_name (child, child_name);
|
||||||
|
else
|
||||||
|
child_name = GES_TIMELINE_ELEMENT_NAME (child);
|
||||||
|
|
||||||
|
res = ges_container_add (container, child);
|
||||||
|
if (res == FALSE) {
|
||||||
|
g_error_new (GES_ERROR, 0, "Could not add child to container");
|
||||||
|
}
|
||||||
|
|
||||||
|
beach:
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_ges_set_child_property_from_struct (GESTimeline * timeline,
|
||||||
|
GstStructure * structure, GError ** error)
|
||||||
|
{
|
||||||
|
const GValue *value;
|
||||||
|
GESTimelineElement *element;
|
||||||
|
const gchar *property_name, *element_name;
|
||||||
|
|
||||||
|
element_name = gst_structure_get_string (structure, "element-name");
|
||||||
|
element = ges_timeline_get_element (timeline, element_name);
|
||||||
|
if (!GES_IS_TRACK_ELEMENT (element)) {
|
||||||
|
*error =
|
||||||
|
g_error_new (GES_ERROR, 0, "Could not find TrackElement %s",
|
||||||
|
element_name);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
property_name = gst_structure_get_string (structure, "property");
|
||||||
|
value = gst_structure_get_value (structure, "value");
|
||||||
|
|
||||||
|
GST_DEBUG ("%s Setting %s property to %p",
|
||||||
|
element->name, property_name, value);
|
||||||
|
|
||||||
|
ges_track_element_set_child_property (GES_TRACK_ELEMENT (element),
|
||||||
|
property_name, (GValue *) value);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
54
ges/ges-structured-interface.h
Normal file
54
ges/ges-structured-interface.h
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
/* GStreamer Editing Services
|
||||||
|
*
|
||||||
|
* Copyright (C) <2015> Thibault Saunier <tsaunier@gnome.org>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GES_STRUCTURED_INTERFACE__
|
||||||
|
#define __GES_STRUCTURED_INTERFACE__
|
||||||
|
|
||||||
|
#include <ges/ges.h>
|
||||||
|
|
||||||
|
typedef gboolean (*ActionFromStructureFunc) (GESTimeline * timeline,
|
||||||
|
GstStructure * structure,
|
||||||
|
GError ** error);
|
||||||
|
|
||||||
|
gboolean _ges_add_remove_keyframe_from_struct (GESTimeline * timeline,
|
||||||
|
GstStructure * structure,
|
||||||
|
GError ** error);
|
||||||
|
G_GNUC_INTERNAL gboolean
|
||||||
|
_ges_add_clip_from_struct (GESTimeline * timeline,
|
||||||
|
GstStructure * structure,
|
||||||
|
GError ** error);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_ges_container_add_child_from_struct (GESTimeline * timeline,
|
||||||
|
GstStructure * structure,
|
||||||
|
GError ** error);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_ges_set_child_property_from_struct (GESTimeline * timeline,
|
||||||
|
GstStructure * structure,
|
||||||
|
GError ** error);
|
||||||
|
|
||||||
|
GESAsset * _ges_get_asset_from_timeline (GESTimeline * timeline,
|
||||||
|
GType type,
|
||||||
|
const gchar * id);
|
||||||
|
GESLayer * _ges_get_layer_by_priority (GESTimeline * timeline,
|
||||||
|
gint priority);
|
||||||
|
|
||||||
|
#endif /* __GES_STRUCTURED_INTERFACE__*/
|
|
@ -28,6 +28,8 @@
|
||||||
#include <gst/validate/validate.h>
|
#include <gst/validate/validate.h>
|
||||||
#include <gst/validate/gst-validate-scenario.h>
|
#include <gst/validate/gst-validate-scenario.h>
|
||||||
#include <gst/validate/gst-validate-utils.h>
|
#include <gst/validate/gst-validate-utils.h>
|
||||||
|
#include "ges-internal.h"
|
||||||
|
#include "ges-structured-interface.h"
|
||||||
|
|
||||||
#define MONITOR_ON_PIPELINE "validate-monitor"
|
#define MONITOR_ON_PIPELINE "validate-monitor"
|
||||||
#define RUNNER_ON_PIPELINE "runner-monitor"
|
#define RUNNER_ON_PIPELINE "runner-monitor"
|
||||||
|
@ -42,35 +44,6 @@ get_timeline (GstValidateScenario * scenario)
|
||||||
return timeline;
|
return timeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
_set_child_property (GstValidateScenario * scenario, GstValidateAction * action)
|
|
||||||
{
|
|
||||||
const GValue *value;
|
|
||||||
GESTimeline *timeline;
|
|
||||||
GESTimelineElement *element;
|
|
||||||
const gchar *property_name, *element_name;
|
|
||||||
|
|
||||||
element_name = gst_structure_get_string (action->structure, "element-name");
|
|
||||||
|
|
||||||
timeline = get_timeline (scenario);
|
|
||||||
g_return_val_if_fail (timeline, FALSE);
|
|
||||||
|
|
||||||
element = ges_timeline_get_element (timeline, element_name);
|
|
||||||
g_return_val_if_fail (GES_IS_TRACK_ELEMENT (element), FALSE);
|
|
||||||
|
|
||||||
property_name = gst_structure_get_string (action->structure, "property");
|
|
||||||
value = gst_structure_get_value (action->structure, "value");
|
|
||||||
|
|
||||||
GST_DEBUG ("%s Setting %s property to %p",
|
|
||||||
element->name, property_name, value);
|
|
||||||
ges_track_element_set_child_property (GES_TRACK_ELEMENT (element),
|
|
||||||
property_name, (GValue *) value);
|
|
||||||
|
|
||||||
g_object_unref (timeline);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
_serialize_project (GstValidateScenario * scenario, GstValidateAction * action)
|
_serialize_project (GstValidateScenario * scenario, GstValidateAction * action)
|
||||||
{
|
{
|
||||||
|
@ -124,25 +97,6 @@ beach:
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GESAsset *
|
|
||||||
_get_asset (GESTimeline * timeline, GType type, const gchar * id)
|
|
||||||
{
|
|
||||||
GESAsset *asset;
|
|
||||||
GError *error = NULL;
|
|
||||||
GESProject *project = ges_timeline_get_project (timeline);
|
|
||||||
|
|
||||||
asset = ges_project_create_asset_sync (project, id, type, &error);
|
|
||||||
if (!asset || error) {
|
|
||||||
GST_ERROR
|
|
||||||
("There was an error requesting the asset with id %s and type %s (%s)",
|
|
||||||
id, g_type_name (type), error ? error->message : "unknown");
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return asset;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
_add_asset (GstValidateScenario * scenario, GstValidateAction * action)
|
_add_asset (GstValidateScenario * scenario, GstValidateAction * action)
|
||||||
{
|
{
|
||||||
|
@ -170,7 +124,7 @@ _add_asset (GstValidateScenario * scenario, GstValidateAction * action)
|
||||||
goto beach;
|
goto beach;
|
||||||
}
|
}
|
||||||
|
|
||||||
asset = _get_asset (timeline, type, id);
|
asset = _ges_get_asset_from_timeline (timeline, type, id);
|
||||||
|
|
||||||
if (!asset) {
|
if (!asset) {
|
||||||
res = FALSE;
|
res = FALSE;
|
||||||
|
@ -185,28 +139,6 @@ beach:
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unref after usage */
|
|
||||||
static GESLayer *
|
|
||||||
_get_layer_by_priority (GESTimeline * timeline, gint priority)
|
|
||||||
{
|
|
||||||
GList *layers, *tmp;
|
|
||||||
GESLayer *layer = NULL;
|
|
||||||
|
|
||||||
layers = ges_timeline_get_layers (timeline);
|
|
||||||
for (tmp = layers; tmp; tmp = tmp->next) {
|
|
||||||
GESLayer *tmp_layer = GES_LAYER (tmp->data);
|
|
||||||
guint tmp_priority;
|
|
||||||
g_object_get (tmp_layer, "priority", &tmp_priority, NULL);
|
|
||||||
if ((gint) tmp_priority == priority) {
|
|
||||||
layer = gst_object_ref (tmp_layer);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g_list_free_full (layers, gst_object_unref);
|
|
||||||
return layer;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
_add_layer (GstValidateScenario * scenario, GstValidateAction * action)
|
_add_layer (GstValidateScenario * scenario, GstValidateAction * action)
|
||||||
{
|
{
|
||||||
|
@ -220,7 +152,7 @@ _add_layer (GstValidateScenario * scenario, GstValidateAction * action)
|
||||||
goto beach;
|
goto beach;
|
||||||
}
|
}
|
||||||
|
|
||||||
layer = _get_layer_by_priority (timeline, priority);
|
layer = _ges_get_layer_by_priority (timeline, priority);
|
||||||
|
|
||||||
if (layer != NULL) {
|
if (layer != NULL) {
|
||||||
GST_ERROR
|
GST_ERROR
|
||||||
|
@ -258,7 +190,7 @@ _remove_layer (GstValidateScenario * scenario, GstValidateAction * action)
|
||||||
goto beach;
|
goto beach;
|
||||||
}
|
}
|
||||||
|
|
||||||
layer = _get_layer_by_priority (timeline, priority);
|
layer = _ges_get_layer_by_priority (timeline, priority);
|
||||||
|
|
||||||
if (layer) {
|
if (layer) {
|
||||||
res = ges_timeline_remove_layer (timeline, layer);
|
res = ges_timeline_remove_layer (timeline, layer);
|
||||||
|
@ -299,78 +231,6 @@ _remove_clip (GstValidateScenario * scenario, GstValidateAction * action)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
_add_clip (GstValidateScenario * scenario, GstValidateAction * action)
|
|
||||||
{
|
|
||||||
GESTimeline *timeline = get_timeline (scenario);
|
|
||||||
GESAsset *asset;
|
|
||||||
GESLayer *layer;
|
|
||||||
GESClip *clip;
|
|
||||||
gint layer_priority;
|
|
||||||
const gchar *name;
|
|
||||||
const gchar *asset_id;
|
|
||||||
const gchar *type_string;
|
|
||||||
GType type;
|
|
||||||
gboolean res = FALSE;
|
|
||||||
GstClockTime duration = 1 * GST_SECOND, inpoint = 0, start =
|
|
||||||
GST_CLOCK_TIME_NONE;
|
|
||||||
|
|
||||||
gst_structure_get_int (action->structure, "layer-priority", &layer_priority);
|
|
||||||
name = gst_structure_get_string (action->structure, "name");
|
|
||||||
asset_id = gst_structure_get_string (action->structure, "asset-id");
|
|
||||||
type_string = gst_structure_get_string (action->structure, "type");
|
|
||||||
|
|
||||||
gst_validate_action_get_clocktime (scenario, action, "start", &start);
|
|
||||||
gst_validate_action_get_clocktime (scenario, action, "inpoint", &inpoint);
|
|
||||||
gst_validate_action_get_clocktime (scenario, action, "duration", &duration);
|
|
||||||
|
|
||||||
gst_validate_printf (action, "Adding clip from asset of type %s with ID %s"
|
|
||||||
" wanted name: %s"
|
|
||||||
" -- start: %" GST_TIME_FORMAT
|
|
||||||
", inpoint: %" GST_TIME_FORMAT
|
|
||||||
", duration: %" GST_TIME_FORMAT "\n",
|
|
||||||
type_string, asset_id, name,
|
|
||||||
GST_TIME_ARGS (start), GST_TIME_ARGS (inpoint), GST_TIME_ARGS (duration));
|
|
||||||
|
|
||||||
if (!(type = g_type_from_name (type_string))) {
|
|
||||||
GST_ERROR ("This type doesn't exist : %s", type_string);
|
|
||||||
goto beach;
|
|
||||||
}
|
|
||||||
|
|
||||||
asset = _get_asset (timeline, type, asset_id);
|
|
||||||
if (!asset) {
|
|
||||||
res = FALSE;
|
|
||||||
|
|
||||||
goto beach;
|
|
||||||
}
|
|
||||||
|
|
||||||
layer = _get_layer_by_priority (timeline, layer_priority);
|
|
||||||
|
|
||||||
if (!layer) {
|
|
||||||
GST_ERROR ("No layer with priority %d", layer_priority);
|
|
||||||
goto beach;
|
|
||||||
}
|
|
||||||
|
|
||||||
clip = ges_layer_add_asset (layer, asset, start, inpoint, duration,
|
|
||||||
GES_TRACK_TYPE_UNKNOWN);
|
|
||||||
|
|
||||||
if (clip) {
|
|
||||||
res = TRUE;
|
|
||||||
if (!ges_timeline_element_set_name (GES_TIMELINE_ELEMENT (clip), name)) {
|
|
||||||
res = FALSE;
|
|
||||||
GST_ERROR ("couldn't set name %s on clip with id %s", name, asset_id);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
GST_ERROR ("Couldn't add clip with id %s to layer with priority %d",
|
|
||||||
asset_id, layer_priority);
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_object_unref (layer);
|
|
||||||
|
|
||||||
beach:
|
|
||||||
g_object_unref (timeline);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
_edit_container (GstValidateScenario * scenario, GstValidateAction * action)
|
_edit_container (GstValidateScenario * scenario, GstValidateAction * action)
|
||||||
|
@ -559,7 +419,7 @@ _set_asset_on_element (GstValidateScenario * scenario,
|
||||||
gst_validate_printf (action, "Setting asset %s on element %s\n",
|
gst_validate_printf (action, "Setting asset %s on element %s\n",
|
||||||
id, element_name);
|
id, element_name);
|
||||||
|
|
||||||
asset = _get_asset (timeline, G_OBJECT_TYPE (element), id);
|
asset = _ges_get_asset_from_timeline (timeline, G_OBJECT_TYPE (element), id);
|
||||||
if (asset == NULL) {
|
if (asset == NULL) {
|
||||||
res = FALSE;
|
res = FALSE;
|
||||||
GST_ERROR ("Could not find asset: %s", id);
|
GST_ERROR ("Could not find asset: %s", id);
|
||||||
|
@ -574,68 +434,6 @@ beach:
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
_container_add_child (GstValidateScenario * scenario,
|
|
||||||
GstValidateAction * action)
|
|
||||||
{
|
|
||||||
GESAsset *asset;
|
|
||||||
GESContainer *container;
|
|
||||||
GESTimelineElement *child = NULL;
|
|
||||||
const gchar *container_name, *child_name, *child_type, *id;
|
|
||||||
|
|
||||||
gboolean res = TRUE;
|
|
||||||
GESTimeline *timeline = get_timeline (scenario);
|
|
||||||
|
|
||||||
container_name =
|
|
||||||
gst_structure_get_string (action->structure, "container-name");
|
|
||||||
container =
|
|
||||||
GES_CONTAINER (ges_timeline_get_element (timeline, container_name));
|
|
||||||
g_return_val_if_fail (GES_IS_CONTAINER (container), FALSE);
|
|
||||||
|
|
||||||
id = gst_structure_get_string (action->structure, "asset-id");
|
|
||||||
child_type = gst_structure_get_string (action->structure, "child-type");
|
|
||||||
|
|
||||||
if (id && child_type) {
|
|
||||||
asset = _get_asset (timeline, g_type_from_name (child_type), id);
|
|
||||||
|
|
||||||
if (asset == NULL) {
|
|
||||||
res = FALSE;
|
|
||||||
GST_ERROR ("Could not find asset: %s", id);
|
|
||||||
goto beach;
|
|
||||||
}
|
|
||||||
|
|
||||||
child = GES_TIMELINE_ELEMENT (ges_asset_extract (asset, NULL));
|
|
||||||
g_return_val_if_fail (GES_IS_TIMELINE_ELEMENT (child), FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
child_name = gst_structure_get_string (action->structure, "child-name");
|
|
||||||
if (!child && child_name) {
|
|
||||||
child = ges_timeline_get_element (timeline, child_name);
|
|
||||||
g_return_val_if_fail (GES_IS_TIMELINE_ELEMENT (child), FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!child) {
|
|
||||||
GST_ERROR_OBJECT (scenario, "Wong parametters, could not get a child");
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (child_name)
|
|
||||||
ges_timeline_element_set_name (child, child_name);
|
|
||||||
else
|
|
||||||
child_name = GES_TIMELINE_ELEMENT_NAME (child);
|
|
||||||
|
|
||||||
gst_validate_printf (action, "Adding child %s to container %s\n",
|
|
||||||
child_name, GES_TIMELINE_ELEMENT_NAME (container));
|
|
||||||
|
|
||||||
res = ges_container_add (container, child);
|
|
||||||
|
|
||||||
beach:
|
|
||||||
gst_object_unref (timeline);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
_container_remove_child (GstValidateScenario * scenario,
|
_container_remove_child (GstValidateScenario * scenario,
|
||||||
GstValidateAction * action)
|
GstValidateAction * action)
|
||||||
|
@ -732,71 +530,38 @@ done:
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
_add_remove_keyframe (GstValidateScenario * scenario,
|
_validate_action_execute (GstValidateScenario * scenario,
|
||||||
GstValidateAction * action)
|
GstValidateAction * action)
|
||||||
{
|
{
|
||||||
GESTrackElement *element;
|
GError *err = NULL;
|
||||||
|
|
||||||
gdouble value;
|
|
||||||
GstClockTime timestamp;
|
|
||||||
GstControlBinding *binding = NULL;
|
|
||||||
GstTimedValueControlSource *source = NULL;
|
|
||||||
gchar *element_name, *property_name;
|
|
||||||
|
|
||||||
gboolean ret = FALSE;
|
|
||||||
GESTimeline *timeline = get_timeline (scenario);
|
GESTimeline *timeline = get_timeline (scenario);
|
||||||
|
ActionFromStructureFunc func;
|
||||||
|
|
||||||
g_return_val_if_fail (gst_structure_get (action->structure,
|
if (gst_structure_has_name (action->structure, "add-keyframe") ||
|
||||||
"element-name", G_TYPE_STRING, &element_name,
|
gst_structure_has_name (action->structure, "remove-keyframe")) {
|
||||||
"property-name", G_TYPE_STRING, &property_name,
|
func = _ges_add_remove_keyframe_from_struct;
|
||||||
"value", G_TYPE_DOUBLE, &value, NULL), FALSE);
|
} else if (gst_structure_has_name (action->structure, "add-clip")) {
|
||||||
|
func = _ges_add_clip_from_struct;
|
||||||
gst_validate_action_get_clocktime (scenario, action, "timestamp", ×tamp);
|
} else if (gst_structure_has_name (action->structure, "container-add-child")) {
|
||||||
|
func = _ges_container_add_child_from_struct;
|
||||||
element =
|
} else if (gst_structure_has_name (action->structure, "set-child-property")) {
|
||||||
GES_TRACK_ELEMENT (ges_timeline_get_element (timeline, element_name));
|
func = _ges_set_child_property_from_struct;
|
||||||
g_return_val_if_fail (GES_IS_TRACK_ELEMENT (element), FALSE);
|
} else {
|
||||||
|
g_assert_not_reached ();
|
||||||
binding = ges_track_element_get_control_binding (element, property_name);
|
|
||||||
if (binding == NULL) {
|
|
||||||
GST_ERROR_OBJECT (scenario, "No control binding found for %s:%s"
|
|
||||||
" you should first set-control-binding on it",
|
|
||||||
element_name, property_name);
|
|
||||||
|
|
||||||
goto done;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g_object_get (binding, "control-source", &source, NULL);
|
if (!func (timeline, action->structure, &err)) {
|
||||||
|
GST_VALIDATE_REPORT (scenario,
|
||||||
|
g_quark_from_string ("scenario::execution-error"), err->message);
|
||||||
|
|
||||||
if (source == NULL) {
|
g_clear_error (&err);
|
||||||
GST_ERROR_OBJECT (scenario, "No control source found for %s:%s"
|
|
||||||
" you should first set-control-binding on it",
|
|
||||||
element_name, property_name);
|
|
||||||
|
|
||||||
goto done;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GST_IS_TIMED_VALUE_CONTROL_SOURCE (source)) {
|
|
||||||
GST_ERROR_OBJECT (scenario, "You can use add-keyframe"
|
|
||||||
" only on GstTimedValueControlSource not %s",
|
|
||||||
G_OBJECT_TYPE_NAME (source));
|
|
||||||
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!g_strcmp0 (action->type, "add-keyframe"))
|
|
||||||
ret = gst_timed_value_control_source_set (source, timestamp, value);
|
|
||||||
else
|
|
||||||
ret = gst_timed_value_control_source_unset (source, timestamp);
|
|
||||||
|
|
||||||
done:
|
|
||||||
gst_object_unref (timeline);
|
gst_object_unref (timeline);
|
||||||
if (source)
|
|
||||||
gst_object_unref (source);
|
|
||||||
g_free (element_name);
|
|
||||||
g_free (property_name);
|
|
||||||
|
|
||||||
return ret;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -991,8 +756,10 @@ ges_validate_register_action_types (void)
|
||||||
(GstValidateActionParameter []) {
|
(GstValidateActionParameter []) {
|
||||||
{
|
{
|
||||||
.name = "priority",
|
.name = "priority",
|
||||||
.description = "The priority of the new layer to add",
|
.description = "The priority of the new layer to add,"
|
||||||
.mandatory = TRUE,
|
"if not specified, the new layer will be"
|
||||||
|
" appended to the timeline",
|
||||||
|
.mandatory = FALSE,
|
||||||
NULL
|
NULL
|
||||||
},
|
},
|
||||||
{ NULL }
|
{ NULL }
|
||||||
|
@ -1018,7 +785,7 @@ ges_validate_register_action_types (void)
|
||||||
},
|
},
|
||||||
"Allows to remove a layer from the current timeline", GST_VALIDATE_ACTION_TYPE_NONE);
|
"Allows to remove a layer from the current timeline", GST_VALIDATE_ACTION_TYPE_NONE);
|
||||||
|
|
||||||
gst_validate_register_action_type ("add-clip", "ges", _add_clip,
|
gst_validate_register_action_type ("add-clip", "ges", _validate_action_execute,
|
||||||
(GstValidateActionParameter []) {
|
(GstValidateActionParameter []) {
|
||||||
{
|
{
|
||||||
.name = "name",
|
.name = "name",
|
||||||
|
@ -1087,7 +854,7 @@ ges_validate_register_action_types (void)
|
||||||
{NULL}
|
{NULL}
|
||||||
}, "serializes a project", GST_VALIDATE_ACTION_TYPE_NONE);
|
}, "serializes a project", GST_VALIDATE_ACTION_TYPE_NONE);
|
||||||
|
|
||||||
gst_validate_register_action_type ("set-child-property", "ges", _set_child_property,
|
gst_validate_register_action_type ("set-child-property", "ges", _validate_action_execute,
|
||||||
(GstValidateActionParameter []) {
|
(GstValidateActionParameter []) {
|
||||||
{
|
{
|
||||||
.name = "element-name",
|
.name = "element-name",
|
||||||
|
@ -1162,7 +929,7 @@ ges_validate_register_action_types (void)
|
||||||
}, "Sets restriction caps on tracks of a specific type.", GST_VALIDATE_ACTION_TYPE_NONE);
|
}, "Sets restriction caps on tracks of a specific type.", GST_VALIDATE_ACTION_TYPE_NONE);
|
||||||
|
|
||||||
|
|
||||||
gst_validate_register_action_type ("container-add-child", "ges", _container_add_child,
|
gst_validate_register_action_type ("container-add-child", "ges", _validate_action_execute,
|
||||||
(GstValidateActionParameter []) {
|
(GstValidateActionParameter []) {
|
||||||
{
|
{
|
||||||
.name = "container-name",
|
.name = "container-name",
|
||||||
|
@ -1252,7 +1019,7 @@ ges_validate_register_action_types (void)
|
||||||
}, "Adds a GstControlSource on @element-name::@property-name"
|
}, "Adds a GstControlSource on @element-name::@property-name"
|
||||||
" allowing you to then add keyframes on that property.", GST_VALIDATE_ACTION_TYPE_NONE);
|
" allowing you to then add keyframes on that property.", GST_VALIDATE_ACTION_TYPE_NONE);
|
||||||
|
|
||||||
gst_validate_register_action_type ("add-keyframe", "ges", _add_remove_keyframe,
|
gst_validate_register_action_type ("add-keyframe", "ges", _validate_action_execute,
|
||||||
(GstValidateActionParameter []) {
|
(GstValidateActionParameter []) {
|
||||||
{
|
{
|
||||||
.name = "element-name",
|
.name = "element-name",
|
||||||
|
@ -1281,7 +1048,7 @@ ges_validate_register_action_types (void)
|
||||||
{NULL}
|
{NULL}
|
||||||
}, "Remove a child from @container-name.", GST_VALIDATE_ACTION_TYPE_NONE);
|
}, "Remove a child from @container-name.", GST_VALIDATE_ACTION_TYPE_NONE);
|
||||||
|
|
||||||
gst_validate_register_action_type ("remove-keyframe", "ges", _add_remove_keyframe,
|
gst_validate_register_action_type ("remove-keyframe", "ges", _validate_action_execute,
|
||||||
(GstValidateActionParameter []) {
|
(GstValidateActionParameter []) {
|
||||||
{
|
{
|
||||||
.name = "element-name",
|
.name = "element-name",
|
||||||
|
|
Loading…
Reference in a new issue