diff options
Diffstat (limited to 'libgupnp-dlna')
-rw-r--r-- | libgupnp-dlna/Makefile.am | 5 | ||||
-rw-r--r-- | libgupnp-dlna/gupnp-dlna-discoverer.h | 2 | ||||
-rw-r--r-- | libgupnp-dlna/gupnp-dlna-information.h | 2 | ||||
-rw-r--r-- | libgupnp-dlna/gupnp-dlna-load.c | 264 | ||||
-rw-r--r-- | libgupnp-dlna/gupnp-dlna-load.h | 5 | ||||
-rw-r--r-- | libgupnp-dlna/gupnp-dlna-profile-private.h | 37 | ||||
-rw-r--r-- | libgupnp-dlna/gupnp-dlna-profile.c | 140 | ||||
-rw-r--r-- | libgupnp-dlna/gupnp-dlna-profile.h | 9 | ||||
-rw-r--r-- | libgupnp-dlna/gupnp-dlna-profiles.c | 85 |
9 files changed, 320 insertions, 229 deletions
diff --git a/libgupnp-dlna/Makefile.am b/libgupnp-dlna/Makefile.am index c8039e1..47d114c 100644 --- a/libgupnp-dlna/Makefile.am +++ b/libgupnp-dlna/Makefile.am @@ -12,7 +12,6 @@ LTVERSION = 0:0:0 shareddir = $(datadir)/gupnp-dlna AM_CFLAGS = -I$(top_srcdir) \ - -I$(top_srcdir)/gst-convenience/gst-libs \ $(LIBXML_CFLAGS) \ $(GST_CFLAGS) \ $(GST_PBU_CFLAGS) \ @@ -39,7 +38,8 @@ libgupnp_dlna_inc_HEADERS = gupnp-dlna-profile.h \ gupnp-dlna-information.h \ gupnp-dlna-discoverer.h -noinst_HEADERS = gupnp-dlna-load.h +noinst_HEADERS = gupnp-dlna-load.h \ + gupnp-dlna-profile-private.h libgupnp_dlna_1_0_la_SOURCES = gupnp-dlna-information.c \ gupnp-dlna-discoverer.c \ @@ -49,7 +49,6 @@ libgupnp_dlna_1_0_la_SOURCES = gupnp-dlna-information.c \ $(BUILT_SOURCES) libgupnp_dlna_1_0_la_LIBADD = $(LIBXML_LIBS) \ - $(top_builddir)/gst-convenience/gst-libs/gst/profile/.libs/libgstprofile-gupnp-dlna-0.10.la \ $(GST_PBU_LIBS) EXTRA_DIST = gupnp-dlna-marshal.list diff --git a/libgupnp-dlna/gupnp-dlna-discoverer.h b/libgupnp-dlna/gupnp-dlna-discoverer.h index ef59c7b..bdf9e45 100644 --- a/libgupnp-dlna/gupnp-dlna-discoverer.h +++ b/libgupnp-dlna/gupnp-dlna-discoverer.h @@ -23,7 +23,7 @@ #define _GUPNP_DLNA_DISCOVERER #include <glib-object.h> -#include <gst/pbutils/gstdiscoverer.h> +#include <gst/pbutils/pbutils.h> #include "gupnp-dlna-information.h" #include "gupnp-dlna-profile.h" diff --git a/libgupnp-dlna/gupnp-dlna-information.h b/libgupnp-dlna/gupnp-dlna-information.h index 481e9e2..5293fc1 100644 --- a/libgupnp-dlna/gupnp-dlna-information.h +++ b/libgupnp-dlna/gupnp-dlna-information.h @@ -22,7 +22,7 @@ #ifndef __GUPNP_DLNA_INFORMATION_H__ #define __GUPNP_DLNA_INFORMATION_H__ -#include <gst/pbutils/gstdiscoverer.h> +#include <gst/pbutils/pbutils.h> #include <glib-object.h> G_BEGIN_DECLS diff --git a/libgupnp-dlna/gupnp-dlna-load.c b/libgupnp-dlna/gupnp-dlna-load.c index 6d71e28..d9203a2 100644 --- a/libgupnp-dlna/gupnp-dlna-load.c +++ b/libgupnp-dlna/gupnp-dlna-load.c @@ -24,9 +24,10 @@ #include <glib-object.h> #include <libxml/xmlreader.h> #include <libxml/relaxng.h> -#include <gst/profile/gstprofile.h> +#include <gst/pbutils/pbutils.h> #include "gupnp-dlna-load.h" #include "gupnp-dlna-profile.h" +#include "gupnp-dlna-profile-private.h" #define GST_CAPS_NULL_NAME "NULL" #define DLNA_DATA_DIR DATA_DIR \ @@ -154,33 +155,15 @@ xml_str_free (xmlChar *str, gpointer unused) } static void -dlna_encoding_profile_add_stream (GstEncodingProfile *profile, - GstStreamEncodingProfile *stream_profile) +free_restrictions_struct (gpointer data, gpointer user_data) { - GList *i; + GUPnPDLNARestrictionsPriv *priv = (GUPnPDLNARestrictionsPriv *)data; + if (priv) { + if (priv->caps) + gst_caps_unref (priv->caps); - /* Try to merge with an existing stream profile of the same type */ - for (i = profile->encodingprofiles; i; i = i->next) { - GstStreamEncodingProfile *cur = - (GstStreamEncodingProfile *) i->data; - - if (cur->type != stream_profile->type) - continue; - - /* Since we maintain only one stream profile for each type, - * this will get executed exactly once */ - gst_caps_merge (cur->format, - gst_caps_copy (stream_profile->format)); - - gst_stream_encoding_profile_free (stream_profile); - goto done; + g_free (priv); } - - /* If we get here, there's no existing stream of this type */ - gst_encoding_profile_add_stream (profile, stream_profile); - -done: - return; } static void @@ -320,15 +303,12 @@ process_field (xmlTextReaderPtr reader, return ret; } -static GstStreamEncodingProfile * -process_parent (xmlTextReaderPtr reader, - GHashTable *restrictions, - gboolean relaxed_mode, - gboolean extended_mode) +static GUPnPDLNARestrictionsPriv * +process_parent (xmlTextReaderPtr reader, GUPnPDLNALoadState *data) { xmlChar *parent; xmlChar *used; - GstStreamEncodingProfile *profile; + GUPnPDLNARestrictionsPriv *priv = NULL; /* * Check to see if we need to follow any relaxed/strict mode @@ -336,11 +316,11 @@ process_parent (xmlTextReaderPtr reader, */ used = xmlTextReaderGetAttribute (reader, BAD_CAST ("used")); if (used) { - if ((relaxed_mode == FALSE) && + if ((data->relaxed_mode == FALSE) && xmlStrEqual (used, BAD_CAST ("in-relaxed"))) { xmlFree (used); return NULL; - } else if ((relaxed_mode == TRUE) && + } else if ((data->relaxed_mode == TRUE) && (xmlStrEqual (used, BAD_CAST ("in-strict")))) { xmlFree (used); return NULL; @@ -348,9 +328,9 @@ process_parent (xmlTextReaderPtr reader, } parent = xmlTextReaderGetAttribute (reader, BAD_CAST ("name")); - profile = g_hash_table_lookup (restrictions, parent); + priv = g_hash_table_lookup (data->restrictions, parent); - if (!profile) { + if (!priv) { g_warning ("Could not find parent restriction: %s", parent); return NULL; } @@ -358,14 +338,14 @@ process_parent (xmlTextReaderPtr reader, xmlFree (parent); xmlFree (used); - return gst_stream_encoding_profile_copy (profile); + return priv; } -static GstStreamEncodingProfile * +static GUPnPDLNARestrictionsPriv * process_restriction (xmlTextReaderPtr reader, GUPnPDLNALoadState *data) { - GstStreamEncodingProfile *stream_profile = NULL; - GstEncodingProfileType type; + GUPnPDLNARestrictionsPriv *restr = NULL; + GType type; GstCaps *caps = NULL; GString *caps_str = g_string_sized_new (100); GList *parents = NULL, *tmp; @@ -390,8 +370,7 @@ process_restriction (xmlTextReaderPtr reader, GUPnPDLNALoadState *data) /* We then walk through the fields in this restriction, and make a * string that can be parsed by gst_caps_from_string (). We then make - * a GstCaps from this string, and use the other metadata to make a - * GstStreamEncodingProfile */ + * a GstCaps from this string */ id = xmlTextReaderGetAttribute (reader, BAD_CAST ("id")); restr_type = xmlTextReaderGetAttribute (reader, BAD_CAST ("type")); @@ -427,17 +406,15 @@ process_restriction (xmlTextReaderPtr reader, GUPnPDLNALoadState *data) xmlFree (field); } else if (xmlStrEqual (tag, BAD_CAST ("parent"))) { /* <parent> */ - GstStreamEncodingProfile *profile = - process_parent (reader, - data->restrictions, - data->relaxed_mode, - data->extended_mode); + GUPnPDLNARestrictionsPriv *priv = + process_parent (reader, data); - if (profile) + if (priv && priv->caps) /* Collect parents in a list - we'll * coalesce them later */ parents = g_list_append (parents, - profile); + gst_caps_copy + (priv->caps)); } break; @@ -467,13 +444,13 @@ process_restriction (xmlTextReaderPtr reader, GUPnPDLNALoadState *data) xmlFree (name); if (xmlStrEqual (restr_type, BAD_CAST ("container"))) - type = GST_ENCODING_PROFILE_UNKNOWN; + type = GST_TYPE_ENCODING_CONTAINER_PROFILE; else if (xmlStrEqual (restr_type, BAD_CAST ("audio"))) - type = GST_ENCODING_PROFILE_AUDIO; + type = GST_TYPE_ENCODING_AUDIO_PROFILE; else if (xmlStrEqual (restr_type, BAD_CAST ("video"))) - type = GST_ENCODING_PROFILE_VIDEO; + type = GST_TYPE_ENCODING_VIDEO_PROFILE; else if (xmlStrEqual (restr_type, BAD_CAST ("image"))) - type = GST_ENCODING_PROFILE_IMAGE; + type = GST_TYPE_ENCODING_VIDEO_PROFILE; else { g_warning ("Support for '%s' restrictions not yet implemented", restr_type); @@ -488,26 +465,19 @@ process_restriction (xmlTextReaderPtr reader, GUPnPDLNALoadState *data) while (tmp) { /* Merge all the parent caps. The child overrides parent * attributes */ - GstStreamEncodingProfile *profile = tmp->data; - caps = merge_caps (caps, profile->format); - gst_stream_encoding_profile_free (profile); + GstCaps *tmp_caps = (GstCaps *)tmp->data; + caps = merge_caps (caps, tmp_caps); + gst_caps_unref (tmp_caps); tmp = tmp->next; } - stream_profile = gst_stream_encoding_profile_new (type, - caps, - NULL, - GST_CAPS_ANY, - 0); + restr = g_new0 (GUPnPDLNARestrictionsPriv, 1); - if (id) { - /* Make a copy so we can free it at the end of processing - * without worrying about it being reffed by an encoding - * profile */ - GstStreamEncodingProfile *tmp = - gst_stream_encoding_profile_copy (stream_profile); - g_hash_table_insert (data->restrictions, id, tmp); - } + restr->caps = gst_caps_copy (caps); + restr->type = type; + + if (id) + g_hash_table_insert (data->restrictions, id, restr); out: xmlFree (restr_type); @@ -518,20 +488,12 @@ out: if (parents) g_list_free (parents); - return stream_profile; + return restr; } static void process_restrictions (xmlTextReaderPtr reader, GUPnPDLNALoadState *data) { - /* While we use a GstStreamEncodingProfile to store restrictions here, - * this is not how they are finally used. This is just a convenient - * container for the format caps and stream type. Once the restriction - * is used in a profile, all the restrictions of the same type - * (audio/video) are merged into a single GstStreamEncodingProfile, - * which is added to the GstEncodingProfile for the DLNA profile. - */ - int ret = xmlTextReaderRead (reader); while (ret == 1) { @@ -543,10 +505,9 @@ process_restrictions (xmlTextReaderPtr reader, GUPnPDLNALoadState *data) case 1: if (xmlStrEqual (tag, BAD_CAST ("restriction"))) { /* <restriction> */ - GstStreamEncodingProfile *stream = + GUPnPDLNARestrictionsPriv *priv = process_restriction (reader, data); - gst_stream_encoding_profile_free (stream); } break; @@ -572,14 +533,13 @@ process_dlna_profile (xmlTextReaderPtr reader, GList **profiles, GUPnPDLNALoadState *data) { - int ret; - GUPnPDLNAProfile *profile; - GstStreamEncodingProfile *stream_profile; - GstEncodingProfile *enc_profile, *base = NULL; - GstCaps *format = NULL; - GList *stream_profiles = NULL, *streams; + guint ret; + GUPnPDLNAProfile *profile = NULL; + GUPnPDLNAProfile *base = NULL; + GUPnPDLNARestrictionsPriv *restr = NULL; + GstCaps *temp_audio = NULL, *temp_video = NULL, *temp_container = NULL; xmlChar *name, *mime, *id, *base_profile, *extended; - gboolean done = FALSE, is_extended = FALSE;; + gboolean done = FALSE, is_extended = FALSE; name = xmlTextReaderGetAttribute (reader, BAD_CAST ("name")); mime = xmlTextReaderGetAttribute (reader, BAD_CAST ("mime")); @@ -588,6 +548,11 @@ process_dlna_profile (xmlTextReaderPtr reader, base_profile = xmlTextReaderGetAttribute (reader, BAD_CAST ("base-profile")); + /* Create temporary place-holders for caps */ + temp_container = gst_caps_new_empty (); + temp_video = gst_caps_new_empty (); + temp_audio = gst_caps_new_empty (); + if (!name) { g_assert (mime == NULL); @@ -614,30 +579,25 @@ process_dlna_profile (xmlTextReaderPtr reader, switch (xmlTextReaderNodeType (reader)) { case 1: - if (xmlStrEqual (tag, BAD_CAST ("restriction"))) { - stream_profile = - process_restriction (reader, - data); - } else if (xmlStrEqual (tag, BAD_CAST ("parent"))) { - stream_profile = - process_parent (reader, - data->restrictions, - data->relaxed_mode, - data->extended_mode); - } + if (xmlStrEqual (tag, BAD_CAST ("restriction"))) + restr = process_restriction (reader, data); + else if (xmlStrEqual (tag, BAD_CAST ("parent"))) + restr = process_parent (reader, data); - if (!stream_profile) + if (!restr) break; - if (stream_profile->type == - GST_ENCODING_PROFILE_UNKNOWN) { - format = gst_caps_copy (stream_profile->format); - gst_stream_encoding_profile_free (stream_profile); - } else { - stream_profiles = - g_list_append (stream_profiles, - stream_profile); - } + if (restr->type == GST_TYPE_ENCODING_CONTAINER_PROFILE) + gst_caps_merge (temp_container, + gst_caps_copy (restr->caps)); + else if (restr->type == GST_TYPE_ENCODING_VIDEO_PROFILE) + gst_caps_merge (temp_video, + gst_caps_copy (restr->caps)); + else if (restr->type == GST_TYPE_ENCODING_AUDIO_PROFILE) + gst_caps_merge (temp_audio, + gst_caps_copy (restr->caps)); + else + g_assert_not_reached (); break; @@ -659,52 +619,56 @@ process_dlna_profile (xmlTextReaderPtr reader, g_warning ("Invalid base-profile reference"); } - if (!base) { - /* Create a new GstEncodingProfile */ - if (!format) - format = GST_CAPS_NONE; - enc_profile = gst_encoding_profile_new ((gchar *) name, - format, - NULL, - 0); - } else { - /* We're inherting from a parent profile */ - enc_profile = gst_encoding_profile_copy (base); - - g_free (enc_profile->name); - enc_profile->name = g_strdup ((gchar *) name); - - if (format) { - gst_caps_unref (enc_profile->format); - enc_profile->format = gst_caps_copy (format); - } - } - for (streams = stream_profiles; streams; streams = streams->next) { - GstStreamEncodingProfile *stream_profile = - (GstStreamEncodingProfile *) - streams->data; - /* The stream profile *must* not be referenced after this */ - dlna_encoding_profile_add_stream (enc_profile, stream_profile); + /* create a new GUPnPDLNAProfile */ + profile = gupnp_dlna_profile_new ((gchar *)name, + (gchar *)mime, + GST_CAPS_NONE, + GST_CAPS_NONE, + GST_CAPS_NONE, + is_extended); + + /* Inherit from base profile, if it exists*/ + if (base) { + const GstCaps *video_caps = gupnp_dlna_profile_get_video_caps (base); + const GstCaps *audio_caps = gupnp_dlna_profile_get_audio_caps (base); + + + if (GST_IS_CAPS (video_caps)) + gst_caps_merge (temp_video, + gst_caps_copy (video_caps)); + if (GST_IS_CAPS (audio_caps)) + gst_caps_merge (temp_audio, + gst_caps_copy (audio_caps)); + } - profile = gupnp_dlna_profile_new ((gchar *) name, - (gchar *) mime, - enc_profile, - is_extended); + + /* The merged caps will be our new GUPnPDLNAProfile */ + if (GST_IS_CAPS (temp_container)) + gupnp_dlna_profile_set_container_caps (profile, temp_container); + if (GST_IS_CAPS (temp_video)) + gupnp_dlna_profile_set_video_caps (profile, temp_video); + if (GST_IS_CAPS (temp_audio)) + gupnp_dlna_profile_set_audio_caps (profile, temp_audio); + *profiles = g_list_append (*profiles, profile); - if (id) + if (id) { /* id is freed when the hash table is destroyed */ - g_hash_table_insert (data->profile_ids, id, enc_profile); - else - /* we've got a copy in profile, so we're done with this */ - gst_encoding_profile_free (enc_profile); + g_object_ref (profile); + g_hash_table_insert (data->profile_ids, id, profile); + } out: - g_list_free (stream_profiles); - if (format) - gst_caps_unref (format); + + if (temp_container) + gst_caps_unref (temp_container); + if (temp_audio) + gst_caps_unref (temp_audio); + if (temp_video) + gst_caps_unref (temp_video); + xmlFree (mime); xmlFree (name); if (extended) @@ -868,13 +832,13 @@ gupnp_dlna_load_profiles_from_dir (gchar *profile_dir, GUPnPDLNALoadState *data) g_str_equal, (GDestroyNotify) xmlFree, (GDestroyNotify) - gst_stream_encoding_profile_free); + free_restrictions_struct); data->profile_ids = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) xmlFree, (GDestroyNotify) - gst_encoding_profile_free); + g_object_unref); GList *profiles = NULL; @@ -932,13 +896,15 @@ gupnp_dlna_load_profiles_from_disk (gboolean relaxed_mode, * name which are only used for inheritance and not matching. */ i = ret; while (i) { + const gchar *name; GUPnPDLNAProfile *profile = i->data; - const GstEncodingProfile *enc_profile = + GstEncodingProfile *enc_profile = gupnp_dlna_profile_get_encoding_profile (profile); GList *tmp = g_list_next (i); - if (enc_profile->name[0] == '\0') { + name = gst_encoding_profile_get_name (enc_profile); + if (name[0] == '\0') { ret = g_list_delete_link (ret, i); g_object_unref (profile); } diff --git a/libgupnp-dlna/gupnp-dlna-load.h b/libgupnp-dlna/gupnp-dlna-load.h index a294b85..e6e04ef 100644 --- a/libgupnp-dlna/gupnp-dlna-load.h +++ b/libgupnp-dlna/gupnp-dlna-load.h @@ -35,6 +35,11 @@ typedef struct { gboolean extended_mode; } GUPnPDLNALoadState; +typedef struct { + GstCaps *caps; + GType type; +} GUPnPDLNARestrictionsPriv; + GList * gupnp_dlna_load_profiles_from_file (const gchar *file_name, GUPnPDLNALoadState *data); diff --git a/libgupnp-dlna/gupnp-dlna-profile-private.h b/libgupnp-dlna/gupnp-dlna-profile-private.h new file mode 100644 index 0000000..8994b24 --- /dev/null +++ b/libgupnp-dlna/gupnp-dlna-profile-private.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2011 Nokia Corporation. + * + * Authors: Parthasarathi Susarla <partha.susarla@collabora.co.uk> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + + +GUPnPDLNAProfile * gupnp_dlna_profile_new (gchar *name, + gchar *mime, + GstCaps *container_caps, + GstCaps *video_caps, + GstCaps *audio_caps, + gboolean extended); + + +const GstCaps * gupnp_dlna_profile_get_container_caps (GUPnPDLNAProfile *self); +const GstCaps * gupnp_dlna_profile_get_video_caps (GUPnPDLNAProfile *self); +const GstCaps * gupnp_dlna_profile_get_audio_caps (GUPnPDLNAProfile *self); + +void gupnp_dlna_profile_set_container_caps (GUPnPDLNAProfile *self, GstCaps *caps); +void gupnp_dlna_profile_set_video_caps (GUPnPDLNAProfile *self, GstCaps *caps); +void gupnp_dlna_profile_set_audio_caps (GUPnPDLNAProfile *self, GstCaps *caps); diff --git a/libgupnp-dlna/gupnp-dlna-profile.c b/libgupnp-dlna/gupnp-dlna-profile.c index 9931e23..9cb4f9c 100644 --- a/libgupnp-dlna/gupnp-dlna-profile.c +++ b/libgupnp-dlna/gupnp-dlna-profile.c @@ -20,6 +20,7 @@ */ #include "gupnp-dlna-profile.h" +#include <gst/gstminiobject.h> /** * SECTION:gupnp-dlna-profile @@ -43,15 +44,17 @@ typedef struct _GUPnPDLNAProfilePrivate GUPnPDLNAProfilePrivate; struct _GUPnPDLNAProfilePrivate { gchar *name; gchar *mime; - GstEncodingProfile *enc_profile; + GstCaps *container_caps; + GstCaps *video_caps; + GstCaps *audio_caps; gboolean extended; + GstEncodingProfile *enc_profile; }; enum { PROP_0, PROP_DLNA_NAME, PROP_DLNA_MIME, - PROP_ENCODING_PROFILE, PROP_DLNA_EXTENDED, }; @@ -73,10 +76,6 @@ gupnp_dlna_profile_get_property (GObject *object, g_value_set_string (value, priv->mime); break; - case PROP_ENCODING_PROFILE: - g_value_set_boxed (value, priv->enc_profile); - break; - case PROP_DLNA_EXTENDED: g_value_set_boolean (value, priv->extended); break; @@ -109,12 +108,6 @@ gupnp_dlna_profile_set_property (GObject *object, priv->mime = g_value_dup_string (value); break; - case PROP_ENCODING_PROFILE: - if (priv->enc_profile) - gst_encoding_profile_free (priv->enc_profile); - priv->enc_profile = g_value_dup_boxed (value); - break; - case PROP_DLNA_EXTENDED: priv->extended = g_value_get_boolean (value); break; @@ -136,7 +129,7 @@ gupnp_dlna_profile_finalize (GObject *object) g_free (priv->mime); if (priv->enc_profile) - gst_encoding_profile_free (priv->enc_profile); + gst_encoding_profile_unref (priv->enc_profile); G_OBJECT_CLASS (gupnp_dlna_profile_parent_class)->finalize (object); } @@ -169,17 +162,6 @@ gupnp_dlna_profile_class_init (GUPnPDLNAProfileClass *klass) G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (object_class, PROP_DLNA_MIME, pspec); - pspec = g_param_spec_boxed ("encoding-profile", - "Encoding profile for the DLNA profile", - "GstEncodingProfile object " - "corresponding to the DLNA profile", - GST_TYPE_ENCODING_PROFILE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY); - g_object_class_install_property (object_class, - PROP_ENCODING_PROFILE, - pspec); - pspec = g_param_spec_boolean ("extended", "Extended mode property", "Indicates that this profile is not " @@ -204,6 +186,57 @@ gupnp_dlna_profile_init (GUPnPDLNAProfile *self) priv->extended = FALSE; } +GstCaps * +gupnp_dlna_profile_get_container_caps (GUPnPDLNAProfile *self) +{ + GUPnPDLNAProfilePrivate *priv = GET_PRIVATE (self); + return priv->container_caps; +} + +GstCaps * +gupnp_dlna_profile_get_video_caps (GUPnPDLNAProfile *self) +{ + GUPnPDLNAProfilePrivate *priv = GET_PRIVATE (self); + return priv->video_caps; +} + +GstCaps * +gupnp_dlna_profile_get_audio_caps (GUPnPDLNAProfile *self) +{ + GUPnPDLNAProfilePrivate *priv = GET_PRIVATE (self); + return priv->audio_caps; +} + +void +gupnp_dlna_profile_set_container_caps (GUPnPDLNAProfile *self, GstCaps *caps) +{ + GUPnPDLNAProfilePrivate *priv = GET_PRIVATE (self); + + if (priv->container_caps) + gst_caps_unref (priv->container_caps); + priv->container_caps = gst_caps_copy (caps); +} + +void +gupnp_dlna_profile_set_video_caps (GUPnPDLNAProfile *self, GstCaps *caps) +{ + GUPnPDLNAProfilePrivate *priv = GET_PRIVATE (self); + + if (priv->video_caps) + gst_caps_unref (priv->video_caps); + priv->video_caps = gst_caps_copy (caps); +} + +void +gupnp_dlna_profile_set_audio_caps (GUPnPDLNAProfile *self, GstCaps *caps) +{ + GUPnPDLNAProfilePrivate *priv = GET_PRIVATE (self); + + if (priv->audio_caps) + gst_caps_unref (priv->audio_caps); + priv->audio_caps = gst_caps_copy (caps); +} + /** * gupnp_dlna_profile_new: * @@ -214,15 +247,24 @@ gupnp_dlna_profile_init (GUPnPDLNAProfile *self) GUPnPDLNAProfile * gupnp_dlna_profile_new (gchar *name, gchar *mime, - GstEncodingProfile *enc_profile, + GstCaps *container_caps, + GstCaps *video_caps, + GstCaps *audio_caps, gboolean extended) { - return g_object_new (GUPNP_TYPE_DLNA_PROFILE, - "name", name, - "mime", mime, - "encoding-profile", enc_profile, - "extended", extended, - NULL); + GUPnPDLNAProfile *prof; + + prof = g_object_new (GUPNP_TYPE_DLNA_PROFILE, + "name", name, + "mime", mime, + "extended", extended, + NULL); + + gupnp_dlna_profile_set_container_caps (prof, container_caps); + gupnp_dlna_profile_set_video_caps (prof, video_caps); + gupnp_dlna_profile_set_audio_caps (prof, audio_caps); + + return prof; } /** @@ -259,11 +301,43 @@ gupnp_dlna_profile_get_mime (GUPnPDLNAProfile *self) * to transcode a given stream to match the DLNA profile represented * by @self. */ -const GstEncodingProfile * +GstEncodingProfile * gupnp_dlna_profile_get_encoding_profile (GUPnPDLNAProfile *self) { GUPnPDLNAProfilePrivate *priv = GET_PRIVATE (self); - return priv->enc_profile; + + /* check if we have it cached already */ + if (priv->enc_profile) { + gst_encoding_profile_ref (priv->enc_profile); + } else { + /* create an encoding-profile */ + if (GST_IS_CAPS (priv->container_caps)) { + priv->enc_profile = + (GstEncodingProfile *)gst_encoding_container_profile_new + (priv->name, + priv->mime, + priv->container_caps, + NULL); + + if (GST_IS_CAPS (priv->video_caps) && + !gst_caps_is_empty (priv->video_caps)) + gst_encoding_container_profile_add_profile + ((GstEncodingContainerProfile *)priv->enc_profile, + (GstEncodingProfile *)gst_encoding_video_profile_new + (priv->video_caps, NULL, NULL, 0)); + + + if (GST_IS_CAPS (priv->audio_caps) && + !gst_caps_is_empty (priv->audio_caps)) + gst_encoding_container_profile_add_profile + ((GstEncodingContainerProfile *)priv->enc_profile, + (GstEncodingProfile *)gst_encoding_audio_profile_new + (priv->audio_caps, NULL, NULL, 0)); + + } + } + + return (GstEncodingProfile *)priv->enc_profile; } /** diff --git a/libgupnp-dlna/gupnp-dlna-profile.h b/libgupnp-dlna/gupnp-dlna-profile.h index 63eba96..91f3f4d 100644 --- a/libgupnp-dlna/gupnp-dlna-profile.h +++ b/libgupnp-dlna/gupnp-dlna-profile.h @@ -22,7 +22,7 @@ #ifndef __GUPNP_DLNA_PROFILE_H__ #define __GUPNP_DLNA_PROFILE_H__ -#include <gst/profile/gstprofile.h> +#include <gst/pbutils/pbutils.h> #include <glib-object.h> G_BEGIN_DECLS @@ -60,14 +60,9 @@ typedef struct { GType gupnp_dlna_profile_get_type (void); -GUPnPDLNAProfile * gupnp_dlna_profile_new (gchar *name, - gchar *mime, - GstEncodingProfile *enc_profile, - gboolean extended); - const gchar * gupnp_dlna_profile_get_name (GUPnPDLNAProfile *self); const gchar * gupnp_dlna_profile_get_mime (GUPnPDLNAProfile *self); -const GstEncodingProfile * +GstEncodingProfile * gupnp_dlna_profile_get_encoding_profile (GUPnPDLNAProfile *self); gboolean gupnp_dlna_profile_get_extended (GUPnPDLNAProfile *self); diff --git a/libgupnp-dlna/gupnp-dlna-profiles.c b/libgupnp-dlna/gupnp-dlna-profiles.c index 0de4f4b..027982a 100644 --- a/libgupnp-dlna/gupnp-dlna-profiles.c +++ b/libgupnp-dlna/gupnp-dlna-profiles.c @@ -20,9 +20,8 @@ */ #include <glib.h> -#include <gst/profile/gstprofile.h> +#include <gst/pbutils/pbutils.h> #include "gupnp-dlna-discoverer.h" -#include "gupnp-dlna-load.h" #include "gupnp-dlna-profile.h" /* @@ -77,12 +76,16 @@ do { \ static gboolean is_video_profile (const GstEncodingProfile *profile) { - GList *i; - - for (i = profile->encodingprofiles; i; i = i->next) - if (((GstStreamEncodingProfile *) i->data)->type == - GST_ENCODING_PROFILE_VIDEO) - return TRUE; + const GList *i; + + if (GST_IS_ENCODING_CONTAINER_PROFILE (profile)) { + for (i = gst_encoding_container_profile_get_profiles + (GST_ENCODING_CONTAINER_PROFILE (profile)); + i; + i = i->next) + if (GST_IS_ENCODING_VIDEO_PROFILE (i->data)) + return TRUE; + } return FALSE; } @@ -133,7 +136,7 @@ structure_is_subset (const GstStructure *st1, const GstStructure *st2) * restrictions) */ static gboolean -caps_can_intersect_and_is_subset (GstCaps *stream_caps, GstCaps *profile_caps) +caps_can_intersect_and_is_subset (GstCaps *stream_caps, const GstCaps *profile_caps) { int i; GstStructure *stream_st, *profile_st; @@ -152,23 +155,30 @@ caps_can_intersect_and_is_subset (GstCaps *stream_caps, GstCaps *profile_caps) } static gboolean -match_profile (const GstEncodingProfile *profile, - GstCaps *caps, - GstEncodingProfileType type) +match_profile (GstEncodingProfile *profile, + GstCaps *caps, + GType type) { - GList *i; + const GList *i; + const gchar *name; /* Profiles with an empty name are used only for inheritance and should * not be matched against. */ - if (profile->name[0] == '\0') + name = gst_encoding_profile_get_name (profile); + if (name[0] == '\0') return FALSE; - for (i = profile->encodingprofiles; i; i = i->next) { - GstStreamEncodingProfile *enc_profile = i->data; - - if (enc_profile->type == type && - caps_can_intersect_and_is_subset (caps, - enc_profile->format)) + for (i = gst_encoding_container_profile_get_profiles + (GST_ENCODING_CONTAINER_PROFILE (profile)); + i; + i = i->next){ + GstEncodingProfile *enc_profile = GST_ENCODING_PROFILE + (i->data); + const GstCaps *format = gst_encoding_profile_get_format + (enc_profile); + + if (type == G_TYPE_FROM_INSTANCE (enc_profile) && + caps_can_intersect_and_is_subset (caps, format)) return TRUE; } @@ -176,14 +186,16 @@ match_profile (const GstEncodingProfile *profile, } static gboolean -check_container (GstDiscovererInfo *info, - const GstEncodingProfile *profile) +check_container (GstDiscovererInfo *info, + GstEncodingProfile *profile) { GstDiscovererStreamInfo *stream_info; GType stream_type; GstCaps *stream_caps; gboolean ret = FALSE; + const GstCaps *profile_caps = gst_encoding_profile_get_format (profile); + /* Top-level GstStreamInformation in the topology will be * the container */ stream_info = gst_discoverer_info_get_stream_info (info); @@ -191,10 +203,10 @@ check_container (GstDiscovererInfo *info, stream_type = G_TYPE_FROM_INSTANCE (stream_info); if (stream_type == GST_TYPE_DISCOVERER_CONTAINER_INFO && - gst_caps_can_intersect (stream_caps, profile->format)) + gst_caps_can_intersect (stream_caps, profile_caps)) ret = TRUE; else if (stream_type != GST_TYPE_DISCOVERER_CONTAINER_INFO && - gst_caps_is_empty (profile->format)) + gst_caps_is_empty (profile_caps)) ret = TRUE; gst_discoverer_stream_info_unref (stream_info); @@ -239,8 +251,8 @@ caps_from_audio_stream_info (GstDiscovererStreamInfo *info) } static gboolean -check_audio_profile (GstDiscovererInfo *info, - const GstEncodingProfile *profile) +check_audio_profile (GstDiscovererInfo *info, + GstEncodingProfile *profile) { GstCaps *caps; GList *i, *stream_list; @@ -262,7 +274,9 @@ check_audio_profile (GstDiscovererInfo *info, caps = caps_from_audio_stream_info (stream); - if (match_profile (profile, caps, GST_ENCODING_PROFILE_AUDIO)) { + if (match_profile (profile, + caps, + GST_TYPE_ENCODING_AUDIO_PROFILE)) { found = TRUE; break; } @@ -283,7 +297,7 @@ guess_audio_profile (GstDiscovererInfo *info, { GList *i; GUPnPDLNAProfile *profile; - const GstEncodingProfile *enc_profile; + GstEncodingProfile *enc_profile; for (i = profiles; i; i = i->next) { profile = (GUPnPDLNAProfile *)(i->data); @@ -373,8 +387,8 @@ caps_from_video_stream_info (GstDiscovererStreamInfo *info) } static gboolean -check_video_profile (GstDiscovererInfo *info, - const GstEncodingProfile *profile) +check_video_profile (GstDiscovererInfo *info, + GstEncodingProfile *profile) { GList *i, *stream_list; gboolean found_video = FALSE, found_audio = FALSE;; @@ -397,7 +411,7 @@ check_video_profile (GstDiscovererInfo *info, caps = caps_from_video_stream_info (stream); if (match_profile (profile, caps, - GST_ENCODING_PROFILE_VIDEO)) + GST_TYPE_ENCODING_VIDEO_PROFILE)) found_video = TRUE; else gupnp_dlna_debug (" Video did not match"); @@ -406,7 +420,7 @@ check_video_profile (GstDiscovererInfo *info, caps = caps_from_audio_stream_info (stream); if (match_profile (profile, caps, - GST_ENCODING_PROFILE_AUDIO)) + GST_TYPE_ENCODING_AUDIO_PROFILE)) found_audio = TRUE; else gupnp_dlna_debug (" Audio did not match"); @@ -437,7 +451,7 @@ guess_video_profile (GstDiscovererInfo *info, GList *profiles) { GUPnPDLNAProfile *profile = NULL; - const GstEncodingProfile *enc_profile; + GstEncodingProfile *enc_profile; GList *i; for (i = profiles; i; i = i->next) { @@ -464,7 +478,7 @@ guess_image_profile (GstDiscovererStreamInfo *info, GList *i; gboolean found = FALSE; GUPnPDLNAProfile *profile; - const GstEncodingProfile *enc_profile; + GstEncodingProfile *enc_profile; const GstDiscovererVideoInfo *video_info = GST_DISCOVERER_VIDEO_INFO (info); @@ -483,7 +497,7 @@ guess_image_profile (GstDiscovererStreamInfo *info, if (match_profile (enc_profile, caps, - GST_ENCODING_PROFILE_IMAGE)) { + GST_TYPE_ENCODING_VIDEO_PROFILE)) { /* Found a match */ *name = g_strdup (gupnp_dlna_profile_get_name (profile)); *mime = g_strdup (gupnp_dlna_profile_get_mime (profile)); @@ -522,6 +536,7 @@ gupnp_dlna_information_new_from_discoverer_info (GstDiscovererInfo *info, dlna = gupnp_dlna_information_new (name, mime, info); + g_free (name); g_free (mime); |