Commit 17c22857 authored by npzacs's avatar npzacs

Hide dirty details

parent d57bc6c8
......@@ -67,6 +67,9 @@ libbluray_la_SOURCES = \
libbluray/disc/bdplus.c \
libbluray/disc/disc.h \
libbluray/disc/disc.c \
libbluray/disc/dec.h \
libbluray/disc/dec.c \
libbluray/disc/enc_info.h \
libbluray/hdmv/hdmv_insn.h \
libbluray/hdmv/hdmv_vm.h \
libbluray/hdmv/hdmv_vm.c \
......
......@@ -44,9 +44,8 @@
#include "decoders/graphics_controller.h"
#include "decoders/m2ts_filter.h"
#include "decoders/overlay.h"
#include "disc/aacs.h"
#include "disc/bdplus.h"
#include "disc/disc.h"
#include "disc/enc_info.h"
#include "file/file.h"
#ifdef USING_BDJAVA
#include "bdj/bdj.h"
......@@ -91,9 +90,6 @@ typedef struct {
uint16_t pg_pid; /* pid of currently selected PG stream */
M2TS_FILTER *m2ts_filter;
/* BD+ */
BD_BDPLUS_ST *bdplus;
} BD_STREAM;
typedef struct {
......@@ -136,12 +132,6 @@ struct bluray {
uint64_t next_mark_pos;
int next_mark;
/* AACS */
BD_AACS *libaacs;
/* BD+ */
BD_BDPLUS *libbdplus;
/* player state */
BD_REGISTERS *regs; // player registers
BD_EVENT_QUEUE *event_queue; // navigation mode event queue
......@@ -535,8 +525,6 @@ static void _close_m2ts(BD_STREAM *st)
m2ts_filter_close(&st->m2ts_filter);
libbdplus_m2ts_close(&st->bdplus);
/* reset UO mask */
memset(&st->uo_mask, 0, sizeof(st->uo_mask));
}
......@@ -545,7 +533,7 @@ static int _open_m2ts(BLURAY *bd, BD_STREAM *st)
{
_close_m2ts(st);
st->fp = disc_open_file(bd->disc, "BDMV" DIR_SEP "STREAM", st->clip->name);
st->fp = disc_open_stream(bd->disc, st->clip->name);
st->clip_size = 0;
st->clip_pos = (uint64_t)st->clip->start_pkt * 192;
......@@ -564,8 +552,6 @@ static int _open_m2ts(BLURAY *bd, BD_STREAM *st)
st->clip_size = clip_size;
st->int_buf_off = 6144;
libaacs_select_title(bd->libaacs, bd_psr_read(bd->regs, PSR_TITLE_NUMBER));
if (st == &bd->st0) {
MPLS_PL *pl = st->clip->title->pl;
MPLS_STN *stn = &pl->play_item[st->clip->ref].stn;
......@@ -585,8 +571,6 @@ static int _open_m2ts(BLURAY *bd, BD_STREAM *st)
_init_textst_timer(bd);
}
st->bdplus = libbdplus_m2ts(bd->libbdplus, st->clip->clip_id, st->clip_block_pos);
return 1;
}
......@@ -613,14 +597,6 @@ static int _read_block(BLURAY *bd, BD_STREAM *st, uint8_t *buf)
if (read_len != len) {
BD_DEBUG(DBG_STREAM | DBG_CRIT, "Read %d bytes at %"PRIu64" ; requested %d !\n", (int)read_len, st->clip_block_pos, (int)len);
}
if (bd->libaacs && libaacs_decrypt_unit(bd->libaacs, buf)) {
_queue_event(bd, BD_EVENT_ENCRYPTED, BD_ERROR_AACS);
return -1;
}
if (st->bdplus && (libbdplus_fixup(st->bdplus, buf, len) < 0)) {
_queue_event(bd, BD_EVENT_ENCRYPTED, BD_ERROR_BDPLUS);
}
st->clip_block_pos += len;
/* Check TP_extra_header Copy_permission_indicator. If != 0, unit is still encrypted. */
......@@ -824,102 +800,6 @@ static int _run_gc(BLURAY *bd, gc_ctrl_e msg, uint32_t param)
return result;
}
/*
* libaacs and libbdplus open / close
*/
static int _libaacs_init(BLURAY *bd, const char *keyfile_path)
{
int result;
const uint8_t *disc_id;
libaacs_unload(&bd->libaacs);
bd->disc_info.aacs_detected = libaacs_required(bd->disc);
if (!bd->disc_info.aacs_detected) {
/* no AACS */
return 1; /* no error if libaacs is not needed */
}
bd->libaacs = libaacs_load();
bd->disc_info.libaacs_detected = !!bd->libaacs;
if (!bd->libaacs) {
/* no libaacs */
return 0;
}
result = libaacs_open(bd->libaacs, bd->disc, keyfile_path);
bd->disc_info.aacs_error_code = result;
bd->disc_info.aacs_handled = !result;
bd->disc_info.aacs_mkbv = libaacs_get_mkbv(bd->libaacs);
disc_id = libaacs_get_aacs_data(bd->libaacs, BD_AACS_DISC_ID);
if (disc_id) {
memcpy(bd->disc_info.disc_id, disc_id, 20);
}
if (result) {
BD_DEBUG(DBG_BLURAY | DBG_CRIT, "aacs_open() failed!\n");
libaacs_unload(&bd->libaacs);
return 0;
}
BD_DEBUG(DBG_BLURAY, "Opened libaacs\n");
return 1;
}
const uint8_t *bd_get_aacs_data(BLURAY *bd, int type)
{
/* internal function. Used by BD-J and libbdplus loader. */
return libaacs_get_aacs_data(bd->libaacs, type);
}
static int _libbdplus_init(BLURAY *bd)
{
libbdplus_unload(&bd->libbdplus);
bd->disc_info.bdplus_detected = libbdplus_required(bd->disc);
if (!bd->disc_info.bdplus_detected) {
return 0;
}
bd->libbdplus = libbdplus_load();
bd->disc_info.libbdplus_detected = !!bd->libbdplus;
if (!bd->libbdplus) {
return 0;
}
const uint8_t *vid = libaacs_get_aacs_data(bd->libaacs, BD_AACS_MEDIA_VID);
const uint8_t *mk = libaacs_get_aacs_data(bd->libaacs, BD_AACS_MEDIA_KEY);
if (!vid) {
BD_DEBUG(DBG_BLURAY | DBG_CRIT, "BD+ initialization failed (no AACS ?)\n");
libaacs_unload(&bd->libaacs);
return 0;
}
if (libbdplus_init(bd->libbdplus, bd->disc, vid, mk)) {
BD_DEBUG(DBG_BLURAY | DBG_CRIT, "bdplus_init() failed\n");
bd->disc_info.bdplus_handled = 0;
libbdplus_unload(&bd->libbdplus);
return 0;
}
BD_DEBUG(DBG_BLURAY, "libbdplus initialized\n");
/* map player memory regions */
libbdplus_mmap(bd->libbdplus, 0, (void*)bd->regs);
libbdplus_mmap(bd->libbdplus, 1, (void*)((uint8_t *)bd->regs + sizeof(uint32_t) * 128));
/* connect registers */
libbdplus_psr(bd->libbdplus, (void*)bd->regs, (void*)bd_psr_read, (void*)bd_psr_write);
bd->disc_info.bdplus_gen = libbdplus_get_gen(bd->libbdplus);
bd->disc_info.bdplus_date = libbdplus_get_date(bd->libbdplus);
bd->disc_info.bdplus_handled = 1;
return 1;
}
/*
* meta open
*/
......@@ -942,8 +822,20 @@ const BLURAY_DISC_INFO *bd_get_disc_info(BLURAY *bd)
return &bd->disc_info;
}
static void _fill_disc_info(BLURAY *bd)
static void _fill_disc_info(BLURAY *bd, BD_ENC_INFO *enc_info)
{
bd->disc_info.aacs_detected = enc_info->aacs_detected;
bd->disc_info.libaacs_detected = enc_info->libaacs_detected;
bd->disc_info.aacs_error_code = enc_info->aacs_error_code;
bd->disc_info.aacs_handled = enc_info->aacs_handled;
bd->disc_info.aacs_mkbv = enc_info->aacs_mkbv;
memcpy(bd->disc_info.disc_id, enc_info->disc_id, 20);
bd->disc_info.bdplus_detected = enc_info->bdplus_detected;
bd->disc_info.libbdplus_detected = enc_info->libbdplus_detected;
bd->disc_info.bdplus_handled = enc_info->bdplus_handled;
bd->disc_info.bdplus_gen = enc_info->bdplus_gen;
bd->disc_info.bdplus_date = enc_info->bdplus_date;
bd->disc_info.bluray_detected = 0;
bd->disc_info.top_menu_supported = 0;
bd->disc_info.first_play_supported = 0;
......@@ -1101,6 +993,13 @@ static void _fill_disc_info(BLURAY *bd)
* bdj
*/
#ifdef USING_BDJAVA
const uint8_t *bd_get_aacs_data(BLURAY *bd, int type)
{
return disc_get_data(bd->disc, type);
}
#endif
#ifdef USING_BDJAVA
void bd_set_bdj_uo_mask(BLURAY *bd, unsigned mask)
{
......@@ -1344,8 +1243,10 @@ static void _storage_free(BLURAY *bd)
* open / close
*/
BLURAY *bd_open(const char* device_path, const char* keyfile_path)
BLURAY *bd_open(const char *device_path, const char *keyfile_path)
{
BD_ENC_INFO enc_info;
BD_DEBUG(DBG_BLURAY, "libbluray version "BLURAY_VERSION_STRING"\n");
if (!device_path) {
......@@ -1367,13 +1268,11 @@ BLURAY *bd_open(const char* device_path, const char* keyfile_path)
return NULL;
}
bd->disc = disc_open(device_path);
_libaacs_init(bd, keyfile_path);
bd->disc = disc_open(device_path,
&enc_info, keyfile_path,
(void*)bd->regs, (void*)bd_psr_read, (void*)bd_psr_write);
_libbdplus_init(bd);
_fill_disc_info(bd);
_fill_disc_info(bd, &enc_info);
bd_mutex_init(&bd->mutex);
#ifdef USING_BDJAVA
......@@ -1389,14 +1288,10 @@ void bd_close(BLURAY *bd)
{
_close_bdj(bd);
libaacs_unload(&bd->libaacs);
_close_m2ts(&bd->st0);
_close_preload(&bd->st_ig);
_close_preload(&bd->st_textst);
libbdplus_unload(&bd->libbdplus);
if (bd->title_list != NULL) {
nav_free_title_list(bd->title_list);
}
......@@ -1495,8 +1390,6 @@ static void _seek_internal(BLURAY *bd,
}
BD_DEBUG(DBG_BLURAY, "Seek to %"PRIu64"\n", bd->s_pos);
libbdplus_seek(bd->st0.bdplus, bd->st0.clip_block_pos);
}
}
......@@ -2376,10 +2269,7 @@ uint32_t bd_get_titles(BLURAY *bd, uint8_t flags, uint32_t min_title_length)
return 0;
}
/* start BD+. No real title info will be passed to BD+ VM ... */
if (bd->libbdplus) {
libbdplus_event(bd->libbdplus, 0xffffffff, bd->disc_info.num_titles, 0);
}
disc_event(bd->disc, DISC_EVENT_START, bd->disc_info.num_titles);
return bd->title_list->count;
}
......@@ -2764,7 +2654,6 @@ static void _process_psr_write_event(BLURAY *bd, BD_PSR_EVENT *ev)
break;
case PSR_TITLE_NUMBER:
_queue_event(bd, BD_EVENT_TITLE, ev->new_val);
libbdplus_event(bd->libbdplus, 0x110, ev->new_val, 0);
break;
case PSR_PLAYLIST:
_bdj_event (bd, BDJ_EVENT_PLAYLIST,ev->new_val);
......@@ -2786,7 +2675,7 @@ static void _process_psr_write_event(BLURAY *bd, BD_PSR_EVENT *ev)
_bdj_event (bd, BDJ_EVENT_PSR102, ev->new_val);
break;
case 103:
libbdplus_event(bd->libbdplus, 0x210, ev->new_val, 0);
disc_event(bd->disc, DISC_EVENT_APPLICATION, ev->new_val);
break;
default:;
......@@ -2801,6 +2690,12 @@ static void _process_psr_change_event(BLURAY *bd, BD_PSR_EVENT *ev)
switch (ev->psr_idx) {
/* current playback position */
case PSR_TITLE_NUMBER:
disc_event(bd->disc, DISC_EVENT_TITLE, ev->new_val);
break;
/* stream selection */
case PSR_IG_STREAM_ID:
......@@ -3039,15 +2934,16 @@ int bd_play(BLURAY *bd)
hdmv_vm_free(&bd->hdmv_vm);
}
_init_event_queue(bd);
if (!bd->event_queue) {
_init_event_queue(bd);
bd_psr_lock(bd->regs);
bd_psr_register_cb(bd->regs, _process_psr_event, bd);
_queue_initial_psr_events(bd);
bd_psr_unlock(bd->regs);
bd_psr_lock(bd->regs);
bd_psr_register_cb(bd->regs, _process_psr_event, bd);
_queue_initial_psr_events(bd);
bd_psr_unlock(bd->regs);
}
/* start BD+ VM */
libbdplus_start(bd->libbdplus);
disc_event(bd->disc, DISC_EVENT_START, 0);
/* start playback from FIRST PLAY title */
......
/*
* This file is part of libbluray
* Copyright (C) 2013 VideoLAN
* Copyright (C) 2013-2015 VideoLAN
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -19,8 +19,6 @@
#include "aacs.h"
#include "disc.h"
#include "file/dl.h"
#include "file/file.h"
#include "util/logging.h"
......@@ -69,9 +67,9 @@ void libaacs_unload(BD_AACS **p)
}
}
int libaacs_required(BD_DISC *disc)
int libaacs_required(void *have_file_handle, int (*have_file)(void *, const char *, const char *))
{
if (disc_have_file(disc, "AACS", "Unit_Key_RO.inf")) {
if (have_file(have_file_handle, "AACS", "Unit_Key_RO.inf")) {
BD_DEBUG(DBG_BLURAY, "AACS" DIR_SEP "Unit_Key_RO.inf found. Disc seems to be AACS protected.\n");
return 1;
}
......@@ -138,7 +136,10 @@ BD_AACS *libaacs_load(void)
return p;
}
int libaacs_open(BD_AACS *p, BD_DISC *disc, const char *keyfile_path)
int libaacs_open(BD_AACS *p, const char *device,
void *file_open_handle, void *file_open_fp,
const char *keyfile_path)
{
int error_code = 0;
......@@ -160,14 +161,14 @@ int libaacs_open(BD_AACS *p, BD_DISC *disc, const char *keyfile_path)
if (init && open_device) {
p->aacs = init();
DL_CALL(p->h_libaacs, aacs_set_fopen, p->aacs, disc, disc_open_path);
error_code = open_device(p->aacs, disc_device(disc), keyfile_path);
DL_CALL(p->h_libaacs, aacs_set_fopen, p->aacs, file_open_handle, file_open_fp);
error_code = open_device(p->aacs, device, keyfile_path);
} else if (open2) {
BD_DEBUG(DBG_BLURAY, "Using old aacs_open2(), no UDF support available\n");
p->aacs = open2(disc_root(disc), keyfile_path, &error_code);
p->aacs = open2(device, keyfile_path, &error_code);
} else if (open) {
BD_DEBUG(DBG_BLURAY, "Using old aacs_open(), no verbose error reporting available\n");
p->aacs = open(disc_root(disc), keyfile_path);
p->aacs = open(device, keyfile_path);
} else {
BD_DEBUG(DBG_BLURAY, "aacs_open() not found\n");
}
......
/*
* This file is part of libbluray
* Copyright (C) 2013 VideoLAN
* Copyright (C) 2013-2015 VideoLAN
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -27,11 +27,11 @@
typedef struct bd_aacs BD_AACS;
struct bd_disc;
BD_PRIVATE int libaacs_required(struct bd_disc *disc);
BD_PRIVATE int libaacs_required(void *h, int (*have_file)(void *, const char *, const char *));
BD_PRIVATE BD_AACS *libaacs_load(void);
BD_PRIVATE int libaacs_open(BD_AACS *p, struct bd_disc *disc, const char *keyfile_path);
BD_PRIVATE int libaacs_open(BD_AACS *p, const char *device,
void *file_open_handle, void *file_open_fp,
const char *keyfile_path);
BD_PRIVATE void libaacs_unload(BD_AACS **p);
BD_PRIVATE void libaacs_select_title(BD_AACS *p, uint32_t title);
......
/*
* This file is part of libbluray
* Copyright (C) 2013 VideoLAN
* Copyright (C) 2013-2015 VideoLAN
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -19,8 +19,6 @@
#include "bdplus.h"
#include "disc.h"
#include "file/dl.h"
#include "file/file.h"
#include "util/logging.h"
......@@ -68,9 +66,9 @@ void libbdplus_unload(BD_BDPLUS **p)
}
}
int libbdplus_required(BD_DISC *disc)
int libbdplus_required(void *have_file_handle, int (*have_file)(void *, const char *, const char *))
{
if (disc_have_file(disc, "BDSVM", "00000.svm")) {
if (have_file(have_file_handle, "BDSVM", "00000.svm")) {
BD_DEBUG(DBG_BLURAY, "BDSVM" DIR_SEP "00000.svm found. Disc seems to be BD+ protected.\n");
return 1;
}
......@@ -139,7 +137,9 @@ BD_BDPLUS *libbdplus_load(void)
return p;
}
int libbdplus_init(BD_BDPLUS *p, BD_DISC *disc, const uint8_t *vid, const uint8_t *mk)
int libbdplus_init(BD_BDPLUS *p, const char *root,
void *file_open_handle, void *file_open_fp,
const uint8_t *vid, const uint8_t *mk)
{
fptr_p_void bdplus_init;
fptr_void set_fopen;
......@@ -156,9 +156,9 @@ int libbdplus_init(BD_BDPLUS *p, BD_DISC *disc, const uint8_t *vid, const uint8_
if (set_fopen) {
p->bdplus = bdplus_init(NULL, NULL, vid);
set_fopen(p->bdplus, disc, disc_open_path);
set_fopen(p->bdplus, file_open_handle, file_open_fp);
} else {
p->bdplus = bdplus_init(disc_root(disc), NULL, vid);
p->bdplus = bdplus_init(root, NULL, vid);
}
if (!p->bdplus) {
......
/*
* This file is part of libbluray
* Copyright (C) 2013 VideoLAN
* Copyright (C) 2013-2015 VideoLAN
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -27,11 +27,11 @@
typedef struct bd_bdplus BD_BDPLUS;
struct bd_disc;
BD_PRIVATE int libbdplus_required(struct bd_disc *disc);
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_init(BD_BDPLUS *p, struct bd_disc *disc, const uint8_t *vid, const uint8_t *mk);
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);
BD_PRIVATE void libbdplus_unload(BD_BDPLUS **p);
BD_PRIVATE int libbdplus_get_gen(BD_BDPLUS *p);
......
/*
* This file is part of libbluray
* Copyright (C) 2014 VideoLAN
*
* 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 HAVE_CONFIG_H
#include "config.h"
#endif
#include "dec.h"
#include "enc_info.h"
#include "aacs.h"
#include "bdplus.h"
#include "util/logging.h"
#include "util/macro.h"
#include "file/file.h"
#include <string.h>
struct bd_dec {
int use_menus;
BD_AACS *aacs;
BD_BDPLUS *bdplus;
};
/*
* stream
*/
typedef struct {
BD_FILE_H *fp;
BD_AACS *aacs;
BD_BDPLUS_ST *bdplus;
} DEC_STREAM;
static int64_t _stream_read(BD_FILE_H *fp, uint8_t *buf, int64_t size)
{
DEC_STREAM *st = (DEC_STREAM *)fp->internal;
int64_t result;
if (size != 6144) {
BD_DEBUG(DBG_CRIT, "read size != unit size\n");
return 0;
}
result = st->fp->read(st->fp, buf, size);
if (result <= 0) {
return result;
}
if (st->aacs) {
if (libaacs_decrypt_unit(st->aacs, buf)) {
/* failure is detected from TP header */
}
}
if (st->bdplus) {
if (libbdplus_fixup(st->bdplus, buf, size) < 0) {
/* there's no way to verify if the stream was decoded correctly */
}
}
return result;
}
static int64_t _stream_seek(BD_FILE_H *fp, int64_t offset, int32_t origin)
{
DEC_STREAM *st = (DEC_STREAM *)fp->internal;
int64_t result = st->fp->seek(st->fp, offset, origin);
if (result >= 0 && st->bdplus) {
libbdplus_seek(st->bdplus, st->fp->tell(st->fp));
}
return result;
}
static int64_t _stream_tell(BD_FILE_H *fp)
{
DEC_STREAM *st = (DEC_STREAM *)fp->internal;
return st->fp->tell(st->fp);
}
static void _stream_close(BD_FILE_H *fp)
{
DEC_STREAM *st = (DEC_STREAM *)fp->internal;
if (st->bdplus) {
libbdplus_m2ts_close(&st->bdplus);
}
st->fp->close(st->fp);
X_FREE(fp->internal);
X_FREE(fp);
}
BD_FILE_H *dec_open_stream(BD_DEC *dec, BD_FILE_H *fp, uint32_t clip_id)
{
DEC_STREAM *st;
BD_FILE_H *p = calloc(1, sizeof(BD_FILE_H));
if (!p) {
return NULL;
}
st = calloc(1, sizeof(DEC_STREAM));
if (!st) {
X_FREE(p);
return NULL;
}
st->fp = fp;
if (dec->bdplus) {
st->bdplus = libbdplus_m2ts(dec->bdplus, clip_id, 0);
}
if (dec->aacs) {
st->aacs = dec->aacs;
if (!dec->use_menus) {
/* There won't be title events --> need to manually reset AACS CPS */
libaacs_select_title(dec->aacs, 0xffff);
}
}
p->internal = st;
p->read = _stream_read;
p->seek = _stream_seek;
p->tell = _stream_tell;
p->close = _stream_close;
return p;
}
/*
*
*/
static int _libaacs_init(BD_DEC *dec, struct dec_dev *dev,
BD_ENC_INFO *i, const char *keyfile_path)
{
int result;
const uint8_t *disc_id;
libaacs_unload(&dec->aacs);
i->aacs_detected = libaacs_required(dev->file_open_handle, dev->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;
}
result = libaacs_open(dec->aacs, dev->device, dev->file_open_handle, dev->file_open, keyfile_path);
i->aacs_error_code = result;
i->aacs_handled = !result;
i->aacs_mkbv = libaacs_get_mkbv(dec->aacs);
disc_id = libaacs_get_aacs_data(dec->aacs, BD_AACS_DISC_ID);
if (disc_id) {
memcpy(i->disc_id, disc_id, 20);
}
if (result) {
BD_DEBUG(DBG_BLURAY | DBG_CRIT, "aacs_open() failed!\n");
libaacs_unload(&dec->aacs);
return 0;
}
BD_DEBUG(DBG_BLURAY, "Opened libaacs\n");
return 1;
}
static int _libbdplus_init(BD_DEC *dec, struct dec_dev *dev,
BD_ENC_INFO *i,
void *regs, void *psr_read, void *psr_write)
{
libbdplus_unload(&dec->bdplus);
i->bdplus_detected = libbdplus_required(dev->file_open_handle, dev->have_file);
if (!i->bdplus_detected) {
return 0;
}
dec->bdplus = libbdplus_load();
i->libbdplus_detected = !!dec->bdplus;
if (!dec->bdplus) {
return 0;
}
const uint8_t *vid = libaacs_get_aacs_data(dec->aacs, BD_AACS_MEDIA_VID);
const uint8_t *mk = libaacs_get_aacs_data(dec->aacs, BD_AACS_MEDIA_KEY);
if (!vid) {
BD_DEBUG(DBG_BLURAY | DBG_CRIT, "BD+ initialization failed (no AACS ?)\n");
libbdplus_unload(&dec->bdplus);
return 0;
}
if (libbdplus_init(dec->bdplus, dev->root, dev->file_open_handle, dev->file_open, vid, mk)) {
BD_DEBUG(DBG_BLURAY | DBG_CRIT, "bdplus_init() failed\n");
i->bdplus_handled = 0;
libbdplus_unload(&dec->bdplus);
return 0;
}
BD_DEBUG(DBG_BLURAY, "libbdplus initialized\n");
/* map player memory regions */
libbdplus_mmap(dec->bdplus, 0, regs);
libbdplus_mmap(dec->bdplus, 1, (void*)((uint8_t *)regs + sizeof(uint32_t) * 128));
/* connect registers */
libbdplus_psr(dec->bdplus, regs, psr_read, psr_write);
i->bdplus_gen = libbdplus_get_gen(dec->bdplus);
i->bdplus_date = libbdplus_get_date(dec->bdplus);
i->bdplus_handled = 1;