summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Popa <stefanpopa2209@gmail.com>2017-08-22 14:23:45 +0000
committerThibault Saunier <thibault.saunier@osg.samsung.com>2017-08-26 11:28:42 -0300
commit3012516b5b79da18a49f1625a03f86ec954fc48b (patch)
treecbf9bac24b8b26ad37bb9cd42fff9b1c254fbbbf
parentc3f332e51b11527b6a867f321b8138c6f9fe90df (diff)
xml-formatter: Save encoder and muxer advanced settings
Added support for saving/loading encoder and muxer advanced settings. Differential Revision: https://phabricator.freedesktop.org/D1837
-rw-r--r--ges/ges-base-xml-formatter.c98
-rw-r--r--ges/ges-internal.h8
-rw-r--r--ges/ges-xml-formatter.c86
3 files changed, 164 insertions, 28 deletions
diff --git a/ges/ges-base-xml-formatter.c b/ges/ges-base-xml-formatter.c
index 63284ec058..ede45c8d9b 100644
--- a/ges/ges-base-xml-formatter.c
+++ b/ges/ges-base-xml-formatter.c
@@ -792,12 +792,49 @@ done:
_loading_done (self);
}
+GstElement *
+get_element_for_encoding_profile (GstEncodingProfile * prof,
+ GstElementFactoryListType type)
+{
+ GstEncodingProfile *prof_copy;
+ GstElement *encodebin;
+ GList *tmp;
+ GstElement *element = NULL;
+
+ prof_copy = gst_encoding_profile_copy (prof);
+
+ gst_encoding_profile_set_presence (prof_copy, 1);
+ gst_encoding_profile_set_preset (prof_copy, NULL);
+
+ encodebin = gst_element_factory_make ("encodebin", NULL);
+ g_object_set (encodebin, "profile", prof_copy, NULL);
+
+ GST_OBJECT_LOCK (encodebin);
+ for (tmp = GST_BIN (encodebin)->children; tmp; tmp = tmp->next) {
+ GstElementFactory *factory;
+ factory = gst_element_get_factory (GST_ELEMENT (tmp->data));
+
+ if (factory && gst_element_factory_list_is_type (factory, type)) {
+ element = GST_ELEMENT (tmp->data);
+ gst_object_ref (element);
+ break;
+ }
+ }
+ GST_OBJECT_UNLOCK (encodebin);
+ gst_object_unref (encodebin);
+
+ gst_encoding_profile_unref (prof_copy);
+
+ return element;
+}
+
static GstEncodingProfile *
_create_profile (GESBaseXmlFormatter * self,
const gchar * type, const gchar * parent, const gchar * name,
const gchar * description, GstCaps * format, const gchar * preset,
- const gchar * preset_name, gint id, guint presence, GstCaps * restriction,
- guint pass, gboolean variableframerate, gboolean enabled)
+ GstStructure * preset_properties, const gchar * preset_name, gint id,
+ guint presence, GstCaps * restriction, guint pass,
+ gboolean variableframerate, gboolean enabled)
{
GstEncodingProfile *profile = NULL;
@@ -805,8 +842,6 @@ _create_profile (GESBaseXmlFormatter * self,
profile = GST_ENCODING_PROFILE (gst_encoding_container_profile_new (name,
description, format, preset));
gst_encoding_profile_set_preset_name (profile, preset_name);
-
- return profile;
} else if (!g_strcmp0 (type, "video")) {
GstEncodingVideoProfile *sprof = gst_encoding_video_profile_new (format,
preset, restriction, presence);
@@ -824,10 +859,43 @@ _create_profile (GESBaseXmlFormatter * self,
return NULL;
}
- gst_encoding_profile_set_name (profile, name);
- gst_encoding_profile_set_enabled (profile, enabled);
- gst_encoding_profile_set_description (profile, description);
- gst_encoding_profile_set_preset_name (profile, preset_name);
+ if (!g_strcmp0 (type, "video") || !g_strcmp0 (type, "audio")) {
+ gst_encoding_profile_set_name (profile, name);
+ gst_encoding_profile_set_enabled (profile, enabled);
+ gst_encoding_profile_set_description (profile, description);
+ gst_encoding_profile_set_preset_name (profile, preset_name);
+ }
+
+ if (preset && preset_properties) {
+ GstElement *element;
+
+ if (!g_strcmp0 (type, "container")) {
+ element = get_element_for_encoding_profile (profile,
+ GST_ELEMENT_FACTORY_TYPE_MUXER);
+ } else {
+ element = get_element_for_encoding_profile (profile,
+ GST_ELEMENT_FACTORY_TYPE_ENCODER);
+ }
+
+ if (G_UNLIKELY (!element || !GST_IS_PRESET (element))) {
+ GST_WARNING_OBJECT (element, "Element is not a GstPreset");
+ goto done;
+ }
+
+ /* If the preset doesn't exist on the system, create it */
+ if (!gst_preset_load_preset (GST_PRESET (element), preset)) {
+ gst_structure_foreach (preset_properties,
+ (GstStructureForeachFunc) set_property_foreach, element);
+
+ if (!gst_preset_save_preset (GST_PRESET (element), preset)) {
+ GST_WARNING_OBJECT (element, "Could not save preset %s", preset);
+ }
+ }
+
+ done:
+ if (element)
+ gst_object_unref (element);
+ }
return profile;
}
@@ -1236,9 +1304,10 @@ void
ges_base_xml_formatter_add_encoding_profile (GESBaseXmlFormatter * self,
const gchar * type, const gchar * parent, const gchar * name,
const gchar * description, GstCaps * format, const gchar * preset,
- const gchar * preset_name, guint id, guint presence, GstCaps * restriction,
- guint pass, gboolean variableframerate, GstStructure * properties,
- gboolean enabled, GError ** error)
+ GstStructure * preset_properties, const gchar * preset_name, guint id,
+ guint presence, GstCaps * restriction, guint pass,
+ gboolean variableframerate, GstStructure * properties, gboolean enabled,
+ GError ** error)
{
const GList *tmp;
GstEncodingProfile *profile;
@@ -1251,8 +1320,8 @@ ges_base_xml_formatter_add_encoding_profile (GESBaseXmlFormatter * self,
if (parent == NULL) {
profile =
_create_profile (self, type, parent, name, description, format, preset,
- preset_name, id, presence, restriction, pass, variableframerate,
- enabled);
+ preset_properties, preset_name, id, presence, restriction, pass,
+ variableframerate, enabled);
ges_project_add_encoding_profile (GES_FORMATTER (self)->project, profile);
gst_object_unref (profile);
@@ -1285,7 +1354,8 @@ ges_base_xml_formatter_add_encoding_profile (GESBaseXmlFormatter * self,
profile =
_create_profile (self, type, parent, name, description, format, preset,
- preset_name, id, presence, restriction, pass, variableframerate, enabled);
+ preset_properties, preset_name, id, presence, restriction, pass,
+ variableframerate, enabled);
if (profile == NULL)
goto done;
diff --git a/ges/ges-internal.h b/ges/ges-internal.h
index 508b099c2b..ba96742eec 100644
--- a/ges/ges-internal.h
+++ b/ges/ges-internal.h
@@ -20,8 +20,8 @@
#ifndef __GES_INTERNAL_H__
#define __GES_INTERNAL_H__
-
#include <gst/gst.h>
+#include <gst/pbutils/encoding-profile.h>
#include <gio/gio.h>
#include "ges-timeline.h"
@@ -256,6 +256,7 @@ G_GNUC_INTERNAL void ges_base_xml_formatter_add_encoding_profile(GESBaseXmlForma
const gchar * description,
GstCaps * format,
const gchar * preset,
+ GstStructure * preset_properties,
const gchar * preset_name,
guint id,
guint presence,
@@ -297,7 +298,10 @@ G_GNUC_INTERNAL void ges_base_xml_formatter_add_control_binding (GESBaseXmlForma
G_GNUC_INTERNAL gboolean set_property_foreach (GQuark field_id,
const GValue * value,
- GObject * object);;
+ GObject * object);
+
+G_GNUC_INTERNAL GstElement * get_element_for_encoding_profile (GstEncodingProfile *prof,
+ GstElementFactoryListType type);
/* Function to initialise GES */
G_GNUC_INTERNAL void _init_standard_transition_assets (void);
diff --git a/ges/ges-xml-formatter.c b/ges/ges-xml-formatter.c
index 28ddf480cc..bf2f9c7816 100644
--- a/ges/ges-xml-formatter.c
+++ b/ges/ges-xml-formatter.c
@@ -141,8 +141,9 @@ _parse_encoding_profile (GMarkupParseContext * context,
const gchar ** attribute_values, GESXmlFormatter * self, GError ** error)
{
GstCaps *capsformat = NULL;
- const gchar *name, *description, *type, *preset = NULL, *preset_name =
- NULL, *format;
+ GstStructure *preset_properties = NULL;
+ const gchar *name, *description, *type, *preset = NULL,
+ *str_preset_properties = NULL, *preset_name = NULL, *format;
if (!g_markup_collect_attributes (element_name, attribute_names,
attribute_values, error,
@@ -150,6 +151,7 @@ _parse_encoding_profile (GMarkupParseContext * context,
G_MARKUP_COLLECT_STRING, "description", &description,
G_MARKUP_COLLECT_STRING, "type", &type,
COLLECT_STR_OPT, "preset", &preset,
+ COLLECT_STR_OPT, "preset-properties", &str_preset_properties,
COLLECT_STR_OPT, "preset-name", &preset_name,
COLLECT_STR_OPT, "format", &format, G_MARKUP_COLLECT_INVALID))
return;
@@ -157,9 +159,18 @@ _parse_encoding_profile (GMarkupParseContext * context,
if (format)
capsformat = gst_caps_from_string (format);
+ if (str_preset_properties) {
+ preset_properties = gst_structure_from_string (str_preset_properties, NULL);
+ if (preset_properties == NULL) {
+ g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
+ "element '%s', Wrong preset-properties format.", element_name);
+ return;
+ }
+ }
+
ges_base_xml_formatter_add_encoding_profile (GES_BASE_XML_FORMATTER (self),
- type, NULL, name, description, capsformat, preset, preset_name, 0, 0,
- NULL, 0, FALSE, NULL, TRUE, error);
+ type, NULL, name, description, capsformat, preset, preset_properties,
+ preset_name, 0, 0, NULL, 0, FALSE, NULL, TRUE, error);
}
static inline void
@@ -170,10 +181,11 @@ _parse_stream_profile (GMarkupParseContext * context,
gboolean variableframerate = FALSE, enabled = TRUE;
guint id = 0, presence = 0, pass = 0;
GstCaps *format_caps = NULL, *restriction_caps = NULL;
+ GstStructure *preset_properties = NULL;
const gchar *parent, *strid, *type, *strpresence, *format = NULL,
- *name = NULL, *description = NULL, *preset, *preset_name =
- NULL, *restriction = NULL, *strpass = NULL, *strvariableframerate = NULL,
- *strenabled = NULL;
+ *name = NULL, *description = NULL, *preset,
+ *str_preset_properties = NULL, *preset_name = NULL, *restriction = NULL,
+ *strpass = NULL, *strvariableframerate = NULL, *strenabled = NULL;
/* FIXME Looks like there is a bug in that function, if we put the parent
* at the beginning it set %NULL and not the real value... :/ */
@@ -186,6 +198,7 @@ _parse_stream_profile (GMarkupParseContext * context,
COLLECT_STR_OPT, "name", &name,
COLLECT_STR_OPT, "description", &description,
COLLECT_STR_OPT, "preset", &preset,
+ COLLECT_STR_OPT, "preset-properties", &str_preset_properties,
COLLECT_STR_OPT, "preset-name", &preset_name,
COLLECT_STR_OPT, "restriction", &restriction,
COLLECT_STR_OPT, "pass", &strpass,
@@ -205,6 +218,12 @@ _parse_stream_profile (GMarkupParseContext * context,
goto convertion_failed;
}
+ if (str_preset_properties) {
+ preset_properties = gst_structure_from_string (str_preset_properties, NULL);
+ if (preset_properties == NULL)
+ goto convertion_failed;
+ }
+
if (strpass) {
pass = g_ascii_strtoll (strpass, NULL, 10);
if (errno)
@@ -230,9 +249,12 @@ _parse_stream_profile (GMarkupParseContext * context,
restriction_caps = gst_caps_from_string (restriction);
ges_base_xml_formatter_add_encoding_profile (GES_BASE_XML_FORMATTER (self),
- type, parent, name, description, format_caps, preset, preset_name, id,
- presence, restriction_caps, pass, variableframerate, NULL, enabled,
- error);
+ type, parent, name, description, format_caps, preset, preset_properties,
+ preset_name, id, presence, restriction_caps, pass, variableframerate,
+ NULL, enabled, error);
+
+ if (preset_properties)
+ gst_structure_free (preset_properties);
return;
@@ -1363,9 +1385,26 @@ _save_stream_profiles (GESXmlFormatter * self, GString * str,
description));
preset = gst_encoding_profile_get_preset (sprof);
- if (preset)
+ if (preset) {
+ GstElement *encoder;
+
append_escaped (str, g_markup_printf_escaped ("preset='%s' ", preset));
+ encoder = get_element_for_encoding_profile (sprof,
+ GST_ELEMENT_FACTORY_TYPE_ENCODER);
+ if (encoder) {
+ if (GST_IS_PRESET (encoder) &&
+ gst_preset_load_preset (GST_PRESET (encoder), preset)) {
+
+ gchar *settings = _serialize_properties (G_OBJECT (encoder), NULL);
+ append_escaped (str,
+ g_markup_printf_escaped ("preset-properties='%s' ", settings));
+ g_free (settings);
+ }
+ gst_object_unref (encoder);
+ }
+ }
+
preset_name = gst_encoding_profile_get_preset_name (sprof);
if (preset_name)
append_escaped (str, g_markup_printf_escaped ("preset-name='%s' ",
@@ -1416,10 +1455,33 @@ _save_encoding_profiles (GESXmlFormatter * self, GString * str,
(" <encoding-profile name='%s' description='%s' type='%s' ",
profname, profdesc, proftype));
- if (profpreset)
+ if (profpreset) {
+ GstElement *element;
+
append_escaped (str, g_markup_printf_escaped ("preset='%s' ",
profpreset));
+ if (GST_IS_ENCODING_CONTAINER_PROFILE (prof)) {
+ element = get_element_for_encoding_profile (prof,
+ GST_ELEMENT_FACTORY_TYPE_MUXER);
+ } else {
+ element = get_element_for_encoding_profile (prof,
+ GST_ELEMENT_FACTORY_TYPE_ENCODER);
+ }
+
+ if (element) {
+ if (GST_IS_PRESET (element) &&
+ gst_preset_load_preset (GST_PRESET (element), profpreset)) {
+ gchar *settings = _serialize_properties (G_OBJECT (element), NULL);
+ append_escaped (str,
+ g_markup_printf_escaped ("preset-properties='%s' ", settings));
+ g_free (settings);
+ }
+ gst_object_unref (element);
+ }
+
+ }
+
if (profpresetname)
append_escaped (str, g_markup_printf_escaped ("preset-name='%s' ",
profpresetname));