mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-10-03 17:22:29 +00:00
gesdemux: Compute sinkpad caps based on formatter mimetypes
Implement lazy loading asset cache so gesdemux use the formatters assets while GES hasn't been initialized. And set extensions to temporary files as some formatters require the information (otio)
This commit is contained in:
parent
7caa424aaf
commit
f51f2f70de
6 changed files with 199 additions and 54 deletions
|
@ -144,8 +144,6 @@ typedef struct
|
||||||
GESAsset *asset;
|
GESAsset *asset;
|
||||||
} GESAssetCacheEntry;
|
} GESAssetCacheEntry;
|
||||||
|
|
||||||
/* Also protect all the entries in the cache */
|
|
||||||
G_LOCK_DEFINE_STATIC (asset_cache_lock);
|
|
||||||
/* We are mapping entries by types and ID, such as:
|
/* We are mapping entries by types and ID, such as:
|
||||||
*
|
*
|
||||||
* {
|
* {
|
||||||
|
@ -169,8 +167,10 @@ G_LOCK_DEFINE_STATIC (asset_cache_lock);
|
||||||
* different extractable types.
|
* different extractable types.
|
||||||
**/
|
**/
|
||||||
static GHashTable *type_entries_table = NULL;
|
static GHashTable *type_entries_table = NULL;
|
||||||
#define LOCK_CACHE (G_LOCK (asset_cache_lock))
|
/* Protect all the entries in the cache */
|
||||||
#define UNLOCK_CACHE (G_UNLOCK (asset_cache_lock))
|
static GRecMutex asset_cache_lock;
|
||||||
|
#define LOCK_CACHE (g_rec_mutex_lock (&asset_cache_lock))
|
||||||
|
#define UNLOCK_CACHE (g_rec_mutex_unlock (&asset_cache_lock))
|
||||||
|
|
||||||
static gchar *
|
static gchar *
|
||||||
_check_and_update_parameters (GType * extractable_type, const gchar * id,
|
_check_and_update_parameters (GType * extractable_type, const gchar * id,
|
||||||
|
@ -470,12 +470,39 @@ _extractable_type_name (GType type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ges_asset_cache_init_unlocked (void)
|
||||||
|
{
|
||||||
|
if (type_entries_table)
|
||||||
|
return;
|
||||||
|
|
||||||
|
type_entries_table = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||||
|
g_free, (GDestroyNotify) g_hash_table_unref);
|
||||||
|
|
||||||
|
_init_formatter_assets ();
|
||||||
|
_init_standard_transition_assets ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* WITH LOCK_CACHE */
|
||||||
|
static GHashTable *
|
||||||
|
_get_type_entries ()
|
||||||
|
{
|
||||||
|
if (type_entries_table)
|
||||||
|
return type_entries_table;
|
||||||
|
|
||||||
|
ges_asset_cache_init_unlocked ();
|
||||||
|
|
||||||
|
return type_entries_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* WITH LOCK_CACHE */
|
||||||
static inline GESAssetCacheEntry *
|
static inline GESAssetCacheEntry *
|
||||||
_lookup_entry (GType extractable_type, const gchar * id)
|
_lookup_entry (GType extractable_type, const gchar * id)
|
||||||
{
|
{
|
||||||
GHashTable *entries_table;
|
GHashTable *entries_table;
|
||||||
|
|
||||||
entries_table = g_hash_table_lookup (type_entries_table,
|
entries_table = g_hash_table_lookup (_get_type_entries (),
|
||||||
_extractable_type_name (extractable_type));
|
_extractable_type_name (extractable_type));
|
||||||
if (entries_table)
|
if (entries_table)
|
||||||
return g_hash_table_lookup (entries_table, id);
|
return g_hash_table_lookup (entries_table, id);
|
||||||
|
@ -608,13 +635,13 @@ ges_asset_cache_put (GESAsset * asset, GTask * task)
|
||||||
if (!(entry = _lookup_entry (extractable_type, asset_id))) {
|
if (!(entry = _lookup_entry (extractable_type, asset_id))) {
|
||||||
GHashTable *entries_table;
|
GHashTable *entries_table;
|
||||||
|
|
||||||
entries_table = g_hash_table_lookup (type_entries_table,
|
entries_table = g_hash_table_lookup (_get_type_entries (),
|
||||||
_extractable_type_name (extractable_type));
|
_extractable_type_name (extractable_type));
|
||||||
if (entries_table == NULL) {
|
if (entries_table == NULL) {
|
||||||
entries_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
|
entries_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
|
||||||
_free_entries);
|
_free_entries);
|
||||||
|
|
||||||
g_hash_table_insert (type_entries_table,
|
g_hash_table_insert (_get_type_entries (),
|
||||||
g_strdup (_extractable_type_name (extractable_type)), entries_table);
|
g_strdup (_extractable_type_name (extractable_type)), entries_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -637,18 +664,20 @@ ges_asset_cache_put (GESAsset * asset, GTask * task)
|
||||||
void
|
void
|
||||||
ges_asset_cache_init (void)
|
ges_asset_cache_init (void)
|
||||||
{
|
{
|
||||||
type_entries_table = g_hash_table_new_full (g_str_hash, g_str_equal,
|
LOCK_CACHE;
|
||||||
g_free, (GDestroyNotify) g_hash_table_unref);
|
ges_asset_cache_init_unlocked ();
|
||||||
|
UNLOCK_CACHE;
|
||||||
_init_formatter_assets ();
|
|
||||||
_init_standard_transition_assets ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ges_asset_cache_deinit (void)
|
ges_asset_cache_deinit (void)
|
||||||
{
|
{
|
||||||
|
_deinit_formatter_assets ();
|
||||||
|
|
||||||
|
LOCK_CACHE;
|
||||||
g_hash_table_destroy (type_entries_table);
|
g_hash_table_destroy (type_entries_table);
|
||||||
type_entries_table = NULL;
|
type_entries_table = NULL;
|
||||||
|
UNLOCK_CACHE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
@ -750,17 +779,21 @@ ges_asset_set_proxy (GESAsset * asset, GESAsset * proxy)
|
||||||
GHashTable *entries_table;
|
GHashTable *entries_table;
|
||||||
GESAssetCacheEntry *entry;
|
GESAssetCacheEntry *entry;
|
||||||
|
|
||||||
entries_table = g_hash_table_lookup (type_entries_table,
|
LOCK_CACHE;
|
||||||
|
entries_table = g_hash_table_lookup (_get_type_entries (),
|
||||||
_extractable_type_name (proxy->priv->extractable_type));
|
_extractable_type_name (proxy->priv->extractable_type));
|
||||||
entry = g_hash_table_find (entries_table, (GHRFunc) _lookup_proxied_asset,
|
entry = g_hash_table_find (entries_table, (GHRFunc) _lookup_proxied_asset,
|
||||||
(gpointer) ges_asset_get_id (proxy));
|
(gpointer) ges_asset_get_id (proxy));
|
||||||
|
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
|
UNLOCK_CACHE;
|
||||||
GST_DEBUG_OBJECT (asset, "Not proxying any asset %s", proxy->priv->id);
|
GST_DEBUG_OBJECT (asset, "Not proxying any asset %s", proxy->priv->id);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
asset = entry->asset;
|
asset = entry->asset;
|
||||||
|
UNLOCK_CACHE;
|
||||||
|
|
||||||
while (asset->priv->proxies)
|
while (asset->priv->proxies)
|
||||||
asset = asset->priv->proxies->data;
|
asset = asset->priv->proxies->data;
|
||||||
|
|
||||||
|
@ -914,7 +947,7 @@ ges_asset_set_id (GESAsset * asset, const gchar * id)
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCK_CACHE;
|
LOCK_CACHE;
|
||||||
entries = g_hash_table_lookup (type_entries_table,
|
entries = g_hash_table_lookup (_get_type_entries (),
|
||||||
_extractable_type_name (asset->priv->extractable_type));
|
_extractable_type_name (asset->priv->extractable_type));
|
||||||
|
|
||||||
g_return_if_fail (g_hash_table_lookup_extended (entries, priv->id, &orig_id,
|
g_return_if_fail (g_hash_table_lookup_extended (entries, priv->id, &orig_id,
|
||||||
|
@ -1369,7 +1402,7 @@ ges_list_assets (GType filter)
|
||||||
g_return_val_if_fail (g_type_is_a (filter, GES_TYPE_EXTRACTABLE), NULL);
|
g_return_val_if_fail (g_type_is_a (filter, GES_TYPE_EXTRACTABLE), NULL);
|
||||||
|
|
||||||
LOCK_CACHE;
|
LOCK_CACHE;
|
||||||
g_hash_table_iter_init (&types_iter, type_entries_table);
|
g_hash_table_iter_init (&types_iter, _get_type_entries ());
|
||||||
while (g_hash_table_iter_next (&types_iter, &typename, &assets)) {
|
while (g_hash_table_iter_next (&types_iter, &typename, &assets)) {
|
||||||
if (g_type_is_a (filter, g_type_from_name ((gchar *) typename)) == FALSE)
|
if (g_type_is_a (filter, g_type_from_name ((gchar *) typename)) == FALSE)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -36,6 +36,10 @@
|
||||||
#include "ges-formatter.h"
|
#include "ges-formatter.h"
|
||||||
#include "ges-internal.h"
|
#include "ges-internal.h"
|
||||||
#include "ges.h"
|
#include "ges.h"
|
||||||
|
#ifndef DISABLE_XPTV
|
||||||
|
#include "ges-pitivi-formatter.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAS_PYTHON
|
#ifdef HAS_PYTHON
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include "ges-resources.h"
|
#include "ges-resources.h"
|
||||||
|
@ -44,6 +48,7 @@
|
||||||
GST_DEBUG_CATEGORY_STATIC (ges_formatter_debug);
|
GST_DEBUG_CATEGORY_STATIC (ges_formatter_debug);
|
||||||
#undef GST_CAT_DEFAULT
|
#undef GST_CAT_DEFAULT
|
||||||
#define GST_CAT_DEFAULT ges_formatter_debug
|
#define GST_CAT_DEFAULT ges_formatter_debug
|
||||||
|
static gboolean initialized = FALSE;
|
||||||
|
|
||||||
/* TODO Add a GCancellable somewhere in the API */
|
/* TODO Add a GCancellable somewhere in the API */
|
||||||
static void ges_extractable_interface_init (GESExtractableInterface * iface);
|
static void ges_extractable_interface_init (GESExtractableInterface * iface);
|
||||||
|
@ -477,7 +482,8 @@ ges_formatter_class_register_metas (GESFormatterClass * class,
|
||||||
class->version = version;
|
class->version = version;
|
||||||
class->rank = rank;
|
class->rank = rank;
|
||||||
|
|
||||||
if (ges_is_initialized () && g_type_class_peek (G_OBJECT_CLASS_TYPE (class)))
|
if (g_atomic_int_get (&initialized)
|
||||||
|
&& g_type_class_peek (G_OBJECT_CLASS_TYPE (class)))
|
||||||
gst_object_unref (ges_asset_request (G_OBJECT_CLASS_TYPE (class), NULL,
|
gst_object_unref (ges_asset_request (G_OBJECT_CLASS_TYPE (class), NULL,
|
||||||
NULL));
|
NULL));
|
||||||
}
|
}
|
||||||
|
@ -622,13 +628,35 @@ _init_formatter_assets (void)
|
||||||
g_once_init_leave (&init_debug, TRUE);
|
g_once_init_leave (&init_debug, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
load_python_formatters ();
|
if (g_atomic_int_compare_and_exchange (&initialized, FALSE, TRUE)) {
|
||||||
|
/* register formatter types with the system */
|
||||||
|
#ifndef DISABLE_XPTV
|
||||||
|
g_type_class_ref (GES_TYPE_PITIVI_FORMATTER);
|
||||||
|
#endif
|
||||||
|
g_type_class_ref (GES_TYPE_COMMAND_LINE_FORMATTER);
|
||||||
|
g_type_class_ref (GES_TYPE_XML_FORMATTER);
|
||||||
|
|
||||||
|
load_python_formatters ();
|
||||||
|
|
||||||
formatters = g_type_children (GES_TYPE_FORMATTER, &n_formatters);
|
formatters = g_type_children (GES_TYPE_FORMATTER, &n_formatters);
|
||||||
_list_formatters (formatters, n_formatters);
|
_list_formatters (formatters, n_formatters);
|
||||||
g_free (formatters);
|
g_free (formatters);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_deinit_formatter_assets (void)
|
||||||
|
{
|
||||||
|
if (g_atomic_int_compare_and_exchange (&initialized, TRUE, FALSE)) {
|
||||||
|
|
||||||
|
#ifndef DISABLE_XPTV
|
||||||
|
g_type_class_unref (g_type_class_peek (GES_TYPE_PITIVI_FORMATTER));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
g_type_class_unref (g_type_class_peek (GES_TYPE_COMMAND_LINE_FORMATTER));
|
||||||
|
g_type_class_unref (g_type_class_peek (GES_TYPE_XML_FORMATTER));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static gint
|
static gint
|
||||||
_sort_formatters (GESAsset * asset, GESAsset * asset1)
|
_sort_formatters (GESAsset * asset, GESAsset * asset1)
|
||||||
|
|
|
@ -343,6 +343,7 @@ G_GNUC_INTERNAL GstElement * get_element_for_encoding_profile (GstEncodingProf
|
||||||
/* Function to initialise GES */
|
/* Function to initialise GES */
|
||||||
G_GNUC_INTERNAL void _init_standard_transition_assets (void);
|
G_GNUC_INTERNAL void _init_standard_transition_assets (void);
|
||||||
G_GNUC_INTERNAL void _init_formatter_assets (void);
|
G_GNUC_INTERNAL void _init_formatter_assets (void);
|
||||||
|
G_GNUC_INTERNAL void _deinit_formatter_assets (void);
|
||||||
|
|
||||||
/* Utilities */
|
/* Utilities */
|
||||||
G_GNUC_INTERNAL gint element_start_compare (GESTimelineElement * a,
|
G_GNUC_INTERNAL gint element_start_compare (GESTimelineElement * a,
|
||||||
|
|
19
ges/ges.c
19
ges/ges.c
|
@ -83,6 +83,7 @@ ges_init_post (GOptionContext * context, GOptionGroup * group, gpointer data,
|
||||||
|
|
||||||
uriasset_klass = g_type_class_ref (GES_TYPE_URI_CLIP_ASSET);
|
uriasset_klass = g_type_class_ref (GES_TYPE_URI_CLIP_ASSET);
|
||||||
|
|
||||||
|
_init_formatter_assets ();
|
||||||
if (!_ges_uri_asset_ensure_setup (uriasset_klass)) {
|
if (!_ges_uri_asset_ensure_setup (uriasset_klass)) {
|
||||||
GST_ERROR ("cannot setup uri asset");
|
GST_ERROR ("cannot setup uri asset");
|
||||||
goto failed;
|
goto failed;
|
||||||
|
@ -99,8 +100,6 @@ ges_init_post (GOptionContext * context, GOptionGroup * group, gpointer data,
|
||||||
}
|
}
|
||||||
gst_object_unref (nlecomposition_factory);
|
gst_object_unref (nlecomposition_factory);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* register clip classes with the system */
|
/* register clip classes with the system */
|
||||||
|
|
||||||
g_type_class_ref (GES_TYPE_TEST_CLIP);
|
g_type_class_ref (GES_TYPE_TEST_CLIP);
|
||||||
|
@ -112,13 +111,6 @@ ges_init_post (GOptionContext * context, GOptionGroup * group, gpointer data,
|
||||||
|
|
||||||
g_type_class_ref (GES_TYPE_GROUP);
|
g_type_class_ref (GES_TYPE_GROUP);
|
||||||
|
|
||||||
/* register formatter types with the system */
|
|
||||||
#ifndef DISABLE_XPTV
|
|
||||||
g_type_class_ref (GES_TYPE_PITIVI_FORMATTER);
|
|
||||||
#endif
|
|
||||||
g_type_class_ref (GES_TYPE_COMMAND_LINE_FORMATTER);
|
|
||||||
g_type_class_ref (GES_TYPE_XML_FORMATTER);
|
|
||||||
|
|
||||||
/* Register track elements */
|
/* Register track elements */
|
||||||
g_type_class_ref (GES_TYPE_EFFECT);
|
g_type_class_ref (GES_TYPE_EFFECT);
|
||||||
|
|
||||||
|
@ -209,15 +201,6 @@ ges_deinit (void)
|
||||||
g_type_class_unref (g_type_class_peek (GES_TYPE_OVERLAY_TEXT_CLIP));
|
g_type_class_unref (g_type_class_peek (GES_TYPE_OVERLAY_TEXT_CLIP));
|
||||||
|
|
||||||
g_type_class_unref (g_type_class_peek (GES_TYPE_GROUP));
|
g_type_class_unref (g_type_class_peek (GES_TYPE_GROUP));
|
||||||
|
|
||||||
/* register formatter types with the system */
|
|
||||||
#ifndef DISABLE_XPTV
|
|
||||||
g_type_class_unref (g_type_class_peek (GES_TYPE_PITIVI_FORMATTER));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
g_type_class_unref (g_type_class_peek (GES_TYPE_COMMAND_LINE_FORMATTER));
|
|
||||||
g_type_class_unref (g_type_class_peek (GES_TYPE_XML_FORMATTER));
|
|
||||||
|
|
||||||
/* Register track elements */
|
/* Register track elements */
|
||||||
g_type_class_unref (g_type_class_peek (GES_TYPE_EFFECT));
|
g_type_class_unref (g_type_class_peek (GES_TYPE_EFFECT));
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,7 @@ if otio is not None:
|
||||||
GObject.type_register(GESOtioFormatter)
|
GObject.type_register(GESOtioFormatter)
|
||||||
known_extensions_mimetype_map = [
|
known_extensions_mimetype_map = [
|
||||||
("otio", "xml", "fcpxml"),
|
("otio", "xml", "fcpxml"),
|
||||||
("application/otio", "application/xmeml", "application/fcpxml")
|
("application/vnd.pixar.opentimelineio+json", "application/vnd.apple-xmeml+xml", "application/vnd.apple-fcp+xml")
|
||||||
]
|
]
|
||||||
|
|
||||||
extensions = []
|
extensions = []
|
||||||
|
|
|
@ -47,11 +47,6 @@
|
||||||
GST_DEBUG_CATEGORY_STATIC (gesdemux);
|
GST_DEBUG_CATEGORY_STATIC (gesdemux);
|
||||||
#define GST_CAT_DEFAULT gesdemux
|
#define GST_CAT_DEFAULT gesdemux
|
||||||
|
|
||||||
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
|
|
||||||
GST_PAD_SINK,
|
|
||||||
GST_PAD_ALWAYS,
|
|
||||||
GST_STATIC_CAPS ("application/xges"));
|
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE (GESDemux, ges_demux, GES, Demux, GESBaseBin);
|
G_DECLARE_FINAL_TYPE (GESDemux, ges_demux, GES, Demux, GESBaseBin);
|
||||||
|
|
||||||
struct _GESDemux
|
struct _GESDemux
|
||||||
|
@ -79,6 +74,92 @@ enum
|
||||||
|
|
||||||
static GParamSpec *properties[PROP_LAST];
|
static GParamSpec *properties[PROP_LAST];
|
||||||
|
|
||||||
|
static GstCaps *
|
||||||
|
ges_demux_get_sinkpad_caps ()
|
||||||
|
{
|
||||||
|
GList *tmp, *formatters;
|
||||||
|
GstCaps *sinkpad_caps = gst_caps_new_empty ();
|
||||||
|
|
||||||
|
formatters = ges_list_assets (GES_TYPE_FORMATTER);
|
||||||
|
for (tmp = formatters; tmp; tmp = tmp->next) {
|
||||||
|
GstCaps *caps;
|
||||||
|
const gchar *mimetype =
|
||||||
|
ges_meta_container_get_string (GES_META_CONTAINER (tmp->data),
|
||||||
|
GES_META_FORMATTER_MIMETYPE);
|
||||||
|
if (!mimetype)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
caps = gst_caps_from_string (mimetype);
|
||||||
|
|
||||||
|
if (!caps) {
|
||||||
|
GST_INFO_OBJECT (tmp->data,
|
||||||
|
"%s - could not create caps from mimetype: %s",
|
||||||
|
ges_meta_container_get_string (GES_META_CONTAINER (tmp->data),
|
||||||
|
GES_META_FORMATTER_NAME), mimetype);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_caps_append (sinkpad_caps, caps);
|
||||||
|
}
|
||||||
|
g_list_free (formatters);
|
||||||
|
|
||||||
|
return sinkpad_caps;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gchar *
|
||||||
|
ges_demux_get_extension (GstStructure * _struct)
|
||||||
|
{
|
||||||
|
GList *tmp, *formatters;
|
||||||
|
gchar *ext = NULL;
|
||||||
|
|
||||||
|
formatters = ges_list_assets (GES_TYPE_FORMATTER);
|
||||||
|
for (tmp = formatters; tmp; tmp = tmp->next) {
|
||||||
|
gchar **extensions_a;
|
||||||
|
gint i, n_exts;
|
||||||
|
GstCaps *caps;
|
||||||
|
const gchar *mimetype =
|
||||||
|
ges_meta_container_get_string (GES_META_CONTAINER (tmp->data),
|
||||||
|
GES_META_FORMATTER_MIMETYPE);
|
||||||
|
const gchar *extensions =
|
||||||
|
ges_meta_container_get_string (GES_META_CONTAINER (tmp->data),
|
||||||
|
GES_META_FORMATTER_EXTENSION);
|
||||||
|
if (!mimetype)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!extensions)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
caps = gst_caps_from_string (mimetype);
|
||||||
|
if (!caps) {
|
||||||
|
GST_INFO_OBJECT (tmp->data,
|
||||||
|
"%s - could not create caps from mimetype: %s",
|
||||||
|
ges_meta_container_get_string (GES_META_CONTAINER (tmp->data),
|
||||||
|
GES_META_FORMATTER_NAME), mimetype);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
extensions_a = g_strsplit (extensions, ",", -1);
|
||||||
|
n_exts = g_strv_length (extensions_a);
|
||||||
|
for (i = 0; i < gst_caps_get_size (caps) && i < n_exts; i++) {
|
||||||
|
GstStructure *structure = gst_caps_get_structure (caps, i);
|
||||||
|
|
||||||
|
if (gst_structure_has_name (_struct, gst_structure_get_name (structure))) {
|
||||||
|
ext = g_strdup (extensions_a[i]);
|
||||||
|
g_strfreev (extensions_a);
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_strfreev (extensions_a);
|
||||||
|
}
|
||||||
|
done:
|
||||||
|
g_list_free (formatters);
|
||||||
|
|
||||||
|
return ext;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ges_demux_get_property (GObject * object, guint property_id,
|
ges_demux_get_property (GObject * object, guint property_id,
|
||||||
GValue * value, GParamSpec * pspec)
|
GValue * value, GParamSpec * pspec)
|
||||||
|
@ -110,6 +191,7 @@ ges_demux_class_init (GESDemuxClass * self_class)
|
||||||
{
|
{
|
||||||
GObjectClass *gclass = G_OBJECT_CLASS (self_class);
|
GObjectClass *gclass = G_OBJECT_CLASS (self_class);
|
||||||
GstElementClass *gstelement_klass = GST_ELEMENT_CLASS (self_class);
|
GstElementClass *gstelement_klass = GST_ELEMENT_CLASS (self_class);
|
||||||
|
GstCaps *sinkpad_caps = ges_demux_get_sinkpad_caps ();
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_INIT (gesdemux, "gesdemux", 0, "ges demux element");
|
GST_DEBUG_CATEGORY_INIT (gesdemux, "gesdemux", 0, "ges demux element");
|
||||||
|
|
||||||
|
@ -128,13 +210,16 @@ ges_demux_class_init (GESDemuxClass * self_class)
|
||||||
GES_TYPE_TIMELINE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
GES_TYPE_TIMELINE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||||
g_object_class_override_property (gclass, PROP_TIMELINE, "timeline");
|
g_object_class_override_property (gclass, PROP_TIMELINE, "timeline");
|
||||||
|
|
||||||
gst_element_class_add_pad_template (gstelement_klass,
|
|
||||||
gst_static_pad_template_get (&sink_template));
|
|
||||||
gst_element_class_set_static_metadata (gstelement_klass,
|
gst_element_class_set_static_metadata (gstelement_klass,
|
||||||
"GStreamer Editing Services based 'demuxer'",
|
"GStreamer Editing Services based 'demuxer'",
|
||||||
"Codec/Demux/Editing",
|
"Codec/Demux/Editing",
|
||||||
"Demuxer for complex timeline file formats using GES.",
|
"Demuxer for complex timeline file formats using GES.",
|
||||||
"Thibault Saunier <tsaunier@igalia.com");
|
"Thibault Saunier <tsaunier@igalia.com");
|
||||||
|
|
||||||
|
gst_element_class_add_pad_template (gstelement_klass,
|
||||||
|
gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
|
||||||
|
sinkpad_caps));
|
||||||
|
gst_caps_unref (sinkpad_caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -455,10 +540,22 @@ ges_demux_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
||||||
|
|
||||||
xges_buffer = gst_adapter_take_buffer (self->input_adapter, available);
|
xges_buffer = gst_adapter_take_buffer (self->input_adapter, available);
|
||||||
if (gst_buffer_map (xges_buffer, &map, GST_MAP_READ)) {
|
if (gst_buffer_map (xges_buffer, &map, GST_MAP_READ)) {
|
||||||
|
gint f;
|
||||||
GError *err = NULL;
|
GError *err = NULL;
|
||||||
|
gchar *template = NULL;
|
||||||
gchar *filename = NULL, *uri = NULL;
|
gchar *filename = NULL, *uri = NULL;
|
||||||
GError *error = NULL;
|
GstCaps *caps = gst_pad_get_current_caps (pad);
|
||||||
gint f = g_file_open_tmp (NULL, &filename, &err);
|
GstStructure *structure = gst_caps_get_structure (caps, 0);
|
||||||
|
gchar *ext = ges_demux_get_extension (structure);
|
||||||
|
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
if (ext) {
|
||||||
|
template = g_strdup_printf ("XXXXXX.%s", ext);
|
||||||
|
g_free (ext);
|
||||||
|
}
|
||||||
|
|
||||||
|
f = g_file_open_tmp (template, &filename, &err);
|
||||||
|
g_free (template);
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
GST_ELEMENT_ERROR (self, RESOURCE, OPEN_WRITE,
|
GST_ELEMENT_ERROR (self, RESOURCE, OPEN_WRITE,
|
||||||
|
@ -480,8 +577,8 @@ ges_demux_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
||||||
uri = gst_filename_to_uri (filename, NULL);
|
uri = gst_filename_to_uri (filename, NULL);
|
||||||
GST_INFO_OBJECT (self, "Pre loading the timeline.");
|
GST_INFO_OBJECT (self, "Pre loading the timeline.");
|
||||||
|
|
||||||
ges_demux_create_timeline (self, uri, &error);
|
ges_demux_create_timeline (self, uri, &err);
|
||||||
if (error)
|
if (err)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
@ -493,9 +590,9 @@ ges_demux_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
||||||
error:
|
error:
|
||||||
ret = FALSE;
|
ret = FALSE;
|
||||||
gst_element_post_message (GST_ELEMENT (self),
|
gst_element_post_message (GST_ELEMENT (self),
|
||||||
gst_message_new_error (parent, error,
|
gst_message_new_error (parent, err,
|
||||||
"Could not create timeline from description"));
|
"Could not create timeline from description"));
|
||||||
g_clear_error (&error);
|
g_clear_error (&err);
|
||||||
|
|
||||||
goto done;
|
goto done;
|
||||||
} else {
|
} else {
|
||||||
|
@ -528,7 +625,10 @@ static void
|
||||||
ges_demux_init (GESDemux * self)
|
ges_demux_init (GESDemux * self)
|
||||||
{
|
{
|
||||||
ges_init ();
|
ges_init ();
|
||||||
self->sinkpad = gst_pad_new_from_static_template (&sink_template, "sink");
|
|
||||||
|
self->sinkpad =
|
||||||
|
gst_pad_new_from_template (gst_element_get_pad_template (GST_ELEMENT
|
||||||
|
(self), "sink"), "sink");
|
||||||
gst_element_add_pad (GST_ELEMENT (self), self->sinkpad);
|
gst_element_add_pad (GST_ELEMENT (self), self->sinkpad);
|
||||||
|
|
||||||
self->input_adapter = gst_adapter_new ();
|
self->input_adapter = gst_adapter_new ();
|
||||||
|
|
Loading…
Reference in a new issue