From 5e18ad2eab7992d4631a4eba16734080c6170b10 Mon Sep 17 00:00:00 2001 From: Jens Georg Date: Mon, 17 Dec 2012 16:53:58 +0100 Subject: [PATCH] media-export,engine-gst: Port to new GUPnP-DLNA --- configure.ac | 14 +-- .../gstreamer/rygel-gst-media-engine.vala | 4 +- .../rygel-media-export-harvesting-task.vala | 9 +- .../rygel-media-export-item-factory.vala | 114 +++++++++++---------- .../rygel-media-export-metadata-extractor.vala | 62 ++++++----- 5 files changed, 113 insertions(+), 90 deletions(-) diff --git a/configure.ac b/configure.ac index bbd4920..d77f043 100644 --- a/configure.ac +++ b/configure.ac @@ -36,7 +36,7 @@ VALADOC_REQUIRED=0.2 GSSDP_REQUIRED=0.13.0 GUPNP_REQUIRED=0.19.0 GUPNP_AV_REQUIRED=0.11.4 -GUPNP_DLNA_REQUIRED=0.7.0 +GUPNP_DLNA_REQUIRED=0.9.4 GSTREAMER_REQUIRED=1.0 GSTPBU_REQUIRED=1.0 GIO_REQUIRED=2.26 @@ -103,9 +103,10 @@ AS_IF([test "x$with_media_engine" = "xgstreamer"], PKG_CHECK_MODULES([RYGEL_MEDIA_ENGINE_GSTREAMER_DEPS], [$RYGEL_COMMON_MODULES gstreamer-pbutils-1.0 >= $GSTPBU_REQUIRED - gupnp-dlna-1.1 >= $GUPNP_DLNA_REQUIRED + gstreamer-app-1.0 >= $GSTREAMER_APP_REQUIRED + gupnp-dlna-2.0 >= $GUPNP_DLNA_REQUIRED gio-2.0 >= GIO_REQUIRED]) - RYGEL_MEDIA_ENGINE_GSTREAMER_DEPS_VALAFLAGS="$RYGEL_COMMON_MODULES_VALAFLAGS --pkg gstreamer-base-1.0 --pkg gstreamer-pbutils-1.0 --pkg gupnp-dlna-1.1" + RYGEL_MEDIA_ENGINE_GSTREAMER_DEPS_VALAFLAGS="$RYGEL_COMMON_MODULES_VALAFLAGS --pkg gstreamer-base-1.0 --pkg gstreamer-pbutils-1.0 --pkg gupnp-dlna-2.0" AC_SUBST([RYGEL_MEDIA_ENGINE_GSTREAMER_DEPS_VALAFLAGS]) PKG_CHECK_MODULES([LIBRYGEL_RENDERER_GST_DEPS], [$RYGEL_COMMON_MODULES gstreamer-1.0 >= $GSTREAMER_REQUIRED]) @@ -152,13 +153,14 @@ AS_IF([test "x$with_media_engine" = "xgstreamer"], [ PKG_CHECK_MODULES([RYGEL_PLUGIN_MEDIA_EXPORT_DEPS], [$RYGEL_COMMON_MODULES gio-2.0 >= $GIO_REQUIRED - gupnp-dlna-1.1 >= $GUPNP_DLNA_REQUIRED + gupnp-dlna-2.0 >= $GUPNP_DLNA_REQUIRED + gupnp-dlna-gst-2.0 >= $GUPNP_DLNA_REQUIRED + gstreamer-app-1.0 >= $GSTREAMER_APP_REQUIRED gstreamer-tag-1.0 >= $GSTREAMER_TAG_REQUIRED - gstreamer-app-1.0 >= $GSTREAMER_TAG_REQUIRED gstreamer-pbutils-1.0 >= $GSTPBU_REQUIRED sqlite3 >= $LIBSQLITE3_REQUIRED uuid]) - RYGEL_PLUGIN_MEDIA_EXPORT_DEPS_VALAFLAGS="$RYGEL_COMMON_MODULES_VALAFLAGS --pkg gupnp-dlna-1.1 --pkg gstreamer-tag-1.0 --pkg gstreamer-app-1.0 --pkg sqlite3" + RYGEL_PLUGIN_MEDIA_EXPORT_DEPS_VALAFLAGS="$RYGEL_COMMON_MODULES_VALAFLAGS --pkg gupnp-dlna-2.0 --pkg gupnp-dlna-gst-2.0 --pkg gstreamer-tag-1.0 --pkg gstreamer-app-1.0 --pkg gstreamer-pbutils-1.0 --pkg sqlite3" AC_SUBST([RYGEL_PLUGIN_MEDIA_EXPORT_DEPS_VALAFLAGS]) ]) diff --git a/src/media-engines/gstreamer/rygel-gst-media-engine.vala b/src/media-engines/gstreamer/rygel-gst-media-engine.vala index bc4a5a3..a2d8722 100644 --- a/src/media-engines/gstreamer/rygel-gst-media-engine.vala +++ b/src/media-engines/gstreamer/rygel-gst-media-engine.vala @@ -44,9 +44,7 @@ public class Rygel.GstMediaEngine : Rygel.MediaEngine { * to add to the list of DLNA profiles supported by * this media engine, for get_dlna_profiles(): */ - var discoverer = new GUPnPDLNA.Discoverer ((ClockTime) SECOND, - true, - false); + var discoverer = new GUPnPDLNA.ProfileGuesser (true, false); foreach (var profile in discoverer.list_profiles ()) { var p = new DLNAProfile (profile.name, profile.mime); diff --git a/src/plugins/media-export/rygel-media-export-harvesting-task.vala b/src/plugins/media-export/rygel-media-export-harvesting-task.vala index 91c584b..9ba5cea 100644 --- a/src/plugins/media-export/rygel-media-export-harvesting-task.vala +++ b/src/plugins/media-export/rygel-media-export-harvesting-task.vala @@ -20,6 +20,7 @@ using GLib; using Gee; +using Gst.PbUtils; internal class FileQueueEntry { public File file; @@ -296,9 +297,10 @@ public class Rygel.MediaExport.HarvestingTask : Rygel.StateMachine, return false; } - private void on_extracted_cb (File file, - GUPnPDLNA.Information? dlna, - FileInfo file_info) { + private void on_extracted_cb (File file, + DiscovererInfo? dlna, + GUPnPDLNA.Profile? profile, + FileInfo file_info) { if (this.cancellable.is_cancelled ()) { this.completed (); } @@ -319,6 +321,7 @@ public class Rygel.MediaExport.HarvestingTask : Rygel.StateMachine, item = ItemFactory.create_from_info (this.containers.peek_head (), file, dlna, + profile, file_info); } diff --git a/src/plugins/media-export/rygel-media-export-item-factory.vala b/src/plugins/media-export/rygel-media-export-item-factory.vala index 672ddfb..9eb5796 100644 --- a/src/plugins/media-export/rygel-media-export-item-factory.vala +++ b/src/plugins/media-export/rygel-media-export-item-factory.vala @@ -1,8 +1,10 @@ /* * Copyright (C) 2008 Zeeshan Ali . * Copyright (C) 2008 Nokia Corporation. + * Copyright (C) 2012 Intel Corporation. * * Author: Zeeshan Ali + * Jens Georg * * This file is part of Rygel. * @@ -110,20 +112,20 @@ namespace Rygel.MediaExport.ItemFactory { } } - public static MediaItem? create_from_info - (MediaContainer parent, - File file, - GUPnPDLNA.Information dlna_info, - FileInfo file_info) { + public static MediaItem? create_from_info (MediaContainer parent, + File file, + DiscovererInfo info, + GUPnPDLNA.Profile? profile, + FileInfo file_info) { MediaItem item; string id = MediaCache.get_id (file); GLib.List audio_streams; GLib.List video_streams; audio_streams = (GLib.List) - dlna_info.info.get_audio_streams (); + info.get_audio_streams (); video_streams = (GLib.List) - dlna_info.info.get_video_streams (); + info.get_video_streams (); if (audio_streams == null && video_streams == null) { debug ("%s had neither audio nor video/picture " + @@ -137,7 +139,8 @@ namespace Rygel.MediaExport.ItemFactory { item = new PhotoItem (id, parent, ""); return fill_photo_item (item as PhotoItem, file, - dlna_info, + info, + profile, video_streams.data, file_info); } else if (video_streams != null) { @@ -150,7 +153,8 @@ namespace Rygel.MediaExport.ItemFactory { return fill_video_item (item as VideoItem, file, - dlna_info, + info, + profile, video_streams.data, audio_info, file_info); @@ -158,7 +162,8 @@ namespace Rygel.MediaExport.ItemFactory { item = new MusicItem (id, parent, ""); return fill_music_item (item as MusicItem, file, - dlna_info, + info, + profile, audio_streams.data, file_info); } else { @@ -166,11 +171,11 @@ namespace Rygel.MediaExport.ItemFactory { } } - private static void fill_audio_item (AudioItem item, - GUPnPDLNA.Information dlna_info, - DiscovererAudioInfo? audio_info) { - if (dlna_info.info.get_duration () > 0) { - item.duration = (long) (dlna_info.info.get_duration () / Gst.SECOND); + private static void fill_audio_item (AudioItem item, + DiscovererInfo info, + DiscovererAudioInfo? audio_info) { + if (info.get_duration () > 0) { + item.duration = (long) (info.get_duration () / Gst.SECOND); } else { item.duration = -1; } @@ -187,14 +192,15 @@ namespace Rygel.MediaExport.ItemFactory { } - private static MediaItem fill_video_item (VideoItem item, - File file, - GUPnPDLNA.Information dlna_info, - DiscovererVideoInfo video_info, - DiscovererAudioInfo? audio_info, - FileInfo file_info) { - fill_audio_item (item as AudioItem, dlna_info, audio_info); - fill_media_item (item, file, dlna_info, file_info); + private static MediaItem fill_video_item (VideoItem item, + File file, + DiscovererInfo info, + GUPnPDLNA.Profile? profile, + DiscovererVideoInfo video_info, + DiscovererAudioInfo? audio_info, + FileInfo file_info) { + fill_audio_item (item as AudioItem, info, audio_info); + fill_media_item (item, file, info, profile, file_info); item.width = (int) video_info.get_width (); item.height = (int) video_info.get_height (); @@ -205,12 +211,13 @@ namespace Rygel.MediaExport.ItemFactory { return item; } - private static MediaItem fill_photo_item (PhotoItem item, - File file, - GUPnPDLNA.Information dlna_info, - DiscovererVideoInfo video_info, - FileInfo file_info) { - fill_media_item (item, file, dlna_info, file_info); + private static MediaItem fill_photo_item (PhotoItem item, + File file, + DiscovererInfo info, + GUPnPDLNA.Profile? profile, + DiscovererVideoInfo video_info, + FileInfo file_info) { + fill_media_item (item, file, info, profile, file_info); item.width = (int) video_info.get_width (); item.height = (int) video_info.get_height (); @@ -221,35 +228,35 @@ namespace Rygel.MediaExport.ItemFactory { return item; } - private static MediaItem fill_music_item (MusicItem item, - File file, - GUPnPDLNA.Information dlna_info, - DiscovererAudioInfo? audio_info, - FileInfo file_info) { - fill_audio_item (item as AudioItem, dlna_info, audio_info); - fill_media_item (item, file, dlna_info, file_info); + private static MediaItem fill_music_item (MusicItem item, + File file, + DiscovererInfo info, + GUPnPDLNA.Profile? profile, + DiscovererAudioInfo? audio_info, + FileInfo file_info) { + fill_audio_item (item as AudioItem, info, audio_info); + fill_media_item (item, file, info, profile, file_info); if (audio_info == null) { return item; } string artist; - dlna_info.info.get_tags ().get_string (Tags.ARTIST, out artist); + info.get_tags ().get_string (Tags.ARTIST, out artist); item.artist = artist; string album; - dlna_info.info.get_tags ().get_string (Tags.ALBUM, out album); + info.get_tags ().get_string (Tags.ALBUM, out album); item.album = album; string genre; - dlna_info.info.get_tags ().get_string (Tags.GENRE, out genre); + info.get_tags ().get_string (Tags.GENRE, out genre); item.genre = genre; uint tmp; - dlna_info.info.get_tags ().get_uint (Tags.ALBUM_VOLUME_NUMBER, - out tmp); + info.get_tags ().get_uint (Tags.ALBUM_VOLUME_NUMBER, out tmp); item.disc = (int) tmp; - dlna_info.info.get_tags() .get_uint (Tags.TRACK_NUMBER, out tmp); + info.get_tags() .get_uint (Tags.TRACK_NUMBER, out tmp); item.track_number = (int) tmp; if (audio_info.get_tags () == null) { @@ -284,22 +291,23 @@ namespace Rygel.MediaExport.ItemFactory { return item; } - private static void fill_media_item (MediaItem item, - File file, - GUPnPDLNA.Information dlna_info, - FileInfo file_info) { + private static void fill_media_item (MediaItem item, + File file, + DiscovererInfo info, + GUPnPDLNA.Profile? profile, + FileInfo file_info) { string title = null; - if (dlna_info.info.get_tags () == null || - !dlna_info.info.get_tags ().get_string (Tags.TITLE, out title)) { + if (info.get_tags () == null || + !info.get_tags ().get_string (Tags.TITLE, out title)) { title = file_info.get_display_name (); } item.title = title; - if (dlna_info.info.get_tags () != null) { + if (info.get_tags () != null) { GLib.Date? date; - if (dlna_info.info.get_tags ().get_date (Tags.DATE, out date) && + if (info.get_tags ().get_date (Tags.DATE, out date) && date.valid ()) { char[] datestr = new char[30]; date.strftime (datestr, "%F"); @@ -318,9 +326,9 @@ namespace Rygel.MediaExport.ItemFactory { item.size = (int64) file_info.get_size (); item.modified = (int64) mtime; - if (dlna_info.name != null) { - item.dlna_profile = dlna_info.name; - item.mime_type = dlna_info.mime; + if (profile != null && profile.name != null) { + item.dlna_profile = profile.name; + item.mime_type = profile.mime; } else { item.mime_type = ContentType.get_mime_type (file_info.get_content_type ()); diff --git a/src/plugins/media-export/rygel-media-export-metadata-extractor.vala b/src/plugins/media-export/rygel-media-export-metadata-extractor.vala index ad10d3b..11cded1 100644 --- a/src/plugins/media-export/rygel-media-export-metadata-extractor.vala +++ b/src/plugins/media-export/rygel-media-export-metadata-extractor.vala @@ -27,6 +27,7 @@ using Gst; using Gst.PbUtils; using Gee; using GUPnP; +using GUPnPDLNA; /** * Metadata extractor based on Gstreamer. Just set the URI of the media on the @@ -35,23 +36,26 @@ using GUPnP; */ public class Rygel.MediaExport.MetadataExtractor: GLib.Object { /* Signals */ - public signal void extraction_done (File file, - GUPnPDLNA.Information? dlna, - FileInfo file_info); + public signal void extraction_done (File file, + DiscovererInfo? info, + GUPnPDLNA.Profile? profile, + FileInfo file_info); /** * Signalize that an error occured during metadata extraction */ public signal void error (File file, Error err); - private GUPnPDLNA.Discoverer discoverer; + private Discoverer discoverer; + private ProfileGuesser guesser; + /** * We export a GLib.File-based API but GstDiscoverer works with URIs, so * we store uri->GLib.File mappings in this hashmap, so that we can get * the GLib.File back from the URI in on_discovered(). */ private HashMap file_hash; - private uint64 timeout = 10; /* seconds */ + private uint timeout = 10; /* seconds */ private bool extract_metadata; @@ -66,50 +70,58 @@ public class Rygel.MediaExport.MetadataExtractor: GLib.Object { public void extract (File file, string content_type) { if (this.extract_metadata && !content_type.has_prefix ("text/")) { string uri = file.get_uri (); - this.file_hash.set (uri, file); var gst_timeout = (ClockTime) (this.timeout * Gst.SECOND); - this.discoverer = new GUPnPDLNA.Discoverer (gst_timeout, - true, - true); - this.discoverer.done.connect (on_done); - this.discoverer.start (); - this.discoverer.discover_uri (uri); + try { + this.discoverer = new Discoverer (gst_timeout); + this.file_hash.set (uri, file); + this.discoverer.discovered.connect (on_done); + this.discoverer.start (); + this.discoverer.discover_uri_async (uri); + this.guesser = new GUPnPDLNA.ProfileGuesser (true, true); + } catch (Error error) { + this.on_done (null, error); + } } else { - this.extract_basic_information (file); + this.extract_basic_information (file, null, null); } } - private void on_done (GUPnPDLNA.Information dlna, - GLib.Error err) { + private void on_done (DiscovererInfo? info, GLib.Error err) { this.discoverer = null; - var file = this.file_hash.get (dlna.info.get_uri ()); + var file = this.file_hash.get (info.get_uri ()); if (file == null) { warning ("File %s already handled, ignoring event", - dlna.info.get_uri ()); + info.get_uri ()); return; } - this.file_hash.unset (dlna.info.get_uri ()); + this.file_hash.unset (info.get_uri ()); - if ((dlna.info.get_result () & DiscovererResult.TIMEOUT) != 0) { + if ((info.get_result () & DiscovererResult.TIMEOUT) != 0) { debug ("Extraction timed out on %s", file.get_uri ()); // set dlna to null to extract basic file information - dlna = null; - } else if ((dlna.info.get_result () & + info = null; + this.extract_basic_information (file, info, null); + + return; + } else if ((info.get_result () & DiscovererResult.ERROR) != 0) { this.error (file, err); return; } - this.extract_basic_information (file, dlna); + var dlna_info = GUPnPDLNAGst.utils_information_from_discoverer_info (info); + var dlna = this.guesser.guess_profile_from_info (dlna_info); + this.extract_basic_information (file, info, dlna); } private void extract_basic_information - (File file, - GUPnPDLNA.Information? dlna = null) { + (File file, + DiscovererInfo? info, + GUPnPDLNA.Profile? dlna) { try { FileInfo file_info; @@ -133,6 +145,7 @@ public class Rygel.MediaExport.MetadataExtractor: GLib.Object { } this.extraction_done (file, + info, dlna, file_info); } catch (Error error) { @@ -143,7 +156,6 @@ public class Rygel.MediaExport.MetadataExtractor: GLib.Object { } } - private void on_config_changed (Configuration config, string section, string key) { -- 2.7.4