libbluray | branch: master | npzacs <npz...@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; } _______________________________________________ libbluray-devel mailing list libbluray-devel@videolan.org https://mailman.videolan.org/listinfo/libbluray-devel