mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 19:51:11 +00:00
ges: Use a ges:
uri to define timeline from description
This way the command line formatter actually uses an URI and not an ugly hack where were passing a random string instead of an URI. This also allows the `gessrc` element to handle timelines described in its URI meaning that you can now use, for example: gst-play-1.0 "ges:+test-clip blue d=4.0 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/227>
This commit is contained in:
parent
7499d41213
commit
70e3b8ae2a
6 changed files with 154 additions and 70 deletions
|
@ -660,26 +660,74 @@ _parse_structures (const gchar * string)
|
|||
return parser;
|
||||
}
|
||||
|
||||
/* @uri: (transfer full): */
|
||||
static gchar *
|
||||
get_timeline_desc_from_uri (GstUri * uri)
|
||||
{
|
||||
gchar *res, *path;
|
||||
|
||||
if (!uri)
|
||||
return NULL;
|
||||
|
||||
/* Working around parser requiring a space to begin with */
|
||||
path = gst_uri_get_path (uri);
|
||||
res = g_strconcat (" ", path, NULL);
|
||||
g_free (path);
|
||||
|
||||
gst_uri_unref (uri);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_can_load (GESFormatter * dummy_formatter, const gchar * string,
|
||||
GError ** error)
|
||||
{
|
||||
gboolean res = FALSE;
|
||||
GstUri *uri;
|
||||
const gchar *scheme;
|
||||
gchar *timeline_desc = NULL;
|
||||
GESStructureParser *parser;
|
||||
|
||||
if (string == NULL)
|
||||
if (string == NULL) {
|
||||
GST_ERROR ("No URI!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
parser = _parse_structures (string);
|
||||
uri = gst_uri_from_string (string);
|
||||
if (!uri) {
|
||||
GST_INFO_OBJECT (dummy_formatter, "Wrong uri: %s", string);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
scheme = gst_uri_get_scheme (uri);
|
||||
if (!g_strcmp0 (scheme, "ges:")) {
|
||||
GST_INFO_OBJECT (dummy_formatter, "Wrong scheme: %s", string);
|
||||
gst_uri_unref (uri);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
timeline_desc = get_timeline_desc_from_uri (uri);
|
||||
parser = _parse_structures (timeline_desc);
|
||||
if (parser->structures)
|
||||
res = TRUE;
|
||||
|
||||
gst_object_unref (parser);
|
||||
g_free (timeline_desc);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_set_project_loaded (GESFormatter * self)
|
||||
{
|
||||
ges_project_set_loaded (self->project, self, NULL);
|
||||
gst_object_unref (self);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_load (GESFormatter * self, GESTimeline * timeline, const gchar * string,
|
||||
GError ** error)
|
||||
|
@ -687,7 +735,11 @@ _load (GESFormatter * self, GESTimeline * timeline, const gchar * string,
|
|||
guint i;
|
||||
GList *tmp;
|
||||
GError *err;
|
||||
GESStructureParser *parser = _parse_structures (string);
|
||||
gchar *timeline_desc =
|
||||
get_timeline_desc_from_uri (gst_uri_from_string (string));
|
||||
GESStructureParser *parser = _parse_structures (timeline_desc);
|
||||
|
||||
g_free (timeline_desc);
|
||||
|
||||
err = ges_structure_parser_get_error (parser);
|
||||
|
||||
|
@ -719,6 +771,8 @@ _load (GESFormatter * self, GESTimeline * timeline, const gchar * string,
|
|||
|
||||
gst_object_unref (parser);
|
||||
|
||||
ges_idle_add ((GSourceFunc) _set_project_loaded, g_object_ref (self), NULL);
|
||||
|
||||
return TRUE;
|
||||
|
||||
fail:
|
||||
|
|
|
@ -87,10 +87,31 @@ ges_src_uri_get_uri (GstURIHandler * handler)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
ges_src_uri_set_uri (GstURIHandler * handler, const gchar * uri,
|
||||
ges_src_uri_set_uri (GstURIHandler * handler, const gchar * uristr,
|
||||
GError ** error)
|
||||
{
|
||||
return TRUE;
|
||||
gboolean res = FALSE;
|
||||
GstUri *uri = gst_uri_from_string (uristr);
|
||||
GESProject *project = NULL;
|
||||
GESTimeline *timeline = NULL;
|
||||
|
||||
if (!gst_uri_get_path (uri)) {
|
||||
GST_INFO_OBJECT (handler, "User need to specify the timeline");
|
||||
res = TRUE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
project = ges_project_new (uristr);
|
||||
timeline = (GESTimeline *) ges_asset_extract (GES_ASSET (project), NULL);
|
||||
|
||||
if (timeline)
|
||||
res = ges_base_bin_set_timeline (GES_BASE_BIN (handler), timeline);
|
||||
|
||||
done:
|
||||
gst_uri_unref (uri);
|
||||
gst_clear_object (&project);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -716,7 +716,6 @@ static gboolean
|
|||
_create_timeline (GESLauncher * self, const gchar * serialized_timeline,
|
||||
const gchar * proj_uri, gboolean validate)
|
||||
{
|
||||
GESLauncherParsedOptions *opts = &self->priv->parsed_options;
|
||||
GESProject *project;
|
||||
|
||||
GError *error = NULL;
|
||||
|
@ -724,37 +723,7 @@ _create_timeline (GESLauncher * self, const gchar * serialized_timeline,
|
|||
if (proj_uri != NULL) {
|
||||
project = ges_project_new (proj_uri);
|
||||
} else if (!validate) {
|
||||
GString *timeline_str = g_string_new (serialized_timeline);
|
||||
|
||||
if (!strstr (serialized_timeline, "+track")) {
|
||||
GString *track_def;
|
||||
|
||||
if (opts->track_types & GES_TRACK_TYPE_VIDEO) {
|
||||
track_def = g_string_new (" +track video ");
|
||||
|
||||
if (opts->video_track_caps)
|
||||
g_string_append_printf (track_def, " restrictions=[%s] ",
|
||||
opts->video_track_caps);
|
||||
|
||||
g_string_prepend (timeline_str, track_def->str);
|
||||
g_string_free (track_def, TRUE);
|
||||
}
|
||||
|
||||
if (opts->track_types & GES_TRACK_TYPE_AUDIO) {
|
||||
track_def = g_string_new (" +track audio ");
|
||||
|
||||
if (opts->audio_track_caps)
|
||||
g_string_append_printf (track_def, " restrictions=[%s] ",
|
||||
opts->audio_track_caps);
|
||||
|
||||
g_string_prepend (timeline_str, track_def->str);
|
||||
g_string_free (track_def, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
GST_INFO ("Launching timeline: `%s`", timeline_str->str);
|
||||
project = ges_project_new (timeline_str->str);
|
||||
g_string_free (timeline_str, TRUE);
|
||||
project = ges_project_new (serialized_timeline);
|
||||
} else {
|
||||
project = ges_project_new (NULL);
|
||||
}
|
||||
|
@ -1366,7 +1335,7 @@ _local_command_line (GApplication * application, gchar ** arguments[],
|
|||
|
||||
g_option_context_free (ctx);
|
||||
|
||||
opts->sanitized_timeline = sanitize_timeline_description (*arguments);
|
||||
opts->sanitized_timeline = sanitize_timeline_description (*arguments, opts);
|
||||
|
||||
if (!g_application_register (application, NULL, &error)) {
|
||||
*exit_status = 1;
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
|
||||
#include <ges/ges.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GES_TYPE_LAUNCHER ges_launcher_get_type()
|
||||
|
@ -28,35 +30,6 @@ G_BEGIN_DECLS
|
|||
typedef struct _GESLauncherPrivate GESLauncherPrivate;
|
||||
G_DECLARE_FINAL_TYPE(GESLauncher, ges_launcher, GES, LAUNCHER, GApplication);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gboolean mute;
|
||||
gboolean disable_mixing;
|
||||
gchar *save_path;
|
||||
gchar *save_only_path;
|
||||
gchar *load_path;
|
||||
GESTrackType track_types;
|
||||
gboolean needs_set_state;
|
||||
gboolean smartrender;
|
||||
gchar *scenario;
|
||||
gchar *testfile;
|
||||
gchar *format;
|
||||
gchar *outputuri;
|
||||
gchar *encoding_profile;
|
||||
gchar *videosink;
|
||||
gchar *audiosink;
|
||||
gboolean list_transitions;
|
||||
gboolean inspect_action_type;
|
||||
gchar *sanitized_timeline;
|
||||
gchar *video_track_caps;
|
||||
gchar *audio_track_caps;
|
||||
gboolean embed_nesteds;
|
||||
gboolean disable_validate;
|
||||
|
||||
gboolean ignore_eos;
|
||||
gboolean interactive;
|
||||
} GESLauncherParsedOptions;
|
||||
|
||||
struct _GESLauncher {
|
||||
GApplication parent;
|
||||
|
||||
|
|
|
@ -89,10 +89,12 @@ _sanitize_argument (gchar * arg, const gchar * prev_arg)
|
|||
}
|
||||
|
||||
gchar *
|
||||
sanitize_timeline_description (gchar ** args)
|
||||
sanitize_timeline_description (gchar ** args, GESLauncherParsedOptions * opts)
|
||||
{
|
||||
gint i;
|
||||
gchar *prev_arg = NULL;
|
||||
GString *track_def;
|
||||
GString *timeline_str;
|
||||
|
||||
gchar *string = g_strdup (" ");
|
||||
|
||||
|
@ -108,7 +110,41 @@ sanitize_timeline_description (gchar ** args)
|
|||
prev_arg = args[i];
|
||||
}
|
||||
|
||||
return string;
|
||||
if (strstr (string, "+track")) {
|
||||
gchar *res = g_strconcat ("ges:", string, NULL);
|
||||
g_free (string);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
timeline_str = g_string_new (string);
|
||||
g_free (string);
|
||||
|
||||
if (opts->track_types & GES_TRACK_TYPE_VIDEO) {
|
||||
track_def = g_string_new (" +track video ");
|
||||
|
||||
if (opts->video_track_caps)
|
||||
g_string_append_printf (track_def, " restrictions=[%s] ",
|
||||
opts->video_track_caps);
|
||||
|
||||
g_string_prepend (timeline_str, track_def->str);
|
||||
g_string_free (track_def, TRUE);
|
||||
}
|
||||
|
||||
if (opts->track_types & GES_TRACK_TYPE_AUDIO) {
|
||||
track_def = g_string_new (" +track audio ");
|
||||
|
||||
if (opts->audio_track_caps)
|
||||
g_string_append_printf (track_def, " restrictions=[%s] ",
|
||||
opts->audio_track_caps);
|
||||
|
||||
g_string_prepend (timeline_str, track_def->str);
|
||||
g_string_free (track_def, TRUE);
|
||||
}
|
||||
|
||||
g_string_prepend (timeline_str, "ges:");
|
||||
|
||||
return g_string_free (timeline_str, FALSE);
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
|
|
@ -21,7 +21,38 @@
|
|||
#include <gst/pbutils/pbutils.h>
|
||||
#include <gst/pbutils/encoding-profile.h>
|
||||
|
||||
gchar * sanitize_timeline_description (gchar **args);
|
||||
#pragma once
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gboolean mute;
|
||||
gboolean disable_mixing;
|
||||
gchar *save_path;
|
||||
gchar *save_only_path;
|
||||
gchar *load_path;
|
||||
GESTrackType track_types;
|
||||
gboolean needs_set_state;
|
||||
gboolean smartrender;
|
||||
gchar *scenario;
|
||||
gchar *testfile;
|
||||
gchar *format;
|
||||
gchar *outputuri;
|
||||
gchar *encoding_profile;
|
||||
gchar *videosink;
|
||||
gchar *audiosink;
|
||||
gboolean list_transitions;
|
||||
gboolean inspect_action_type;
|
||||
gchar *sanitized_timeline;
|
||||
gchar *video_track_caps;
|
||||
gchar *audio_track_caps;
|
||||
gboolean embed_nesteds;
|
||||
gboolean disable_validate;
|
||||
|
||||
gboolean ignore_eos;
|
||||
gboolean interactive;
|
||||
} GESLauncherParsedOptions;
|
||||
|
||||
gchar * sanitize_timeline_description (gchar **args, GESLauncherParsedOptions *opts);
|
||||
gboolean get_flags_from_string (GType type, const gchar * str_flags, guint *val);
|
||||
gchar * ensure_uri (const gchar * location);
|
||||
GstEncodingProfile * parse_encoding_profile (const gchar * format);
|
||||
|
|
Loading…
Reference in a new issue