3 Commits

Author SHA1 Message Date
Rafał Dzięgiel
696b9a2d2e clapper: Rename "uri-list-demux" element
Move as harvest URI demuxer since it is supposed to work only with
harvest data from extractable src. Also change caps media type
to "text/x-uri" which is non-standard, but we have to differentiate
single URI from harvest and URI list (one or more URIs).
2025-07-20 20:23:21 +02:00
Rafał Dzięgiel
edd3d5b8f1 clapper: Handle parsed playlists
Handle "ClapperPlaylistParsed" messages on playbin bus by updating current media
item (playlist) to redirect to the first item in that playlist (with changed tags)
and appending remaining items to the queue after that playlist position.

This basically means that playlist gets resolved into simply adding more
items to the queue. This should also work with nested playlists within playlist.
2025-07-19 15:43:40 +02:00
Rafał Dzięgiel
7821b5bc20 clapper: Add playlist demuxer element
Uses "Playlistable" enhancers to parse playlist and demux first URI in it
2025-07-19 15:43:38 +02:00
8 changed files with 140 additions and 284 deletions

View File

@@ -642,6 +642,18 @@ clapper_app_application_command_line (GApplication *app, GApplicationCommandLine
return EXIT_SUCCESS;
}
static gboolean
_is_claps_file (GFile *file)
{
gchar *basename = g_file_get_basename (file);
gboolean is_claps;
is_claps = (basename && g_str_has_suffix (basename, ".claps"));
g_free (basename);
return is_claps;
}
static void
add_item_from_file (GFile *file, ClapperQueue *queue)
{
@@ -654,6 +666,51 @@ add_item_from_file (GFile *file, ClapperQueue *queue)
gst_object_unref (item);
}
static void
add_items_from_claps_file (GFile *file, ClapperQueue *queue)
{
GDataInputStream *dstream = NULL;
GFileInputStream *stream;
GError *error = NULL;
gchar *line;
if (!(stream = g_file_read (file, NULL, &error)))
goto finish;
dstream = g_data_input_stream_new (G_INPUT_STREAM (stream));
while ((line = g_data_input_stream_read_line (
dstream, NULL, NULL, &error))) {
g_strstrip (line);
if (strlen (line) > 0) {
GFile *tmp_file = gst_uri_is_valid (line)
? g_file_new_for_uri (line)
: g_file_new_for_path (line);
if (_is_claps_file (tmp_file))
add_items_from_claps_file (tmp_file, queue);
else
add_item_from_file (tmp_file, queue);
g_object_unref (tmp_file);
}
g_free (line);
}
finish:
if (error) {
GST_ERROR ("Could not read \".claps\" file, reason: %s", error->message);
g_error_free (error);
}
if (stream) {
g_input_stream_close (G_INPUT_STREAM (stream), NULL, NULL);
g_object_unref (stream);
}
g_clear_object (&dstream);
}
static void
add_item_with_subtitles (GFile *media_file,
GFile *subs_file, ClapperQueue *queue)
@@ -722,8 +779,12 @@ clapper_app_application_open (GApplication *app,
if (!handled) {
gint i;
for (i = 0; i < n_files; ++i)
add_item_from_file (files[i], queue);
for (i = 0; i < n_files; ++i) {
if (_is_claps_file (files[i]))
add_items_from_claps_file (files[i], queue);
else
add_item_from_file (files[i], queue);
}
}
add_only = (g_strcmp0 (hint, "add-only") == 0);

View File

@@ -29,9 +29,6 @@ G_BEGIN_DECLS
G_GNUC_INTERNAL
ClapperHarvest * clapper_harvest_new (void);
G_GNUC_INTERNAL
void clapper_harvest_set_enhancer_in_caps (ClapperHarvest *harvest, ClapperEnhancerProxy *proxy);
G_GNUC_INTERNAL
gboolean clapper_harvest_unpack (ClapperHarvest *harvest, GstBuffer **buffer, gsize *buf_size, GstCaps **caps, GstTagList **tags, GstToc **toc, GstStructure **headers);

View File

@@ -94,13 +94,6 @@ clapper_harvest_new (void)
return harvest;
}
void
clapper_harvest_set_enhancer_in_caps (ClapperHarvest *self, ClapperEnhancerProxy *proxy)
{
gst_caps_set_simple (self->caps, "enhancer", G_TYPE_STRING,
clapper_enhancer_proxy_get_module_name (proxy), NULL);
}
gboolean
clapper_harvest_unpack (ClapperHarvest *self,
GstBuffer **buffer, gsize *buf_size, GstCaps **caps,
@@ -228,6 +221,7 @@ clapper_harvest_fill_from_cache (ClapperHarvest *self, ClapperEnhancerProxy *pro
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;
@@ -287,10 +281,10 @@ clapper_harvest_fill_from_cache (ClapperHarvest *self, ClapperEnhancerProxy *pro
goto finish;
}
/* Read caps */
/* Read media type */
read_str = clapper_cache_read_string (&data);
if (G_UNLIKELY (read_str == NULL)) {
GST_ERROR_OBJECT (self, "Could not read caps from cache file");
GST_ERROR_OBJECT (self, "Could not read media type from cache file");
goto finish;
}
@@ -302,12 +296,9 @@ clapper_harvest_fill_from_cache (ClapperHarvest *self, ClapperEnhancerProxy *pro
}
/* Fill harvest */
if (!(self->caps = gst_caps_from_string (read_str))) {
GST_ERROR_OBJECT (self, "Could not construct caps from cache");
buf_copy = g_memdup2 (buf_data, buf_size);
if (!clapper_harvest_fill (self, read_str, buf_copy, buf_size))
goto finish;
}
self->buffer = gst_buffer_new_memdup (buf_data, buf_size);
self->buf_size = buf_size;
/* Read tags */
read_str = clapper_cache_read_string (&data);
@@ -341,6 +332,7 @@ clapper_harvest_export_to_cache (ClapperHarvest *self, ClapperEnhancerProxy *pro
const GstStructure *config, GUri *uri)
{
GByteArray *bytes;
const GstStructure *caps_structure;
gchar *filename, *temp_str = NULL;
gboolean data_ok = TRUE;
@@ -374,13 +366,12 @@ clapper_harvest_export_to_cache (ClapperHarvest *self, ClapperEnhancerProxy *pro
clapper_cache_store_string (bytes, temp_str); // NULL when no config
g_clear_pointer (&temp_str, g_free);
/* Store caps */
temp_str = gst_caps_to_string (self->caps);
if (G_LIKELY (temp_str != NULL)) {
clapper_cache_store_string (bytes, temp_str);
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 caps");
GST_ERROR_OBJECT (self, "Cannot cache empty caps");
data_ok = FALSE;
}
@@ -443,15 +434,11 @@ clapper_harvest_export_to_cache (ClapperHarvest *self, ClapperEnhancerProxy *pro
*
* Commonly used media types are:
*
* * `application/dash+xml` - DASH manifest
* * `application/dash+xml`
*
* * `application/x-hls` - HLS manifest
* * `application/x-hls`
*
* * `text/x-uri` - direct media URI
*
* * `text/uri-list` - playlist of URIs
*
* * `application/clapper-playlist` - custom playlist format
* * `text/uri-list`
*
* Returns: %TRUE when filled successfully, %FALSE if taken data was empty.
*
@@ -472,7 +459,6 @@ clapper_harvest_fill (ClapperHarvest *self, const gchar *media_type, gpointer da
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/x-uri") == 0)
|| (strcmp (media_type, "text/uri-list") == 0);
if (is_printable) {

View File

@@ -202,12 +202,6 @@ clapper_media_item_get_id (ClapperMediaItem *self)
return self->id;
}
/* FIXME: 1.0:
* Consider change to be transfer-full and just return latest data from redirects
* list (alternatively expose redirect URI). This should make it possible to work
* with enhancers that would benefit from knowledge about URI changes
* (e.g "Recall" could read actual media instead of playlist file).
*/
/**
* clapper_media_item_get_uri:
* @item: a #ClapperMediaItem
@@ -697,8 +691,6 @@ gboolean
clapper_media_item_update_from_item (ClapperMediaItem *self, ClapperMediaItem *other_item,
ClapperPlayer *player)
{
gboolean title_changed = FALSE;
if (!clapper_media_item_set_redirect_uri (self, clapper_media_item_get_uri (other_item)))
return FALSE;
@@ -707,30 +699,8 @@ clapper_media_item_update_from_item (ClapperMediaItem *self, ClapperMediaItem *o
if (other_item->tags)
clapper_media_item_update_from_tag_list (self, other_item->tags, player);
/* Since its redirect now, we have to update title to describe new file instead of
* being a playlist title. If other item had parsed title, it also means that tags
* did not contain it, thus we have to manually update it and notify. */
if (other_item->title_is_parsed) {
GST_OBJECT_LOCK (self);
title_changed = g_set_str (&self->title, other_item->title);
self->title_is_parsed = TRUE;
GST_OBJECT_UNLOCK (self);
}
GST_OBJECT_UNLOCK (other_item);
if (title_changed) {
ClapperReactableItemUpdatedFlags flags = CLAPPER_REACTABLE_ITEM_UPDATED_TITLE;
ClapperFeaturesManager *features_manager;
clapper_app_bus_post_prop_notify (player->app_bus, GST_OBJECT_CAST (self), param_specs[PROP_TITLE]);
if (player->reactables_manager)
clapper_reactables_manager_trigger_item_updated (player->reactables_manager, self, flags);
if ((features_manager = clapper_player_get_features_manager (player)))
clapper_features_manager_trigger_item_updated (features_manager, self);
}
return TRUE;
}

View File

@@ -873,20 +873,8 @@ _handle_element_msg (GstMessage *msg, ClapperPlayer *player)
updated = clapper_media_item_update_from_item (playlist_item, active_item, player);
gst_object_unref (active_item);
if (!updated) {
GstMessage *msg;
GError *error;
error = g_error_new (GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_FAILED,
"Detected infinite redirection in playlist");
msg = gst_message_new_error (GST_OBJECT (player), error, NULL);
_handle_error_msg (msg, player);
g_error_free (error);
gst_message_unref (msg);
} else if (n_items > 1) {
/* Forward to append remaining items (must be done from main thread) */
/* Forward to append remaining items (must be done from main thread) */
if (updated && n_items > 1) {
clapper_app_bus_post_insert_playlist (player->app_bus,
GST_OBJECT_CAST (player),
GST_OBJECT_CAST (playlist_item),

View File

@@ -39,7 +39,6 @@
*/
#include <gst/gst.h>
#include <gst/tag/tag.h>
#include <gst/pbutils/pbutils.h>
#include "clapper-discoverer.h"
@@ -129,9 +128,8 @@ _run_discovery (ClapperDiscoverer *self)
ClapperMediaItem *item;
ClapperQueue *queue;
ClapperDiscovererDiscoveryMode discovery_mode;
GstTagList *tags;
const gchar *uri;
gboolean empty_tags, success = FALSE;
gboolean success = FALSE;
if (self->pending_items->len == 0) {
GST_DEBUG_OBJECT (self, "No more pending items");
@@ -159,16 +157,6 @@ _run_discovery (ClapperDiscoverer *self)
goto finish;
}
tags = clapper_media_item_get_tags (item);
empty_tags = gst_tag_list_is_empty (tags);
gst_tag_list_unref (tags);
if (!empty_tags) {
GST_DEBUG_OBJECT (self, "Queued %" GST_PTR_FORMAT
" already has tags, ignoring discovery", item);
goto finish;
}
uri = clapper_media_item_get_uri (item);
GST_DEBUG_OBJECT (self, "Starting discovery of %"
GST_PTR_FORMAT "(%s)", item, uri);

View File

@@ -106,10 +106,9 @@ clapper_enhancer_director_extract_in_thread (ClapperEnhancerDirectorData *data)
/* We are done with extractable, but keep harvest and try to cache it */
if (success) {
if (!g_cancellable_is_cancelled (data->cancellable)) {
clapper_harvest_set_enhancer_in_caps (harvest, proxy);
if (!g_cancellable_is_cancelled (data->cancellable))
clapper_harvest_export_to_cache (harvest, proxy, config, data->uri);
}
gst_clear_structure (&config);
break;
}
@@ -164,8 +163,7 @@ clapper_enhancer_director_parse_in_thread (ClapperEnhancerDirectorData *data)
mem = gst_buffer_peek_memory (data->buffer, 0);
if (!mem || !gst_memory_map (mem, &info, GST_MAP_READ)) {
g_set_error (data->error, GST_RESOURCE_ERROR,
GST_RESOURCE_ERROR_FAILED, "Could not read playlist buffer data");
GST_ERROR_OBJECT (self, "Could not read playlist buffer data");
return NULL;
}

View File

@@ -25,9 +25,7 @@
#include "../clapper-media-item.h"
#include "../clapper-playlistable.h"
#define CLAPPER_PLAYLIST_MEDIA_TYPE "application/clapper-playlist"
#define CLAPPER_CLAPS_MEDIA_TYPE "text/clapper-claps"
#define URI_LIST_MEDIA_TYPE "text/uri-list"
#define CLAPPER_PLAYLIST_MEDIA_TYPE "text/clapper-playlist"
#define DATA_CHUNK_SIZE 4096
#define GST_CAT_DEFAULT clapper_playlist_demux_debug
@@ -55,32 +53,30 @@ static GParamSpec *param_specs[PROP_LAST] = { NULL, };
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (CLAPPER_PLAYLIST_MEDIA_TYPE ";" CLAPPER_CLAPS_MEDIA_TYPE ";" URI_LIST_MEDIA_TYPE));
GST_STATIC_CAPS (CLAPPER_PLAYLIST_MEDIA_TYPE));
static GstStaticCaps clapper_playlist_caps = GST_STATIC_CAPS (CLAPPER_PLAYLIST_MEDIA_TYPE);
static GstStaticCaps clapper_claps_caps = GST_STATIC_CAPS (CLAPPER_CLAPS_MEDIA_TYPE);
static GstStaticCaps type_find_caps = GST_STATIC_CAPS (CLAPPER_PLAYLIST_MEDIA_TYPE);
static void
clapper_playlist_type_find (GstTypeFind *tf, ClapperEnhancerProxy *proxy)
{
const gchar *prefix, *contains, *regex, *module_name;
if (!clapper_enhancer_proxy_get_target_creation_allowed (proxy))
return;
const gchar *prefix, *contains, *regex, *data;
guint prob = 0;
if ((prefix = clapper_enhancer_proxy_get_extra_data (proxy, "X-Data-Prefix"))) {
size_t len = strlen (prefix);
const gchar *data = (const gchar *) gst_type_find_peek (tf, 0, (guint) len);
data = (const gchar *) gst_type_find_peek (tf, 0, (guint) len);
if (!data || memcmp (data, prefix, len) != 0)
return;
prob += 40;
}
contains = clapper_enhancer_proxy_get_extra_data (proxy, "X-Data-Contains");
regex = clapper_enhancer_proxy_get_extra_data (proxy, "X-Data-Regex");
if (contains || regex) {
const gchar *data;
guint data_size = DATA_CHUNK_SIZE;
if (!(data = (const gchar *) gst_type_find_peek (tf, 0, data_size))) {
@@ -97,9 +93,12 @@ clapper_playlist_type_find (GstTypeFind *tf, ClapperEnhancerProxy *proxy)
return;
}
if (contains && !g_strstr_len (data, data_size, contains))
return;
if (contains) {
if (!g_strstr_len (data, data_size, contains))
return;
prob += 50;
}
if (regex) {
GRegex *reg;
GError *error = NULL;
@@ -117,45 +116,21 @@ clapper_playlist_type_find (GstTypeFind *tf, ClapperEnhancerProxy *proxy)
if (!matched)
return;
prob += 50;
}
}
module_name = clapper_enhancer_proxy_get_module_name (proxy);
GST_INFO ("Suggesting likely type: " CLAPPER_PLAYLIST_MEDIA_TYPE
", enhancer: %s", module_name);
if (prob > 0) {
const gchar *module_name = clapper_enhancer_proxy_get_module_name (proxy);
gst_type_find_suggest_simple (tf, GST_TYPE_FIND_LIKELY,
CLAPPER_PLAYLIST_MEDIA_TYPE, "enhancer", G_TYPE_STRING, module_name, NULL);
}
if (prob > 100)
prob = 100;
/* Finds text file of full file paths. Claps file might also use URIs,
* but in that case lets GStreamer built-in type finders find that as
* "text/uri-list" and we will handle it with this element too. */
static void
clapper_claps_type_find (GstTypeFind *tf, gpointer user_data G_GNUC_UNUSED)
{
const guint8 *data;
GST_INFO ("Type find prob of %s: %u%%", module_name, prob);
if ((data = gst_type_find_peek (tf, 0, 3))) {
gboolean possible;
/* Linux file path */
possible = (data[0] == '/' && g_ascii_isalnum (data[1]));
#ifdef G_OS_WIN32
/* Windows file path ("C:\..." or "D:/...") */
if (!possible)
possible = (g_ascii_isalpha (data[0]) && data[1] == ':' && (data[2] == '\\' || data[2] == '/'));
/* Windows UNC Path */
if (!possible)
possible = (data[0] == '\\' && data[1] == '\\' && g_ascii_isalnum (data[2]));
#endif
if (possible) {
GST_INFO ("Suggesting possible type: " CLAPPER_CLAPS_MEDIA_TYPE);
gst_type_find_suggest_empty_simple (tf, GST_TYPE_FIND_POSSIBLE, CLAPPER_CLAPS_MEDIA_TYPE);
}
gst_type_find_suggest_simple (tf, prob, CLAPPER_PLAYLIST_MEDIA_TYPE,
"enhancer", G_TYPE_STRING, module_name, NULL);
}
}
@@ -163,25 +138,16 @@ static gboolean
type_find_register (GstPlugin *plugin)
{
ClapperEnhancerProxyList *global_proxies = clapper_get_global_enhancer_proxies ();
GstCaps *reg_caps;
GstCaps *reg_caps = NULL;
guint i, n_proxies = clapper_enhancer_proxy_list_get_n_proxies (global_proxies);
gboolean res;
reg_caps = gst_static_caps_get (&clapper_claps_caps);
res = gst_type_find_register (plugin, "clapper-claps",
GST_RANK_MARGINAL + 1, (GstTypeFindFunction) clapper_claps_type_find,
"claps", reg_caps, NULL, NULL);
gst_clear_caps (&reg_caps);
gboolean res = FALSE;
for (i = 0; i < n_proxies; ++i) {
ClapperEnhancerProxy *proxy = clapper_enhancer_proxy_list_peek_proxy (global_proxies, i);
if (clapper_enhancer_proxy_target_has_interface (proxy, CLAPPER_TYPE_PLAYLISTABLE)
&& (clapper_enhancer_proxy_get_extra_data (proxy, "X-Data-Prefix")
|| clapper_enhancer_proxy_get_extra_data (proxy, "X-Data-Contains")
|| clapper_enhancer_proxy_get_extra_data (proxy, "X-Data-Regex"))) {
if (clapper_enhancer_proxy_target_has_interface (proxy, CLAPPER_TYPE_PLAYLISTABLE)) {
if (!reg_caps)
reg_caps = gst_static_caps_get (&clapper_playlist_caps);
reg_caps = gst_static_caps_get (&type_find_caps);
res |= gst_type_find_register (plugin, clapper_enhancer_proxy_get_module_name (proxy),
GST_RANK_MARGINAL + 1, (GstTypeFindFunction) clapper_playlist_type_find,
@@ -200,86 +166,6 @@ GST_TYPE_FIND_REGISTER_DEFINE_CUSTOM (clapperplaylistdemux, type_find_register);
GST_ELEMENT_REGISTER_DEFINE (clapperplaylistdemux, "clapperplaylistdemux",
512, CLAPPER_TYPE_PLAYLIST_DEMUX);
static GListStore *
_parse_uri_list (ClapperPlaylistDemux *self, GUri *uri, GstBuffer *buffer,
GCancellable *cancellable, GError **error)
{
GListStore *playlist;
GstMemory *mem;
GstMapInfo info;
const gchar *ptr, *end;
mem = gst_buffer_peek_memory (buffer, 0);
if (!mem || !gst_memory_map (mem, &info, GST_MAP_READ)) {
g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_FAILED,
"Could not read URI list buffer data");
return NULL;
}
playlist = g_list_store_new (CLAPPER_TYPE_MEDIA_ITEM);
ptr = (gchar *) info.data;
end = ptr + info.size;
while (ptr < end) {
ClapperMediaItem *item = NULL;
const gchar *nl = memchr (ptr, '\n', end - ptr);
gsize len = nl ? nl - ptr : end - ptr;
gchar *line;
if (g_cancellable_is_cancelled (cancellable))
break;
line = g_strndup (ptr, len);
GST_DEBUG_OBJECT (self, "Parsing line: %s", line);
if (gst_uri_is_valid (line)) {
GST_DEBUG_OBJECT (self, "Found URI: %s", line);
item = clapper_media_item_new (line);
} else {
gchar *base_uri, *res_uri;
base_uri = g_uri_to_string (uri);
res_uri = g_uri_resolve_relative (base_uri, line, G_URI_FLAGS_ENCODED, error);
g_free (base_uri);
if (res_uri) {
GST_DEBUG_OBJECT (self, "Resolved URI: %s", res_uri);
item = clapper_media_item_new (res_uri);
g_free (res_uri);
}
}
g_free (line);
if (G_UNLIKELY (*error != NULL)) {
g_clear_object (&playlist);
break;
}
if (G_LIKELY (item != NULL))
g_list_store_append (playlist, (GObject *) item);
/* Advance to the next line */
ptr = nl ? (nl + 1) : end;
}
gst_memory_unmap (mem, &info);
return playlist;
}
static gboolean
_caps_have_media_type (GstCaps *caps, const gchar *media_type)
{
GstStructure *structure;
gboolean is_media_type = FALSE;
if (caps && (structure = gst_caps_get_structure (caps, 0)))
is_media_type = gst_structure_has_name (structure, media_type);
return is_media_type;
}
static void
clapper_playlist_demux_handle_caps (ClapperUriBaseDemux *uri_bd, GstCaps *caps)
{
@@ -315,7 +201,7 @@ _handle_playlist (ClapperPlaylistDemux *self, GListStore *playlist, GCancellable
if (G_UNLIKELY (item == NULL)) {
GST_ELEMENT_ERROR (self, RESOURCE, OPEN_READ,
("This playlist appears to be empty"), (NULL));
("%s", "This playlist appears to be empty"), (NULL));
return FALSE;
}
@@ -325,7 +211,7 @@ _handle_playlist (ClapperPlaylistDemux *self, GListStore *playlist, GCancellable
if (G_UNLIKELY (!success)) {
GST_ELEMENT_ERROR (self, RESOURCE, OPEN_READ,
("Resolved item URI was rejected"), (NULL));
("%s", "Resolved item URI was rejected"), (NULL));
return FALSE;
}
@@ -337,7 +223,7 @@ _handle_playlist (ClapperPlaylistDemux *self, GListStore *playlist, GCancellable
gst_message_new_element (GST_OBJECT_CAST (self), structure));
}
return TRUE;
return success;
}
static gboolean
@@ -345,17 +231,15 @@ clapper_playlist_demux_process_buffer (ClapperUriBaseDemux *uri_bd,
GstBuffer *buffer, GCancellable *cancellable)
{
ClapperPlaylistDemux *self = CLAPPER_PLAYLIST_DEMUX_CAST (uri_bd);
GstPad *sink_pad;
GstQuery *query;
ClapperEnhancerProxyList *proxies;
GList *filtered_proxies;
GstCaps *caps = NULL;
GstQuery *query = gst_query_new_uri ();
GUri *uri = NULL;
GListStore *playlist;
GError *error = NULL;
gboolean handled;
sink_pad = gst_element_get_static_pad (GST_ELEMENT_CAST (self), "sink");
query = gst_query_new_uri ();
if (gst_pad_peer_query (sink_pad, query)) {
if (gst_pad_peer_query (GST_ELEMENT_CAST (self)->sinkpads->data, query)) {
gchar *query_uri;
gst_query_parse_uri (query, &query_uri);
@@ -366,52 +250,39 @@ clapper_playlist_demux_process_buffer (ClapperUriBaseDemux *uri_bd,
g_free (query_uri);
}
}
gst_query_unref (query);
gst_object_unref (sink_pad);
if (G_UNLIKELY (uri == NULL)) {
GST_ERROR_OBJECT (self, "Could not query source URI");
return FALSE;
}
if (_caps_have_media_type (self->caps, CLAPPER_PLAYLIST_MEDIA_TYPE)) {
ClapperEnhancerProxyList *proxies;
GList *filtered_proxies;
if (!self->director)
self->director = clapper_enhancer_director_new ();
GST_OBJECT_LOCK (self);
GST_OBJECT_LOCK (self);
if (G_LIKELY (self->enhancer_proxies != NULL)) {
GST_INFO_OBJECT (self, "Using enhancer proxies: %" GST_PTR_FORMAT, self->enhancer_proxies);
proxies = gst_object_ref (self->enhancer_proxies);
} else {
/* Compat for old ClapperDiscoverer feature that does not set this property */
GST_WARNING_OBJECT (self, "Falling back to using global enhancer proxy list!");
proxies = gst_object_ref (clapper_get_global_enhancer_proxies ());
}
GST_OBJECT_UNLOCK (self);
if (!self->director)
self->director = clapper_enhancer_director_new ();
filtered_proxies = _filter_playlistables (self, self->caps, proxies);
gst_object_unref (proxies);
playlist = clapper_enhancer_director_parse (self->director,
filtered_proxies, uri, buffer, cancellable, &error);
g_clear_list (&filtered_proxies, gst_object_unref);
} else if (_caps_have_media_type (self->caps, URI_LIST_MEDIA_TYPE)
|| _caps_have_media_type (self->caps, CLAPPER_CLAPS_MEDIA_TYPE)) {
playlist = _parse_uri_list (self, uri, buffer, cancellable, &error);
} else { // Should never happen
playlist = NULL;
error = g_error_new (GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_FAILED,
"Unsupported media type in caps");
if (G_LIKELY (self->enhancer_proxies != NULL)) {
GST_INFO_OBJECT (self, "Using enhancer proxies: %" GST_PTR_FORMAT, self->enhancer_proxies);
proxies = gst_object_ref (self->enhancer_proxies);
} else {
/* Compat for old ClapperDiscoverer feature that does not set this property */
GST_WARNING_OBJECT (self, "Falling back to using global enhancer proxy list!");
proxies = gst_object_ref (clapper_get_global_enhancer_proxies ());
}
g_uri_unref (uri);
gst_caps_replace (&caps, self->caps);
GST_OBJECT_UNLOCK (self);
filtered_proxies = _filter_playlistables (self, caps, proxies);
gst_clear_caps (&caps);
gst_object_unref (proxies);
playlist = clapper_enhancer_director_parse (self->director,
filtered_proxies, uri, buffer, cancellable, &error);
g_clear_list (&filtered_proxies, gst_object_unref);
if (!playlist) {
GST_ELEMENT_ERROR (self, RESOURCE, OPEN_READ,
@@ -421,10 +292,7 @@ clapper_playlist_demux_process_buffer (ClapperUriBaseDemux *uri_bd,
return FALSE;
}
handled = _handle_playlist (self, playlist, cancellable);
g_object_unref (playlist);
return handled;
return _handle_playlist (self, playlist, cancellable);
}
static void