Commit 74991017 authored by Petri Hintukainen's avatar Petri Hintukainen

Add BD_DISC

parent f55ec399
SET_FEATURES = -D_ISOC99_SOURCE -D_POSIX_C_SOURCE=200112L -D_REENTRANT
SET_INCLUDES = -I$(top_srcdir) -Ifile -Ilibbluray -Ilibbluray/bdnav $(BDJAVA_CFLAGS)
SET_INCLUDES = -I$(top_srcdir) -Ifile -Ilibbluray -Ilibbluray/bdnav -I$(top_srcdir)/src/libbluray $(BDJAVA_CFLAGS)
AM_CFLAGS = -std=c99 $(SET_FEATURES) $(SET_INCLUDES) $(LIBXML2_CFLAGS) $(FT2_CFLAGS) $(FONTCONFIG_CFLAGS)
......@@ -61,6 +61,8 @@ libbluray_la_SOURCES = \
libbluray/decoders/graphics_processor.c \
libbluray/decoders/graphics_controller.h \
libbluray/decoders/graphics_controller.c \
libbluray/disc/disc.h \
libbluray/disc/disc.c \
libbluray/hdmv/hdmv_insn.h \
libbluray/hdmv/hdmv_vm.h \
libbluray/hdmv/hdmv_vm.c \
......
......@@ -30,10 +30,12 @@
*/
#ifdef __cplusplus
typedef void (*fptr_void)(...);
typedef int (*fptr_int)(...);
typedef int32_t (*fptr_int32)(...);
typedef void* (*fptr_p_void)(...);
#else
typedef void (*fptr_void)();
typedef int (*fptr_int)();
typedef int32_t (*fptr_int32)();
typedef void* (*fptr_p_void)();
......
......@@ -21,6 +21,9 @@
#include "dl.h"
#include "file.h"
#include "disc/disc.h"
#include "util/logging.h"
#include "util/macro.h"
#include "util/strutl.h"
......@@ -67,18 +70,9 @@ void libaacs_unload(BD_AACS **p)
}
}
int libaacs_required(const char *device_path)
int libaacs_required(BD_DISC *disc)
{
BD_FILE_H *fd;
char *tmp;
tmp = str_printf("%s" DIR_SEP "AACS" DIR_SEP "Unit_Key_RO.inf", device_path);
fd = file_open(tmp, "rb");
X_FREE(tmp);
if (fd) {
file_close(fd);
if (disc_have_file(disc, "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;
}
......@@ -145,12 +139,14 @@ BD_AACS *libaacs_load(void)
return p;
}
int libaacs_open(BD_AACS *p, const char *device_path, const char *keyfile_path)
int libaacs_open(BD_AACS *p, BD_DISC *disc, const char *keyfile_path)
{
int error_code = 0;
fptr_p_void open;
fptr_p_void open2;
fptr_p_void init;
fptr_int open_device;
fptr_int aacs_get_mkb_version;
fptr_p_void aacs_get_disc_id;
......@@ -158,14 +154,21 @@ int libaacs_open(BD_AACS *p, const char *device_path, const char *keyfile_path)
*(void **)(&open) = dl_dlsym(p->h_libaacs, "aacs_open");
*(void **)(&open2) = dl_dlsym(p->h_libaacs, "aacs_open2");
*(void **)(&init) = dl_dlsym(p->h_libaacs, "aacs_init");
*(void **)(&aacs_get_mkb_version) = dl_dlsym(p->h_libaacs, "aacs_get_mkb_version");
*(void **)(&aacs_get_disc_id) = dl_dlsym(p->h_libaacs, "aacs_get_disc_id");
if (open2) {
p->aacs = open2(device_path, keyfile_path, &error_code);
*(void **)(&open_device) = dl_dlsym(p->h_libaacs, "aacs_open_device");
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);
} 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);
} else if (open) {
BD_DEBUG(DBG_BLURAY, "Using old aacs_open(), no verbose error reporting available\n");
p->aacs = open(device_path, keyfile_path);
p->aacs = open(disc_root(disc), keyfile_path);
} else {
BD_DEBUG(DBG_BLURAY, "aacs_open() not found\n");
}
......
......@@ -27,9 +27,11 @@
typedef struct bd_aacs BD_AACS;
BD_PRIVATE int libaacs_required(const char *device_path);
struct bd_disc;
BD_PRIVATE int libaacs_required(struct bd_disc *disc);
BD_PRIVATE BD_AACS *libaacs_load(void);
BD_PRIVATE int libaacs_open(BD_AACS *p, const char *device_path, const char *keyfile_path);
BD_PRIVATE int libaacs_open(BD_AACS *p, struct bd_disc *disc, const char *keyfile_path);
BD_PRIVATE void libaacs_unload(BD_AACS **p);
BD_PRIVATE void libaacs_select_title(BD_AACS *p, uint32_t title);
......
......@@ -21,6 +21,9 @@
#include "dl.h"
#include "file.h"
#include "disc/disc.h"
#include "util/logging.h"
#include "util/macro.h"
#include "util/strutl.h"
......@@ -66,18 +69,9 @@ void libbdplus_unload(BD_BDPLUS **p)
}
}
int libbdplus_required(const char *device_path)
int libbdplus_required(BD_DISC *disc)
{
BD_FILE_H *fd;
char *tmp;
tmp = str_printf("%s" DIR_SEP "BDSVM" DIR_SEP "00000.svm", device_path);
fd = file_open(tmp, "rb");
X_FREE(tmp);
if (fd) {
file_close(fd);
if (disc_have_file(disc, "BDSVM", "00000.svm")) {
BD_DEBUG(DBG_BLURAY, "BDSVM" DIR_SEP "00000.svm found. Disc seems to be BD+ protected.\n");
return 1;
}
......@@ -152,20 +146,28 @@ BD_BDPLUS *libbdplus_load(void)
return p;
}
int libbdplus_init(BD_BDPLUS *p, const char *device_path, const uint8_t *vid, const uint8_t *mk)
int libbdplus_init(BD_BDPLUS *p, BD_DISC *disc, const uint8_t *vid, const uint8_t *mk)
{
fptr_p_void bdplus_init;
fptr_void set_fopen;
_libbdplus_close(p);
*(void **)(&bdplus_init) = dl_dlsym(p->h_libbdplus, "bdplus_init");
*(void **)(&set_fopen) = dl_dlsym(p->h_libbdplus, "bdplus_set_fopen");
if (!bdplus_init) {
BD_DEBUG(DBG_BLURAY | DBG_CRIT, "libbdplus dlsym(bdplus_init) failed! (%p)\n", p->h_libbdplus);
return -1;
}
p->bdplus = bdplus_init(device_path, NULL, vid);
if (set_fopen) {
p->bdplus = bdplus_init(NULL, NULL, vid);
set_fopen(p->bdplus, disc, disc_open_path);
} else {
p->bdplus = bdplus_init(disc_root(disc), NULL, vid);
}
if (!p->bdplus) {
BD_DEBUG(DBG_BLURAY | DBG_CRIT, "bdplus_init() failed! (%p)\n", p->h_libbdplus);
return -1;
......
......@@ -27,9 +27,11 @@
typedef struct bd_bdplus BD_BDPLUS;
BD_PRIVATE int libbdplus_required(const char *device_path);
struct bd_disc;
BD_PRIVATE int libbdplus_required(struct bd_disc *disc);
BD_PRIVATE BD_BDPLUS *libbdplus_load(void);
BD_PRIVATE int libbdplus_init(BD_BDPLUS *p, const char *device_path, const uint8_t *vid, const uint8_t *mk);
BD_PRIVATE int libbdplus_init(BD_BDPLUS *p, struct bd_disc *disc, 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);
......
......@@ -22,14 +22,15 @@
#include "bdjo_data.h"
#include <stdlib.h>
#include <string.h>
#include "disc/disc.h"
#include "file/file.h"
#include "util/bits.h"
#include "util/logging.h"
#include "util/macro.h"
#include <stdlib.h>
#include <string.h>
static char *_read_string(BITSTREAM* bs, uint32_t length)
{
......@@ -497,20 +498,31 @@ static int _check_version(BITSTREAM *bs)
return 1;
}
static int _parse_bdjo(BITSTREAM* bs, BDJO *p)
static BDJO *_bdjo_parse(BD_FILE_H *fp)
{
if (_check_version(bs) < 0 ||
_parse_terminal_info(bs, &p->terminal_info) < 0 ||
_parse_app_cache_info(bs, &p->app_cache_info) < 0 ||
_parse_accessible_playlists(bs, &p->accessible_playlists) < 0 ||
_parse_app_management_table(bs, &p->app_table) < 0 ||
_parse_key_interest_table(bs, &p->key_interest_table) < 0 ||
_parse_file_access_info(bs, &p->file_access_info) < 0) {
BITSTREAM bs;
BDJO *p;
bs_init(&bs, fp);
return -1;
p = calloc(1, sizeof(BDJO));
if (!p) {
BD_DEBUG(DBG_BDJ | DBG_CRIT, "Out of memory\n");
return NULL;
}
return 1;
if (_check_version(&bs) < 0 ||
_parse_terminal_info(&bs, &p->terminal_info) < 0 ||
_parse_app_cache_info(&bs, &p->app_cache_info) < 0 ||
_parse_accessible_playlists(&bs, &p->accessible_playlists) < 0 ||
_parse_app_management_table(&bs, &p->app_table) < 0 ||
_parse_key_interest_table(&bs, &p->key_interest_table) < 0 ||
_parse_file_access_info(&bs, &p->file_access_info) < 0) {
bdjo_free(&p);
}
return p;
}
/*
......@@ -527,27 +539,46 @@ void bdjo_free(BDJO **pp)
BDJO *bdjo_parse(const char *path)
{
BITSTREAM bs;
BD_FILE_H *fp = file_open(path, "rb");
BDJO *p;
BD_FILE_H *fp;
BDJO *bdjo;
fp = file_open(path, "rb");
if (!fp) {
BD_DEBUG(DBG_BDJ | DBG_CRIT, "Failed to open bdjo file (%s)\n", path);
return NULL;
}
bs_init(&bs, fp);
bdjo = _bdjo_parse(fp);
file_close(fp);
return bdjo;
}
p = calloc(1, sizeof(BDJO));
if (!p) {
BD_DEBUG(DBG_BDJ | DBG_CRIT, "Out of memory\n");
} else {
if (_parse_bdjo(&bs, p) < 0) {
bdjo_free(&p);
}
static BDJO *_bdjo_get(BD_DISC *disc, const char *dir, const char *file)
{
BD_FILE_H *fp;
BDJO *bdjo;
fp = disc_open_file(disc, dir, file);
if (!fp) {
return NULL;
}
bdjo = _bdjo_parse(fp);
file_close(fp);
return p;
return bdjo;
}
BDJO *bdjo_get(BD_DISC *disc, const char *file)
{
BDJO *bdjo;
bdjo = _bdjo_get(disc, "BDMV" DIR_SEP "BDJO", file);
if (bdjo) {
return bdjo;
}
/* if failed, try backup file */
bdjo = _bdjo_get(disc, "BDMV" DIR_SEP "BACKUP" DIR_SEP "BDJO", file);
return bdjo;
}
......@@ -23,8 +23,10 @@
#include "util/attributes.h"
struct bdjo_data;
struct bd_disc;
BD_PRIVATE struct bdjo_data *bdjo_parse(const char *path);
BD_PRIVATE struct bdjo_data *bdjo_get(struct bd_disc *disc, const char *file);
BD_PRIVATE void bdjo_free(struct bdjo_data **pp);
#endif // _BDJO_PARSE_H_
......@@ -320,11 +320,7 @@ public class Libbluray {
}
public static Bdjo getBdjo(String name) {
return getBdjoN(nativePointer,
System.getProperty("bluray.vfs.root") + File.separator +
"BDMV" + File.separator +
"BDJO" + File.separator +
name + ".bdjo");
return getBdjoN(nativePointer, name + ".bdjo");
}
public static void updateGraphic(int width, int height, int[] rgbArray) {
......
......@@ -22,7 +22,6 @@
#include "util.h"
#include "libbluray/bdj/bdjo_data.h"
#include "libbluray/bdj/bdjo_parse.h"
#include "util/logging.h"
......@@ -189,7 +188,7 @@ static jobjectArray _make_app_management_table(JNIEnv* env, BDJO_APP_MANAGEMENT_
return entries;
}
static jobject _make_bdjo(JNIEnv* env, BDJO *p)
jobject bdjo_make_jobj(JNIEnv* env, BDJO *p)
{
jobject terminal_info = _make_terminal_info(env, &p->terminal_info);
JNICHK(terminal_info);
......@@ -227,20 +226,3 @@ static jobject _make_bdjo(JNIEnv* env, BDJO *p)
return result;
}
jobject bdjo_get(JNIEnv* env, const char* bdjo_path)
{
jobject result = NULL;
BDJO *bdjo = bdjo_parse(bdjo_path);
if (!bdjo) {
BD_DEBUG(DBG_BDJ | DBG_CRIT, "Failed to read bdjo file (%s)\n", bdjo_path);
return NULL;
}
result = _make_bdjo(env, bdjo);
bdjo_free(&bdjo);
return result;
}
......@@ -24,6 +24,8 @@
#include <jni.h>
BD_PRIVATE jobject bdjo_get(JNIEnv* env, const char *bdjo_path);
struct bdjo_data;
BD_PRIVATE jobject bdjo_make_jobj(JNIEnv* env, struct bdjo_data *bdjo);
#endif /* BDJO_H_ */
......@@ -305,25 +305,29 @@ JNIEXPORT jint JNICALL Java_org_videolan_Libbluray_readPSRN(JNIEnv * env,
}
JNIEXPORT jobject JNICALL Java_org_videolan_Libbluray_getBdjoN(JNIEnv * env,
jclass cls, jlong np, jstring jpath) {
jclass cls, jlong np, jstring jfile) {
(void)np;
BLURAY *bd = (BLURAY*)(intptr_t)np;
struct bdjo_data *bdjo;
jobject jbdjo = NULL;
const char *path = (*env)->GetStringUTFChars(env, jpath, NULL);
if (!path) {
const char *file = (*env)->GetStringUTFChars(env, jfile, NULL);
if (!file) {
BD_DEBUG(DBG_JNI | DBG_CRIT, "getBdjoN() failed: no path\n");
return NULL;
}
BD_DEBUG(DBG_JNI, "getBdjoN(%s)\n", path);
BD_DEBUG(DBG_JNI, "getBdjoN(%s)\n", file);
jobject bdjo = bdjo_get(env, path);
if (!bdjo) {
BD_DEBUG(DBG_JNI | DBG_CRIT, "getBdjoN(%s) failed\n", path);
bdjo = bd_bdjo_get(bd, file);
if (bdjo) {
jbdjo = bdjo_make_jobj(env, bdjo);
} else {
BD_DEBUG(DBG_JNI | DBG_CRIT, "getBdjoN(%s) failed\n", file);
}
(*env)->ReleaseStringUTFChars(env, jpath, path);
(*env)->ReleaseStringUTFChars(env, jfile, file);
return bdjo;
return jbdjo;
}
static void _updateGraphic(JNIEnv * env,
......
......@@ -19,6 +19,8 @@
#include "bdid_parse.h"
#include "disc/disc.h"
#include "file/file.h"
#include "util/bits.h"
#include "util/logging.h"
......@@ -53,26 +55,19 @@ static int _parse_header(BITSTREAM *bs, uint32_t *data_start, uint32_t *extensio
return 1;
}
static BDID_DATA *_bdid_parse(const char *file_name)
static BDID_DATA *_bdid_parse(BD_FILE_H *fp)
{
BITSTREAM bs;
BD_FILE_H *fp;
BDID_DATA *bdid = NULL;
uint32_t data_start, extension_data_start;
uint8_t tmp[16];
fp = file_open(file_name, "rb");
if (!fp) {
BD_DEBUG(DBG_NAV | DBG_CRIT, "bdid_parse(): error opening %s\n", file_name);
return NULL;
}
bs_init(&bs, fp);
if (!_parse_header(&bs, &data_start, &extension_data_start)) {
BD_DEBUG(DBG_NAV | DBG_CRIT, "id.bdmv: invalid header\n");
goto error;
return NULL;
}
bdid = calloc(1, sizeof(BDID_DATA));
......@@ -85,31 +80,35 @@ static BDID_DATA *_bdid_parse(const char *file_name)
bs_read_bytes(&bs, tmp, 16);
str_print_hex(bdid->disc_id, tmp, 16);
file_close(fp);
return bdid;
}
error:
X_FREE(bdid);
static BDID_DATA *_bdid_get(BD_DISC *disc, const char *path)
{
BD_FILE_H *fp;
BDID_DATA *bdid;
fp = disc_open_path(disc, path);
if (!fp) {
return NULL;
}
bdid = _bdid_parse(fp);
file_close(fp);
return NULL;
return bdid;
}
BDID_DATA *bdid_parse(const char *disc_root)
BDID_DATA *bdid_get(BD_DISC *disc)
{
BDID_DATA *bdid;
char *file;
file = str_printf("%s" DIR_SEP "CERTIFICATE" DIR_SEP "id.bdmv", disc_root);
bdid = _bdid_parse(file);
X_FREE(file);
if (bdid) {
return bdid;
}
bdid = _bdid_get(disc, "CERTIFICATE" DIR_SEP "id.bdmv");
/* if failed, try backup file */
file = str_printf("%s" DIR_SEP "CERTIFICATE" DIR_SEP "BACKUP" DIR_SEP "bdid.bdmv", disc_root);
bdid = _bdid_parse(file);
X_FREE(file);
if (!bdid) {
bdid = _bdid_get(disc, "CERTIFICATE" DIR_SEP "BACKUP" DIR_SEP "id.bdmv");
}
return bdid;
}
......
......@@ -30,7 +30,9 @@ typedef struct bdid_s {
} BDID_DATA;
BD_PRIVATE BDID_DATA* bdid_parse(const char *disc_root); /* parse id.bdmv */
struct bd_disc;
BD_PRIVATE BDID_DATA* bdid_get(struct bd_disc *disc); /* parse id.bdmv */
BD_PRIVATE void bdid_free(BDID_DATA **p);
#endif // _BDID_PARSE_H_
......@@ -22,6 +22,8 @@
#include "extdata_parse.h"
#include "disc/disc.h"
#include "file/file.h"
#include "util/bits.h"
#include "util/macro.h"
......@@ -674,27 +676,19 @@ clpi_free(CLPI_CL *cl)
}
static CLPI_CL*
_clpi_parse(const char *path)
_clpi_parse(BD_FILE_H *fp)
{
BITSTREAM bits;
BD_FILE_H *fp;
CLPI_CL *cl;
cl = calloc(1, sizeof(CLPI_CL));
if (cl == NULL) {
return NULL;
}
fp = file_open(path, "rb");
if (fp == NULL) {
BD_DEBUG(DBG_NAV | DBG_CRIT, "Failed to open %s\n", path);
X_FREE(cl);
BD_DEBUG(DBG_CRIT, "out of memory\n");
return NULL;
}
bs_init(&bits, fp);
if (!_parse_header(&bits, cl)) {
file_close(fp);
clpi_free(cl);
return NULL;
}
......@@ -707,48 +701,70 @@ _clpi_parse(const char *path)
}
if (!_parse_clipinfo(&bits, cl)) {
file_close(fp);
clpi_free(cl);
return NULL;
}
if (!_parse_sequence(&bits, cl)) {
file_close(fp);
clpi_free(cl);
return NULL;
}
if (!_parse_program_info(&bits, cl)) {
file_close(fp);
clpi_free(cl);
return NULL;
}
if (!_parse_cpi_info(&bits, cl)) {
file_close(fp);
clpi_free(cl);
return NULL;
}
file_close(fp);
return cl;
}
CLPI_CL*
clpi_parse(const char *path)
{
CLPI_CL *cl = _clpi_parse(path);
BD_FILE_H *fp;
CLPI_CL *cl;
/* if failed, try backup file */
if (!cl) {
size_t len = strlen(path);
char *backup = malloc(len + 8);
fp = file_open(path, "rb");
if (!fp) {
BD_DEBUG(DBG_NAV | DBG_CRIT, "Failed to open %s\n", path);
return NULL;
}
cl = _clpi_parse(fp);
file_close(fp);
return cl;
}
strncpy(backup, path, len - 18);
strcpy(backup + len - 18, "BACKUP" DIR_SEP);
strcpy(backup + len - 18 + 7, path + len - 18);
static CLPI_CL*
_clpi_get(BD_DISC *disc, const char *dir, const char *file)
{
BD_FILE_H *fp;
CLPI_CL *cl;
cl = _clpi_parse(backup);
fp = disc_open_file(disc, dir, file);
if (!fp) {
return NULL;
}
X_FREE(backup);
cl = _clpi_parse(fp);
file_close(fp);
return cl;
}
CLPI_CL*
clpi_get(BD_DISC *disc, const char *file)
{
CLPI_CL *cl;
cl = _clpi_get(disc, "BDMV" DIR_SEP "CLIPINF", file);
if (cl) {
return cl;
}
/* if failed, try backup file */
cl = _clpi_get(disc, "BDMV" DIR_SEP "BACKUP" DIR_SEP "CLIPINF", file);
return cl;
}
......
......@@ -25,9 +25,12 @@
#include <stdint.h>
struct bd_disc;
BD_PRIVATE uint32_t clpi_lookup_spn(const CLPI_CL *cl, uint32_t timestamp, int before, uint8_t stc_id);
BD_PRIVATE uint32_t clpi_access_point(const CLPI_CL *cl, uint32_t pkt, int next, int angle_change, uint32_t *time);
BD_PRIVATE CLPI_CL* clpi_parse(const char *path) BD_ATTR_MALLOC;
BD_PRIVATE CLPI_CL* clpi_get(struct bd_disc *disc, const char *file);
BD_PRIVATE CLPI_CL* clpi_copy(const CLPI_CL* src_cl);
BD_PRIVATE void clpi_free(CLPI_CL *cl);
......
......@@ -19,6 +19,8 @@
#include "index_parse.h"
#include "disc/disc.h"
#include "file/file.h"
#include "util/bits.h"
#include "util/logging.h"
......@@ -177,70 +179,65 @@ static int _parse_header(BITSTREAM *bs, int *index_start, int *extension_data_st
return 1;
}
static INDX_ROOT *_indx_parse(const char *file_name)
static INDX_ROOT *_indx_parse(BD_FILE_H *fp)
{
BITSTREAM bs;
BD_FILE_H *fp;
INDX_ROOT *index = calloc(1, sizeof(INDX_ROOT));
int indexes_start, extension_data_start;
fp = file_open(file_name, "rb");
if (!fp) {
BD_DEBUG(DBG_NAV | DBG_CRIT, "indx_parse(): error opening %s\n", file_name);
X_FREE(index);
if (!index) {
BD_DEBUG(DBG_CRIT, "out of memory\n");
return NULL;
}
bs_init(&bs, fp);
if (!_parse_header(&bs, &indexes_start, &extension_data_start)) {
BD_DEBUG(DBG_NAV | DBG_CRIT, "index.bdmv: invalid header\n");
goto error;
if (!_parse_header(&bs, &indexes_start, &extension_data_start) ||
!_parse_app_info(&bs, &index->app_info)) {
indx_free(&index);
return NULL;
}
bs_seek_byte(&bs, indexes_start);
if (!_parse_index(&bs, index)) {
indx_free(&index);
return NULL;
}
if (extension_data_start) {
BD_DEBUG(DBG_NAV | DBG_CRIT, "index.bdmv: unknown extension data at %d\n", extension_data_start);
}
if (!_parse_app_info(&bs, &index->app_info)) {
BD_DEBUG(DBG_NAV | DBG_CRIT