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
This commit is contained in:
Stefan Popa 2017-08-22 14:23:45 +00:00 committed by Thibault Saunier
parent ce4d2d8102
commit 6b67ff61ad
3 changed files with 164 additions and 28 deletions

View file

@ -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;

View file

@ -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"
@ -258,6 +258,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,
@ -299,7 +300,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);

View file

@ -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));