1 /* GStreamer Editing Services
3 * Copyright (C) 2012 Thibault Saunier <thibault.saunier@collabora.com>
4 * Copyright (C) 2012 Volodymyr Rudyi <vladimir.rudoy@gmail.com>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
22 * SECTION: gesextractable
23 * @title: GESExtractable Interface
24 * @short_description: An interface for objects which can be extracted
27 * A #GObject that implements the #GESExtractable interface can be
28 * extracted from a #GESAsset using ges_asset_extract().
30 * Each extractable type will have its own way of interpreting the
31 * #GESAsset:id of an asset (or, if it is associated with a specific
32 * subclass of #GESAsset, the asset subclass may handle the
33 * interpretation of the #GESAsset:id). By default, the requested asset
34 * #GESAsset:id will be ignored by a #GESExtractable and will be set to
35 * the type name of the extractable instead. Also by default, when the
36 * requested asset is extracted, the returned object will simply be a
37 * newly created default object of that extractable type. You should check
38 * the documentation for each extractable type to see if they differ from
41 * After the object is extracted, it will have a reference to the asset it
42 * came from, which you can retrieve using ges_extractable_get_asset().
48 #include "ges-asset.h"
49 #include "ges-internal.h"
50 #include "ges-extractable.h"
51 #include "ges-uri-clip.h"
53 static GQuark ges_asset_key;
55 G_DEFINE_INTERFACE_WITH_CODE (GESExtractable, ges_extractable,
56 G_TYPE_INITIALLY_UNOWNED,
57 ges_asset_key = g_quark_from_static_string ("ges-extractable-data"));
60 ges_extractable_check_id_default (GType type, const gchar * id, GError ** error)
62 return g_strdup (g_type_name (type));
66 ges_extractable_get_real_extractable_type_default (GType type, const gchar * id)
71 G_GNUC_BEGIN_IGNORE_DEPRECATIONS; /* Start ignoring GParameter deprecation */
73 extractable_get_parameters_from_id (const gchar * id, guint * n_params)
80 G_GNUC_END_IGNORE_DEPRECATIONS; /* End ignoring GParameter deprecation */
82 extractable_get_id (GESExtractable * self)
86 if ((asset = ges_extractable_get_asset (self)))
87 return g_strdup (ges_asset_get_id (asset));
89 return g_strdup (g_type_name (G_OBJECT_TYPE (self)));
94 ges_extractable_default_init (GESExtractableInterface * iface)
96 iface->asset_type = GES_TYPE_ASSET;
97 iface->check_id = ges_extractable_check_id_default;
98 iface->get_real_extractable_type =
99 ges_extractable_get_real_extractable_type_default;
100 iface->get_parameters_from_id = extractable_get_parameters_from_id;
101 iface->set_asset = NULL;
102 iface->set_asset_full = NULL;
103 iface->get_id = extractable_get_id;
104 iface->register_metas = NULL;
105 iface->can_update_asset = FALSE;
109 * ges_extractable_get_asset:
110 * @self: A #GESExtractable
112 * Get the asset that has been set on the extractable object.
114 * Returns: (transfer none) (nullable): The asset set on @self, or %NULL
115 * if no asset has been set.
118 ges_extractable_get_asset (GESExtractable * self)
120 g_return_val_if_fail (GES_IS_EXTRACTABLE (self), NULL);
122 return g_object_get_qdata (G_OBJECT (self), ges_asset_key);;
126 * ges_extractable_set_asset:
127 * @self: A #GESExtractable
128 * @asset: (transfer none): The asset to set
130 * Sets the asset for this extractable object.
132 * When an object is extracted from an asset using ges_asset_extract() its
133 * asset will be automatically set. Note that many classes that implement
134 * #GESExtractable will automatically create their objects using assets
135 * when you call their @new methods. However, you can use this method to
136 * associate an object with a compatible asset if it was created by other
137 * means and does not yet have an asset. Or, for some implementations of
138 * #GESExtractable, you can use this to change the asset of the given
139 * extractable object, which will lead to a change in its state to
140 * match the new asset #GESAsset:id.
142 * Returns: %TRUE if @asset could be successfully set on @self.
145 ges_extractable_set_asset (GESExtractable * self, GESAsset * asset)
147 GESExtractableInterface *iface;
150 g_return_val_if_fail (GES_IS_EXTRACTABLE (self), FALSE);
152 iface = GES_EXTRACTABLE_GET_INTERFACE (self);
153 GST_DEBUG_OBJECT (self, "Setting asset to %" GST_PTR_FORMAT, asset);
155 if (iface->can_update_asset == FALSE &&
156 g_object_get_qdata (G_OBJECT (self), ges_asset_key)) {
157 GST_WARNING_OBJECT (self, "Can not reset asset on object");
158 /* FIXME: do not fail if the same asset */
163 extract_type = ges_asset_get_extractable_type (asset);
164 if (G_OBJECT_TYPE (self) != extract_type) {
165 GST_WARNING_OBJECT (self, "Can not set the asset to %" GST_PTR_FORMAT
166 " because its extractable-type is %s, rather than %s",
167 asset, g_type_name (extract_type), G_OBJECT_TYPE_NAME (self));
172 g_object_set_qdata_full (G_OBJECT (self), ges_asset_key,
173 gst_object_ref (asset), gst_object_unref);
175 /* Let classes that implement the interface know that a asset has been set */
176 if (iface->set_asset_full)
177 /* FIXME: return to the previous asset if the setting fails */
178 return iface->set_asset_full (self, asset);
180 if (iface->set_asset)
181 iface->set_asset (self, asset);
187 * ges_extractable_get_id:
188 * @self: A #GESExtractable
190 * Gets the #GESAsset:id of some associated asset. It may be the case
191 * that the object has no set asset, or even that such an asset does not
192 * yet exist in the GES cache. Instead, this will return the asset
193 * #GESAsset:id that is _compatible_ with the current state of the object,
194 * as determined by the #GESExtractable implementer. If it was indeed
195 * extracted from an asset, this should return the same as its
196 * corresponding asset #GESAsset:id.
198 * Returns: (transfer full): The #GESAsset:id of some associated #GESAsset
199 * that is compatible with @self's current state.
202 ges_extractable_get_id (GESExtractable * self)
204 g_return_val_if_fail (GES_IS_EXTRACTABLE (self), NULL);
206 return GES_EXTRACTABLE_GET_INTERFACE (self)->get_id (self);
209 G_GNUC_BEGIN_IGNORE_DEPRECATIONS; /* Start ignoring GParameter deprecation */
211 * ges_extractable_type_get_parameters_for_id:
212 * @type: The #GType implementing #GESExtractable
213 * @id: The ID of the Extractable
214 * @n_params: (out): Return location for the returned array
216 * Returns: (transfer full) (array length=n_params): an array of #GParameter
217 * needed to extract the #GESExtractable from a #GESAsset of @id
220 ges_extractable_type_get_parameters_from_id (GType type, const gchar * id,
224 GESExtractableInterface *iface;
226 GParameter *ret = NULL;
228 g_return_val_if_fail (g_type_is_a (type, G_TYPE_OBJECT), NULL);
229 g_return_val_if_fail (g_type_is_a (type, GES_TYPE_EXTRACTABLE), NULL);
231 klass = g_type_class_ref (type);
232 iface = g_type_interface_peek (klass, GES_TYPE_EXTRACTABLE);
234 ret = iface->get_parameters_from_id (id, n_params);
236 g_type_class_unref (klass);
241 G_GNUC_END_IGNORE_DEPRECATIONS; /* End ignoring GParameter deprecation */
244 * ges_extractable_type_get_asset_type:
245 * @type: The #GType implementing #GESExtractable
247 * Get the #GType, subclass of #GES_TYPE_ASSET to instanciate
248 * to be able to extract a @type
250 * Returns: the #GType to use to create a asset to extract @type
253 ges_extractable_type_get_asset_type (GType type)
256 GESExtractableInterface *iface;
258 g_return_val_if_fail (g_type_is_a (type, G_TYPE_OBJECT), G_TYPE_INVALID);
259 g_return_val_if_fail (g_type_is_a (type, GES_TYPE_EXTRACTABLE),
262 klass = g_type_class_ref (type);
264 iface = g_type_interface_peek (klass, GES_TYPE_EXTRACTABLE);
266 g_type_class_unref (klass);
268 return iface->asset_type;
272 * ges_extractable_type_check_id:
273 * @type: The #GType implementing #GESExtractable
274 * @id: The ID to check
276 * Check if @id is valid for @type
278 * Returns: (transfer full) (nullable): A newly allocated string containing
279 * the actual ID (after some processing) or %NULL if the ID is wrong.
282 ges_extractable_type_check_id (GType type, const gchar * id, GError ** error)
285 GESExtractableInterface *iface;
287 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
288 g_return_val_if_fail (g_type_is_a (type, G_TYPE_OBJECT), NULL);
289 g_return_val_if_fail (g_type_is_a (type, GES_TYPE_EXTRACTABLE), NULL);
291 klass = g_type_class_ref (type);
293 iface = g_type_interface_peek (klass, GES_TYPE_EXTRACTABLE);
295 g_type_class_unref (klass);
297 return iface->check_id (type, id, error);
301 * ges_extractable_get_real_extractable_type:
302 * @type: The #GType implementing #GESExtractable
303 * @id: The ID to check
305 * Get the #GType that should be used as extractable_type for @type and
306 * @id. Usually this will be the same as @type but in some cases they can
307 * be some subclasses of @type. For example, in the case of #GESFormatter,
308 * the returned #GType will be a subclass of #GESFormatter that can be used
309 * to load the file pointed by @id.
311 * Returns: Return the #GESExtractable type that should be used for @id
314 ges_extractable_get_real_extractable_type_for_id (GType type, const gchar * id)
318 GESExtractableInterface *iface;
320 klass = g_type_class_ref (type);
321 iface = g_type_interface_peek (klass, GES_TYPE_EXTRACTABLE);
322 g_type_class_unref (klass);
324 ret = iface->get_real_extractable_type (type, id);
326 GST_DEBUG ("Extractable type for id %s and wanted type %s is: %s",
327 id, g_type_name (type), g_type_name (ret));
333 * ges_extractable_register_metas:
334 * @self: A #GESExtractable
335 * @asset: The #GESAsset on which metadatas should be registered
337 * Lets you register standard method for @extractable_type on @asset
339 * Returns: %TRUE if metas could be register %FALSE otherwize
342 ges_extractable_register_metas (GType extractable_type, GESAsset * asset)
345 gboolean ret = FALSE;
346 GESExtractableInterface *iface;
348 g_return_val_if_fail (g_type_is_a (extractable_type, GES_TYPE_EXTRACTABLE),
351 klass = g_type_class_ref (extractable_type);
352 iface = g_type_interface_peek (klass, GES_TYPE_EXTRACTABLE);
354 if (iface->register_metas)
355 ret = iface->register_metas (iface, klass, asset);
357 g_type_class_unref (klass);