diff options
author | Krzesimir Nowak <krnowak@openismus.com> | 2013-01-02 14:42:07 +0100 |
---|---|---|
committer | Jens Georg <mail@jensge.org> | 2013-01-16 11:27:53 +0100 |
commit | 20a524c1727886ac317eab598a334e1b00efe930 (patch) | |
tree | 2053384a20c300459791422a4bf242c34e9150d1 /libgupnp-dlna/gupnp-dlna-profile-guesser-impl.c | |
parent | 9dc43ea0b96a0fae23d2f31d548831ea8c80657d (diff) | |
download | gupnp-dlna-20a524c1727886ac317eab598a334e1b00efe930.tar.gz |
Remove GUPnPDLNANativeProfileGuesser.
It existed only because we didn't want to expose GUPnPDLNAInformation
at first in its public API. And we recently exposed it there anyway.
Diffstat (limited to 'libgupnp-dlna/gupnp-dlna-profile-guesser-impl.c')
-rw-r--r-- | libgupnp-dlna/gupnp-dlna-profile-guesser-impl.c | 651 |
1 files changed, 596 insertions, 55 deletions
diff --git a/libgupnp-dlna/gupnp-dlna-profile-guesser-impl.c b/libgupnp-dlna/gupnp-dlna-profile-guesser-impl.c index 785b457..af93fb5 100644 --- a/libgupnp-dlna/gupnp-dlna-profile-guesser-impl.c +++ b/libgupnp-dlna/gupnp-dlna-profile-guesser-impl.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2010 Nokia Corporation. - * Copyright (C) 2012 Intel Corporation. + * Copyright (C) 2012, 2013 Intel Corporation. * * Authors: Arun Raghavan <arun.raghavan@collabora.co.uk> * Krzesimir Nowak <krnowak@openismus.com> @@ -21,80 +21,621 @@ * Boston, MA 02110-1301, USA. */ +#include <glib.h> + +#include "gupnp-dlna-profile.h" #include "gupnp-dlna-profile-guesser-impl.h" +#include "gupnp-dlna-information.h" +#include "gupnp-dlna-audio-information.h" +#include "gupnp-dlna-container-information.h" +#include "gupnp-dlna-image-information.h" +#include "gupnp-dlna-video-information.h" +#include "gupnp-dlna-native-sets.h" +#include "gupnp-dlna-native-utils.h" + +static gboolean +is_video_profile (GUPnPDLNAProfile *profile) +{ + GList *container_restrictions = + gupnp_dlna_profile_get_container_restrictions (profile); + GList *video_restrictions = + gupnp_dlna_profile_get_video_restrictions (profile); + + return (container_restrictions != NULL && video_restrictions != NULL); +} + +static gboolean +match_profile (GUPnPDLNAProfile *profile, + GUPnPDLNANativeInfoSet *stream_info_set, + GList *profile_restrictions) +{ + const gchar *name = gupnp_dlna_profile_get_name (profile); + GList *iter; + gchar *stream_dump; + gchar *restrictions_dump; + + /* Profiles with an empty name are used only for inheritance + * and should not be matched against. */ + if (name == NULL || name[0] == '\0') { + /* TODO: if this warning never happens, then remove + * profile parameter from this function. + */ + g_warning ("Profiles weren't cleaned up properly?"); + return FALSE; + } + + stream_dump = gupnp_dlna_native_info_set_to_string (stream_info_set); + restrictions_dump = gupnp_dlna_native_utils_restrictions_list_to_string + (profile_restrictions); + g_debug ("Stream: %s\nRestrictions: %s", + stream_dump, + restrictions_dump); + g_free (stream_dump); + g_free (restrictions_dump); + + for (iter = profile_restrictions; iter != NULL; iter = iter->next) { + GUPnPDLNARestriction *restriction = + GUPNP_DLNA_RESTRICTION (iter->data); + + if (restriction != NULL && + gupnp_dlna_native_info_set_fits_restriction + (stream_info_set, + restriction)) + return TRUE; + } + + return FALSE; +} + +static void +add_bool (GUPnPDLNANativeInfoSet *info_set, + const gchar *name, + GUPnPDLNABoolValue value, + const gchar *type) +{ + switch (value.state) { + case GUPNP_DLNA_VALUE_STATE_SET: + if (!gupnp_dlna_native_info_set_add_bool (info_set, + name, + value.value)) + g_warning ("Failed to add '%s' bool value (%s) to %s " + "info set.", + name, + (value.value ? "true" : "false"), + type); -G_DEFINE_ABSTRACT_TYPE (GUPnPDLNAProfileGuesserImpl, - gupnp_dlna_profile_guesser_impl, - G_TYPE_OBJECT) + break; + case GUPNP_DLNA_VALUE_STATE_UNSET: + break; + case GUPNP_DLNA_VALUE_STATE_UNSUPPORTED: + if (!gupnp_dlna_native_info_set_add_unsupported_bool (info_set, + name)) + g_warning ("Failed to add '%s' bool unsupported value" + " to %s info set.", + name, + type); -struct _GUPnPDLNAProfileGuesserImplPrivate { - gpointer placeholder; -}; + break; + default: + g_critical ("Wrong value state value (%d).", value.state); + } +} static void -gupnp_dlna_profile_guesser_impl_class_init - (GUPnPDLNAProfileGuesserImplClass *guesser_impl_class) +add_fraction (GUPnPDLNANativeInfoSet *info_set, + const gchar *name, + GUPnPDLNAFractionValue value, + const gchar *type) { - g_type_class_add_private (guesser_impl_class, - sizeof (GUPnPDLNAProfileGuesserImplPrivate)); + switch (value.state) { + case GUPNP_DLNA_VALUE_STATE_SET: + if (!gupnp_dlna_native_info_set_add_fraction + (info_set, + name, + value.numerator, + value.denominator)) + g_warning ("Failed to add '%s' fraction value (%d/%d)" + " to %s info set.", + name, + value.numerator, + value.denominator, + type); + + break; + case GUPNP_DLNA_VALUE_STATE_UNSET: + break; + case GUPNP_DLNA_VALUE_STATE_UNSUPPORTED: + if (!gupnp_dlna_native_info_set_add_unsupported_fraction + (info_set, + name)) + g_warning ("Failed to add '%s' fraction unsupported" + " value to %s info set.", + name, + type); + + break; + default: + g_critical ("Wrong value state value (%d).", value.state); + } } static void -gupnp_dlna_profile_guesser_impl_init (GUPnPDLNAProfileGuesserImpl *self) +add_int (GUPnPDLNANativeInfoSet *info_set, + const gchar *name, + GUPnPDLNAIntValue value, + const gchar *type) { - GUPnPDLNAProfileGuesserImplPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE - (self, - GUPNP_TYPE_DLNA_PROFILE_GUESSER_IMPL, - GUPnPDLNAProfileGuesserImplPrivate); + switch (value.state) { + case GUPNP_DLNA_VALUE_STATE_SET: + if (!gupnp_dlna_native_info_set_add_int (info_set, + name, + value.value)) + g_warning ("Failed to add '%s' int value (%d) to %s " + "info set.", + name, + value.value, + type); - self->priv = priv; + break; + case GUPNP_DLNA_VALUE_STATE_UNSET: + break; + case GUPNP_DLNA_VALUE_STATE_UNSUPPORTED: + if (!gupnp_dlna_native_info_set_add_unsupported_int (info_set, + name)) + g_warning ("Failed to add '%s' int unsupported value" + " to %s info set.", + name, + type); + + break; + default: + g_critical ("Wrong value state value (%d).", value.state); + } } -GUPnPDLNAProfile * -gupnp_dlna_profile_guesser_impl_guess_profile - (GUPnPDLNAProfileGuesserImpl *guesser_impl, - GUPnPDLNAInformation *info, - GList *profiles) +static void +add_string (GUPnPDLNANativeInfoSet *info_set, + const gchar *name, + GUPnPDLNAStringValue value, + const gchar *type) +{ + switch (value.state) { + case GUPNP_DLNA_VALUE_STATE_SET: + if (!gupnp_dlna_native_info_set_add_string (info_set, + name, + value.value)) + g_warning ("Failed to add '%s' int value (%s) to %s " + "info set.", + name, + value.value, + type); + g_free (value.value); + + break; + case GUPNP_DLNA_VALUE_STATE_UNSET: + break; + case GUPNP_DLNA_VALUE_STATE_UNSUPPORTED: + if (!gupnp_dlna_native_info_set_add_unsupported_string + (info_set, + name)) + g_warning ("Failed to add '%s' string unsupported value" + " to %s info set.", + name, + type); + + break; + default: + g_critical ("Wrong value state value (%d).", value.state); + } +} + +static GUPnPDLNANativeInfoSet * +create_info_set (GUPnPDLNAStringValue value, + const gchar *type) +{ + gchar *mime; + gchar *lctype; + GUPnPDLNANativeInfoSet *info_set; + + if (value.state == GUPNP_DLNA_VALUE_STATE_SET) { + mime = value.value; + lctype = g_ascii_strdown (type, -1); + } else { + g_warning ("%s information holds no mime type, expect it" + "to match to no DLNA profile.", + type); + mime = g_ascii_strdown (type, -1); + lctype = g_strdup (mime); + } + + info_set = gupnp_dlna_native_info_set_new (mime); + if (info_set == NULL) + g_warning ("Failed to create %s info set with mime '%s'.", + lctype, + mime); + g_free (mime); + g_free (lctype); + + return info_set; +} + +static GUPnPDLNANativeInfoSet * +info_set_from_container_information (GUPnPDLNAContainerInformation *info) +{ + static const gchar *const type = "container"; + GUPnPDLNANativeInfoSet *info_set = create_info_set + (gupnp_dlna_container_information_get_mime (info), + "Container"); + + if (info_set == NULL) + return NULL; + + add_int (info_set, + "mpegversion", + gupnp_dlna_container_information_get_mpeg_version (info), + type); + + add_int (info_set, + "packetsize", + gupnp_dlna_container_information_get_packet_size (info), + type); + + add_string (info_set, + "profile", + gupnp_dlna_container_information_get_profile (info), + type); + + add_bool (info_set, + "systemstream", + gupnp_dlna_container_information_is_system_stream (info), + type); + + add_string (info_set, + "variant", + gupnp_dlna_container_information_get_variant (info), + type); + + return info_set; +} + +static gboolean +check_container_profile (GUPnPDLNAInformation *info, + GUPnPDLNAProfile *profile) +{ + GUPnPDLNAContainerInformation *container_info = + gupnp_dlna_information_get_container_information (info); + gboolean matched = FALSE; + GList *profile_restrictions = + gupnp_dlna_profile_get_container_restrictions (profile); + + if (profile_restrictions != NULL && container_info != NULL) { + GUPnPDLNANativeInfoSet *stream_info_set = + info_set_from_container_information (container_info); + + if (match_profile (profile, + stream_info_set, + profile_restrictions)) + matched = TRUE; + else + g_debug ("Container did not match."); + gupnp_dlna_native_info_set_free (stream_info_set); + } else if (profile_restrictions == NULL && container_info == NULL) + matched = TRUE; + + return matched; +} + +static GUPnPDLNANativeInfoSet * +info_set_from_audio_information (GUPnPDLNAAudioInformation *info) +{ + static const gchar *const type = "audio"; + GUPnPDLNANativeInfoSet *info_set = create_info_set + (gupnp_dlna_audio_information_get_mime (info), + "Audio"); + + if (info_set == NULL) + return NULL; + + add_int (info_set, + "bitrate", + gupnp_dlna_audio_information_get_bitrate (info), + type); + + add_int (info_set, + "channels", + gupnp_dlna_audio_information_get_channels (info), + type); + + add_int (info_set, + "depth", + gupnp_dlna_audio_information_get_depth (info), + type); + + add_int (info_set, + "layer", + gupnp_dlna_audio_information_get_layer (info), + type); + + add_string (info_set, + "level", + gupnp_dlna_audio_information_get_level (info), + type); + + add_int (info_set, + "mpegaudioversion", + gupnp_dlna_audio_information_get_mpeg_audio_version (info), + type); + + add_int (info_set, + "mpegversion", + gupnp_dlna_audio_information_get_mpeg_version (info), + type); + + add_string (info_set, + "profile", + gupnp_dlna_audio_information_get_profile (info), + type); + + add_int (info_set, + "rate", + gupnp_dlna_audio_information_get_rate (info), + type); + + add_string (info_set, + "stream-format", + gupnp_dlna_audio_information_get_stream_format (info), + type); + + add_int (info_set, + "wmaversion", + gupnp_dlna_audio_information_get_wma_version (info), + type); + + return info_set; +} + +static gboolean +check_audio_profile (GUPnPDLNAInformation *info, + GUPnPDLNAProfile *profile) +{ + GUPnPDLNANativeInfoSet *info_set; + gboolean matched; + GUPnPDLNAAudioInformation *audio_info; + GList *restrictions; + + if (is_video_profile (profile)) + return FALSE; + + matched = FALSE; + audio_info = gupnp_dlna_information_get_audio_information (info); + info_set = info_set_from_audio_information (audio_info); + restrictions = gupnp_dlna_profile_get_audio_restrictions (profile); + if (match_profile (profile, info_set, restrictions)) + matched = TRUE; + else + g_debug ("Audio did not match."); + gupnp_dlna_native_info_set_free (info_set); + + return matched; +} + +static GUPnPDLNANativeInfoSet * +info_set_from_video_information (GUPnPDLNAVideoInformation *info) +{ + static const gchar *const type = "video"; + GUPnPDLNANativeInfoSet *info_set = create_info_set + (gupnp_dlna_video_information_get_mime (info), + "Video"); + + if (info_set == NULL) + return NULL; + + add_int (info_set, + "bitrate", + gupnp_dlna_video_information_get_bitrate (info), + type); + + add_fraction (info_set, + "framerate", + gupnp_dlna_video_information_get_framerate (info), + type); + + add_int (info_set, + "height", + gupnp_dlna_video_information_get_height (info), + type); + + add_bool (info_set, + "interlaced", + gupnp_dlna_video_information_is_interlaced (info), + type); + + add_string (info_set, + "level", + gupnp_dlna_video_information_get_level (info), + type); + + add_int (info_set, + "mpegversion", + gupnp_dlna_video_information_get_mpeg_version (info), + type); + + add_fraction + (info_set, + "pixel-aspect-ratio", + gupnp_dlna_video_information_get_pixel_aspect_ratio (info), + type); + + add_string (info_set, + "profile", + gupnp_dlna_video_information_get_profile (info), + type); + + add_bool (info_set, + "systemstream", + gupnp_dlna_video_information_is_system_stream (info), + type); + + add_int (info_set, + "width", + gupnp_dlna_video_information_get_width (info), + type); + + return info_set; +} + +static gboolean +check_video_profile (GUPnPDLNAInformation *info, + GUPnPDLNAProfile *profile) { GUPnPDLNAVideoInformation *video_info = gupnp_dlna_information_get_video_information (info); GUPnPDLNAAudioInformation *audio_info = gupnp_dlna_information_get_audio_information (info); + GUPnPDLNANativeInfoSet *info_set = NULL; + GList *restrictions; + gboolean result = FALSE; + + if (video_info == NULL || audio_info == NULL) + goto out; + + restrictions = gupnp_dlna_profile_get_video_restrictions (profile); + info_set = info_set_from_video_information (video_info); + if (!match_profile (profile, info_set, restrictions)) { + g_debug ("Video did not match"); + + goto out; + } + gupnp_dlna_native_info_set_free (info_set); + + restrictions = gupnp_dlna_profile_get_audio_restrictions (profile); + info_set = info_set_from_audio_information (audio_info); + if (!match_profile (profile, info_set, restrictions)) { + g_debug ("Audio did not match"); + + goto out; + } + + if (check_container_profile (info, profile)) + result = TRUE; + out: + gupnp_dlna_native_info_set_free (info_set); + + return result; +} + +static GUPnPDLNANativeInfoSet * +info_set_from_image_information (GUPnPDLNAImageInformation *info) +{ + static const gchar *const type = "image"; + GUPnPDLNANativeInfoSet *info_set = create_info_set + (gupnp_dlna_image_information_get_mime (info), + "Image"); + + if (info_set == NULL) + return NULL; + + add_int (info_set, + "depth", + gupnp_dlna_image_information_get_depth (info), + type); + + add_int (info_set, + "height", + gupnp_dlna_image_information_get_height (info), + type); + + add_int (info_set, + "width", + gupnp_dlna_image_information_get_width (info), + type); + + return info_set; +} + +GUPnPDLNAProfile * +gupnp_dlna_profile_guesser_impl_guess_image_profile + (GUPnPDLNAInformation *info, + GList *profiles) +{ + GList *iter; GUPnPDLNAImageInformation *image_info = gupnp_dlna_information_get_image_information (info); - GUPnPDLNAProfile *profile = NULL; - GUPnPDLNAProfileGuesserImplClass *guesser_impl_class = - GUPNP_DLNA_PROFILE_GUESSER_IMPL_GET_CLASS (guesser_impl); - - g_return_val_if_fail - (GUPNP_IS_DLNA_PROFILE_GUESSER_IMPL_CLASS (guesser_impl_class), - NULL); - - if (image_info) { - g_return_val_if_fail - (guesser_impl_class->guess_image_profile != NULL, - NULL); - - profile = guesser_impl_class->guess_image_profile (guesser_impl, - info, - profiles); - } else if (video_info) { - g_return_val_if_fail - (guesser_impl_class->guess_video_profile != NULL, - NULL); - - profile = guesser_impl_class->guess_video_profile (guesser_impl, - info, - profiles); - } else if (audio_info) { - g_return_val_if_fail - (guesser_impl_class->guess_audio_profile != NULL, - NULL); - - profile = guesser_impl_class->guess_audio_profile (guesser_impl, - info, - profiles); + GUPnPDLNANativeInfoSet *info_set; + GUPnPDLNAProfile *found_profile; + + if (!image_info) + return NULL; + + info_set = info_set_from_image_information (image_info); + found_profile = NULL; + + for (iter = profiles; iter; iter = iter->next) { + GUPnPDLNAProfile *profile = GUPNP_DLNA_PROFILE (iter->data); + GList *restrictions = + gupnp_dlna_profile_get_image_restrictions (profile); + + g_debug ("Matching image against profile: %s", + gupnp_dlna_profile_get_name (profile)); + + if (match_profile (profile, info_set, restrictions)) { + found_profile = profile; + + break; + } else + g_debug ("Image did not match"); + } + + gupnp_dlna_native_info_set_free (info_set); + + return found_profile; +} + +GUPnPDLNAProfile * +gupnp_dlna_profile_guesser_impl_guess_video_profile + (GUPnPDLNAInformation *info, + GList *profiles) +{ + GUPnPDLNAProfile *found_profile = NULL; + GList *iter; + + for (iter = profiles; iter; iter = iter->next) { + GUPnPDLNAProfile *profile = GUPNP_DLNA_PROFILE (iter->data); + + g_debug ("Matching video against profile: %s", + gupnp_dlna_profile_get_name (profile)); + + if (check_video_profile (info, profile)) { + found_profile = profile; + + break; + } + } + + return found_profile; +} + +GUPnPDLNAProfile * +gupnp_dlna_profile_guesser_impl_guess_audio_profile + (GUPnPDLNAInformation *info, + GList *profiles) +{ + GList *iter; + GUPnPDLNAProfile *found_profile = NULL; + + for (iter = profiles; iter != NULL; iter = iter->next) { + GUPnPDLNAProfile *profile = GUPNP_DLNA_PROFILE (iter->data); + + g_debug ("Matching audio against profile: %s", + gupnp_dlna_profile_get_name (profile)); + + if (check_audio_profile (info, profile) && + check_container_profile (info, profile)) { + found_profile = profile; + + break; + } } - return profile; + return found_profile; } |