[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