[gvfs] common: Use libbluray to get Blu-Ray metadata



commit 21c319c85fe53769c3c3a7ca50d065e4b1c4ef10
Author: Bastien Nocera <hadess hadess net>
Date:   Thu Apr 7 20:50:55 2011 +0100

    common: Use libbluray to get Blu-Ray metadata
    
    This means we can finally get localised versions, and
    support the biggest thumbnails.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=646984

 common/Makefile.am     |    5 +-
 common/gvfsmountinfo.c |  279 ++++++++++++++++++++----------------------------
 common/meta_data.h     |   55 ++++++++++
 configure.ac           |   49 ++++++---
 4 files changed, 205 insertions(+), 183 deletions(-)
---
diff --git a/common/Makefile.am b/common/Makefile.am
index 7204a2a..0d0dbc6 100644
--- a/common/Makefile.am
+++ b/common/Makefile.am
@@ -4,7 +4,7 @@ lib_LTLIBRARIES=libgvfscommon.la
 
 INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/gvfs \
 	-I$(top_srcdir)/daemon \
-	$(GLIB_CFLAGS) $(DBUS_CFLAGS) $(EXPAT_CFLAGS) \
+	$(GLIB_CFLAGS) $(DBUS_CFLAGS) $(BLURAY_CFLAGS) \
 	-DG_LOG_DOMAIN=\"GVFS\" -DG_DISABLE_DEPRECATED \
 	-DDBUS_API_SUBJECT_TO_CHANGE
 
@@ -19,6 +19,7 @@ libgvfscommon_la_SOURCES = 	\
 	gvfsicon.h gvfsicon.c \
 	gvfsmountinfo.h gvfsmountinfo.c \
 	gvfsfileinfo.c gvfsfileinfo.h \
+	meta_data.h \
 	$(NULL)
 
 # needed by cygwin (see bug #564003)
@@ -27,7 +28,7 @@ libgvfscommon_la_LDFLAGS = -no-undefined
 libgvfscommon_la_LIBADD =	\
 	$(DBUS_LIBS) 		\
 	$(GLIB_LIBS)		\
-	$(EXPAT_LIBS)
+	$(BLURAY_LIBS)
 
 if HAVE_AVAHI
 lib_LTLIBRARIES += libgvfscommon-dnssd.la
diff --git a/common/gvfsmountinfo.c b/common/gvfsmountinfo.c
index 3ebbef8..a9bc121 100644
--- a/common/gvfsmountinfo.c
+++ b/common/gvfsmountinfo.c
@@ -25,9 +25,11 @@
 #include <string.h>
 #include <glib/gi18n-lib.h>
 
-#ifdef HAVE_EXPAT
-#include <expat.h>
-#endif
+#ifdef HAVE_BLURAY
+#include <langinfo.h>
+#include <libbluray/bluray.h>
+#include "meta_data.h"
+#endif /* HAVE_BLURAY */
 
 #include "gvfsmountinfo.h"
 
