Commit 23fdb5e0 authored by hpi1's avatar hpi1

Added player registers

parent 69b8f236
......@@ -25,6 +25,8 @@ lib_LTLIBRARIES=libbluray.la
libbluray_ladir= $(includedir)/libbluray
libbluray_la_SOURCES=libbluray/bluray.h \
libbluray/bluray.c \
libbluray/register.h \
libbluray/register.c \
libbluray/bdnav \
libbluray/bdnav/bdparse.h \
libbluray/bdnav/navigation.h \
......
......@@ -32,6 +32,7 @@
#endif
#include "bluray.h"
#include "register.h"
#include "util/macro.h"
#include "util/logging.h"
#include "util/strutl.h"
......@@ -217,6 +218,8 @@ BLURAY *bd_open(const char* device_path, const char* keyfile_path)
_index_open(bd);
bd->regs = bd_registers_init();
DEBUG(DBG_BLURAY, "BLURAY initialized! (%p)\n", bd);
} else {
X_FREE(bd);
......@@ -262,6 +265,8 @@ void bd_close(BLURAY *bd)
indx_free(bd->index);
}
bd_registers_free(bd->regs);
X_FREE(bd->device_path);
DEBUG(DBG_BLURAY, "BLURAY destroyed! (%p)\n", bd);
......
......@@ -34,6 +34,7 @@
#include "navigation.h"
struct indx_root_s;
struct bd_registers_s;
typedef int (*fptr_int)();
typedef int32_t (*fptr_int32)();
......@@ -65,6 +66,7 @@ struct bluray {
int angle;
struct indx_root_s *index;
struct bd_registers_s *regs;
};
typedef struct bd_chapter {
......
/*
* This file is part of libbluray
* Copyright (C) 2010 hpi1
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders of libbluray
* gives permission to link the code of its release of libbluray with the
* OpenSSL project's "OpenSSL" library (or with modified versions of it
* that use the same license as the "OpenSSL" library), and distribute
* the linked executables. You must obey the GNU General Public License
* in all respects for all of the code used other than "OpenSSL". If you
* modify this file, you may extend this exception to your version of the
* file, but you are not obligated to do so. If you do not wish to do
* so, delete this exception statement from your version.
*/
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include "util/attributes.h"
#include "util/macro.h"
#include "util/logging.h"
#include "register.h"
#define BD_PSR_COUNT 128
#define BD_GPR_COUNT 4096
/*
* Initial values for player status/setting registers (5.8.2).
*
* PS in comment indicates player setting -> register can't be changed from movie object code.
*/
const uint32_t bd_psr_init[BD_PSR_COUNT] = {
1, /* PSR0: Interactive graphics stream number */
0xff, /* PSR1: Primary audio stream number */
0x0fff0fff, /* PSR2: PG TextST stream number and PiP PG stream number*/
1, /* PSR3: Angle number */
0xffff, /* PSR4: Title number */
0xffff, /* PSR5: Chapter number */
0, /* PSR6: PlayList ID */
0, /* PSR7: PlayItem ID */
0, /* PSR8: Presentation time */
0, /* PSR9: Navigation timer */
0xffff, /* PSR10: Selected button ID */
0, /* PSR11: Page ID */
0xff, /* PSR12: User style number */
0xff, /* PS: PSR13: User age */
0xffff, /* PSR14: Secondary audio stream number and secondary video stream number */
0xffff, /* PS: PSR15: player capability for audio */
0xffffff, /* PS: PSR16: Language code for audio */
0xffffff, /* PS: PSR17: Language code for PG and Text subtitles */
0xffffff, /* PS: PSR18: Menu description language code */
0xffff, /* PS: PSR19: Country code */
0x07, /* PS: PSR20: Region code */ /* 1 - A, 2 - B, 4 - C */
0, /* PSR21 */
0, /* PSR22 */
0, /* PSR23 */
0, /* PSR24 */
0, /* PSR25 */
0, /* PSR26 */
0, /* PSR27 */
0, /* PSR28 */
0x03, /* PS: PSR29: player capability for video */
0x1ffff, /* PS: PSR30: player capability for text subtitle */
0x080200, /* PS: PSR31: Player profile and version */
0, /* PSR32 */
0, /* PSR33 */
0, /* PSR34 */
0, /* PSR35 */
0xffff, /* PSR36: backup PSR4 */
0xffff, /* PSR37: backup PSR5 */
0, /* PSR38: backup PSR6 */
0, /* PSR39: backup PSR7 */
0, /* PSR40: backup PSR8 */
0, /* PSR41: */
0xffff, /* PSR42: backup PSR10 */
0, /* PSR43: backup PSR11 */
0xff, /* PSR44: backup PSR12 */
0, /* PSR45: */
0, /* PSR46: */
0, /* PSR47: */
0xffffffff, /* PS: PSR48: Characteristic text caps */
0xffffffff, /* PS: PSR49: Characteristic text caps */
0xffffffff, /* PS: PSR50: Characteristic text caps */
0xffffffff, /* PS: PSR51: Characteristic text caps */
0xffffffff, /* PS: PSR52: Characteristic text caps */
0xffffffff, /* PS: PSR53: Characteristic text caps */
0xffffffff, /* PS: PSR54: Characteristic text caps */
0xffffffff, /* PS: PSR55: Characteristic text caps */
0xffffffff, /* PS: PSR56: Characteristic text caps */
0xffffffff, /* PS: PSR57: Characteristic text caps */
0xffffffff, /* PS: PSR58: Characteristic text caps */
0xffffffff, /* PS: PSR59: Characteristic text caps */
0xffffffff, /* PS: PSR60: Characteristic text caps */
0xffffffff, /* PS: PSR61: Characteristic text caps */
/* 62-95: reserved */
/* 96-111: reserved for BD system use */
/* 112-127: reserved */
};
/*
* PSR ids for debugging
*/
const char *bd_psr_name[BD_PSR_COUNT] = {
"IG_STREAM_ID",
"PRIMARY_AUDIO_ID",
"PG_PIP_STREAM",
"ANGLE_ID",
"TITLE_ID",
"CHAPTER",
"PLAYLIST",
"PLAYITEM",
"TIME",
"NAV_TIMER",
"SELECTED_BUTTON_ID",
"MENU_PAGE_ID",
"STYLE",
"PARENTAL",
"SECONDARY_AUDIO_VIDEO",
"AUDIO_CAP",
"AUDIO_LANG",
"PG_AND_SUB_LANG",
"PSR_MENU_LANG",
"PSR_COUNTRY",
"PSR_REGION",
"PSR_VIDEO_CAP",
};
/*
* data
*/
typedef struct {
void *handle;
void (*cb)(void *, BD_PSR_EVENT*);
} PSR_CB_DATA;
struct bd_registers_s
{
uint32_t psr[BD_PSR_COUNT];
uint32_t gpr[BD_GPR_COUNT];
/* callbacks */
int num_cb;
PSR_CB_DATA *cb;
};
/*
* init / free
*/
BD_REGISTERS *bd_registers_init(void)
{
BD_REGISTERS *p = calloc(1, sizeof(BD_REGISTERS));
memcpy(p->psr, bd_psr_init, sizeof(bd_psr_init));
return p;
}
void bd_registers_free(BD_REGISTERS *p)
{
if (p) {
X_FREE(p->cb);
}
X_FREE(p);
}
/*
* register / unregister state change callback
*/
void bd_psr_register_cb (BD_REGISTERS *p, void (*callback)(void*,BD_PSR_EVENT*), void *cb_handle)
{
p->num_cb++;
p->cb = realloc(p->cb, p->num_cb * sizeof(PSR_CB_DATA));
p->cb[p->num_cb - 1].cb = callback;
p->cb[p->num_cb - 1].handle = cb_handle;
}
void bd_psr_unregister_cb(BD_REGISTERS *p, void (*callback)(void*,BD_PSR_EVENT*), void *cb_handle)
{
if (p->cb) {
int i = 0;
while (i < p->num_cb) {
if (p->cb[i].handle == cb_handle && p->cb[i].cb == callback) {
if (--p->num_cb) {
memmove(p->cb + i, p->cb + i + 1, sizeof(PSR_CB_DATA) * p->num_cb);
continue;
}
}
i++;
}
}
}
/*
* save / restore
*/
void bd_psr_save_state(BD_REGISTERS *p)
{
/* store registers 4-8 and 10-12 to backup registers */
memcpy(p->psr + 36, p->psr + 4, sizeof(uint32_t) * 5);
memcpy(p->psr + 42, p->psr + 10, sizeof(uint32_t) * 3);
}
void bd_psr_restore_state(BD_REGISTERS *p)
{
uint32_t old_psr[BD_PSR_COUNT];
if (p->cb)
memcpy(old_psr, p->psr, sizeof(old_psr));
/* restore backup registers */
memcpy(p->psr + 4, p->psr + 36, sizeof(uint32_t) * 5);
memcpy(p->psr + 10, p->psr + 42, sizeof(uint32_t) * 3);
/* init backup registers to default */
memcpy(p->psr + 36, bd_psr_init + 36, sizeof(uint32_t) * 5);
memcpy(p->psr + 42, bd_psr_init + 42, sizeof(uint32_t) * 3);
/* generate restore events */
if (p->cb) {
int i;
for (i = 4; i < 13; i++) {
if (i != 9 && old_psr[i] != p->psr[i]) {
BD_PSR_EVENT ev;
int j;
ev.ev_type = BD_PSR_RESTORE;
ev.psr_idx = i;
ev.old_val = old_psr[i];
ev.new_val = p->psr[i];
for (j = 0; j < p->num_cb; i++) {
p->cb[i].cb(p->cb[i].handle, &ev);
}
}
}
}
}
/*
* GPR read / write
*/
int bd_gpr_write(BD_REGISTERS *p, int reg, uint32_t val)
{
if (reg < 0 || reg > BD_GPR_COUNT) {
DEBUG(DBG_BLURAY, "bd_gpr_write(%d): invalid register\n", reg);
return -1;
}
p->gpr[reg] = val;
return 0;
}
uint32_t bd_gpr_read(BD_REGISTERS *p, int reg)
{
if (reg < 0 || reg > BD_GPR_COUNT) {
DEBUG(DBG_BLURAY, "bd_gpr_read(%d): invalid register\n", reg);
return -1;
}
return p->gpr[reg];
}
/*
* PSR read / write
*/
uint32_t bd_psr_read(BD_REGISTERS *p, int reg)
{
if (reg < 0 || reg > BD_PSR_COUNT) {
DEBUG(DBG_BLURAY, "bd_psr_read(%d): invalid register\n", reg);
return -1;
}
return p->psr[reg];
}
int bd_psr_setting_write(BD_REGISTERS *p, int reg, uint32_t val)
{
if (reg < 0 || reg > BD_PSR_COUNT) {
DEBUG(DBG_BLURAY, "bd_psr_write(%d, %d): invalid register\n", reg, val);
return -1;
}
if (p->psr[reg] == val) {
DEBUG(DBG_BLURAY, "bd_psr_write(%d, %d): no change in value\n", reg, val);
return 0;
}
if (bd_psr_name[reg]) {
DEBUG(DBG_BLURAY, "bd_psr_write(): PSR%-4d (%s) 0x%x -> 0x%x\n", reg, bd_psr_name[reg], p->psr[reg], val);
} else {
DEBUG(DBG_BLURAY, "bd_psr_write(): PSR%-4d 0x%x -> 0x%x\n", reg, p->psr[reg], val);
}
if (p->num_cb) {
BD_PSR_EVENT ev;
int i;
ev.ev_type = BD_PSR_CHANGE;
ev.psr_idx = reg;
ev.old_val = p->psr[reg];
ev.new_val = val;
p->psr[reg] = val;
for (i = 0; i < p->num_cb; i++) {
p->cb[i].cb(p->cb[i].handle, &ev);
}
} else {
p->psr[reg] = val;
}
return 0;
}
int bd_psr_write(BD_REGISTERS *p, int reg, uint32_t val)
{
if ((reg == 13) ||
(reg >= 15 && reg <= 20) ||
(reg >= 29 && reg <= 31) ||
(reg >= 48 && reg <= 61)) {
DEBUG(DBG_BLURAY, "bd_psr_write(%d, %d): read-only register !\n", reg, val);
return -2;
}
return bd_psr_setting_write(p, reg, val);
}
/*
* This file is part of libbluray
* Copyright (C) 2010 hpi1
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders of libbluray
* gives permission to link the code of its release of libbluray with the
* OpenSSL project's "OpenSSL" library (or with modified versions of it
* that use the same license as the "OpenSSL" library), and distribute
* the linked executables. You must obey the GNU General Public License
* in all respects for all of the code used other than "OpenSSL". If you
* modify this file, you may extend this exception to your version of the
* file, but you are not obligated to do so. If you do not wish to do
* so, delete this exception statement from your version.
*/
#if !defined(_BD_REGISTER_H_)
#define _BD_REGISTER_H_
#include <stdint.h>
/*
* Player Status Registers
*/
typedef enum {
PSR_IG_STREAM_ID = 0,
PSR_PRIMARY_AUDIO_ID = 1,
PSR_PG_PIP_STREAM = 2,
PSR_ANGLE_ID = 3,
PSR_TITLE_ID = 4,
PSR_CHAPTER = 5,
PSR_PLAYLIST = 6,
PSR_PLAYITEM = 7,
PSR_TIME = 8, /* presetation time */
PSR_NAV_TIMER = 9,
PSR_SELECTED_BUTTON_ID = 10,
PSR_MENU_PAGE_ID = 11,
PSR_STYLE = 12,
PSR_PARENTAL = 13,
PSR_SECONDARY_AUDIO_VIDEO = 14,
PSR_AUDIO_CAP = 15,
PSR_AUDIO_LANG = 16,
PSR_PG_AND_SUB_LANG = 17,
PSR_MENU_LANG = 18,
PSR_COUNTRY = 19,
PSR_REGION = 20,
PSR_VIDEO_CAP = 29,
PSR_TEXT_CAP = 30, /* text subtitles */
PSR_PROFILE_VERSION = 31, /* player profile and version */
PSR_BACKUP_PSR4 = 36,
PSR_BACKUP_PSR5 = 37,
PSR_BACKUP_PSR6 = 38,
PSR_BACKUP_PSR7 = 39,
PSR_BACKUP_PSR8 = 40,
PSR_BACKUP_PSR10 = 42,
PSR_BACKUP_PSR11 = 43,
PSR_BACKUP_PSR12 = 44,
/* 48-61: caps for characteristic text subtitle */
} bd_psr_idx;
/*
*
*/
typedef struct bd_registers_s BD_REGISTERS;
BD_REGISTERS *bd_registers_init(void);
void bd_registers_free(BD_REGISTERS *);
int bd_psr_setting_write(BD_REGISTERS *, int reg, uint32_t val);
int bd_psr_write(BD_REGISTERS *, int reg, uint32_t val);
uint32_t bd_psr_read(BD_REGISTERS *, int reg);
void bd_psr_save_state(BD_REGISTERS *);
void bd_psr_restore_state(BD_REGISTERS *);
int bd_gpr_write(BD_REGISTERS *, int reg, uint32_t val);
uint32_t bd_gpr_read(BD_REGISTERS *, int reg);
/*
* Events when PSR value is changed
*/
#define BD_PSR_CHANGE 1
#define BD_PSR_RESTORE 2
typedef struct {
int ev_type;
int psr_idx;
uint32_t old_val;
uint32_t new_val;
} BD_PSR_EVENT;
void bd_psr_register_cb (BD_REGISTERS *, void (*callback)(void*,BD_PSR_EVENT*), void *cb_handle);
void bd_psr_unregister_cb(BD_REGISTERS *, void (*callback)(void*,BD_PSR_EVENT*), void *cb_handle);
#endif /* _BD_REGISTER_H_ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment