|
Packit |
5e46da |
/*
|
|
Packit |
5e46da |
* This file is part of libbluray
|
|
Packit |
5e46da |
* Copyright (C) 2010-2017 Petri Hintukainen <phintuka@users.sourceforge.net>
|
|
Packit |
5e46da |
*
|
|
Packit |
5e46da |
* This library is free software; you can redistribute it and/or
|
|
Packit |
5e46da |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit |
5e46da |
* License as published by the Free Software Foundation; either
|
|
Packit |
5e46da |
* version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
5e46da |
*
|
|
Packit |
5e46da |
* This library is distributed in the hope that it will be useful,
|
|
Packit |
5e46da |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
5e46da |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
5e46da |
* Lesser General Public License for more details.
|
|
Packit |
5e46da |
*
|
|
Packit |
5e46da |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
5e46da |
* License along with this library. If not, see
|
|
Packit |
5e46da |
* <http://www.gnu.org/licenses/>.
|
|
Packit |
5e46da |
*/
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
#if HAVE_CONFIG_H
|
|
Packit |
5e46da |
#include "config.h"
|
|
Packit |
5e46da |
#endif
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
#include "register.h"
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
#include "player_settings.h"
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
#include "util/attributes.h"
|
|
Packit |
5e46da |
#include "util/macro.h"
|
|
Packit |
5e46da |
#include "util/logging.h"
|
|
Packit |
5e46da |
#include "util/mutex.h"
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
#include <stdlib.h>
|
|
Packit |
5e46da |
#include <string.h>
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
/*
|
|
Packit |
5e46da |
* Initial values for player status/setting registers (5.8.2).
|
|
Packit |
5e46da |
*
|
|
Packit |
5e46da |
* PS in comment indicates player setting -> register can't be changed from movie object code.
|
|
Packit |
5e46da |
*/
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
static const uint32_t bd_psr_init[BD_PSR_COUNT] = {
|
|
Packit |
5e46da |
1, /* PSR0: Interactive graphics stream number */
|
|
Packit |
5e46da |
0xff, /* PSR1: Primary audio stream number */
|
|
Packit |
5e46da |
0x0fff0fff, /* PSR2: PG TextST stream number and PiP PG stream number*/
|
|
Packit |
5e46da |
1, /* PSR3: Angle number */
|
|
Packit |
5e46da |
0xffff, /* PSR4: Title number */
|
|
Packit |
5e46da |
0xffff, /* PSR5: Chapter number */
|
|
Packit |
5e46da |
0, /* PSR6: PlayList ID */
|
|
Packit |
5e46da |
0, /* PSR7: PlayItem ID */
|
|
Packit |
5e46da |
0, /* PSR8: Presentation time */
|
|
Packit |
5e46da |
0, /* PSR9: Navigation timer */
|
|
Packit |
5e46da |
0xffff, /* PSR10: Selected button ID */
|
|
Packit |
5e46da |
0, /* PSR11: Page ID */
|
|
Packit |
5e46da |
0xff, /* PSR12: User style number */
|
|
Packit |
5e46da |
0xff, /* PS: PSR13: User age */
|
|
Packit |
5e46da |
0xffff, /* PSR14: Secondary audio stream number and secondary video stream number */
|
|
Packit |
5e46da |
/* PS: PSR15: player capability for audio */
|
|
Packit |
5e46da |
BLURAY_ACAP_LPCM_48_96_SURROUND |
|
|
Packit |
5e46da |
BLURAY_ACAP_LPCM_192_SURROUND |
|
|
Packit |
5e46da |
BLURAY_ACAP_DDPLUS_SURROUND |
|
|
Packit |
5e46da |
BLURAY_ACAP_DDPLUS_DEP_SURROUND |
|
|
Packit |
5e46da |
BLURAY_ACAP_DTSHD_CORE_SURROUND |
|
|
Packit |
5e46da |
BLURAY_ACAP_DTSHD_EXT_SURROUND |
|
|
Packit |
5e46da |
BLURAY_ACAP_DD_SURROUND |
|
|
Packit |
5e46da |
BLURAY_ACAP_MLP_SURROUND,
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
0xffffff, /* PS: PSR16: Language code for audio */
|
|
Packit |
5e46da |
0xffffff, /* PS: PSR17: Language code for PG and Text subtitles */
|
|
Packit |
5e46da |
0xffffff, /* PS: PSR18: Menu description language code */
|
|
Packit |
5e46da |
0xffff, /* PS: PSR19: Country code */
|
|
Packit |
5e46da |
/* PS: PSR20: Region code */ /* 1 - A, 2 - B, 4 - C */
|
|
Packit |
5e46da |
BLURAY_REGION_B,
|
|
Packit |
5e46da |
/* PS: PSR21: Output mode preference */
|
|
Packit |
5e46da |
BLURAY_OUTPUT_PREFER_2D,
|
|
Packit |
5e46da |
0, /* PSR22: Stereoscopic status */
|
|
Packit |
5e46da |
0, /* PS: PSR23: Display capability */
|
|
Packit |
5e46da |
0, /* PS: PSR24: 3D capability */
|
|
Packit |
5e46da |
0, /* PS: PSR25: UHD capability */
|
|
Packit |
5e46da |
0, /* PS: PSR26: UHD display capability */
|
|
Packit |
5e46da |
0, /* PS: PSR27: HDR preference */
|
|
Packit |
5e46da |
0, /* PS: PSR28: SDR conversion preference */
|
|
Packit |
5e46da |
/* PS: PSR29: player capability for video */
|
|
Packit |
5e46da |
BLURAY_VCAP_SECONDARY_HD |
|
|
Packit |
5e46da |
BLURAY_VCAP_25Hz_50Hz,
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
0x1ffff, /* PS: PSR30: player capability for text subtitle */
|
|
Packit |
5e46da |
/* PS: PSR31: Player profile and version */
|
|
Packit |
5e46da |
BLURAY_PLAYER_PROFILE_2_v2_0,
|
|
Packit |
5e46da |
0, /* PSR32 */
|
|
Packit |
5e46da |
0, /* PSR33 */
|
|
Packit |
5e46da |
0, /* PSR34 */
|
|
Packit |
5e46da |
0, /* PSR35 */
|
|
Packit |
5e46da |
0xffff, /* PSR36: backup PSR4 */
|
|
Packit |
5e46da |
0xffff, /* PSR37: backup PSR5 */
|
|
Packit |
5e46da |
0, /* PSR38: backup PSR6 */
|
|
Packit |
5e46da |
0, /* PSR39: backup PSR7 */
|
|
Packit |
5e46da |
0, /* PSR40: backup PSR8 */
|
|
Packit |
5e46da |
0, /* PSR41: */
|
|
Packit |
5e46da |
0xffff, /* PSR42: backup PSR10 */
|
|
Packit |
5e46da |
0, /* PSR43: backup PSR11 */
|
|
Packit |
5e46da |
0xff, /* PSR44: backup PSR12 */
|
|
Packit |
5e46da |
0, /* PSR45: */
|
|
Packit |
5e46da |
0, /* PSR46: */
|
|
Packit |
5e46da |
0, /* PSR47: */
|
|
Packit |
5e46da |
0xffffffff, /* PS: PSR48: Characteristic text caps */
|
|
Packit |
5e46da |
0xffffffff, /* PS: PSR49: Characteristic text caps */
|
|
Packit |
5e46da |
0xffffffff, /* PS: PSR50: Characteristic text caps */
|
|
Packit |
5e46da |
0xffffffff, /* PS: PSR51: Characteristic text caps */
|
|
Packit |
5e46da |
0xffffffff, /* PS: PSR52: Characteristic text caps */
|
|
Packit |
5e46da |
0xffffffff, /* PS: PSR53: Characteristic text caps */
|
|
Packit |
5e46da |
0xffffffff, /* PS: PSR54: Characteristic text caps */
|
|
Packit |
5e46da |
0xffffffff, /* PS: PSR55: Characteristic text caps */
|
|
Packit |
5e46da |
0xffffffff, /* PS: PSR56: Characteristic text caps */
|
|
Packit |
5e46da |
0xffffffff, /* PS: PSR57: Characteristic text caps */
|
|
Packit |
5e46da |
0xffffffff, /* PS: PSR58: Characteristic text caps */
|
|
Packit |
5e46da |
0xffffffff, /* PS: PSR59: Characteristic text caps */
|
|
Packit |
5e46da |
0xffffffff, /* PS: PSR60: Characteristic text caps */
|
|
Packit |
5e46da |
0xffffffff, /* PS: PSR61: Characteristic text caps */
|
|
Packit |
5e46da |
/* 62-95: reserved */
|
|
Packit |
5e46da |
/* 96-111: reserved for BD system use */
|
|
Packit |
5e46da |
/* 112-127: reserved */
|
|
Packit |
5e46da |
};
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
/*
|
|
Packit |
5e46da |
* PSR ids for debugging
|
|
Packit |
5e46da |
*/
|
|
Packit |
5e46da |
static const char * const bd_psr_name[BD_PSR_COUNT] = {
|
|
Packit |
5e46da |
"IG_STREAM_ID",
|
|
Packit |
5e46da |
"PRIMARY_AUDIO_ID",
|
|
Packit |
5e46da |
"PG_STREAM",
|
|
Packit |
5e46da |
"ANGLE_NUMBER",
|
|
Packit |
5e46da |
"TITLE_NUMBER",
|
|
Packit |
5e46da |
"CHAPTER",
|
|
Packit |
5e46da |
"PLAYLIST",
|
|
Packit |
5e46da |
"PLAYITEM",
|
|
Packit |
5e46da |
"TIME",
|
|
Packit |
5e46da |
"NAV_TIMER",
|
|
Packit |
5e46da |
"SELECTED_BUTTON_ID",
|
|
Packit |
5e46da |
"MENU_PAGE_ID",
|
|
Packit |
5e46da |
"STYLE",
|
|
Packit |
5e46da |
"PARENTAL",
|
|
Packit |
5e46da |
"SECONDARY_AUDIO_VIDEO",
|
|
Packit |
5e46da |
"AUDIO_CAP",
|
|
Packit |
5e46da |
"AUDIO_LANG",
|
|
Packit |
5e46da |
"PG_AND_SUB_LANG",
|
|
Packit |
5e46da |
"MENU_LANG",
|
|
Packit |
5e46da |
"COUNTRY",
|
|
Packit |
5e46da |
"REGION",
|
|
Packit |
5e46da |
"OUTPUT_PREFER",
|
|
Packit |
5e46da |
"3D_STATUS",
|
|
Packit |
5e46da |
"DISPLAY_CAP",
|
|
Packit |
5e46da |
"3D_CAP",
|
|
Packit |
5e46da |
//"PSR_VIDEO_CAP",
|
|
Packit |
5e46da |
};
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
/*
|
|
Packit |
5e46da |
* data
|
|
Packit |
5e46da |
*/
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
typedef struct {
|
|
Packit |
5e46da |
void *handle;
|
|
Packit |
5e46da |
void (*cb)(void *, BD_PSR_EVENT*);
|
|
Packit |
5e46da |
} PSR_CB_DATA;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
struct bd_registers_s
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
uint32_t psr[BD_PSR_COUNT];
|
|
Packit |
5e46da |
uint32_t gpr[BD_GPR_COUNT];
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
/* callbacks */
|
|
Packit |
5e46da |
unsigned num_cb;
|
|
Packit |
5e46da |
PSR_CB_DATA *cb;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
BD_MUTEX mutex;
|
|
Packit |
5e46da |
};
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
/*
|
|
Packit |
5e46da |
* init / free
|
|
Packit |
5e46da |
*/
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
BD_REGISTERS *bd_registers_init(void)
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
BD_REGISTERS *p = calloc(1, sizeof(BD_REGISTERS));
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
if (p) {
|
|
Packit |
5e46da |
memcpy(p->psr, bd_psr_init, sizeof(bd_psr_init));
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bd_mutex_init(&p->mutex);
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
return p;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
void bd_registers_free(BD_REGISTERS *p)
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
if (p) {
|
|
Packit |
5e46da |
bd_mutex_destroy(&p->mutex);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
X_FREE(p->cb);
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
X_FREE(p);
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
/*
|
|
Packit |
5e46da |
* PSR lock / unlock
|
|
Packit |
5e46da |
*/
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
void bd_psr_lock(BD_REGISTERS *p)
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
bd_mutex_lock(&p->mutex);
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
void bd_psr_unlock(BD_REGISTERS *p)
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
bd_mutex_unlock(&p->mutex);
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
/*
|
|
Packit |
5e46da |
* PSR change callback register / unregister
|
|
Packit |
5e46da |
*/
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
void bd_psr_register_cb (BD_REGISTERS *p, void (*callback)(void*,BD_PSR_EVENT*), void *cb_handle)
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
/* no duplicates ! */
|
|
Packit |
5e46da |
PSR_CB_DATA *cb;
|
|
Packit |
5e46da |
unsigned i;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bd_psr_lock(p);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
for (i = 0; i < p->num_cb; i++) {
|
|
Packit |
5e46da |
if (p->cb[i].handle == cb_handle && p->cb[i].cb == callback) {
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bd_psr_unlock(p);
|
|
Packit |
5e46da |
return;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
cb = realloc(p->cb, (p->num_cb + 1) * sizeof(PSR_CB_DATA));
|
|
Packit |
5e46da |
if (cb) {
|
|
Packit |
5e46da |
p->cb = cb;
|
|
Packit |
5e46da |
p->cb[p->num_cb].cb = callback;
|
|
Packit |
5e46da |
p->cb[p->num_cb].handle = cb_handle;
|
|
Packit |
5e46da |
p->num_cb++;
|
|
Packit |
5e46da |
} else {
|
|
Packit |
5e46da |
BD_DEBUG(DBG_BLURAY|DBG_CRIT, "bd_psr_register_cb(): realloc failed\n");
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bd_psr_unlock(p);
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
void bd_psr_unregister_cb(BD_REGISTERS *p, void (*callback)(void*,BD_PSR_EVENT*), void *cb_handle)
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
unsigned i = 0;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bd_psr_lock(p);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
while (i < p->num_cb) {
|
|
Packit |
5e46da |
if (p->cb[i].handle == cb_handle && p->cb[i].cb == callback) {
|
|
Packit |
5e46da |
if (--p->num_cb && i < p->num_cb) {
|
|
Packit |
5e46da |
memmove(p->cb + i, p->cb + i + 1, sizeof(PSR_CB_DATA) * (p->num_cb - i));
|
|
Packit |
5e46da |
continue;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
i++;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bd_psr_unlock(p);
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
/*
|
|
Packit |
5e46da |
* PSR state save / restore
|
|
Packit |
5e46da |
*/
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
void bd_psr_save_state(BD_REGISTERS *p)
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
/* store registers 4-8 and 10-12 to backup registers */
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bd_psr_lock(p);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
memcpy(p->psr + 36, p->psr + 4, sizeof(uint32_t) * 5);
|
|
Packit |
5e46da |
memcpy(p->psr + 42, p->psr + 10, sizeof(uint32_t) * 3);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
/* generate save event */
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
if (p->num_cb) {
|
|
Packit |
5e46da |
BD_PSR_EVENT ev;
|
|
Packit |
5e46da |
ev.ev_type = BD_PSR_SAVE;
|
|
Packit |
5e46da |
ev.psr_idx = -1;
|
|
Packit |
5e46da |
ev.old_val = 0;
|
|
Packit |
5e46da |
ev.new_val = 0;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
unsigned j;
|
|
Packit |
5e46da |
for (j = 0; j < p->num_cb; j++) {
|
|
Packit |
5e46da |
p->cb[j].cb(p->cb[j].handle, &ev;;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bd_psr_unlock(p);
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
void bd_psr_reset_backup_registers(BD_REGISTERS *p)
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
bd_psr_lock(p);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
/* init backup registers to default */
|
|
Packit |
5e46da |
memcpy(p->psr + 36, bd_psr_init + 36, sizeof(uint32_t) * 5);
|
|
Packit |
5e46da |
memcpy(p->psr + 42, bd_psr_init + 42, sizeof(uint32_t) * 3);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bd_psr_unlock(p);
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
void bd_psr_restore_state(BD_REGISTERS *p)
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
uint32_t old_psr[13];
|
|
Packit |
5e46da |
uint32_t new_psr[13];
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bd_psr_lock(p);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
if (p->num_cb) {
|
|
Packit |
5e46da |
memcpy(old_psr, p->psr, sizeof(old_psr[0]) * 13);
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
/* restore backup registers */
|
|
Packit |
5e46da |
memcpy(p->psr + 4, p->psr + 36, sizeof(uint32_t) * 5);
|
|
Packit |
5e46da |
memcpy(p->psr + 10, p->psr + 42, sizeof(uint32_t) * 3);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
if (p->num_cb) {
|
|
Packit |
5e46da |
memcpy(new_psr, p->psr, sizeof(new_psr[0]) * 13);
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
/* init backup registers to default */
|
|
Packit |
5e46da |
memcpy(p->psr + 36, bd_psr_init + 36, sizeof(uint32_t) * 5);
|
|
Packit |
5e46da |
memcpy(p->psr + 42, bd_psr_init + 42, sizeof(uint32_t) * 3);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
/* generate restore events */
|
|
Packit |
5e46da |
if (p->num_cb) {
|
|
Packit |
5e46da |
BD_PSR_EVENT ev;
|
|
Packit |
5e46da |
unsigned i, j;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
ev.ev_type = BD_PSR_RESTORE;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
for (i = 4; i < 13; i++) {
|
|
Packit |
5e46da |
if (i != PSR_NAV_TIMER) {
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
ev.psr_idx = i;
|
|
Packit |
5e46da |
ev.old_val = old_psr[i];
|
|
Packit |
5e46da |
ev.new_val = new_psr[i];
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
for (j = 0; j < p->num_cb; j++) {
|
|
Packit |
5e46da |
p->cb[j].cb(p->cb[j].handle, &ev;;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bd_psr_unlock(p);
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
/*
|
|
Packit |
5e46da |
* GPR read / write
|
|
Packit |
5e46da |
*/
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
int bd_gpr_write(BD_REGISTERS *p, unsigned int reg, uint32_t val)
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
if (reg >= BD_GPR_COUNT) {
|
|
Packit |
5e46da |
BD_DEBUG(DBG_BLURAY, "bd_gpr_write(%d): invalid register\n", reg);
|
|
Packit |
5e46da |
return -1;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
p->gpr[reg] = val;
|
|
Packit |
5e46da |
return 0;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
uint32_t bd_gpr_read(BD_REGISTERS *p, unsigned int reg)
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
if (reg >= BD_GPR_COUNT) {
|
|
Packit |
5e46da |
BD_DEBUG(DBG_BLURAY, "bd_gpr_read(%d): invalid register\n", reg);
|
|
Packit |
5e46da |
return 0;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
return p->gpr[reg];
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
/*
|
|
Packit |
5e46da |
* PSR read / write
|
|
Packit |
5e46da |
*/
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
uint32_t bd_psr_read(BD_REGISTERS *p, unsigned int reg)
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
uint32_t val;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
if (reg >= BD_PSR_COUNT) {
|
|
Packit |
5e46da |
BD_DEBUG(DBG_BLURAY, "bd_psr_read(%d): invalid register\n", reg);
|
|
Packit |
5e46da |
return -1;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bd_psr_lock(p);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
val = p->psr[reg];
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bd_psr_unlock(p);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
return val;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
int bd_psr_setting_write(BD_REGISTERS *p, unsigned int reg, uint32_t val)
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
if (reg >= BD_PSR_COUNT) {
|
|
Packit |
5e46da |
BD_DEBUG(DBG_BLURAY, "bd_psr_write(%d, %d): invalid register\n", reg, val);
|
|
Packit |
5e46da |
return -1;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bd_psr_lock(p);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
if (p->psr[reg] == val) {
|
|
Packit |
5e46da |
BD_DEBUG(DBG_BLURAY, "bd_psr_write(%d, %d): no change in value\n", reg, val);
|
|
Packit |
5e46da |
} else if (bd_psr_name[reg]) {
|
|
Packit |
5e46da |
BD_DEBUG(DBG_BLURAY, "bd_psr_write(): PSR%-4d (%s) 0x%x -> 0x%x\n", reg, bd_psr_name[reg], p->psr[reg], val);
|
|
Packit |
5e46da |
} else {
|
|
Packit |
5e46da |
BD_DEBUG(DBG_BLURAY, "bd_psr_write(): PSR%-4d 0x%x -> 0x%x\n", reg, p->psr[reg], val);
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
if (p->num_cb) {
|
|
Packit |
5e46da |
BD_PSR_EVENT ev;
|
|
Packit |
5e46da |
unsigned i;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
ev.ev_type = p->psr[reg] == val ? BD_PSR_WRITE : BD_PSR_CHANGE;
|
|
Packit |
5e46da |
ev.psr_idx = reg;
|
|
Packit |
5e46da |
ev.old_val = p->psr[reg];
|
|
Packit |
5e46da |
ev.new_val = val;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
p->psr[reg] = val;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
for (i = 0; i < p->num_cb; i++) {
|
|
Packit |
5e46da |
p->cb[i].cb(p->cb[i].handle, &ev;;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
} else {
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
p->psr[reg] = val;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bd_psr_unlock(p);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
return 0;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
int bd_psr_write(BD_REGISTERS *p, unsigned int reg, uint32_t val)
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
if ((reg == 13) ||
|
|
Packit |
5e46da |
(reg >= 15 && reg <= 21) ||
|
|
Packit |
5e46da |
(reg >= 23 && reg <= 31) ||
|
|
Packit |
5e46da |
(reg >= 48 && reg <= 61)) {
|
|
Packit |
5e46da |
BD_DEBUG(DBG_BLURAY | DBG_CRIT, "bd_psr_write(%d, %d): read-only register !\n", reg, val);
|
|
Packit |
5e46da |
return -2;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
return bd_psr_setting_write(p, reg, val);
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
int bd_psr_write_bits(BD_REGISTERS *p, unsigned int reg, uint32_t val, uint32_t mask)
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
int result;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
if (mask == 0xffffffff) {
|
|
Packit |
5e46da |
return bd_psr_write(p, reg, val);
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bd_psr_lock(p);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
uint32_t psr_value = bd_psr_read(p, reg);
|
|
Packit |
5e46da |
psr_value = (psr_value & (~mask)) | (val & mask);
|
|
Packit |
5e46da |
result = bd_psr_write(p, reg, psr_value);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bd_psr_unlock(p);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
return result;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
/*
|
|
Packit |
5e46da |
* save / restore registers between playback sessions
|
|
Packit |
5e46da |
*/
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
void registers_save(BD_REGISTERS *p, uint32_t *psr, uint32_t *gpr)
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
bd_psr_lock(p);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
memcpy(gpr, p->gpr, sizeof(p->gpr));
|
|
Packit |
5e46da |
memcpy(psr, p->psr, sizeof(p->psr));
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bd_psr_unlock(p);
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
void registers_restore(BD_REGISTERS *p, const uint32_t *psr, const uint32_t *gpr)
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
uint32_t new_psr[13];
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bd_psr_lock(p);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
memcpy(p->gpr, gpr, sizeof(p->gpr));
|
|
Packit |
5e46da |
memcpy(p->psr, psr, sizeof(p->psr));
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
memcpy(new_psr, p->psr, sizeof(new_psr[0]) * 13);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
/* generate restore events */
|
|
Packit |
5e46da |
if (p->num_cb) {
|
|
Packit |
5e46da |
BD_PSR_EVENT ev;
|
|
Packit |
5e46da |
unsigned i, j;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
ev.ev_type = BD_PSR_RESTORE;
|
|
Packit |
5e46da |
ev.old_val = 0; /* not used with BD_PSR_RESTORE */
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
for (i = 4; i < 13; i++) {
|
|
Packit |
5e46da |
if (i != PSR_NAV_TIMER) {
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
p->psr[i] = new_psr[i];
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
ev.psr_idx = i;
|
|
Packit |
5e46da |
ev.new_val = new_psr[i];
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
for (j = 0; j < p->num_cb; j++) {
|
|
Packit |
5e46da |
p->cb[j].cb(p->cb[j].handle, &ev;;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bd_psr_unlock(p);
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
/*
|
|
Packit |
5e46da |
*
|
|
Packit |
5e46da |
*/
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
int psr_init_3D(BD_REGISTERS *p, int initial_mode, int force)
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
bd_psr_lock(p);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
/* make automatic initialization to fail if app has already changed player profile */
|
|
Packit |
5e46da |
if (!force) {
|
|
Packit |
5e46da |
if ((bd_psr_read(p, PSR_PROFILE_VERSION) & BLURAY_PLAYER_PROFILE_VERSION_MASK) >= 0x0300) {
|
|
Packit |
5e46da |
BD_DEBUG(DBG_BLURAY | DBG_CRIT, "psr_init_3D() failed: profile version already set to >= 0x0300 (profile 6)\n");
|
|
Packit |
5e46da |
bd_psr_unlock(p);
|
|
Packit |
5e46da |
return -1;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
if (bd_psr_read(p, PSR_PROFILE_VERSION) & BLURAY_PLAYER_PROFILE_3D_FLAG) {
|
|
Packit |
5e46da |
BD_DEBUG(DBG_BLURAY | DBG_CRIT, "psr_init_3D() failed: 3D already set in profile\n");
|
|
Packit |
5e46da |
bd_psr_unlock(p);
|
|
Packit |
5e46da |
return -1;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bd_psr_setting_write(p, PSR_OUTPUT_PREFER,
|
|
Packit |
5e46da |
BLURAY_OUTPUT_PREFER_3D);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bd_psr_setting_write(p, PSR_DISPLAY_CAP,
|
|
Packit |
5e46da |
BLURAY_DCAP_1080p_720p_3D |
|
|
Packit |
5e46da |
BLURAY_DCAP_720p_50Hz_3D |
|
|
Packit |
5e46da |
BLURAY_DCAP_NO_3D_CLASSES_REQUIRED |
|
|
Packit |
5e46da |
BLURAY_DCAP_INTERLACED_3D |
|
|
Packit |
5e46da |
0);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bd_psr_setting_write(p, PSR_3D_CAP,
|
|
Packit |
5e46da |
/* TODO */ 0xffffffff );
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bd_psr_setting_write(p, PSR_PROFILE_VERSION,
|
|
Packit |
5e46da |
BLURAY_PLAYER_PROFILE_5_v2_4);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bd_psr_write(p, PSR_3D_STATUS,
|
|
Packit |
5e46da |
!!initial_mode);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bd_psr_unlock(p);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
return 0;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
int psr_init_UHD(BD_REGISTERS *p, int force)
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
bd_psr_lock(p);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
/* make automatic initialization to fail if app has already changed player profile */
|
|
Packit |
5e46da |
if (!force) {
|
|
Packit |
5e46da |
if ((bd_psr_read(p, PSR_PROFILE_VERSION) & BLURAY_PLAYER_PROFILE_VERSION_MASK) >= 0x0300) {
|
|
Packit |
5e46da |
BD_DEBUG(DBG_BLURAY | DBG_CRIT, "psr_init_UHD() failed: profile version already >= 0x0300\n");
|
|
Packit |
5e46da |
bd_psr_unlock(p);
|
|
Packit |
5e46da |
return -1;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
if (bd_psr_read(p, PSR_PROFILE_VERSION) & BLURAY_PLAYER_PROFILE_3D_FLAG) {
|
|
Packit |
5e46da |
BD_DEBUG(DBG_BLURAY | DBG_CRIT, "psr_init_UHD() failed: 3D already set in profile\n");
|
|
Packit |
5e46da |
bd_psr_unlock(p);
|
|
Packit |
5e46da |
return -1;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bd_psr_setting_write(p, PSR_UHD_CAP,
|
|
Packit |
5e46da |
/* TODO */ 0xffffffff );
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bd_psr_setting_write(p, PSR_UHD_DISPLAY_CAP,
|
|
Packit |
5e46da |
/* TODO */ 0xffffffff );
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bd_psr_setting_write(p, PSR_UHD_HDR_PREFER,
|
|
Packit |
5e46da |
/* TODO */ 0xffffffff );
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bd_psr_setting_write(p, PSR_UHD_SDR_CONV_PREFER,
|
|
Packit |
5e46da |
/* TODO */ 0 );
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bd_psr_setting_write(p, PSR_PROFILE_VERSION,
|
|
Packit |
5e46da |
BLURAY_PLAYER_PROFILE_6_v3_1);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
bd_psr_unlock(p);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
return 0;
|
|
Packit |
5e46da |
}
|