[libbluray-devel] Improve libmmbd compability

npzacs git at videolan.org
Thu Mar 17 10:29:39 CET 2016


libbluray | branch: master | npzacs <npzacs at gmail.com> | Tue Feb 23 17:56:33 2016 +0200| [224054270c4b772c495b96f6f3b18f74abd6ffd4] | committer: npzacs

Improve libmmbd compability

libmmbd BD+ can't be used with libaacs.
Detect BD+ library type and force using compatible AACS library.

libaacs and libbdplus are still preferred over libmmbd
(libmmbd BD+ does not work with on-disc menus).

> http://git.videolan.org/gitweb.cgi/libbluray.git/?a=commit;h=224054270c4b772c495b96f6f3b18f74abd6ffd4
---

 src/libbluray/disc/aacs.c   |    8 +++--
 src/libbluray/disc/aacs.h   |    2 +-
 src/libbluray/disc/bdplus.c |    5 +++
 src/libbluray/disc/bdplus.h |    1 +
 src/libbluray/disc/dec.c    |   83 +++++++++++++++++++++++++++++++------------
 5 files changed, 73 insertions(+), 26 deletions(-)

diff --git a/src/libbluray/disc/aacs.c b/src/libbluray/disc/aacs.c
index 2d11a73..13860cd 100644
--- a/src/libbluray/disc/aacs.c
+++ b/src/libbluray/disc/aacs.c
@@ -89,6 +89,10 @@ int libaacs_required(void *have_file_handle, int (*have_file)(void *, const char
     return 0;
 }
 
+#define IMPL_USER       0
+#define IMPL_LIBAACS    1
+#define IMPL_LIBMMBD    2
+
 static void *_open_libaacs(int *impl_id)
 {
     const char * const libaacs[] = {
@@ -153,9 +157,9 @@ static BD_AACS *_load(int impl_id)
     return p;
 }
 
-BD_AACS *libaacs_load(void)
+BD_AACS *libaacs_load(int force_mmbd)
 {
-    return _load(0);
+    return _load(force_mmbd ? IMPL_LIBMMBD : 0);
 }
 
 int libaacs_open(BD_AACS *p, const char *device,
diff --git a/src/libbluray/disc/aacs.h b/src/libbluray/disc/aacs.h
index 0f397a5..7380a5c 100644
--- a/src/libbluray/disc/aacs.h
+++ b/src/libbluray/disc/aacs.h
@@ -28,7 +28,7 @@
 typedef struct bd_aacs BD_AACS;
 
 BD_PRIVATE int  libaacs_required(void *h, int (*have_file)(void *, const char *, const char *));
-BD_PRIVATE BD_AACS *libaacs_load(void);
+BD_PRIVATE BD_AACS *libaacs_load(int force_mmbd);
 BD_PRIVATE int  libaacs_open(BD_AACS *p, const char *device,
                              void *file_open_handle, void *file_open_fp,
                              const char *keyfile_path);
diff --git a/src/libbluray/disc/bdplus.c b/src/libbluray/disc/bdplus.c
index ad98517..44fee89 100644
--- a/src/libbluray/disc/bdplus.c
+++ b/src/libbluray/disc/bdplus.c
@@ -115,6 +115,11 @@ static void *_libbdplus_open(int *impl_id)
     return NULL;
 }
 
+int libbdplus_is_mmbd(BD_BDPLUS *p)
+{
+    return p && (p->impl_id == IMPL_LIBMMBD);
+}
+
 static BD_BDPLUS *_load(int impl_id)
 {
     BD_BDPLUS *p = calloc(1, sizeof(BD_BDPLUS));
diff --git a/src/libbluray/disc/bdplus.h b/src/libbluray/disc/bdplus.h
index 7e1382d..6589d88 100644
--- a/src/libbluray/disc/bdplus.h
+++ b/src/libbluray/disc/bdplus.h
@@ -29,6 +29,7 @@ typedef struct bd_bdplus BD_BDPLUS;
 
 BD_PRIVATE int  libbdplus_required(void *have_file_handle, int (*have_file)(void *, const char *, const char *));
 BD_PRIVATE BD_BDPLUS *libbdplus_load(void);
+BD_PRIVATE int  libbdplus_is_mmbd(BD_BDPLUS *);
 BD_PRIVATE int  libbdplus_init(BD_BDPLUS *p, const char *root,
                                void *open_file_handle, void *open_file_fp,
                                const uint8_t *vid, const uint8_t *mk);
diff --git a/src/libbluray/disc/dec.c b/src/libbluray/disc/dec.c
index a910c33..ebe2c39 100644
--- a/src/libbluray/disc/dec.c
+++ b/src/libbluray/disc/dec.c
@@ -179,16 +179,7 @@ static int _libaacs_init(BD_DEC *dec, struct dec_dev *dev,
     int result;
     const uint8_t *disc_id;
 
-    i->aacs_detected = libaacs_required((void*)dev, _bdrom_have_file);
-    if (!i->aacs_detected) {
-        /* no AACS */
-        return 1; /* no error if libaacs is not needed */
-    }
-
-    dec->aacs = libaacs_load();
-    i->libaacs_detected = !!dec->aacs;
     if (!dec->aacs) {
-        /* no libaacs */
         return 0;
     }
 
@@ -216,13 +207,6 @@ static int _libbdplus_init(BD_DEC *dec, struct dec_dev *dev,
                            BD_ENC_INFO *i,
                            void *regs, void *psr_read, void *psr_write)
 {
-    i->bdplus_detected = libbdplus_required((void*)dev, _bdrom_have_file);
-    if (!i->bdplus_detected) {
-        return 0;
-    }
-
-    dec->bdplus = libbdplus_load();
-    i->libbdplus_detected = !!dec->bdplus;
     if (!dec->bdplus) {
         return 0;
     }
@@ -265,6 +249,37 @@ static int _libbdplus_init(BD_DEC *dec, struct dec_dev *dev,
     return 1;
 }
 
+static int _dec_detect(struct dec_dev *dev, BD_ENC_INFO *i)
+{
+    /* Check for AACS */
+    i->aacs_detected = libaacs_required((void*)dev, _bdrom_have_file);
+    if (!i->aacs_detected) {
+        /* No AACS (=> no BD+) */
+        return 0;
+    }
+
+    /* check for BD+ */
+    i->bdplus_detected = libbdplus_required((void*)dev, _bdrom_have_file);
+    return 1;
+}
+
+static void _dec_load(BD_DEC *dec, BD_ENC_INFO *i)
+{
+    int force_mmbd_aacs = 0;
+
+    if (i->bdplus_detected) {
+        /* load BD+ library and check BD+ library type. libmmbd doesn't work with libaacs */
+        dec->bdplus = libbdplus_load();
+        force_mmbd_aacs = dec->bdplus && libbdplus_is_mmbd(dec->bdplus);
+    }
+
+    /* load AACS library */
+    dec->aacs = libaacs_load(force_mmbd_aacs);
+
+    i->libaacs_detected   = !!dec->aacs;
+    i->libbdplus_detected = !!dec->bdplus;
+}
+
 /*
  *
  */
@@ -273,16 +288,38 @@ BD_DEC *dec_init(struct dec_dev *dev, BD_ENC_INFO *enc_info,
                  const char *keyfile_path,
                  void *regs, void *psr_read, void *psr_write)
 {
-    BD_DEC *dec = calloc(1, sizeof(BD_DEC));
-    if (dec) {
-        memset(enc_info, 0, sizeof(*enc_info));
-        _libaacs_init(dec, dev, enc_info, keyfile_path);
+    BD_DEC *dec = NULL;
+
+    memset(enc_info, 0, sizeof(*enc_info));
+
+    /* detect AACS/BD+ */
+    if (!_dec_detect(dev, enc_info)) {
+        return NULL;
+    }
+
+    dec = calloc(1, sizeof(BD_DEC));
+    if (!dec) {
+        return NULL;
+    }
+
+    /* load compatible libraries */
+    _dec_load(dec, enc_info);
+
+    /* init decoding libraries */
+    /* BD+ won't help unless AACS works ... */
+    if (_libaacs_init(dec, dev, enc_info, keyfile_path)) {
         _libbdplus_init(dec, dev, enc_info, regs, psr_read, psr_write);
+    }
 
-        if (!enc_info->bdplus_handled && !enc_info->aacs_handled) {
-            X_FREE(dec);
-        }
+    if (!enc_info->aacs_handled) {
+        /* AACS failed, clean up */
+        dec_close(&dec);
     }
+
+    /* BD+ failure may be non-fatal (not all titles in disc use BD+).
+     * Keep working AACS decoder even if BD+ init failed
+     */
+
     return dec;
 }
 



More information about the libbluray-devel mailing list