[rygel] media-export: Simplify metadata extraction code



commit 45ee4d534a948a15427ac140f340ad2963646375
Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
Date:   Wed Jul 21 21:18:51 2010 +0300

    media-export: Simplify metadata extraction code
    
    We don't need to transform the metadata into Gst.TagList to be able to
    make use of it so this should not only simplify the code but also optimize
    the extraction process.
    
    Based on a patch from Arun Raghavan <arun raghavan collabora co uk>.

 .../media-export/rygel-media-export-harvester.vala |   17 +-
 .../media-export/rygel-media-export-item.vala      |  285 +++++++++++---------
 .../rygel-media-export-metadata-extractor.vala     |  119 ++-------
 3 files changed, 193 insertions(+), 228 deletions(-)
---
diff --git a/src/plugins/media-export/rygel-media-export-harvester.vala b/src/plugins/media-export/rygel-media-export-harvester.vala
index 4a2c2c0..1861708 100644
--- a/src/plugins/media-export/rygel-media-export-harvester.vala
+++ b/src/plugins/media-export/rygel-media-export-harvester.vala
@@ -284,7 +284,11 @@ public class Rygel.MediaExport.Harvester : GLib.Object {
         }
     }
 
-    private void on_extracted_cb (File file, Gst.TagList tag_list) {
+    private void on_extracted_cb (File                  file,
+                                  GUPnP.DLNAInformation dlna,
+                                  string                mime,
+                                  uint64                size,
+                                  uint64                mtime) {
         if (this.cancellable.is_cancelled ()) {
             harvested (this.origin);
         }
@@ -296,10 +300,13 @@ public class Rygel.MediaExport.Harvester : GLib.Object {
            return;
         }
         if (file == entry) {
-            var item = MediaExportItem.create_from_taglist (
-                                               this.containers.peek_head (),
-                                               file,
-                                               tag_list);
+            var item = MediaExportItem.create_from_info (
+                                        this.containers.peek_head (),
+                                        file,
+                                        dlna,
+                                        mime,
+                                        size,
+                                        mtime);
             if (item != null) {
                 item.parent_ref = this.containers.peek_head ();
                 try {
diff --git a/src/plugins/media-export/rygel-media-export-item.vala b/src/plugins/media-export/rygel-media-export-item.vala
index 6f5163b..5ec1ce1 100644
--- a/src/plugins/media-export/rygel-media-export-item.vala
+++ b/src/plugins/media-export/rygel-media-export-item.vala
@@ -28,153 +28,196 @@ using Gst;
  * Represents MediaExport item.
  */
 public class Rygel.MediaExport.MediaExportItem : Rygel.MediaItem {
-    private const string TAG_WIDTH = MetadataExtractor.TAG_RYGEL_WIDTH;
-    private const string TAG_HEIGHT = MetadataExtractor.TAG_RYGEL_HEIGHT;
-    private const string
-    TAG_DLNA_PROFILE = MetadataExtractor.TAG_RYGEL_DLNA_PROFILE;
-
-    public static MediaExportItem? create_from_taglist (MediaContainer parent,
-                                                  File           file,
-                                                  Gst.TagList    tag_list) {
+    public static MediaExportItem? create_from_info (
+                                        MediaContainer        parent,
+                                        File                  file,
+                                        GUPnP.DLNAInformation dlna_info,
+                                        string                mime,
+                                        uint64                size,
+                                        uint64                mtime) {
         string id = Checksum.compute_for_string (ChecksumType.MD5,
                                                  file.get_uri ());
-        int width = -1;
-        int height = -1;
-        string class_guessed = null;
-
-        if (tag_list != null) {
-            string codec;
-
-            if (!tag_list.get_string (TAG_VIDEO_CODEC, out codec)) {
-                if (!tag_list.get_string (TAG_AUDIO_CODEC, out codec)) {
-                    if (tag_list.get_int (TAG_WIDTH, out width) ||
-                        tag_list.get_int (TAG_HEIGHT, out height)) {
-                        class_guessed = Rygel.MediaItem.PHOTO_CLASS;
-                    } else {
-                        // if it has width and height and a duration, assume
-                        // it is a video (to capture the MPEG TS without audio
-                        // case)
-                        uint64 duration;
-                        if (tag_list.get_uint64 (TAG_DURATION,
-                                                 out duration)) {
-                            class_guessed = Rygel.MediaItem.VIDEO_CLASS;
-                        } else {
-                            string content_type;
-                            tag_list.get_string (MetadataExtractor.TAG_RYGEL_MIME,
-                                                 out content_type);
-                            debug (_("File '%s' is of unknown format/type."),
-                                    file.get_uri ());
-                            debug (_("Trying to guess from content type %s"),
-                                    content_type);
-                            if (content_type.has_prefix ("video/")) {
-                                class_guessed = Rygel.MediaItem.VIDEO_CLASS;
-                            } else if (content_type.has_prefix ("audio/")) {
-                                class_guessed = Rygel.MediaItem.AUDIO_CLASS;
-                            } else if (content_type.has_prefix ("image/")) {
-                                class_guessed = Rygel.MediaItem.PHOTO_CLASS;
-                            }
-
-                            if (class_guessed == null) {
-                                class_guessed = Rygel.MediaItem.AUDIO_CLASS;
-                                warning (_("Failed to detect UPnP class for '%s', assuming '%s'"),
-                                         file.get_uri (),
-                                         class_guessed);
-                            }
-                        }
-                    }
-                } else {
-                    // MPEG TS streams seem to miss VIDEO_CODEC; so if we have
-                    // an AUDIO_CODEC and width or height, assume video as
-                    // well
-                    if (tag_list.get_int (TAG_WIDTH, out width) ||
-                        tag_list.get_int (TAG_HEIGHT, out height)) {
-                        class_guessed = Rygel.MediaItem.VIDEO_CLASS;
-                    } else {
-                        class_guessed = Rygel.MediaItem.AUDIO_CLASS;
-                    }
-                }
+        unowned Gst.StreamInformation audio = null;
+        unowned Gst.StreamInformation video = null;
+
+        foreach (unowned Gst.StreamInformation stream_info in
+                 dlna_info.info.stream_list) {
+            if (audio == null &&
+                stream_info.streamtype == Gst.StreamType.AUDIO) {
+                audio = stream_info;
+            } else if (video == null &&
+                       (stream_info.streamtype == Gst.StreamType.VIDEO ||
+                        stream_info.streamtype == Gst.StreamType.IMAGE)) {
+                video = stream_info;
+            }
+        }
+
+        if (video != null) {
+            if (audio == null && video.streamtype == Gst.StreamType.IMAGE) {
+                return new MediaExportItem.photo (
+                                        parent,
+                                        id,
+                                        file,
+                                        dlna_info,
+                                        (Gst.StreamVideoInformation) video,
+                                        mime,
+                                        size,
+                                        mtime);
             } else {
-                class_guessed = Rygel.MediaItem.VIDEO_CLASS;
+                return new MediaExportItem.video (
+                                        parent,
+                                        id,
+                                        file,
+                                        dlna_info,
+                                        (Gst.StreamVideoInformation) video,
+                                        (Gst.StreamAudioInformation) audio,
+                                        mime,
+                                        size,
+                                        mtime);
             }
+        } else if (audio != null) {
+            return new MediaExportItem.audio (
+                                        parent,
+                                        id,
+                                        file,
+                                        dlna_info,
+                                        (Gst.StreamAudioInformation) audio,
+                                        mime,
+                                        size,
+                                        mtime);
         } else {
-            // throw error. Taglist can't be empty
-            warning (_("Got empty taglist for file %s"), file.get_uri ());
-
             return null;
         }
+    }
+
+    private MediaExportItem.video (MediaContainer              parent,
+                                   string                      id,
+                                   File                        file,
+                                   GUPnP.DLNAInformation       dlna_info,
+                                   Gst.StreamVideoInformation? video,
+                                   Gst.StreamAudioInformation? audio,
+                                   string                      mime,
+                                   uint64                      size,
+                                   uint64                      mtime) {
+        this (parent,
+              id,
+              file,
+              dlna_info,
+              mime,
+              size,
+              mtime,
+              MediaItem.VIDEO_CLASS);
+
+        this.width = (int) video.width;
+        this.height = (int) video.height;
+        this.color_depth = (int) video.depth;
+
+        if (video.tags != null) {
+            uint tmp;
+
+            video.tags.get_uint (TAG_BITRATE, out tmp);
+            this.bitrate = (int) tmp / 8;
+        }
 
-        return new MediaExportItem (parent,
-                                    id,
-                                    file,
-                                    tag_list,
-                                    class_guessed);
+        this.n_audio_channels = (int) audio.channels;
+        this.sample_freq = (int) audio.sample_rate;
     }
 
-    private MediaExportItem (MediaContainer parent,
-                             string         id,
-                             File           file,
-                             Gst.TagList    tag_list,
-                             string         upnp_class) {
-        string title = null;
-        if (upnp_class == Rygel.MediaItem.AUDIO_CLASS ||
-            upnp_class == Rygel.MediaItem.MUSIC_CLASS) {
+    private MediaExportItem.photo (MediaContainer              parent,
+                                   string                      id,
+                                   File                        file,
+                                   GUPnP.DLNAInformation       dlna_info,
+                                   Gst.StreamVideoInformation? video,
+                                   string                      mime,
+                                   uint64                      size,
+                                   uint64                      mtime) {
+        this (parent,
+              id,
+              file,
+              dlna_info,
+              mime,
+              size,
+              mtime,
+              MediaItem.PHOTO_CLASS);
+
+        this.width = (int) video.width;
+        this.height = (int) video.height;
+        this.color_depth = (int) video.depth;
+    }
 
-            if (!tag_list.get_string (TAG_TITLE, out title)) {
-                title = file.get_basename ();
-            }
+    private MediaExportItem.audio (MediaContainer              parent,
+                                   string                      id,
+                                   File                        file,
+                                   GUPnP.DLNAInformation       dlna_info,
+                                   Gst.StreamAudioInformation? audio,
+                                   string                      mime,
+                                   uint64                      size,
+                                   uint64                      mtime) {
+        this (parent,
+              id,
+              file,
+              dlna_info,
+              mime,
+              size,
+              mtime,
+              MediaItem.MUSIC_CLASS);
+
+        this.n_audio_channels = (int) audio.channels;
+        this.sample_freq = (int) audio.sample_rate;
+    }
 
-        } else {
+    private MediaExportItem (MediaContainer        parent,
+                             string                id,
+                             File                  file,
+                             GUPnP.DLNAInformation dlna_info,
+                             string                mime,
+                             uint64                size,
+                             uint64                mtime,
+                             string                upnp_class) {
+        string title = null;
+
+        if (dlna_info.info.tags == null ||
+            !dlna_info.info.tags.get_string (TAG_TITLE, out title)) {
             title = file.get_basename ();
         }
-        base (id, parent, title, upnp_class);
 
-        tag_list.get_int (TAG_WIDTH, out this.width);
-        tag_list.get_int (TAG_HEIGHT, out this.height);
-        tag_list.get_int (MetadataExtractor.TAG_RYGEL_DEPTH,
-                          out this.color_depth);
-        uint64 duration;
-        tag_list.get_uint64 (TAG_DURATION, out duration);
-        this.duration = (duration == -1) ? -1 : (long) (duration / 1000000000);
+        base (id, parent, title, upnp_class);
 
-        tag_list.get_int (MetadataExtractor.TAG_RYGEL_CHANNELS,
-                          out this.n_audio_channels);
+        if (dlna_info.info.duration > -1) {
+            this.duration = -1;
+        } else {
+            this.duration = dlna_info.info.duration / Gst.SECOND;
+        }
 
-        tag_list.get_string (TAG_ARTIST, out this.author);
-        tag_list.get_string (TAG_ALBUM, out this.album);
+        if (dlna_info.info.tags != null) {
+            dlna_info.info.tags.get_string (TAG_ARTIST, out this.author);
+            dlna_info.info.tags.get_string (TAG_ALBUM, out this.album);
 
-        uint tmp;
-        tag_list.get_uint (TAG_TRACK_NUMBER, out tmp);
-        this.track_number = (int) tmp;
-        tag_list.get_uint (TAG_BITRATE, out tmp);
-        this.bitrate = (int) tmp / 8;
-        tag_list.get_int (MetadataExtractor.TAG_RYGEL_RATE,
-                          out this.sample_freq);
+            uint tmp;
+            dlna_info.info.tags.get_uint (TAG_TRACK_NUMBER, out tmp);
+            this.track_number = (int) tmp;
 
+            GLib.Date? date;
+            if (dlna_info.info.tags.get_date (TAG_DATE, out date)) {
+                char[] datestr = new char[30];
+                date.strftime (datestr, "%F");
+                this.date = (string) datestr;
+            } else {
+                TimeVal tv = { (long) mtime, 0 };
+                this.date = tv.to_iso8601 ();
+            }
+        }
 
-        int64 size;
-        tag_list.get_int64 (MetadataExtractor.TAG_RYGEL_SIZE,
-                            out size);
         this.size = (long) size;
-
-        uint64 mtime;
-        tag_list.get_uint64 (MetadataExtractor.TAG_RYGEL_MTIME,
-                             out mtime);
         this.modified = (int64) mtime;
 
-        GLib.Date? date;
-        if (tag_list.get_date (TAG_DATE, out date)) {
-            char[] datestr = new char[30];
-            date.strftime (datestr, "%F");
-            this.date = (string) datestr;
+        if (dlna_info.name != null) {
+            this.dlna_profile = dlna_info.name;
+            this.mime_type = dlna_info.mime;
         } else {
-            TimeVal tv = { (long) mtime, 0 };
-            this.date = tv.to_iso8601 ();
+            this.mime_type = mime;
         }
 
-        tag_list.get_string (TAG_DLNA_PROFILE, out this.dlna_profile);
-        tag_list.get_string (MetadataExtractor.TAG_RYGEL_MIME,
-                             out this.mime_type);
-
         this.add_uri (file.get_uri (), null);
     }
 }
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 0263f73..02ae121 100644
--- a/src/plugins/media-export/rygel-media-export-metadata-extractor.vala
+++ b/src/plugins/media-export/rygel-media-export-metadata-extractor.vala
@@ -33,18 +33,12 @@ using GUPnP;
  * metadata_available for each key/value pair extracted.
  */
 public class Rygel.MediaExport.MetadataExtractor: GLib.Object {
-    public const string TAG_RYGEL_SIZE = "rygel-size";
-    public const string TAG_RYGEL_MIME = "rygel-mime";
-    public const string TAG_RYGEL_CHANNELS = "rygel-channels";
-    public const string TAG_RYGEL_RATE = "rygel-rate";
-    public const string TAG_RYGEL_WIDTH = "rygel-width";
-    public const string TAG_RYGEL_HEIGHT = "rygel-height";
-    public const string TAG_RYGEL_DEPTH = "rygel-depth";
-    public const string TAG_RYGEL_MTIME = "rygel-mtime";
-    public const string TAG_RYGEL_DLNA_PROFILE = "rygel-dlna-profile";
-
     /* Signals */
-    public signal void extraction_done (File file, Gst.TagList tag_list);
+    public signal void extraction_done (File                  file,
+                                        GUPnP.DLNAInformation info,
+                                        string                mime,
+                                        uint64                size,
+                                        uint64                mtime);
 
     /**
      * Signalize that an error occured during metadata extraction
@@ -60,30 +54,11 @@ public class Rygel.MediaExport.MetadataExtractor: GLib.Object {
     private HashMap<string, File> file_hash;
     private uint64 timeout = 10; /* seconds */
 
-    private static void register_custom_tag (string tag, Type type) {
-        Gst.tag_register (tag,
-                          TagFlag.META,
-                          type,
-                          tag,
-                          "",
-                          Gst.tag_merge_use_first);
-    }
-
     public static MetadataExtractor? create () {
         return new MetadataExtractor ();
     }
 
     public MetadataExtractor () {
-        this.register_custom_tag (TAG_RYGEL_SIZE, typeof (int64));
-        this.register_custom_tag (TAG_RYGEL_MIME, typeof (string));
-        this.register_custom_tag (TAG_RYGEL_CHANNELS, typeof (int));
-        this.register_custom_tag (TAG_RYGEL_RATE, typeof (int));
-        this.register_custom_tag (TAG_RYGEL_WIDTH, typeof (int));
-        this.register_custom_tag (TAG_RYGEL_HEIGHT, typeof (int));
-        this.register_custom_tag (TAG_RYGEL_DEPTH, typeof (int));
-        this.register_custom_tag (TAG_RYGEL_MTIME, typeof (uint64));
-        this.register_custom_tag (TAG_RYGEL_DLNA_PROFILE, typeof (string));
-
         this.file_hash = new HashMap<string, File> ();
 
         this.discoverer = new GUPnP.DLNADiscoverer ((ClockTime)
@@ -101,7 +76,6 @@ public class Rygel.MediaExport.MetadataExtractor: GLib.Object {
         assert (this.file_hash.has_key (dlna.info.uri));
 
         File file = this.file_hash.get (dlna.info.uri);
-        TagList tag_list = new TagList ();
 
         this.file_hash.unset (dlna.info.uri);
 
@@ -116,16 +90,11 @@ public class Rygel.MediaExport.MetadataExtractor: GLib.Object {
         }
 
         try {
-            this.extract_mime_and_size (file, tag_list);
-            this.extract_duration (dlna.info, tag_list);
-            this.extract_stream_info (dlna.info, tag_list);
-            if (dlna.name != null) {
-                tag_list.add (TagMergeMode.REPLACE,
-                              TAG_RYGEL_DLNA_PROFILE,
-                              dlna.name);
-                tag_list.add (TagMergeMode.REPLACE, TAG_RYGEL_MIME, dlna.mime);
-            }
-            this.extraction_done (file, tag_list);
+            uint64 size, mtime;
+            string mime;
+
+            this.extract_file_info (file, out mime, out size, out mtime);
+            this.extraction_done (file, dlna, mime, size, mtime);
         } catch (Error e) {
             debug (_("Failed to extract metadata from %s: %s"),
                     dlna.info.uri,
@@ -139,8 +108,10 @@ public class Rygel.MediaExport.MetadataExtractor: GLib.Object {
         this.discoverer.discover_uri (uri);
     }
 
-    private void extract_mime_and_size (File    file,
-                                        TagList tag_list) throws Error {
+    private void extract_file_info (File       file,
+                                    out string mime,
+                                    out uint64 size,
+                                    out uint64 mtime) throws Error {
         FileInfo file_info;
 
         try {
@@ -161,64 +132,8 @@ public class Rygel.MediaExport.MetadataExtractor: GLib.Object {
         }
 
         string content_type = file_info.get_content_type ();
-        string mime = g_content_type_get_mime_type (content_type);
-
-        if (mime != null) {
-            /* add custom mime tag to tag list */
-            tag_list.add (TagMergeMode.REPLACE, TAG_RYGEL_MIME, mime);
-        }
-
-        var size = file_info.get_size ();
-        tag_list.add (TagMergeMode.REPLACE, TAG_RYGEL_SIZE, size);
-
-        var mtime = file_info.get_attribute_uint64 (
-                                        FILE_ATTRIBUTE_TIME_MODIFIED);
-        tag_list.add (TagMergeMode.REPLACE, TAG_RYGEL_MTIME, mtime);
-    }
-
-    private void extract_duration (Gst.DiscovererInformation info,
-                                   TagList                   tag_list) {
-        tag_list.add (TagMergeMode.REPLACE,
-                      TAG_DURATION,
-                      info.duration);
-    }
-
-    private void extract_stream_info (Gst.DiscovererInformation info,
-                                      TagList                   tag_list) {
-        foreach (unowned Gst.StreamInformation i in info.stream_list) {
-            if (i.streamtype == Gst.StreamType.VIDEO) {
-                extract_video_info ((Gst.StreamVideoInformation) i, tag_list);
-            } else if (i.streamtype == Gst.StreamType.AUDIO) {
-                extract_audio_info ((Gst.StreamAudioInformation) i, tag_list);
-            }
-        }
-    }
-
-    private void extract_audio_info (Gst.StreamAudioInformation info,
-                                     TagList                    tag_list) {
-        if (info.sample_rate != 0)
-            tag_list.add (TagMergeMode.REPLACE,
-                          TAG_RYGEL_RATE,
-                          info.sample_rate);
-        if (info.channels != 0)
-            tag_list.add (TagMergeMode.REPLACE,
-                          TAG_RYGEL_CHANNELS,
-                          info.channels);
-    }
-
-    private void extract_video_info (Gst.StreamVideoInformation info,
-                                     TagList                    tag_list) {
-        if (info.depth != 0)
-            tag_list.add (TagMergeMode.REPLACE,
-                          TAG_RYGEL_DEPTH,
-                          info.depth);
-        if (info.width != 0)
-            tag_list.add (TagMergeMode.REPLACE,
-                          TAG_RYGEL_WIDTH,
-                          info.width);
-        if (info.height != 0)
-            tag_list.add (TagMergeMode.REPLACE,
-                          TAG_RYGEL_HEIGHT,
-                          info.height);
+        mime = g_content_type_get_mime_type (content_type);
+        size = file_info.get_size ();
+        mtime = file_info.get_attribute_uint64 (FILE_ATTRIBUTE_TIME_MODIFIED);
     }
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]