@@ -423,186 +425,141 @@ GIcon *g_vfs_mount_info_query_xdg_volume_info_finish (GFile          *directory,
 
 /* ---------------------------------------------------------------------------------------------------- */
 
-#ifdef HAVE_EXPAT
-
-typedef struct {
-  gboolean in_name;
-  char *name;
-  const char *icon_path;
-  gboolean image_is_small;
-} BdmvParseData;
-
-static void
-bdmt_parse_start_tag (void                *data,
-                      const gchar         *element_name,
-                      const gchar        **attr)
+#ifdef HAVE_BLURAY
+static const char *
+get_iso_639_3_for_locale (void)
 {
-  BdmvParseData *bdata = (BdmvParseData *) data;
-  const char *image;
-  gboolean image_small;
-  gint i;
+  const char *lang;
 
-  if (g_str_equal (element_name, "di:name"))
+  lang = nl_langinfo (_NL_ADDRESS_LANG_TERM);
+  if (lang == NULL || *lang == '\0')
     {
-      bdata->in_name = TRUE;
-      return;
+      lang = nl_langinfo (_NL_ADDRESS_COUNTRY_AB3);
+      if (lang == NULL || *lang == '\0')
+        return NULL;
     }
 
-  if (g_str_equal (element_name, "di:thumbnail") == FALSE)
-    return;
-
-  image = NULL;
-  image_small = FALSE;
+  return lang;
+}
 
-  for (i = 0; attr[i]; ++i)
-    {
-      const char *name;
-      const char *value;
+static const char *
+get_icon (META_DL *meta)
+{
+  const char *icon;
+  guint i;
+  guint size;
 
-      name = attr[i];
-      value = attr[++i];
+  icon = NULL;
+  size = 0;
 
-      if (g_str_equal (name, "href"))
-        {
-          image = value;
-        }
-      else if (g_str_equal (name, "size") && value)
+  for (i = 0; i < meta->thumb_count; i++)
+    {
+      if (meta->thumbnails[i].xres > size)
         {
-          image_small = g_str_equal (value, "416x240");
+          icon = meta->thumbnails[i].path;
+          size = meta->thumbnails[i].xres;
         }
     }
 
-  if (bdata->icon_path == NULL)
-    {
-      bdata->icon_path = image;
-      bdata->image_is_small = image_small;
-      return;
-    }
-
-  if (image != NULL &&
-      bdata->icon_path != NULL &&
-      bdata->image_is_small != FALSE)
-    {
-      bdata->icon_path = image;
-      bdata->image_is_small = image_small;
-    }
+  return icon;
 }
 
 static void
-bdmt_parse_end_tag (void                *data,
-                    const gchar         *element_name)
+bdmv_metadata_thread (GSimpleAsyncResult *result,
+                      GObject *object,
+                      GCancellable *cancellable)
 {
-  BdmvParseData *bdata = (BdmvParseData *) data;
-
-  if (g_str_equal (element_name, "di:name"))
-    bdata->in_name = FALSE;
-}
+  BLURAY *bd;
+  META_DL *meta;
+  GError *error;
+  GFile *file;
+  char *disc_root;
+  char *icon;
+  char *name;
+  const char *lang;
 
-static void
-bdmt_parse_text (void                *data,
-                 const XML_Char      *text,
-                 int                  text_len)
-{
-  BdmvParseData *bdata = (BdmvParseData *) data;
+  file = G_FILE (object);
 
-  if (bdata->in_name == FALSE)
-    return;
+  disc_root = g_file_get_path (file);
+  bd = bd_open (disc_root, NULL);
+  g_free (disc_root);
 
-  bdata->name = g_strndup (text, text_len);
-}
+  if (bd == NULL)
+    {
+      error = g_error_new_literal (G_IO_ERROR,
+                                   G_IO_ERROR_FAILED,
+                                   "Device is not a Blu-Ray disc");
+      goto error;
+    }
 
-static void
-on_bdmv_volume_info_loaded (GObject      *source_object,
-                            GAsyncResult *res,
-                            gpointer      user_data)
-{
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
-  GFile *bdmt_volume_info_file;
-  gchar *content;
-  gsize content_length;
-  GError *error;
-  BdmvParseData data;
-  XML_Parser parser;
-  const gchar *icon_file;
-  GIcon *icon;
+  lang = get_iso_639_3_for_locale ();
+  if (lang != NULL)
+    bd_set_player_setting_str (bd, BLURAY_PLAYER_SETTING_MENU_LANG, lang);
 
-  content = NULL;
-  parser = NULL;
-  icon_file = NULL;
-  memset (&data, 0, sizeof (data));
+  meta = bd_get_meta (bd);
+  if (meta == NULL)
+    {
+      error = g_error_new_literal (G_IO_ERROR,
+                                   G_IO_ERROR_FAILED,
+                                   "Device is not a Blu-Ray disc, or has no metadata");
+      bd_close (bd);
+      goto error;
+    }
+  name = icon = NULL;
 
-  bdmt_volume_info_file = G_FILE (source_object);
+  if (meta != NULL)
+    {
+      if (meta->di_name && *meta->di_name)
+        name = g_strdup (meta->di_name);
+      icon = g_strdup (get_icon (meta));
+    }
 
-  error = NULL;
-  if (g_file_load_contents_finish (bdmt_volume_info_file,
-                                   res,
-                                   &content,
-                                   &content_length,
-                                   NULL,
-                                   &error))
+  /* We're missing either an icon, or the name */
+  if (!name || !icon)
     {
-      data.name = NULL;
-
-      parser = XML_ParserCreate (NULL);
-      XML_SetElementHandler (parser,
-                                   (XML_StartElementHandler) bdmt_parse_start_tag,
-                                   (XML_EndElementHandler) bdmt_parse_end_tag);
-      XML_SetCharacterDataHandler (parser,
-                                         (XML_CharacterDataHandler) bdmt_parse_text);
-      XML_SetUserData (parser, &data);
-      if (XML_Parse (parser, content, content_length, TRUE) == 0)
-        {
-          g_warning ("Failed to parse bdmt file");
-          goto out;
-        }
-      g_message ("icon file: %s", data.icon_path);
-      g_message ("name: %s", data.name);
-      icon_file = data.icon_path;
+      bd_set_player_setting_str (bd, BLURAY_PLAYER_SETTING_MENU_LANG, "eng");
+      meta = bd_get_meta (bd);
 
-      icon = NULL;
+      if (meta != NULL && name == NULL && meta->di_name && *meta->di_name)
+        name = meta->di_name;
 
-      if (icon_file != NULL)
-        {
-          GFile *dir, *f;
+      if (meta != NULL && icon == NULL)
+        icon = g_strdup (get_icon (meta));
+    }
 
-          dir = g_file_get_parent (bdmt_volume_info_file);
-          if (dir)
-            {
-              f = g_file_resolve_relative_path (dir, icon_file);
-              if (f)
-                {
-                  icon = g_file_icon_new (f);
-                  g_object_unref (f);
-                }
+  /* Set the results */
+  if (icon != NULL)
+    {
+      char *icon_path;
+      GFile *icon_file;
 
-              g_object_unref (dir);
-            }
-        }
+      icon_path = g_strdup_printf ("BDMV/META/DL/%s", icon);
+      g_free (icon);
+      icon_file = g_file_resolve_relative_path (file, icon_path);
+      g_free (icon_path);
 
-      g_simple_async_result_set_op_res_gpointer (simple, icon, NULL);
-      if (data.name != NULL)
-        g_object_set_data_full (G_OBJECT (simple), "name", data.name, g_free);
-      data.name = NULL; /* steals name */
-      g_simple_async_result_complete_in_idle (simple);
-      g_object_unref (simple);
+      g_simple_async_result_set_op_res_gpointer (result,
+                                                 g_file_icon_new (icon_file),
+                                                 NULL);
     }
-
- out:
-
-  if (error != NULL)
+  else
     {
-      g_simple_async_result_set_from_error (simple, error);
-      g_simple_async_result_complete_in_idle (simple);
-      g_object_unref (simple);
-      g_error_free (error);
+      g_simple_async_result_set_op_res_gpointer (result, NULL, NULL);
     }
 
-  if (parser != NULL)
-    XML_ParserFree (parser);
-  g_free (data.name);
-  g_free (content);
+  if (name != NULL)
+    g_object_set_data_full (G_OBJECT (result), "name", name, g_free);
+
+  bd_close (bd);
+
+  return;
+
+error:
+  g_simple_async_result_set_from_error (result, error);
+  g_simple_async_result_set_op_res_gpointer (result, NULL, NULL);
+  g_error_free (error);
 }
-#endif /* HAVE_EXPAT */
+#endif /* HAVE_BLURAY */
 
 void
 g_vfs_mount_info_query_bdmv_volume_info (GFile               *directory,
@@ -610,28 +567,21 @@ g_vfs_mount_info_query_bdmv_volume_info (GFile               *directory,
                                          GAsyncReadyCallback  callback,
                                          gpointer             user_data)
 {
-#ifdef HAVE_EXPAT
+#ifdef HAVE_BLURAY
   GSimpleAsyncResult *simple;
-  GFile *file;
 
   simple = g_simple_async_result_new (G_OBJECT (directory),
                                       callback,
                                       user_data,
                                       g_vfs_mount_info_query_bdmv_volume_info);
-
-  /* FIXME: handle other languages:
-   * Check the current locale
-   * Get 3 letter-code from 2 letter locale using /usr/share/xml/iso-codes/iso_639_3.xml
-   * load bdmt_<code>.xml
-   * Fall-back to bdmt_eng.xml if it fails */
-  file = g_file_resolve_relative_path (directory, "BDMV/META/DL/bdmt_eng.xml");
-  g_file_load_contents_async (file,
-                              cancellable,
-                              on_bdmv_volume_info_loaded,
-                              simple);
-  g_object_unref (file);
+  g_simple_async_result_run_in_thread (simple,
+                                       (GSimpleAsyncThreadFunc) bdmv_metadata_thread,
+                                       G_PRIORITY_DEFAULT,
+                                       cancellable);
+  g_object_unref (simple);
 #else
   GSimpleAsyncResult *simple;
+
   simple = g_simple_async_result_new (G_OBJECT (directory),
                                       callback,
                                       user_data,
@@ -640,7 +590,8 @@ g_vfs_mount_info_query_bdmv_volume_info (GFile               *directory,
                                    G_IO_ERROR,
                                    G_IO_ERROR_NOT_SUPPORTED,
                                    "gvfs built without Expat support, no BDMV support");
-#endif /* HAVE_EXPAT */
+  g_object_unref (simple);
+#endif /* HAVE_BLURAY */
 }
 
 GIcon *g_vfs_mount_info_query_bdmv_volume_info_finish (GFile          *directory,
diff --git a/common/meta_data.h b/common/meta_data.h
new file mode 100644
index 0000000..0a2c0b3
--- /dev/null
+++ b/common/meta_data.h
@@ -0,0 +1,55 @@
+/*
+ * This file is part of libbluray
+ * Copyright (C) 2010 fraxinas
+ *
+ * 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.1 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, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#if !defined(_META_DATA_H_)
+#define _META_DATA_H_
+
+#include <stdint.h>
+
+typedef struct meta_thumbnail {
+    char *               path;
+    uint32_t             xres;
+    uint32_t             yres;
+} META_THUMBNAIL;
+
+typedef struct meta_title {
+    uint32_t             title_number;
+    char *               title_name;
+} META_TITLE;
+
+typedef struct meta_dl {
+    char                 language_code[4];
+    char *               filename;
+    char *               di_name;
+    char *               di_alternative;
+    uint8_t              di_num_sets;
+    uint8_t              di_set_number;
+    uint32_t             toc_count;
+    META_TITLE *         toc_entries;
+    uint8_t              thumb_count;
+    META_THUMBNAIL *     thumbnails;
+} META_DL;
+
+typedef struct meta_root {
+    uint8_t              dl_count;
+    META_DL *            dl_entries;
+} META_ROOT;
+
+#endif // _META_DATA_H_
+
diff --git a/configure.ac b/configure.ac
index dda022e..5d6d2ae 100644
--- a/configure.ac
+++ b/configure.ac
@@ -196,22 +196,6 @@ fi
 
 AM_CONDITIONAL(USE_FUSE, [test "$msg_fuse" = "yes"])
 
-dnl ********************************************
-dnl *** Check for expat (for obexftp and gdu ***
-dnl ********************************************
-
-dnl Make sure we have expat
-AC_CHECK_LIB(expat, XML_ParserCreate_MM,
-             [ AC_CHECK_HEADERS(expat.h, have_expat=true, have_expat=false) ],
-             have_expat=false)
-if test "x$have_expat" = "xtrue"; then
-  EXPAT_CFLAGS=""
-  EXPAT_LIBS="-lexpat"
-  AC_DEFINE(HAVE_EXPAT,, [Define to 1 if you have expat available])
-fi
-AC_SUBST(EXPAT_CFLAGS)
-AC_SUBST(EXPAT_LIBS)
-
 dnl ************************************
 dnl *** Check for gnome-disk-utility ***
 dnl ************************************
@@ -340,6 +324,11 @@ OBEXFTP_CFLAGS=
 if test "x$enable_obexftp" != "xno";  then
   PKG_CHECK_EXISTS(dbus-glib-1 bluez >= 4.0, msg_obexftp=yes)
 
+  dnl Make sure we have expat
+  AC_CHECK_LIB(expat, XML_ParserCreate_MM,
+               [ AC_CHECK_HEADERS(expat.h, have_expat=true, have_expat=false) ],
+               have_expat=false)
+
   if test "x$msg_obexftp" = "xyes" -a "x$have_expat" = "xtrue"; then
     PKG_CHECK_MODULES(OBEXFTP, dbus-glib-1 bluez >= 4.0)
     AC_SUBST(OBEXFTP_LIBS)
@@ -347,11 +336,15 @@ if test "x$enable_obexftp" != "xno";  then
 
     msg_obexftp=yes
     AC_DEFINE(HAVE_OBEXFTP, 1, [Define to 1 if ObexFTP is going to be built])
+    EXPAT_CFLAGS=""
+    EXPAT_LIBS="-lexpat"
   else
     msg_obexftp=no
   fi
 fi
 
+AC_SUBST(EXPAT_CFLAGS)
+AC_SUBST(EXPAT_LIBS)
 AM_CONDITIONAL(USE_OBEXFTP, [test "$msg_obexftp" = "yes"])
 
 dnl *************************
@@ -407,6 +400,27 @@ fi
 
 AM_CONDITIONAL(USE_KEYRING, [test "$msg_keyring" = "yes"])
 
+dnl ***********************************************
+dnl *** Check if we should build with libbluray ***
+dnl ***********************************************
+AC_ARG_ENABLE(bluray, AS_HELP_STRING([--disable-bluray],[build without bluray metadata support]))
+msg_bluray=no
+BLURAY_CFLAGS=
+BLURAY_LIBS=
+
+if test "x$enable_bluray" != "xno"; then
+  PKG_CHECK_EXISTS(libbluray, msg_bluray=yes)
+
+  if test "x$msg_bluray" = "xyes"; then
+    PKG_CHECK_MODULES(BLURAY, libbluray)
+    AC_DEFINE(HAVE_BLURAY, 1, [Define to 1 if bluray metadata is going to be built])
+  fi
+fi
+
+AC_SUBST(BLURAY_CFLAGS)
+AC_SUBST(BLURAY_LIBS)
+AM_CONDITIONAL(HAVE_BLURAY, [test "$msg_bluray" = "yes"])
+
 dnl ==========================================================================
 dnl Samba 3.0
 
@@ -699,7 +713,8 @@ echo "
 
         hotplug backend:              $msg_hotplug_backend
 
-        FTP/HTTP/WebDAV support       $msg_http
+	Blu-ray metadata support:     $msg_bluray
+        FTP/HTTP/WebDAV support:      $msg_http
         ObexFTP support               $msg_obexftp
 	Samba support:	              $msg_samba
 	FUSE support:                 $msg_fuse



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