From: Thibault Saunier Date: Mon, 18 May 2015 19:24:25 +0000 (+0200) Subject: ges: Enhance xges format versioning X-Git-Tag: 1.19.3~493^2~1206 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=241e809a81b0fc1a2a590882e7362b1eff420c0d;p=platform%2Fupstream%2Fgstreamer.git ges: Enhance xges format versioning Summary: Handle the fact that some new features can be added and that means generated files will not be fully understandable by older versions of the formatter. Make sure that we set the format version to 0.2 when we serialize the GstEncodingProfile.enabled property. Add some tests around that. + Fix a minor bug in the test-utils + Add a meta on the projects to tell in what format version a project has been serialized/parsed back API: GES_META_FORMAT_VERSION Depends on D178 Reviewers: Mathieu_Du Differential Revision: http://phabricator.freedesktop.org/D184 --- diff --git a/docs/libs/ges-sections.txt b/docs/libs/ges-sections.txt index 6283fbe..f6e728f 100644 --- a/docs/libs/ges-sections.txt +++ b/docs/libs/ges-sections.txt @@ -1035,6 +1035,7 @@ GES_META_FORMATTER_VERSION GES_META_FORMATTER_RANK GES_META_DESCRIPTION +GES_META_FORMAT_VERSION GESMetaContainerInterface diff --git a/ges/ges-formatter.c b/ges/ges-formatter.c index a053901..07fa4eb 100644 --- a/ges/ges-formatter.c +++ b/ges/ges-formatter.c @@ -92,6 +92,8 @@ _register_metas (GESExtractableInterface * iface, GObjectClass * class, GES_META_FORMATTER_VERSION, fclass->version); ges_meta_container_register_meta_uint (container, GES_META_READABLE, GES_META_FORMATTER_RANK, fclass->rank); + ges_meta_container_register_meta_string (container, GES_META_READ_WRITE, + GES_META_FORMAT_VERSION, NULL); return TRUE; } diff --git a/ges/ges-meta-container.h b/ges/ges-meta-container.h index 200dab5..bae3a04 100644 --- a/ges/ges-meta-container.h +++ b/ges/ges-meta-container.h @@ -102,6 +102,13 @@ G_BEGIN_DECLS */ #define GES_META_VOLUME_DEFAULT 1.0 +/** + * GES_META_FORMAT_VERSION: + * + * The version of the format in which a project is serialized + */ +#define GES_META_FORMAT_VERSION "format-version" + typedef struct _GESMetaContainer GESMetaContainer; typedef struct _GESMetaContainerInterface GESMetaContainerInterface; diff --git a/ges/ges-xml-formatter.c b/ges/ges-xml-formatter.c index 89d5173..9eded2e 100644 --- a/ges/ges-xml-formatter.c +++ b/ges/ges-xml-formatter.c @@ -32,8 +32,8 @@ G_DEFINE_TYPE (GESXmlFormatter, ges_xml_formatter, GES_TYPE_BASE_XML_FORMATTER); #define API_VERSION 0 -#define MINOR_VERSION 1 -#define VERSION 0.1 +#define MINOR_VERSION 2 +#define VERSION 0.2 #define COLLECT_STR_OPT (G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL) @@ -49,6 +49,8 @@ struct _GESXmlFormatterPrivate GHashTable *element_id; guint nbelements; + + guint min_version; }; static inline void @@ -56,8 +58,8 @@ _parse_ges_element (GMarkupParseContext * context, const gchar * element_name, const gchar ** attribute_names, const gchar ** attribute_values, GESXmlFormatter * self, GError ** error) { + guint api_version; const gchar *version, *properties; - guint api_version, min_version; gchar **split_version = NULL; @@ -84,8 +86,8 @@ _parse_ges_element (GMarkupParseContext * context, const gchar * element_name, if (errno || api_version != API_VERSION) goto stroull_failed; - min_version = g_ascii_strtoull (split_version[1], NULL, 10); - if (min_version > MINOR_VERSION) + self->priv->min_version = g_ascii_strtoull (split_version[1], NULL, 10); + if (self->priv->min_version > MINOR_VERSION) goto failed; _GET_PRIV (self)->ges_opened = TRUE; @@ -780,6 +782,15 @@ _parse_element_end (GMarkupParseContext * context, const gchar * element_name, gpointer self, GError ** error) { /*GESXmlFormatterPrivate *priv = _GET_PRIV (self); */ + if (g_strcmp0 (element_name, "ges") == 0 && GES_FORMATTER (self)->project) { + gchar *version = g_strdup_printf ("%d.%d", + API_VERSION, GES_XML_FORMATTER (self)->priv->min_version); + + ges_meta_container_set_string (GES_META_CONTAINER (GES_FORMATTER + (self)->project), GES_META_FORMAT_VERSION, version); + + g_free (version); + } } static void @@ -1272,8 +1283,8 @@ _save_timeline (GESXmlFormatter * self, GString * str, GESTimeline * timeline) } static void -_save_stream_profiles (GString * str, GstEncodingProfile * sprof, - const gchar * profilename, guint id) +_save_stream_profiles (GESXmlFormatter * self, GString * str, + GstEncodingProfile * sprof, const gchar * profilename, guint id) { gchar *tmpc; GstCaps *tmpcaps; @@ -1282,10 +1293,15 @@ _save_stream_profiles (GString * str, GstEncodingProfile * sprof, append_escaped (str, g_markup_printf_escaped (" priv->min_version = MAX (self->priv->min_version, 2); + } tmpcaps = gst_encoding_profile_get_format (sprof); if (tmpcaps) { @@ -1334,7 +1350,8 @@ _save_stream_profiles (GString * str, GstEncodingProfile * sprof, } static inline void -_save_encoding_profiles (GString * str, GESProject * project) +_save_encoding_profiles (GESXmlFormatter * self, GString * str, + GESProject * project) { GstCaps *profformat; const gchar *profname, *profdesc, *profpreset, *proftype, *profpresetname; @@ -1382,7 +1399,7 @@ _save_encoding_profiles (GString * str, GESProject * project) for (tmp2 = gst_encoding_container_profile_get_profiles (container_prof); tmp2; tmp2 = tmp2->next, i++) { GstEncodingProfile *sprof = (GstEncodingProfile *) tmp2->data; - _save_stream_profiles (str, sprof, profname, i); + _save_stream_profiles (self, str, sprof, profname, i); } } append_escaped (str, @@ -1396,16 +1413,17 @@ _save (GESFormatter * formatter, GESTimeline * timeline, GError ** error) GString *str; GESProject *project; + gchar *projstr = NULL, *version; gchar *properties = NULL, *metas = NULL; GESXmlFormatterPrivate *priv; priv = _GET_PRIV (formatter); + + priv->min_version = 1; project = formatter->project; str = priv->str = g_string_new (NULL); - g_string_append_printf (str, "\n", API_VERSION, - MINOR_VERSION); properties = _serialize_properties (G_OBJECT (project), NULL); metas = ges_meta_container_metas_to_string (GES_META_CONTAINER (project)); append_escaped (str, @@ -1415,7 +1433,7 @@ _save (GESFormatter * formatter, GESTimeline * timeline, GError ** error) g_free (metas); g_string_append (str, " \n"); - _save_encoding_profiles (str, project); + _save_encoding_profiles (GES_XML_FORMATTER (formatter), str, project); g_string_append (str, " \n"); g_string_append (str, " \n"); @@ -1425,6 +1443,22 @@ _save (GESFormatter * formatter, GESTimeline * timeline, GError ** error) _save_timeline (GES_XML_FORMATTER (formatter), str, timeline); g_string_append (str, "\n"); + projstr = g_strdup_printf ("\n", API_VERSION, + priv->min_version); + g_string_prepend (str, projstr); + g_free (projstr); + + ges_meta_container_set_int (GES_META_CONTAINER (project), + GES_META_FORMAT_VERSION, priv->min_version); + + version = g_strdup_printf ("%d.%d", API_VERSION, + GES_XML_FORMATTER (formatter)->priv->min_version); + + ges_meta_container_set_string (GES_META_CONTAINER (project), + GES_META_FORMAT_VERSION, version); + + g_free (version); + priv->str = NULL; return str; @@ -1457,6 +1491,7 @@ ges_xml_formatter_init (GESXmlFormatter * self) priv->element_id = g_hash_table_new (g_direct_hash, g_direct_equal); self->priv = priv; + self->priv->min_version = 1; } static void diff --git a/tests/check/ges/project.c b/tests/check/ges/project.c index 13f8df7..0cb9c60 100644 --- a/tests/check/ges/project.c +++ b/tests/check/ges/project.c @@ -484,63 +484,77 @@ GST_END_TEST; GST_START_TEST (test_project_load_xges) { gboolean saved; - GESProject *project; + GESProject *loaded_project, *saved_project; GESTimeline *timeline; GESAsset *formatter_asset; gchar *uri = ges_test_file_uri ("test-project.xges"); - project = ges_project_new (uri); + loaded_project = ges_project_new (uri); mainloop = g_main_loop_new (NULL, FALSE); - fail_unless (GES_IS_PROJECT (project)); + fail_unless (GES_IS_PROJECT (loaded_project)); /* Connect the signals */ - g_signal_connect (project, "asset-added", (GCallback) asset_added_cb, NULL); - g_signal_connect (project, "loaded", (GCallback) project_loaded_cb, mainloop); + g_signal_connect (loaded_project, "asset-added", (GCallback) asset_added_cb, + NULL); + g_signal_connect (loaded_project, "loaded", (GCallback) project_loaded_cb, + mainloop); /* Make sure we update the project's dummy URL to some actual URL */ - g_signal_connect (project, "missing-uri", (GCallback) _set_new_uri, NULL); + g_signal_connect (loaded_project, "missing-uri", (GCallback) _set_new_uri, + NULL); /* Now extract a timeline from it */ GST_LOG ("Loading project"); - timeline = GES_TIMELINE (ges_asset_extract (GES_ASSET (project), NULL)); + timeline = + GES_TIMELINE (ges_asset_extract (GES_ASSET (loaded_project), NULL)); fail_unless (GES_IS_TIMELINE (timeline)); - assert_equals_int (g_list_length (ges_project_get_loading_assets (project)), - 1); + assert_equals_int (g_list_length (ges_project_get_loading_assets + (loaded_project)), 1); g_main_loop_run (mainloop); GST_LOG ("Test first loading"); - _test_project (project, timeline); + _test_project (loaded_project, timeline); g_free (uri); uri = ges_test_get_tmp_uri ("test-project_TMP.xges"); formatter_asset = ges_asset_request (GES_TYPE_FORMATTER, "ges", NULL); saved = - ges_project_save (project, timeline, uri, formatter_asset, TRUE, NULL); + ges_project_save (loaded_project, timeline, uri, formatter_asset, TRUE, + NULL); fail_unless (saved); gst_object_unref (timeline); - gst_object_unref (project); - project = ges_project_new (uri); - ASSERT_OBJECT_REFCOUNT (project, "Our + cache", 2); - g_signal_connect (project, "asset-added", (GCallback) asset_added_cb, NULL); - g_signal_connect (project, "loaded", (GCallback) project_loaded_cb, mainloop); + saved_project = ges_project_new (uri); + ASSERT_OBJECT_REFCOUNT (saved_project, "Our + cache", 2); + g_signal_connect (saved_project, "asset-added", (GCallback) asset_added_cb, + NULL); + g_signal_connect (saved_project, "loaded", (GCallback) project_loaded_cb, + mainloop); GST_LOG ("Loading saved project"); - timeline = GES_TIMELINE (ges_asset_extract (GES_ASSET (project), NULL)); + timeline = GES_TIMELINE (ges_asset_extract (GES_ASSET (saved_project), NULL)); fail_unless (GES_IS_TIMELINE (timeline)); g_main_loop_run (mainloop); - _test_project (project, timeline); + _test_project (saved_project, timeline); + + fail_unless (ges_meta_container_get_string (GES_META_CONTAINER + (loaded_project), GES_META_FORMAT_VERSION)); + fail_unless_equals_string (ges_meta_container_get_string (GES_META_CONTAINER + (loaded_project), GES_META_FORMAT_VERSION), + ges_meta_container_get_string (GES_META_CONTAINER (loaded_project), + GES_META_FORMAT_VERSION)); gst_object_unref (timeline); - gst_object_unref (project); + gst_object_unref (saved_project); + gst_object_unref (loaded_project); g_free (uri); - ASSERT_OBJECT_REFCOUNT (project, "Still 1 ref for asset cache", 1); + ASSERT_OBJECT_REFCOUNT (saved_project, "Still 1 ref for asset cache", 1); g_main_loop_unref (mainloop); - g_signal_handlers_disconnect_by_func (project, (GCallback) project_loaded_cb, - mainloop); - g_signal_handlers_disconnect_by_func (project, (GCallback) asset_added_cb, - NULL); + g_signal_handlers_disconnect_by_func (saved_project, + (GCallback) project_loaded_cb, mainloop); + g_signal_handlers_disconnect_by_func (saved_project, + (GCallback) asset_added_cb, NULL); } GST_END_TEST; diff --git a/tests/check/ges/test-project.xges b/tests/check/ges/test-project.xges index 2569b01..acc71ed 100644 --- a/tests/check/ges/test-project.xges +++ b/tests/check/ges/test-project.xges @@ -2,7 +2,7 @@ - + diff --git a/tests/check/ges/test-utils.c b/tests/check/ges/test-utils.c index 106e877..86a3bfd 100644 --- a/tests/check/ges/test-utils.c +++ b/tests/check/ges/test-utils.c @@ -283,8 +283,7 @@ ges_test_get_tmp_uri (const gchar * filename) { gchar *location, *uri; - location = g_build_filename (g_get_tmp_dir (), - "test-keyframes-save.xges", NULL); + location = g_build_filename (g_get_tmp_dir (), filename, NULL); uri = g_strconcat ("file://", location, NULL); g_free (location);