mirror of
https://github.com/Rafostar/clapper.git
synced 2025-08-29 15:22:11 +02:00
Merge pull request #553 from Rafostar/harvest-caching
clapper: Implement harvest caching
This commit is contained in:
@@ -27,6 +27,9 @@ G_BEGIN_DECLS
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_cache_initialize (void);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean clapper_cache_is_disabled (void);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GMappedFile * clapper_cache_open (const gchar *filename, const gchar **data, GError **error);
|
||||
|
||||
@@ -39,12 +42,18 @@ gint clapper_cache_read_int (const gchar **data);
|
||||
G_GNUC_INTERNAL
|
||||
guint clapper_cache_read_uint (const gchar **data);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gint64 clapper_cache_read_int64 (const gchar **data);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gdouble clapper_cache_read_double (const gchar **data);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
const gchar * clapper_cache_read_string (const gchar **data);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
const guint8 * clapper_cache_read_data (const gchar **data, gsize *size);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GType clapper_cache_read_enum (const gchar **data);
|
||||
|
||||
@@ -69,12 +78,18 @@ void clapper_cache_store_int (GByteArray *bytes, gint val);
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_cache_store_uint (GByteArray *bytes, guint val);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_cache_store_int64 (GByteArray *bytes, gint64 val);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_cache_store_double (GByteArray *bytes, gdouble val);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_cache_store_string (GByteArray *bytes, const gchar *val);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_cache_store_data (GByteArray *bytes, const guint8 *val, gsize val_size);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_cache_store_enum (GByteArray *bytes, GType enum_type);
|
||||
|
||||
|
@@ -45,6 +45,12 @@ clapper_cache_initialize (void)
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
clapper_cache_is_disabled (void)
|
||||
{
|
||||
return cache_disabled;
|
||||
}
|
||||
|
||||
GMappedFile *
|
||||
clapper_cache_open (const gchar *filename, const gchar **data, GError **error)
|
||||
{
|
||||
@@ -111,6 +117,15 @@ clapper_cache_read_uint (const gchar **data)
|
||||
return val;
|
||||
}
|
||||
|
||||
inline gint64
|
||||
clapper_cache_read_int64 (const gchar **data)
|
||||
{
|
||||
gint64 val = *(const gint64 *) *data;
|
||||
*data += sizeof (gint64);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
inline gdouble
|
||||
clapper_cache_read_double (const gchar **data)
|
||||
{
|
||||
@@ -134,6 +149,22 @@ clapper_cache_read_string (const gchar **data)
|
||||
return str;
|
||||
}
|
||||
|
||||
inline const guint8 *
|
||||
clapper_cache_read_data (const gchar **data, gsize *size)
|
||||
{
|
||||
const guint8 *val = NULL;
|
||||
|
||||
*size = *(const gsize *) *data;
|
||||
*data += sizeof (gsize);
|
||||
|
||||
if (G_LIKELY (*size > 0)) {
|
||||
val = (const guint8 *) *data;
|
||||
*data += *size;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
inline GType
|
||||
clapper_cache_read_enum (const gchar **data)
|
||||
{
|
||||
@@ -332,6 +363,12 @@ clapper_cache_store_uint (GByteArray *bytes, guint val)
|
||||
g_byte_array_append (bytes, (const guint8 *) &val, sizeof (guint));
|
||||
}
|
||||
|
||||
inline void
|
||||
clapper_cache_store_int64 (GByteArray *bytes, gint64 val)
|
||||
{
|
||||
g_byte_array_append (bytes, (const guint8 *) &val, sizeof (gint64));
|
||||
}
|
||||
|
||||
inline void
|
||||
clapper_cache_store_double (GByteArray *bytes, gdouble val)
|
||||
{
|
||||
@@ -349,6 +386,14 @@ clapper_cache_store_string (GByteArray *bytes, const gchar *val)
|
||||
g_byte_array_append (bytes, (const guint8 *) val, strlen (val) + 1);
|
||||
}
|
||||
|
||||
inline void
|
||||
clapper_cache_store_data (GByteArray *bytes, const guint8 *val, gsize val_size)
|
||||
{
|
||||
g_byte_array_append (bytes, (const guint8 *) &val_size, sizeof (gsize));
|
||||
if (G_LIKELY (val_size > 0))
|
||||
g_byte_array_append (bytes, val, val_size);
|
||||
}
|
||||
|
||||
inline void
|
||||
clapper_cache_store_enum (GByteArray *bytes, GType enum_type)
|
||||
{
|
||||
|
@@ -21,6 +21,7 @@
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "clapper-enhancer-proxy.h"
|
||||
|
||||
@@ -45,6 +46,9 @@ G_GNUC_INTERNAL
|
||||
GObject * clapper_enhancer_proxy_get_peas_info (ClapperEnhancerProxy *proxy);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_enhancer_proxy_apply_current_config_to_enhancer (ClapperEnhancerProxy *proxy, GObject *enhancer);
|
||||
GstStructure * clapper_enhancer_proxy_make_current_config (ClapperEnhancerProxy *proxy);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_enhancer_proxy_apply_config_to_enhancer (ClapperEnhancerProxy *proxy, const GstStructure *config, GObject *enhancer);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -507,15 +507,18 @@ _apply_config_cb (GQuark field_id, const GValue *value, GObject *enhancer)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
clapper_enhancer_proxy_apply_current_config_to_enhancer (ClapperEnhancerProxy *self, GObject *enhancer)
|
||||
/*
|
||||
* clapper_enhancer_proxy_make_current_config:
|
||||
*
|
||||
* Returns: (transfer full) (nullable): Current merged global and local config as #GstStructure.
|
||||
*/
|
||||
GstStructure *
|
||||
clapper_enhancer_proxy_make_current_config (ClapperEnhancerProxy *self)
|
||||
{
|
||||
GSettings *settings = clapper_enhancer_proxy_get_settings (self);
|
||||
GstStructure *merged_config = NULL;
|
||||
guint i;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Applying config to enhancer");
|
||||
|
||||
/* Lock here to ensure consistent local config */
|
||||
GST_OBJECT_LOCK (self);
|
||||
|
||||
@@ -587,13 +590,14 @@ clapper_enhancer_proxy_apply_current_config_to_enhancer (ClapperEnhancerProxy *s
|
||||
|
||||
g_clear_object (&settings);
|
||||
|
||||
/* Nothing if no configurable properties
|
||||
* or all have default values */
|
||||
if (merged_config) {
|
||||
gst_structure_foreach (merged_config, (GstStructureForeachFunc) _apply_config_cb, enhancer);
|
||||
gst_structure_free (merged_config);
|
||||
}
|
||||
return merged_config;
|
||||
}
|
||||
|
||||
void
|
||||
clapper_enhancer_proxy_apply_config_to_enhancer (ClapperEnhancerProxy *self, const GstStructure *config, GObject *enhancer)
|
||||
{
|
||||
GST_DEBUG_OBJECT (self, "Applying config to enhancer");
|
||||
gst_structure_foreach (config, (GstStructureForeachFunc) _apply_config_cb, enhancer);
|
||||
GST_DEBUG_OBJECT (self, "Enhancer config applied");
|
||||
}
|
||||
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#include <gst/tag/tag.h>
|
||||
|
||||
#include "clapper-harvest.h"
|
||||
#include "clapper-enhancer-proxy.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -32,4 +33,10 @@ ClapperHarvest * clapper_harvest_new (void);
|
||||
G_GNUC_INTERNAL
|
||||
gboolean clapper_harvest_unpack (ClapperHarvest *harvest, GstBuffer **buffer, gsize *buf_size, GstCaps **caps, GstTagList **tags, GstToc **toc, GstStructure **headers);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean clapper_harvest_fill_from_cache (ClapperHarvest *harvest, ClapperEnhancerProxy *proxy, const GstStructure *config, GUri *uri);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_harvest_export_to_cache (ClapperHarvest *harvest, ClapperEnhancerProxy *proxy, const GstStructure *config, GUri *uri);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -31,7 +31,11 @@
|
||||
* https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/2867
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "clapper-harvest-private.h"
|
||||
#include "clapper-cache-private.h"
|
||||
#include "clapper-utils.h"
|
||||
|
||||
#define GST_CAT_DEFAULT clapper_harvest_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
@@ -50,6 +54,8 @@ struct _ClapperHarvest
|
||||
|
||||
guint16 n_chapters;
|
||||
guint16 n_tracks;
|
||||
|
||||
gint64 exp_epoch;
|
||||
};
|
||||
|
||||
#define parent_class clapper_harvest_parent_class
|
||||
@@ -119,6 +125,302 @@ clapper_harvest_unpack (ClapperHarvest *self,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Custom implementation due to the lack of TOC serialization in GStreamer */
|
||||
static void
|
||||
_harvest_fill_toc_from_cache (ClapperHarvest *self, const gchar **data)
|
||||
{
|
||||
guint i, n_entries;
|
||||
|
||||
n_entries = clapper_cache_read_uint (data);
|
||||
for (i = 0; i < n_entries; ++i) {
|
||||
guint j, n_subentries;
|
||||
|
||||
n_subentries = clapper_cache_read_uint (data);
|
||||
for (j = 0; j < n_subentries; ++j) {
|
||||
GstTocEntryType type;
|
||||
const gchar *title;
|
||||
gdouble start, end;
|
||||
|
||||
type = (GstTocEntryType) clapper_cache_read_int (data);
|
||||
title = clapper_cache_read_string (data);
|
||||
start = clapper_cache_read_double (data);
|
||||
end = clapper_cache_read_double (data);
|
||||
|
||||
clapper_harvest_toc_add (self, type, title, start, end);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_harvest_store_toc_to_cache (ClapperHarvest *self, GByteArray *bytes)
|
||||
{
|
||||
GList *list = NULL, *el;
|
||||
guint n_entries = 0;
|
||||
|
||||
if (self->toc) {
|
||||
list = gst_toc_get_entries (self->toc);
|
||||
n_entries = g_list_length (list);
|
||||
}
|
||||
clapper_cache_store_uint (bytes, n_entries);
|
||||
|
||||
for (el = list; el; el = g_list_next (el)) {
|
||||
const GstTocEntry *entry = (const GstTocEntry *) el->data;
|
||||
GList *subentries, *sub_el;
|
||||
guint n_subentries;
|
||||
|
||||
subentries = gst_toc_entry_get_sub_entries (entry);
|
||||
n_subentries = g_list_length (subentries);
|
||||
|
||||
clapper_cache_store_uint (bytes, n_subentries);
|
||||
|
||||
for (sub_el = subentries; sub_el; sub_el = g_list_next (sub_el)) {
|
||||
const GstTocEntry *subentry = (const GstTocEntry *) sub_el->data;
|
||||
GstTagList *tags;
|
||||
gint64 start = 0, end = 0;
|
||||
gdouble start_dbl, end_dbl;
|
||||
const gchar *title = NULL;
|
||||
|
||||
clapper_cache_store_int (bytes, (gint) gst_toc_entry_get_entry_type (subentry));
|
||||
|
||||
if ((tags = gst_toc_entry_get_tags (subentry)))
|
||||
gst_tag_list_peek_string_index (tags, GST_TAG_TITLE, 0, &title);
|
||||
|
||||
clapper_cache_store_string (bytes, title);
|
||||
|
||||
gst_toc_entry_get_start_stop_times (subentry, &start, &end);
|
||||
start_dbl = ((gdouble) start) / GST_SECOND;
|
||||
end_dbl = (end >= 0) ? ((gdouble) end) / GST_SECOND : -1;
|
||||
|
||||
clapper_cache_store_double (bytes, start_dbl);
|
||||
clapper_cache_store_double (bytes, end_dbl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline gchar *
|
||||
_build_cache_filename (ClapperEnhancerProxy *proxy, GUri *uri)
|
||||
{
|
||||
gchar *uri_str = g_uri_to_string (uri);
|
||||
gchar name[15];
|
||||
|
||||
g_snprintf (name, sizeof (name), "%u.bin", g_str_hash (uri_str));
|
||||
g_free (uri_str);
|
||||
|
||||
return g_build_filename (g_get_user_cache_dir (), CLAPPER_API_NAME,
|
||||
"enhancers", clapper_enhancer_proxy_get_module_name (proxy),
|
||||
"harvests", name, NULL);
|
||||
}
|
||||
|
||||
/* NOTE: On failure, this function must not modify harvest! */
|
||||
gboolean
|
||||
clapper_harvest_fill_from_cache (ClapperHarvest *self, ClapperEnhancerProxy *proxy,
|
||||
const GstStructure *config, GUri *uri)
|
||||
{
|
||||
GMappedFile *mapped_file;
|
||||
GstStructure *config_cached = NULL;
|
||||
GError *error = NULL;
|
||||
gchar *filename;
|
||||
const gchar *data, *read_str;
|
||||
const guint8 *buf_data;
|
||||
guint8 *buf_copy;
|
||||
gsize buf_size;
|
||||
gint64 epoch_cached, epoch_now = 0;
|
||||
gdouble exp_seconds;
|
||||
gboolean changed, read_ok = FALSE;
|
||||
|
||||
filename = _build_cache_filename (proxy, uri);
|
||||
GST_DEBUG_OBJECT (self, "Importing harvest from cache file: \"%s\"", filename);
|
||||
mapped_file = clapper_cache_open (filename, &data, &error);
|
||||
g_free (filename);
|
||||
|
||||
if (!mapped_file) {
|
||||
/* No error if cache disabled or version mismatch */
|
||||
if (error) {
|
||||
if (error->domain == G_FILE_ERROR && error->code == G_FILE_ERROR_NOENT)
|
||||
GST_DEBUG_OBJECT (self, "No cached harvest found");
|
||||
else
|
||||
GST_ERROR_OBJECT (self, "Could not use cached harvest, reason: %s", error->message);
|
||||
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Plugin version check */
|
||||
if (g_strcmp0 (clapper_cache_read_string (&data),
|
||||
clapper_enhancer_proxy_get_version (proxy)) != 0)
|
||||
goto finish; // no error printing here
|
||||
|
||||
if (G_LIKELY ((epoch_cached = clapper_cache_read_int64 (&data)) > 0)) {
|
||||
GDateTime *date = g_date_time_new_now_utc ();
|
||||
epoch_now = g_date_time_to_unix (date);
|
||||
g_date_time_unref (date);
|
||||
}
|
||||
|
||||
/* Check if expired */
|
||||
if ((exp_seconds = (gdouble) (epoch_cached - epoch_now)) <= 0) {
|
||||
GST_DEBUG_OBJECT (self, "Cached harvest expired"); // expiration is not an error
|
||||
goto finish;
|
||||
}
|
||||
GST_DEBUG_OBJECT (self, "Cached harvest expiration in %" CLAPPER_TIME_FORMAT,
|
||||
CLAPPER_TIME_ARGS (exp_seconds));
|
||||
|
||||
/* Read last used config to generate cache data */
|
||||
if ((read_str = clapper_cache_read_string (&data)))
|
||||
config_cached = gst_structure_from_string (read_str, NULL);
|
||||
|
||||
/* Compare used config when cache was generated to the current one */
|
||||
changed = (config_cached && config)
|
||||
? !gst_structure_is_equal (config_cached, config)
|
||||
: (config_cached != config);
|
||||
|
||||
gst_clear_structure (&config_cached);
|
||||
|
||||
if (changed) {
|
||||
GST_DEBUG_OBJECT (self, "Enhancer config differs from the last time");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* Read media type */
|
||||
read_str = clapper_cache_read_string (&data);
|
||||
if (G_UNLIKELY (read_str == NULL)) {
|
||||
GST_ERROR_OBJECT (self, "Could not read media type from cache file");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* Read buffer data */
|
||||
buf_data = clapper_cache_read_data (&data, &buf_size);
|
||||
if (G_UNLIKELY (buf_data == NULL)) {
|
||||
GST_ERROR_OBJECT (self, "Could not read buffer data from cache");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* Fill harvest */
|
||||
buf_copy = g_memdup2 (buf_data, buf_size);
|
||||
if (!clapper_harvest_fill (self, read_str, buf_copy, buf_size))
|
||||
goto finish;
|
||||
|
||||
/* Read tags */
|
||||
read_str = clapper_cache_read_string (&data);
|
||||
if (read_str && (self->tags = gst_tag_list_new_from_string (read_str))) {
|
||||
GST_LOG_OBJECT (self, "Read %s", read_str);
|
||||
gst_tag_list_set_scope (self->tags, GST_TAG_SCOPE_GLOBAL);
|
||||
}
|
||||
|
||||
/* Read TOC */
|
||||
_harvest_fill_toc_from_cache (self, &data);
|
||||
|
||||
/* Read headers */
|
||||
read_str = clapper_cache_read_string (&data);
|
||||
if (read_str && (self->headers = gst_structure_from_string (read_str, NULL)))
|
||||
GST_LOG_OBJECT (self, "Read %s", read_str);
|
||||
|
||||
read_ok = TRUE;
|
||||
|
||||
finish:
|
||||
g_mapped_file_unref (mapped_file);
|
||||
|
||||
if (!read_ok)
|
||||
return FALSE;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Filled harvest from cache");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
clapper_harvest_export_to_cache (ClapperHarvest *self, ClapperEnhancerProxy *proxy,
|
||||
const GstStructure *config, GUri *uri)
|
||||
{
|
||||
GByteArray *bytes;
|
||||
const GstStructure *caps_structure;
|
||||
gchar *filename, *temp_str = NULL;
|
||||
gboolean data_ok = TRUE;
|
||||
|
||||
/* No caching if no expiration date set */
|
||||
if (self->exp_epoch <= 0)
|
||||
return;
|
||||
|
||||
/* Might happen if extractor extract function implementation
|
||||
* returns %TRUE without filling harvest properly */
|
||||
if (G_UNLIKELY (self->caps == NULL || self->buffer == NULL))
|
||||
return; // no data to cache
|
||||
|
||||
bytes = clapper_cache_create ();
|
||||
|
||||
/* If cache disabled */
|
||||
if (G_UNLIKELY (bytes == NULL))
|
||||
return;
|
||||
|
||||
filename = _build_cache_filename (proxy, uri);
|
||||
GST_DEBUG_OBJECT (self, "Exporting harvest to cache file: \"%s\"", filename);
|
||||
|
||||
/* Store enhancer version that generated harvest */
|
||||
clapper_cache_store_string (bytes, clapper_enhancer_proxy_get_version (proxy));
|
||||
|
||||
/* Store expiration date */
|
||||
clapper_cache_store_int64 (bytes, self->exp_epoch);
|
||||
|
||||
/* Store config used to generate harvest */
|
||||
if (config)
|
||||
temp_str = gst_structure_to_string (config);
|
||||
clapper_cache_store_string (bytes, temp_str); // NULL when no config
|
||||
g_clear_pointer (&temp_str, g_free);
|
||||
|
||||
/* Store media type */
|
||||
caps_structure = gst_caps_get_structure (self->caps, 0);
|
||||
if (G_LIKELY (caps_structure != NULL)) {
|
||||
clapper_cache_store_string (bytes, gst_structure_get_name (caps_structure));
|
||||
} else {
|
||||
GST_ERROR_OBJECT (self, "Cannot cache empty caps");
|
||||
data_ok = FALSE;
|
||||
}
|
||||
|
||||
if (G_LIKELY (data_ok)) {
|
||||
GstMemory *mem;
|
||||
GstMapInfo map_info;
|
||||
|
||||
/* Store buffer data */
|
||||
mem = gst_buffer_peek_memory (self->buffer, 0);
|
||||
if (G_LIKELY (gst_memory_map (mem, &map_info, GST_MAP_READ))) {
|
||||
clapper_cache_store_data (bytes, map_info.data, map_info.size);
|
||||
gst_memory_unmap (mem, &map_info);
|
||||
} else {
|
||||
GST_ERROR_OBJECT (self, "Could not map harvest buffer for reading");
|
||||
data_ok = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (G_LIKELY (data_ok)) {
|
||||
GError *error = NULL;
|
||||
|
||||
/* Store tags */
|
||||
if (self->tags)
|
||||
temp_str = gst_tag_list_to_string (self->tags);
|
||||
clapper_cache_store_string (bytes, temp_str);
|
||||
g_clear_pointer (&temp_str, g_free);
|
||||
|
||||
/* Store TOC */
|
||||
_harvest_store_toc_to_cache (self, bytes);
|
||||
|
||||
/* Store headers */
|
||||
if (self->headers)
|
||||
temp_str = gst_structure_to_string (self->headers);
|
||||
clapper_cache_store_string (bytes, temp_str);
|
||||
g_clear_pointer (&temp_str, g_free);
|
||||
|
||||
if (clapper_cache_write (filename, bytes, &error)) {
|
||||
GST_DEBUG_OBJECT (self, "Successfully exported harvest to cache file");
|
||||
} else if (error) {
|
||||
GST_ERROR_OBJECT (self, "Could not cache harvest, reason: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
g_free (filename);
|
||||
g_byte_array_free (bytes, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_harvest_fill:
|
||||
* @harvest: a #ClapperHarvest
|
||||
@@ -155,7 +457,7 @@ clapper_harvest_fill (ClapperHarvest *self, const gchar *media_type, gpointer da
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (gst_debug_category_get_threshold (GST_CAT_DEFAULT) >= GST_LEVEL_DEBUG) {
|
||||
if (gst_debug_category_get_threshold (GST_CAT_DEFAULT) >= GST_LEVEL_LOG) {
|
||||
gboolean is_printable = (strcmp (media_type, "application/dash+xml") == 0)
|
||||
|| (strcmp (media_type, "application/x-hls") == 0)
|
||||
|| (strcmp (media_type, "text/uri-list") == 0);
|
||||
@@ -166,7 +468,7 @@ clapper_harvest_fill (ClapperHarvest *self, const gchar *media_type, gpointer da
|
||||
data_str = g_new0 (gchar, size + 1);
|
||||
memcpy (data_str, data, size);
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Filled with data:\n%s", data_str);
|
||||
GST_LOG_OBJECT (self, "Filled with data:\n%s", data_str);
|
||||
|
||||
g_free (data_str);
|
||||
}
|
||||
@@ -328,7 +630,7 @@ clapper_harvest_toc_add (ClapperHarvest *self, GstTocEntryType type,
|
||||
g_snprintf (edition, sizeof (edition), "0%i", type);
|
||||
g_snprintf (id, sizeof (id), "%s.%" G_GUINT16_FORMAT, id_prefix, nth_entry);
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Inserting TOC %s: \"%s\""
|
||||
GST_LOG_OBJECT (self, "Inserting TOC %s: \"%s\""
|
||||
" (%" G_GUINT64_FORMAT "-%" G_GUINT64_FORMAT ")",
|
||||
id, title, start_time, end_time);
|
||||
|
||||
@@ -380,7 +682,7 @@ clapper_harvest_headers_set (ClapperHarvest *self, const gchar *key, ...)
|
||||
|
||||
while (key != NULL) {
|
||||
const gchar *val = va_arg (args, const gchar *);
|
||||
GST_DEBUG_OBJECT (self, "Set header, \"%s\": \"%s\"", key, val);
|
||||
GST_LOG_OBJECT (self, "Set header, \"%s\": \"%s\"", key, val);
|
||||
gst_structure_set (self->headers, key, G_TYPE_STRING, val, NULL);
|
||||
key = va_arg (args, const gchar *);
|
||||
}
|
||||
@@ -409,10 +711,70 @@ clapper_harvest_headers_set_value (ClapperHarvest *self, const gchar *key, const
|
||||
|
||||
_ensure_headers (self);
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Set header, \"%s\": \"%s\"", key, g_value_get_string (value));
|
||||
GST_LOG_OBJECT (self, "Set header, \"%s\": \"%s\"", key, g_value_get_string (value));
|
||||
gst_structure_set_value (self->headers, key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_harvest_set_expiration_date_utc:
|
||||
* @harvest: a #ClapperHarvest
|
||||
* @date_utc: a #GDateTime in UTC time
|
||||
*
|
||||
* Set date in UTC time until harvested content is expected
|
||||
* to stay alive.
|
||||
*
|
||||
* This is used for harvest caching, so next time user requests to
|
||||
* play the same URI, recently harvested data can be reused without
|
||||
* the need to run [vfunc@Clapper.Extractable.extract] again.
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
void
|
||||
clapper_harvest_set_expiration_date_utc (ClapperHarvest *self, GDateTime *date_utc)
|
||||
{
|
||||
g_return_if_fail (CLAPPER_IS_HARVEST (self));
|
||||
g_return_if_fail (date_utc != NULL);
|
||||
|
||||
self->exp_epoch = g_date_time_to_unix (date_utc);
|
||||
GST_LOG_OBJECT (self, "Expiration epoch: %" G_GINT64_FORMAT, self->exp_epoch);
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_harvest_set_expiration_seconds:
|
||||
* @harvest: a #ClapperHarvest
|
||||
* @seconds: time in seconds until expiration
|
||||
*
|
||||
* Set amount of seconds for how long harvested content is
|
||||
* expected to stay alive.
|
||||
*
|
||||
* Alternative function to [method@Clapper.Harvest.set_expiration_date_utc],
|
||||
* but takes time as number in seconds from now.
|
||||
*
|
||||
* It is safe to pass zero or negative number to this function in
|
||||
* case when calculating time manually and it already expired.
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
void
|
||||
clapper_harvest_set_expiration_seconds (ClapperHarvest *self, gdouble seconds)
|
||||
{
|
||||
GDateTime *date, *date_epoch;
|
||||
|
||||
g_return_if_fail (CLAPPER_IS_HARVEST (self));
|
||||
|
||||
GST_LOG_OBJECT (self, "Set expiration in %" CLAPPER_TIME_FORMAT,
|
||||
CLAPPER_TIME_ARGS (seconds));
|
||||
|
||||
date = g_date_time_new_now_utc ();
|
||||
date_epoch = g_date_time_add_seconds (date, seconds);
|
||||
g_date_time_unref (date);
|
||||
|
||||
self->exp_epoch = g_date_time_to_unix (date_epoch);
|
||||
g_date_time_unref (date_epoch);
|
||||
|
||||
GST_LOG_OBJECT (self, "Expiration epoch: %" G_GINT64_FORMAT, self->exp_epoch);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_harvest_init (ClapperHarvest *self)
|
||||
{
|
||||
|
@@ -61,4 +61,10 @@ void clapper_harvest_headers_set (ClapperHarvest *harvest, const gchar *key, ...
|
||||
CLAPPER_API
|
||||
void clapper_harvest_headers_set_value (ClapperHarvest *harvest, const gchar *key, const GValue *value);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_harvest_set_expiration_date_utc (ClapperHarvest *harvest, GDateTime *date_utc);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_harvest_set_expiration_seconds (ClapperHarvest *harvest, gdouble seconds);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -29,12 +29,7 @@
|
||||
#include "clapper-timeline-private.h"
|
||||
#include "clapper-stream-private.h"
|
||||
#include "clapper-stream-list-private.h"
|
||||
|
||||
#include "clapper-functionalities-availability.h"
|
||||
|
||||
#if CLAPPER_WITH_ENHANCERS_LOADER
|
||||
#include "gst/clapper-enhancer-src-private.h"
|
||||
#endif
|
||||
#include "gst/clapper-extractable-src-private.h"
|
||||
|
||||
#define GST_CAT_DEFAULT clapper_playbin_bus_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
@@ -875,7 +870,6 @@ _handle_tag_msg (GstMessage *msg, ClapperPlayer *player)
|
||||
{
|
||||
GstObject *src = GST_MESSAGE_SRC (msg);
|
||||
GstTagList *tags = NULL;
|
||||
gboolean from_enhancer_src;
|
||||
|
||||
/* Tag messages should only be posted by sink elements */
|
||||
if (G_UNLIKELY (!src))
|
||||
@@ -886,14 +880,8 @@ _handle_tag_msg (GstMessage *msg, ClapperPlayer *player)
|
||||
GST_LOG_OBJECT (player, "Got tags from element: %s: %" GST_PTR_FORMAT,
|
||||
GST_OBJECT_NAME (src), tags);
|
||||
|
||||
#if CLAPPER_WITH_ENHANCERS_LOADER
|
||||
from_enhancer_src = CLAPPER_IS_ENHANCER_SRC (src);
|
||||
#else
|
||||
from_enhancer_src = FALSE;
|
||||
#endif
|
||||
|
||||
/* ClapperEnhancerSrc determines tags before stream start */
|
||||
if (from_enhancer_src) {
|
||||
/* ClapperExtractableSrc determines tags before stream start */
|
||||
if (CLAPPER_IS_EXTRACTABLE_SRC (src)) {
|
||||
if (player->pending_tags) {
|
||||
gst_tag_list_unref (player->pending_tags);
|
||||
}
|
||||
@@ -910,7 +898,7 @@ _handle_toc_msg (GstMessage *msg, ClapperPlayer *player)
|
||||
{
|
||||
GstObject *src = GST_MESSAGE_SRC (msg);
|
||||
GstToc *toc = NULL;
|
||||
gboolean from_enhancer_src, updated = FALSE;
|
||||
gboolean updated = FALSE;
|
||||
|
||||
/* TOC messages should only be posted by sink elements */
|
||||
if (G_UNLIKELY (!src))
|
||||
@@ -923,14 +911,8 @@ _handle_toc_msg (GstMessage *msg, ClapperPlayer *player)
|
||||
" from element: %s, updated: %s",
|
||||
toc, GST_OBJECT_NAME (src), (updated) ? "yes" : "no");
|
||||
|
||||
#if CLAPPER_WITH_ENHANCERS_LOADER
|
||||
from_enhancer_src = CLAPPER_IS_ENHANCER_SRC (src);
|
||||
#else
|
||||
from_enhancer_src = FALSE;
|
||||
#endif
|
||||
|
||||
/* ClapperEnhancerSrc determines TOC before stream start */
|
||||
if (from_enhancer_src) {
|
||||
/* ClapperExtractableSrc determines TOC before stream start */
|
||||
if (CLAPPER_IS_EXTRACTABLE_SRC (src)) {
|
||||
if (player->pending_toc) {
|
||||
gst_toc_unref (player->pending_toc);
|
||||
}
|
||||
|
@@ -816,7 +816,7 @@ _element_setup_cb (GstElement *playbin, GstElement *element, ClapperPlayer *self
|
||||
factory_name = g_intern_static_string (GST_OBJECT_NAME (factory));
|
||||
GST_INFO_OBJECT (self, "Element setup: %s", factory_name);
|
||||
|
||||
if (factory_name == g_intern_static_string ("clapperenhancersrc")) {
|
||||
if (factory_name == g_intern_static_string ("clapperextractablesrc")) {
|
||||
g_object_set (element,
|
||||
"enhancer-proxies", self->enhancer_proxies,
|
||||
NULL);
|
||||
|
@@ -17,12 +17,17 @@
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "clapper-enhancer-director-private.h"
|
||||
#include "../clapper-basic-functions.h"
|
||||
#include "../clapper-cache-private.h"
|
||||
#include "../clapper-enhancer-proxy-private.h"
|
||||
#include "../clapper-extractable-private.h"
|
||||
#include "../clapper-harvest-private.h"
|
||||
#include "../clapper-utils.h"
|
||||
#include "../../shared/clapper-shared-utils-private.h"
|
||||
|
||||
#include "../clapper-functionalities-availability.h"
|
||||
@@ -31,6 +36,8 @@
|
||||
#include "../clapper-enhancers-loader-private.h"
|
||||
#endif
|
||||
|
||||
#define CLEANUP_INTERVAL 10800 // once every 3 hours
|
||||
|
||||
#define GST_CAT_DEFAULT clapper_enhancer_director_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
|
||||
@@ -57,7 +64,7 @@ clapper_enhancer_director_extract_in_thread (ClapperEnhancerDirectorData *data)
|
||||
ClapperEnhancerDirector *self = data->director;
|
||||
GList *el;
|
||||
ClapperHarvest *harvest = NULL;
|
||||
gboolean success = FALSE, cached = FALSE;
|
||||
gboolean success = FALSE;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Extraction start");
|
||||
|
||||
@@ -65,22 +72,22 @@ clapper_enhancer_director_extract_in_thread (ClapperEnhancerDirectorData *data)
|
||||
if (g_cancellable_is_cancelled (data->cancellable))
|
||||
return NULL;
|
||||
|
||||
/* TODO: Cache lookup */
|
||||
if (cached) {
|
||||
// if ((success = fill harvest from cache))
|
||||
// return harvest;
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Enhancer proxies for URI: %u",
|
||||
g_list_length (data->filtered_proxies));
|
||||
|
||||
for (el = data->filtered_proxies; el; el = g_list_next (el)) {
|
||||
ClapperEnhancerProxy *proxy = CLAPPER_ENHANCER_PROXY_CAST (el->data);
|
||||
ClapperExtractable *extractable = NULL;
|
||||
GstStructure *config;
|
||||
|
||||
/* Check just before extract */
|
||||
if (g_cancellable_is_cancelled (data->cancellable))
|
||||
harvest = clapper_harvest_new (); // fresh harvest for each iteration
|
||||
config = clapper_enhancer_proxy_make_current_config (proxy);
|
||||
|
||||
if ((success = clapper_harvest_fill_from_cache (harvest, proxy, config, data->uri))
|
||||
|| g_cancellable_is_cancelled (data->cancellable)) { // Check before extract
|
||||
gst_clear_structure (&config);
|
||||
break;
|
||||
}
|
||||
|
||||
#if CLAPPER_WITH_ENHANCERS_LOADER
|
||||
extractable = CLAPPER_EXTRACTABLE_CAST (
|
||||
@@ -88,32 +95,32 @@ clapper_enhancer_director_extract_in_thread (ClapperEnhancerDirectorData *data)
|
||||
#endif
|
||||
|
||||
if (G_LIKELY (extractable != NULL)) {
|
||||
clapper_enhancer_proxy_apply_current_config_to_enhancer (proxy, (GObject *) extractable);
|
||||
|
||||
harvest = clapper_harvest_new (); // fresh harvest for each extractable
|
||||
clapper_enhancer_proxy_apply_config_to_enhancer (proxy, config, (GObject *) extractable);
|
||||
|
||||
success = clapper_extractable_extract (extractable, data->uri,
|
||||
harvest, data->cancellable, data->error);
|
||||
gst_object_unref (extractable);
|
||||
|
||||
/* We are done with extractable, but keep its harvest */
|
||||
if (success)
|
||||
break;
|
||||
/* We are done with extractable, but keep harvest and try to cache it */
|
||||
if (success) {
|
||||
if (!g_cancellable_is_cancelled (data->cancellable))
|
||||
clapper_harvest_export_to_cache (harvest, proxy, config, data->uri);
|
||||
|
||||
/* Clear harvest and try again with next enhancer */
|
||||
g_clear_object (&harvest);
|
||||
gst_clear_structure (&config);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Cleanup to try again with next enhancer */
|
||||
g_clear_object (&harvest);
|
||||
gst_clear_structure (&config);
|
||||
}
|
||||
|
||||
/* Cancelled during extract */
|
||||
/* Cancelled during extraction or exporting to cache */
|
||||
if (g_cancellable_is_cancelled (data->cancellable))
|
||||
success = FALSE;
|
||||
|
||||
if (success) {
|
||||
if (!cached) {
|
||||
/* TODO: Store in cache */
|
||||
}
|
||||
} else {
|
||||
if (!success) {
|
||||
gst_clear_object (&harvest);
|
||||
|
||||
/* Ensure we have some error set on failure */
|
||||
@@ -131,6 +138,171 @@ clapper_enhancer_director_extract_in_thread (ClapperEnhancerDirectorData *data)
|
||||
return harvest;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_harvest_delete_if_expired (ClapperEnhancerDirector *self,
|
||||
ClapperEnhancerProxy *proxy, GFile *file, const gint64 epoch_now)
|
||||
{
|
||||
GMappedFile *mapped_file;
|
||||
const gchar *data;
|
||||
gchar *filename;
|
||||
GError *error = NULL;
|
||||
gboolean delete = TRUE;
|
||||
|
||||
filename = g_file_get_path (file);
|
||||
|
||||
if ((mapped_file = clapper_cache_open (filename, &data, &error))) {
|
||||
/* Do not delete if versions match and not expired */
|
||||
if (g_strcmp0 (clapper_cache_read_string (&data),
|
||||
clapper_enhancer_proxy_get_version (proxy)) == 0
|
||||
&& clapper_cache_read_int64 (&data) > epoch_now) {
|
||||
delete = FALSE;
|
||||
}
|
||||
g_mapped_file_unref (mapped_file);
|
||||
} else if (error) {
|
||||
if (error->domain == G_FILE_ERROR && error->code == G_FILE_ERROR_NOENT)
|
||||
GST_DEBUG_OBJECT (self, "No cached harvest file found");
|
||||
else
|
||||
GST_ERROR_OBJECT (self, "Could not read cached harvest file, reason: %s", error->message);
|
||||
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
if (delete) {
|
||||
if (G_LIKELY (g_file_delete (file, NULL, &error))) {
|
||||
GST_TRACE_OBJECT (self, "Deleted cached harvest: \"%s\"", filename);
|
||||
} else {
|
||||
GST_ERROR_OBJECT (self, "Could not delete harvest: \"%s\", reason: %s",
|
||||
filename, GST_STR_NULL (error->message));
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
g_free (filename);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_cache_proxy_harvests_cleanup (ClapperEnhancerDirector *self,
|
||||
ClapperEnhancerProxy *proxy, const gint64 epoch_now)
|
||||
{
|
||||
GFile *dir;
|
||||
GFileEnumerator *dir_enum;
|
||||
GError *error = NULL;
|
||||
|
||||
dir = g_file_new_build_filename (g_get_user_cache_dir (), CLAPPER_API_NAME,
|
||||
"enhancers", clapper_enhancer_proxy_get_module_name (proxy),
|
||||
"harvests", NULL);
|
||||
|
||||
if ((dir_enum = g_file_enumerate_children (dir,
|
||||
G_FILE_ATTRIBUTE_STANDARD_NAME "," G_FILE_ATTRIBUTE_STANDARD_TYPE,
|
||||
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &error))) {
|
||||
while (TRUE) {
|
||||
GFileInfo *info = NULL;
|
||||
GFile *child = NULL;
|
||||
|
||||
if (!g_file_enumerator_iterate (dir_enum, &info,
|
||||
&child, NULL, &error) || !info)
|
||||
break;
|
||||
|
||||
if (G_LIKELY (g_file_info_get_file_type (info) == G_FILE_TYPE_REGULAR
|
||||
&& g_str_has_suffix (g_file_info_get_name (info), ".bin")))
|
||||
_harvest_delete_if_expired (self, proxy, child, epoch_now);
|
||||
}
|
||||
|
||||
g_object_unref (dir_enum);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
if (error->domain != G_IO_ERROR || error->code != G_IO_ERROR_NOT_FOUND) {
|
||||
gchar *path = g_file_get_path (dir);
|
||||
|
||||
GST_ERROR_OBJECT (self, "Could not cleanup in dir: \"%s\", reason: %s",
|
||||
path, GST_STR_NULL (error->message));
|
||||
g_free (path);
|
||||
}
|
||||
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
g_object_unref (dir);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_cache_cleanup_func (ClapperEnhancerDirector *self)
|
||||
{
|
||||
GMappedFile *mapped_file;
|
||||
GDateTime *date;
|
||||
GError *error = NULL;
|
||||
gchar *filename;
|
||||
const gchar *data;
|
||||
gint64 since_cleanup, epoch_now, epoch_last = 0;
|
||||
|
||||
date = g_date_time_new_now_utc ();
|
||||
epoch_now = g_date_time_to_unix (date);
|
||||
g_date_time_unref (date);
|
||||
|
||||
filename = g_build_filename (g_get_user_cache_dir (), CLAPPER_API_NAME,
|
||||
"enhancers", "cleanup.bin", NULL);
|
||||
|
||||
if ((mapped_file = clapper_cache_open (filename, &data, &error))) {
|
||||
epoch_last = clapper_cache_read_int64 (&data);
|
||||
g_mapped_file_unref (mapped_file);
|
||||
} else if (error) {
|
||||
if (error->domain == G_FILE_ERROR && error->code == G_FILE_ERROR_NOENT)
|
||||
GST_DEBUG_OBJECT (self, "No cache cleanup file found");
|
||||
else
|
||||
GST_ERROR_OBJECT (self, "Could not read cache cleanup file, reason: %s", error->message);
|
||||
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
since_cleanup = epoch_now - epoch_last;
|
||||
|
||||
if (since_cleanup >= CLEANUP_INTERVAL) {
|
||||
ClapperEnhancerProxyList *proxies;
|
||||
guint i, n_proxies;
|
||||
GByteArray *bytes;
|
||||
|
||||
GST_TRACE_OBJECT (self, "Time for cache cleanup, last was %"
|
||||
CLAPPER_TIME_FORMAT " ago", CLAPPER_TIME_ARGS (since_cleanup));
|
||||
|
||||
/* Start with writing to cache cleanup time,
|
||||
* so other directors can find it earlier */
|
||||
if ((bytes = clapper_cache_create ())) {
|
||||
clapper_cache_store_int64 (bytes, epoch_now);
|
||||
|
||||
if (clapper_cache_write (filename, bytes, &error)) {
|
||||
GST_TRACE_OBJECT (self, "Written data to cache cleanup file, cleanup time: %"
|
||||
G_GINT64_FORMAT, epoch_now);
|
||||
} else if (error) {
|
||||
GST_ERROR_OBJECT (self, "Could not write cache cleanup data, reason: %s", error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
g_byte_array_free (bytes, TRUE);
|
||||
}
|
||||
|
||||
/* Now do cleanup */
|
||||
proxies = clapper_get_global_enhancer_proxies ();
|
||||
n_proxies = clapper_enhancer_proxy_list_get_n_proxies (proxies);
|
||||
|
||||
for (i = 0; i < n_proxies; ++i) {
|
||||
ClapperEnhancerProxy *proxy = clapper_enhancer_proxy_list_peek_proxy (proxies, i);
|
||||
|
||||
if (!clapper_enhancer_proxy_target_has_interface (proxy, CLAPPER_TYPE_EXTRACTABLE))
|
||||
continue;
|
||||
|
||||
_cache_proxy_harvests_cleanup (self, proxy, epoch_now);
|
||||
}
|
||||
} else {
|
||||
GST_TRACE_OBJECT (self, "No cache cleanup yet, last was %"
|
||||
CLAPPER_TIME_FORMAT " ago", CLAPPER_TIME_ARGS (since_cleanup));
|
||||
}
|
||||
|
||||
g_free (filename);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
/*
|
||||
* clapper_enhancer_director_new:
|
||||
*
|
||||
@@ -153,6 +325,8 @@ clapper_enhancer_director_extract (ClapperEnhancerDirector *self,
|
||||
GCancellable *cancellable, GError **error)
|
||||
{
|
||||
ClapperEnhancerDirectorData *data = g_new (ClapperEnhancerDirectorData, 1);
|
||||
GMainContext *context;
|
||||
ClapperHarvest *harvest;
|
||||
|
||||
data->director = self;
|
||||
data->filtered_proxies = filtered_proxies;
|
||||
@@ -160,10 +334,18 @@ clapper_enhancer_director_extract (ClapperEnhancerDirector *self,
|
||||
data->cancellable = cancellable;
|
||||
data->error = error;
|
||||
|
||||
return CLAPPER_HARVEST_CAST (clapper_shared_utils_context_invoke_sync_full (
|
||||
clapper_threaded_object_get_context (CLAPPER_THREADED_OBJECT_CAST (self)),
|
||||
context = clapper_threaded_object_get_context (CLAPPER_THREADED_OBJECT_CAST (self));
|
||||
|
||||
harvest = CLAPPER_HARVEST_CAST (clapper_shared_utils_context_invoke_sync_full (context,
|
||||
(GThreadFunc) clapper_enhancer_director_extract_in_thread,
|
||||
data, (GDestroyNotify) g_free));
|
||||
|
||||
/* Run cleanup async. Since context belongs to "self", do not ref it.
|
||||
* This ensures clean shutdown with thread stop function called. */
|
||||
if (!g_cancellable_is_cancelled (cancellable) && !clapper_cache_is_disabled ())
|
||||
g_main_context_invoke (context, (GSourceFunc) _cache_cleanup_func, self);
|
||||
|
||||
return harvest;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -26,12 +26,12 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLAPPER_TYPE_ENHANCER_SRC (clapper_enhancer_src_get_type())
|
||||
#define CLAPPER_ENHANCER_SRC_CAST(obj) ((ClapperEnhancerSrc *)(obj))
|
||||
#define CLAPPER_TYPE_EXTRACTABLE_SRC (clapper_extractable_src_get_type())
|
||||
#define CLAPPER_EXTRACTABLE_SRC_CAST(obj) ((ClapperExtractableSrc *)(obj))
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
G_DECLARE_FINAL_TYPE (ClapperEnhancerSrc, clapper_enhancer_src, CLAPPER, ENHANCER_SRC, GstPushSrc)
|
||||
G_DECLARE_FINAL_TYPE (ClapperExtractableSrc, clapper_extractable_src, CLAPPER, EXTRACTABLE_SRC, GstPushSrc)
|
||||
|
||||
GST_ELEMENT_REGISTER_DECLARE (clapperenhancersrc)
|
||||
GST_ELEMENT_REGISTER_DECLARE (clapperextractablesrc)
|
||||
|
||||
G_END_DECLS
|
@@ -19,7 +19,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "clapper-enhancer-src-private.h"
|
||||
#include "clapper-extractable-src-private.h"
|
||||
#include "clapper-enhancer-director-private.h"
|
||||
|
||||
#include "../clapper-basic-functions.h"
|
||||
@@ -28,13 +28,13 @@
|
||||
#include "../clapper-extractable.h"
|
||||
#include "../clapper-harvest-private.h"
|
||||
|
||||
#define GST_CAT_DEFAULT clapper_enhancer_src_debug
|
||||
#define GST_CAT_DEFAULT clapper_extractable_src_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
|
||||
#define CHECK_SCHEME_IS_HTTPS(scheme) (g_str_has_prefix (scheme, "http") \
|
||||
&& (scheme[4] == '\0' || (scheme[4] == 's' && scheme[5] == '\0')))
|
||||
|
||||
struct _ClapperEnhancerSrc
|
||||
struct _ClapperExtractableSrc
|
||||
{
|
||||
GstPushSrc parent;
|
||||
|
||||
@@ -65,7 +65,7 @@ static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_STATIC_CAPS_ANY);
|
||||
|
||||
static GstURIType
|
||||
clapper_enhancer_src_uri_handler_get_type (GType type)
|
||||
clapper_extractable_src_uri_handler_get_type (GType type)
|
||||
{
|
||||
return GST_URI_SRC;
|
||||
}
|
||||
@@ -145,19 +145,19 @@ _host_fixup (const gchar *host)
|
||||
}
|
||||
|
||||
/*
|
||||
* _enhancer_check_for_uri:
|
||||
* @self: a #ClapperEnhancerSrc
|
||||
* _extractable_check_for_uri:
|
||||
* @self: a #ClapperExtractableSrc
|
||||
* @uri: a #GUri
|
||||
*
|
||||
* Check whether there is at least one enhancer for @uri in global list.
|
||||
* Check whether there is at least one extractable enhancer for @uri in global list.
|
||||
* This is used to reject URI early, thus making playbin choose different
|
||||
* source element. It uses global list, since at this stage element is not
|
||||
* yet placed within pipeline, so it cannot get proxies from player.
|
||||
*
|
||||
* Returns: whether at least one enhancer advertises support for given URI.
|
||||
* Returns: whether at least one extractable enhancer advertises support for given URI.
|
||||
*/
|
||||
static gboolean
|
||||
_enhancer_check_for_uri (ClapperEnhancerSrc *self, GUri *uri)
|
||||
_extractable_check_for_uri (ClapperExtractableSrc *self, GUri *uri)
|
||||
{
|
||||
ClapperEnhancerProxyList *proxies = clapper_get_global_enhancer_proxies ();
|
||||
gboolean is_https;
|
||||
@@ -168,7 +168,7 @@ _enhancer_check_for_uri (ClapperEnhancerSrc *self, GUri *uri)
|
||||
if (host)
|
||||
host = _host_fixup (host);
|
||||
|
||||
GST_INFO_OBJECT (self, "Enhancer check, scheme: \"%s\", host: \"%s\"",
|
||||
GST_INFO_OBJECT (self, "Extractable check, scheme: \"%s\", host: \"%s\"",
|
||||
scheme, GST_STR_NULL (host));
|
||||
|
||||
/* Whether "http(s)" scheme is used */
|
||||
@@ -191,8 +191,8 @@ _enhancer_check_for_uri (ClapperEnhancerSrc *self, GUri *uri)
|
||||
}
|
||||
|
||||
/*
|
||||
* _filter_enhancers_for_uri:
|
||||
* @self: a #ClapperEnhancerSrc
|
||||
* _filter_extractables_for_uri:
|
||||
* @self: a #ClapperExtractableSrc
|
||||
* @proxies: a #ClapperEnhancerProxyList
|
||||
* @uri: a #GUri
|
||||
*
|
||||
@@ -202,7 +202,7 @@ _enhancer_check_for_uri (ClapperEnhancerSrc *self, GUri *uri)
|
||||
* Returns: (transfer full): A sublist in the form of #GList with proxies.
|
||||
*/
|
||||
static GList *
|
||||
_filter_enhancers_for_uri (ClapperEnhancerSrc *self,
|
||||
_filter_extractables_for_uri (ClapperExtractableSrc *self,
|
||||
ClapperEnhancerProxyList *proxies, GUri *uri)
|
||||
{
|
||||
GList *sublist = NULL;
|
||||
@@ -214,7 +214,7 @@ _filter_enhancers_for_uri (ClapperEnhancerSrc *self,
|
||||
if (host)
|
||||
host = _host_fixup (host);
|
||||
|
||||
GST_INFO_OBJECT (self, "Enhancer filter, scheme: \"%s\", host: \"%s\"",
|
||||
GST_INFO_OBJECT (self, "Extractable filter, scheme: \"%s\", host: \"%s\"",
|
||||
scheme, GST_STR_NULL (host));
|
||||
|
||||
/* Whether "http(s)" scheme is used */
|
||||
@@ -239,7 +239,7 @@ _filter_enhancers_for_uri (ClapperEnhancerSrc *self,
|
||||
}
|
||||
|
||||
static const gchar *const *
|
||||
clapper_enhancer_src_uri_handler_get_protocols (GType type)
|
||||
clapper_extractable_src_uri_handler_get_protocols (GType type)
|
||||
{
|
||||
static GOnce schemes_once = G_ONCE_INIT;
|
||||
|
||||
@@ -248,9 +248,9 @@ clapper_enhancer_src_uri_handler_get_protocols (GType type)
|
||||
}
|
||||
|
||||
static gchar *
|
||||
clapper_enhancer_src_uri_handler_get_uri (GstURIHandler *handler)
|
||||
clapper_extractable_src_uri_handler_get_uri (GstURIHandler *handler)
|
||||
{
|
||||
ClapperEnhancerSrc *self = CLAPPER_ENHANCER_SRC_CAST (handler);
|
||||
ClapperExtractableSrc *self = CLAPPER_EXTRACTABLE_SRC_CAST (handler);
|
||||
gchar *uri;
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
@@ -261,10 +261,10 @@ clapper_enhancer_src_uri_handler_get_uri (GstURIHandler *handler)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clapper_enhancer_src_uri_handler_set_uri (GstURIHandler *handler,
|
||||
clapper_extractable_src_uri_handler_set_uri (GstURIHandler *handler,
|
||||
const gchar *uri, GError **error)
|
||||
{
|
||||
ClapperEnhancerSrc *self = CLAPPER_ENHANCER_SRC_CAST (handler);
|
||||
ClapperExtractableSrc *self = CLAPPER_EXTRACTABLE_SRC_CAST (handler);
|
||||
GUri *guri;
|
||||
const gchar *const *protocols;
|
||||
gboolean supported = FALSE;
|
||||
@@ -300,7 +300,7 @@ clapper_enhancer_src_uri_handler_set_uri (GstURIHandler *handler,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!_enhancer_check_for_uri (self, guri)) {
|
||||
if (!_extractable_check_for_uri (self, guri)) {
|
||||
g_set_error (error, GST_URI_ERROR, GST_URI_ERROR_BAD_URI,
|
||||
"None of the available enhancers can handle this URI");
|
||||
g_uri_unref (guri);
|
||||
@@ -324,22 +324,22 @@ clapper_enhancer_src_uri_handler_set_uri (GstURIHandler *handler,
|
||||
static void
|
||||
_uri_handler_iface_init (GstURIHandlerInterface *iface)
|
||||
{
|
||||
iface->get_type = clapper_enhancer_src_uri_handler_get_type;
|
||||
iface->get_protocols = clapper_enhancer_src_uri_handler_get_protocols;
|
||||
iface->get_uri = clapper_enhancer_src_uri_handler_get_uri;
|
||||
iface->set_uri = clapper_enhancer_src_uri_handler_set_uri;
|
||||
iface->get_type = clapper_extractable_src_uri_handler_get_type;
|
||||
iface->get_protocols = clapper_extractable_src_uri_handler_get_protocols;
|
||||
iface->get_uri = clapper_extractable_src_uri_handler_get_uri;
|
||||
iface->set_uri = clapper_extractable_src_uri_handler_set_uri;
|
||||
}
|
||||
|
||||
#define parent_class clapper_enhancer_src_parent_class
|
||||
G_DEFINE_TYPE_WITH_CODE (ClapperEnhancerSrc, clapper_enhancer_src, GST_TYPE_PUSH_SRC,
|
||||
#define parent_class clapper_extractable_src_parent_class
|
||||
G_DEFINE_TYPE_WITH_CODE (ClapperExtractableSrc, clapper_extractable_src, GST_TYPE_PUSH_SRC,
|
||||
G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER, _uri_handler_iface_init));
|
||||
GST_ELEMENT_REGISTER_DEFINE (clapperenhancersrc, "clapperenhancersrc",
|
||||
512, CLAPPER_TYPE_ENHANCER_SRC);
|
||||
GST_ELEMENT_REGISTER_DEFINE (clapperextractablesrc, "clapperextractablesrc",
|
||||
512, CLAPPER_TYPE_EXTRACTABLE_SRC);
|
||||
|
||||
static gboolean
|
||||
clapper_enhancer_src_start (GstBaseSrc *base_src)
|
||||
clapper_extractable_src_start (GstBaseSrc *base_src)
|
||||
{
|
||||
ClapperEnhancerSrc *self = CLAPPER_ENHANCER_SRC_CAST (base_src);
|
||||
ClapperExtractableSrc *self = CLAPPER_EXTRACTABLE_SRC_CAST (base_src);
|
||||
gboolean can_start;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Start");
|
||||
@@ -358,9 +358,9 @@ clapper_enhancer_src_start (GstBaseSrc *base_src)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clapper_enhancer_src_stop (GstBaseSrc *base_src)
|
||||
clapper_extractable_src_stop (GstBaseSrc *base_src)
|
||||
{
|
||||
ClapperEnhancerSrc *self = CLAPPER_ENHANCER_SRC_CAST (base_src);
|
||||
ClapperExtractableSrc *self = CLAPPER_EXTRACTABLE_SRC_CAST (base_src);
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Stop");
|
||||
|
||||
@@ -370,9 +370,9 @@ clapper_enhancer_src_stop (GstBaseSrc *base_src)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clapper_enhancer_src_get_size (GstBaseSrc *base_src, guint64 *size)
|
||||
clapper_extractable_src_get_size (GstBaseSrc *base_src, guint64 *size)
|
||||
{
|
||||
ClapperEnhancerSrc *self = CLAPPER_ENHANCER_SRC_CAST (base_src);
|
||||
ClapperExtractableSrc *self = CLAPPER_EXTRACTABLE_SRC_CAST (base_src);
|
||||
|
||||
if (self->buf_size > 0) {
|
||||
*size = self->buf_size;
|
||||
@@ -383,15 +383,15 @@ clapper_enhancer_src_get_size (GstBaseSrc *base_src, guint64 *size)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clapper_enhancer_src_is_seekable (GstBaseSrc *base_src)
|
||||
clapper_extractable_src_is_seekable (GstBaseSrc *base_src)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clapper_enhancer_src_unlock (GstBaseSrc *base_src)
|
||||
clapper_extractable_src_unlock (GstBaseSrc *base_src)
|
||||
{
|
||||
ClapperEnhancerSrc *self = CLAPPER_ENHANCER_SRC_CAST (base_src);
|
||||
ClapperExtractableSrc *self = CLAPPER_EXTRACTABLE_SRC_CAST (base_src);
|
||||
|
||||
GST_LOG_OBJECT (self, "Cancel triggered");
|
||||
g_cancellable_cancel (self->cancellable);
|
||||
@@ -400,9 +400,9 @@ clapper_enhancer_src_unlock (GstBaseSrc *base_src)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clapper_enhancer_src_unlock_stop (GstBaseSrc *base_src)
|
||||
clapper_extractable_src_unlock_stop (GstBaseSrc *base_src)
|
||||
{
|
||||
ClapperEnhancerSrc *self = CLAPPER_ENHANCER_SRC_CAST (base_src);
|
||||
ClapperExtractableSrc *self = CLAPPER_EXTRACTABLE_SRC_CAST (base_src);
|
||||
|
||||
GST_LOG_OBJECT (self, "Resetting cancellable");
|
||||
|
||||
@@ -414,7 +414,7 @@ clapper_enhancer_src_unlock_stop (GstBaseSrc *base_src)
|
||||
|
||||
/* Pushes tags, toc and request headers downstream (all transfer full) */
|
||||
static void
|
||||
_push_events (ClapperEnhancerSrc *self, GstTagList *tags, GstToc *toc,
|
||||
_push_events (ClapperExtractableSrc *self, GstTagList *tags, GstToc *toc,
|
||||
GstStructure *headers, gboolean updated)
|
||||
{
|
||||
GstEvent *event;
|
||||
@@ -462,9 +462,9 @@ _push_events (ClapperEnhancerSrc *self, GstTagList *tags, GstToc *toc,
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
clapper_enhancer_src_create (GstPushSrc *push_src, GstBuffer **outbuf)
|
||||
clapper_extractable_src_create (GstPushSrc *push_src, GstBuffer **outbuf)
|
||||
{
|
||||
ClapperEnhancerSrc *self = CLAPPER_ENHANCER_SRC_CAST (push_src);
|
||||
ClapperExtractableSrc *self = CLAPPER_EXTRACTABLE_SRC_CAST (push_src);
|
||||
ClapperEnhancerProxyList *proxies;
|
||||
GList *filtered_proxies;
|
||||
GUri *guri;
|
||||
@@ -502,7 +502,7 @@ clapper_enhancer_src_create (GstPushSrc *push_src, GstBuffer **outbuf)
|
||||
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
filtered_proxies = _filter_enhancers_for_uri (self, proxies, guri);
|
||||
filtered_proxies = _filter_extractables_for_uri (self, proxies, guri);
|
||||
gst_object_unref (proxies);
|
||||
|
||||
harvest = clapper_enhancer_director_extract (self->director,
|
||||
@@ -554,7 +554,7 @@ _handle_uri_query (GstQuery *query)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clapper_enhancer_src_query (GstBaseSrc *base_src, GstQuery *query)
|
||||
clapper_extractable_src_query (GstBaseSrc *base_src, GstQuery *query)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
|
||||
@@ -573,7 +573,7 @@ clapper_enhancer_src_query (GstBaseSrc *base_src, GstQuery *query)
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_enhancer_src_set_enhancer_proxies (ClapperEnhancerSrc *self,
|
||||
clapper_extractable_src_set_enhancer_proxies (ClapperExtractableSrc *self,
|
||||
ClapperEnhancerProxyList *enhancer_proxies)
|
||||
{
|
||||
GST_OBJECT_LOCK (self);
|
||||
@@ -583,15 +583,15 @@ clapper_enhancer_src_set_enhancer_proxies (ClapperEnhancerSrc *self,
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_enhancer_src_init (ClapperEnhancerSrc *self)
|
||||
clapper_extractable_src_init (ClapperExtractableSrc *self)
|
||||
{
|
||||
self->cancellable = g_cancellable_new ();
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_enhancer_src_dispose (GObject *object)
|
||||
clapper_extractable_src_dispose (GObject *object)
|
||||
{
|
||||
ClapperEnhancerSrc *self = CLAPPER_ENHANCER_SRC_CAST (object);
|
||||
ClapperExtractableSrc *self = CLAPPER_EXTRACTABLE_SRC_CAST (object);
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
g_clear_object (&self->director);
|
||||
@@ -601,9 +601,9 @@ clapper_enhancer_src_dispose (GObject *object)
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_enhancer_src_finalize (GObject *object)
|
||||
clapper_extractable_src_finalize (GObject *object)
|
||||
{
|
||||
ClapperEnhancerSrc *self = CLAPPER_ENHANCER_SRC_CAST (object);
|
||||
ClapperExtractableSrc *self = CLAPPER_EXTRACTABLE_SRC_CAST (object);
|
||||
|
||||
GST_TRACE_OBJECT (self, "Finalize");
|
||||
|
||||
@@ -616,10 +616,10 @@ clapper_enhancer_src_finalize (GObject *object)
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_enhancer_src_set_property (GObject *object, guint prop_id,
|
||||
clapper_extractable_src_set_property (GObject *object, guint prop_id,
|
||||
const GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
ClapperEnhancerSrc *self = CLAPPER_ENHANCER_SRC_CAST (object);
|
||||
ClapperExtractableSrc *self = CLAPPER_EXTRACTABLE_SRC_CAST (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_URI:{
|
||||
@@ -632,7 +632,7 @@ clapper_enhancer_src_set_property (GObject *object, guint prop_id,
|
||||
break;
|
||||
}
|
||||
case PROP_ENHANCER_PROXIES:
|
||||
clapper_enhancer_src_set_enhancer_proxies (self, g_value_get_object (value));
|
||||
clapper_extractable_src_set_enhancer_proxies (self, g_value_get_object (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
@@ -641,10 +641,10 @@ clapper_enhancer_src_set_property (GObject *object, guint prop_id,
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_enhancer_src_get_property (GObject *object, guint prop_id,
|
||||
clapper_extractable_src_get_property (GObject *object, guint prop_id,
|
||||
GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
ClapperEnhancerSrc *self = CLAPPER_ENHANCER_SRC_CAST (object);
|
||||
ClapperExtractableSrc *self = CLAPPER_EXTRACTABLE_SRC_CAST (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_URI:
|
||||
@@ -657,30 +657,30 @@ clapper_enhancer_src_get_property (GObject *object, guint prop_id,
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_enhancer_src_class_init (ClapperEnhancerSrcClass *klass)
|
||||
clapper_extractable_src_class_init (ClapperExtractableSrcClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
GstElementClass *gstelement_class = (GstElementClass *) klass;
|
||||
GstBaseSrcClass *gstbasesrc_class = (GstBaseSrcClass *) klass;
|
||||
GstPushSrcClass *gstpushsrc_class = (GstPushSrcClass *) klass;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "clapperenhancersrc", 0,
|
||||
"Clapper Enhancer Source");
|
||||
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "clapperextractablesrc", 0,
|
||||
"Clapper Extractable Source");
|
||||
|
||||
gobject_class->set_property = clapper_enhancer_src_set_property;
|
||||
gobject_class->get_property = clapper_enhancer_src_get_property;
|
||||
gobject_class->dispose = clapper_enhancer_src_dispose;
|
||||
gobject_class->finalize = clapper_enhancer_src_finalize;
|
||||
gobject_class->set_property = clapper_extractable_src_set_property;
|
||||
gobject_class->get_property = clapper_extractable_src_get_property;
|
||||
gobject_class->dispose = clapper_extractable_src_dispose;
|
||||
gobject_class->finalize = clapper_extractable_src_finalize;
|
||||
|
||||
gstbasesrc_class->start = clapper_enhancer_src_start;
|
||||
gstbasesrc_class->stop = clapper_enhancer_src_stop;
|
||||
gstbasesrc_class->get_size = clapper_enhancer_src_get_size;
|
||||
gstbasesrc_class->is_seekable = clapper_enhancer_src_is_seekable;
|
||||
gstbasesrc_class->unlock = clapper_enhancer_src_unlock;
|
||||
gstbasesrc_class->unlock_stop = clapper_enhancer_src_unlock_stop;
|
||||
gstbasesrc_class->query = clapper_enhancer_src_query;
|
||||
gstbasesrc_class->start = clapper_extractable_src_start;
|
||||
gstbasesrc_class->stop = clapper_extractable_src_stop;
|
||||
gstbasesrc_class->get_size = clapper_extractable_src_get_size;
|
||||
gstbasesrc_class->is_seekable = clapper_extractable_src_is_seekable;
|
||||
gstbasesrc_class->unlock = clapper_extractable_src_unlock;
|
||||
gstbasesrc_class->unlock_stop = clapper_extractable_src_unlock_stop;
|
||||
gstbasesrc_class->query = clapper_extractable_src_query;
|
||||
|
||||
gstpushsrc_class->create = clapper_enhancer_src_create;
|
||||
gstpushsrc_class->create = clapper_extractable_src_create;
|
||||
|
||||
param_specs[PROP_URI] = g_param_spec_string ("uri",
|
||||
"URI", "URI", NULL,
|
||||
@@ -694,7 +694,7 @@ clapper_enhancer_src_class_init (ClapperEnhancerSrcClass *klass)
|
||||
|
||||
gst_element_class_add_static_pad_template (gstelement_class, &src_template);
|
||||
|
||||
gst_element_class_set_static_metadata (gstelement_class, "Clapper Enhancer Source",
|
||||
"Source", "A source element that uses Clapper Enhancers to produce data",
|
||||
gst_element_class_set_static_metadata (gstelement_class, "Clapper Extractable Source",
|
||||
"Source", "A source element that uses Clapper extractable enhancers to produce data",
|
||||
"Rafał Dzięgiel <rafostar.github@gmail.com>");
|
||||
}
|
@@ -27,7 +27,7 @@
|
||||
#include "../clapper-extractable.h"
|
||||
|
||||
#include "clapper-plugin-private.h"
|
||||
#include "clapper-enhancer-src-private.h"
|
||||
#include "clapper-extractable-src-private.h"
|
||||
#include "clapper-uri-list-demux-private.h"
|
||||
|
||||
/*
|
||||
@@ -67,7 +67,7 @@ clapper_gst_plugin_init (GstPlugin *plugin)
|
||||
|
||||
/* Avoid registering an URI handler without schemes */
|
||||
if (clapper_gst_plugin_has_enhancers (global_proxies, CLAPPER_TYPE_EXTRACTABLE))
|
||||
res |= GST_ELEMENT_REGISTER (clapperenhancersrc, plugin);
|
||||
res |= GST_ELEMENT_REGISTER (clapperextractablesrc, plugin);
|
||||
|
||||
res |= GST_ELEMENT_REGISTER (clapperurilistdemux, plugin);
|
||||
|
||||
|
@@ -193,7 +193,7 @@ _feature_filter (GstPluginFeature *feature, const gchar *search_proto)
|
||||
feature_name = gst_plugin_feature_get_name (feature);
|
||||
|
||||
/* Do not loop endlessly creating our own sources and demuxers */
|
||||
if (!feature_name || strcmp (feature_name, "clapperenhancersrc") == 0)
|
||||
if (!feature_name || strcmp (feature_name, "clapperextractablesrc") == 0)
|
||||
return FALSE;
|
||||
|
||||
protocols = gst_element_factory_get_uri_protocols (factory);
|
||||
|
@@ -155,7 +155,7 @@ clapper_sources = [
|
||||
'clapper-utils.c',
|
||||
'clapper-video-stream.c',
|
||||
'gst/clapper-plugin.c',
|
||||
'gst/clapper-enhancer-src.c',
|
||||
'gst/clapper-extractable-src.c',
|
||||
'gst/clapper-enhancer-director.c',
|
||||
'gst/clapper-uri-list-demux.c',
|
||||
'../shared/clapper-shared-utils.c',
|
||||
|
Reference in New Issue
Block a user