Skip to content

Commit

Permalink
libmythbluray: Upstream updates.
Browse files Browse the repository at this point in the history
* Be noisy when bd_play_title() or bd_menu_call() is misused
* Handle PSR restore events (restore stored playback position)
* Store current playback location when entering top menu
* bd_psr_restore_state(): call PSR changed callback for all restored registers (even if register value does not change)
* hdmv_vm_suspend_pl(): verify object is suspended because of playlist playback
* HDMV: free possible IG object when resuming suspended object
* HDMV: Verify title number before executing JUMP_TITLE / CALL_TITLE
  • Loading branch information
Robert McNamara committed May 3, 2011
1 parent 6db2c5e commit 4ec47f8
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 12 deletions.
47 changes: 44 additions & 3 deletions mythtv/libs/libmythbluray/bluray.c
Expand Up @@ -1686,6 +1686,43 @@ static void _process_psr_event(void *handle, BD_PSR_EVENT *ev)
{
BLURAY *bd = (BLURAY*)handle;

/* PSR restore events are handled internally */

if (ev->ev_type == BD_PSR_RESTORE) {

BD_DEBUG(DBG_BLURAY, "PSR RESTORE event %d %d (%p)\n", ev->psr_idx, ev->new_val, bd);

/* Restore stored playback position */

switch (ev->psr_idx) {
case PSR_ANGLE_NUMBER:
/* can't set angle before playlist is opened */
return;
case PSR_TITLE_NUMBER:
/* pass to the application */
break;
case PSR_CHAPTER:
/* will be selected automatically */
return;
case PSR_PLAYLIST:
bd_select_playlist(bd, ev->new_val);
nav_set_angle(bd->title, bd->st0.clip, bd_psr_read(bd->regs, PSR_ANGLE_NUMBER) - 1);
return;
case PSR_PLAYITEM:
bd_seek_playitem(bd, ev->new_val);
return;
case PSR_TIME:
bd_seek_time(bd, ((int64_t)ev->new_val) << 1);
return;
case PSR_SELECTED_BUTTON_ID:
case PSR_MENU_PAGE_ID:
/* TODO: need to inform graphics controller ? */
default:
/* others: ignore */
return;
}
}

BD_DEBUG(DBG_BLURAY, "PSR event %d %d (%p)\n", ev->psr_idx, ev->new_val, bd);

switch (ev->psr_idx) {
Expand Down Expand Up @@ -1782,7 +1819,7 @@ static int _play_hdmv(BLURAY *bd, unsigned id_ref)
#endif

if (!bd->hdmv_vm) {
bd->hdmv_vm = hdmv_vm_init(bd->device_path, bd->regs);
bd->hdmv_vm = hdmv_vm_init(bd->device_path, bd->regs, bd->index);
}

if (hdmv_vm_select_object(bd->hdmv_vm, id_ref)) {
Expand Down Expand Up @@ -1883,7 +1920,7 @@ int bd_play(BLURAY *bd)
int bd_play_title(BLURAY *bd, unsigned title)
{
if (bd->title_type == title_undef && title != BLURAY_TITLE_FIRST_PLAY) {
// bd_play not called
BD_DEBUG(DBG_BLURAY|DBG_CRIT, "bd_play_title(): bd_play() not called\n");
return 0;
}

Expand All @@ -1904,7 +1941,7 @@ int bd_menu_call(BLURAY *bd, int64_t pts)
}

if (bd->title_type == title_undef) {
// bd_play not called
BD_DEBUG(DBG_BLURAY|DBG_CRIT, "bd_menu_call(): bd_play() not called\n");
return 0;
}

Expand All @@ -1913,6 +1950,10 @@ int bd_menu_call(BLURAY *bd, int64_t pts)
BD_DEBUG(DBG_BLURAY|DBG_CRIT, "menu call masked by movie object\n");
return 0;
}

if (hdmv_vm_suspend_pl(bd->hdmv_vm) < 0) {
BD_DEBUG(DBG_BLURAY|DBG_CRIT, "bd_menu_call(): error storing playback location\n");
}
}

return _play_title(bd, BLURAY_TITLE_TOP_MENU);
Expand Down
65 changes: 59 additions & 6 deletions mythtv/libs/libmythbluray/hdmv/hdmv_vm.c
Expand Up @@ -23,6 +23,7 @@
#include "hdmv_insn.h"
#include "../register.h"

#include "../bdnav/index_parse.h"
#include "util/macro.h"
#include "util/strutl.h"
#include "util/logging.h"
Expand Down Expand Up @@ -58,6 +59,9 @@ struct hdmv_vm_s {
/* suspended object */
MOBJ_OBJECT *suspended_object;
int suspended_pc;

/* disc index (used to verify CALL_TITLE/JUMP_TITLE) */
INDX_ROOT *indx;
};

/*
Expand Down Expand Up @@ -231,7 +235,7 @@ static int _queue_event(HDMV_VM *p, uint32_t event, uint32_t param)
* vm init
*/

HDMV_VM *hdmv_vm_init(const char *disc_root, BD_REGISTERS *regs)
HDMV_VM *hdmv_vm_init(const char *disc_root, BD_REGISTERS *regs, INDX_ROOT *indx)
{
HDMV_VM *p = calloc(1, sizeof(HDMV_VM));
char *file;
Expand All @@ -246,6 +250,7 @@ HDMV_VM *hdmv_vm_init(const char *disc_root, BD_REGISTERS *regs)
}

p->regs = regs;
p->indx = indx;

bd_mutex_init(&p->mutex);

Expand Down Expand Up @@ -278,6 +283,22 @@ void hdmv_vm_free(HDMV_VM **p)
* suspend/resume ("function call")
*/

static int _suspended_at_play_pl(HDMV_VM *p)
{
int play_pl = 0;
if (p && p->suspended_object) {
MOBJ_CMD *cmd = &p->suspended_object->cmds[p->suspended_pc];
HDMV_INSN *insn = &cmd->insn;
play_pl = (insn->grp == INSN_GROUP_BRANCH &&
insn->sub_grp == BRANCH_PLAY &&
( insn->branch_opt == INSN_PLAY_PL ||
insn->branch_opt == INSN_PLAY_PL_PI ||
insn->branch_opt == INSN_PLAY_PL_PM));
}

return play_pl;
}

static void _suspend_object(HDMV_VM *p, int psr_backup)
{
BD_DEBUG(DBG_HDMV, "_suspend_object()\n");
Expand All @@ -304,6 +325,8 @@ static int _resume_object(HDMV_VM *p, int psr_restore)
return -1;
}

_free_ig_object(p);

p->object = p->suspended_object;
p->pc = p->suspended_pc + 1;

Expand All @@ -323,6 +346,21 @@ static int _resume_object(HDMV_VM *p, int psr_restore)
* branching
*/

static int _is_valid_title(HDMV_VM *p, int title)
{
if (title == 0 || title == 0xffff) {
INDX_PLAY_ITEM *pi = (!title) ? &p->indx->top_menu : &p->indx->first_play;

if (pi->object_type == indx_object_type_hdmv && pi->hdmv.id_ref == 0xffff) {
/* no top menu or first play title (5.2.3.3) */
return 0;
}
return 1;
}

return title > 0 && title <= p->indx->num_titles;
}

static int _jump_object(HDMV_VM *p, int object)
{
if (object < 0 || object >= p->movie_objects->num_objects) {
Expand All @@ -344,7 +382,7 @@ static int _jump_object(HDMV_VM *p, int object)

static int _jump_title(HDMV_VM *p, int title)
{
if (title >= 0 && title <= 0xffff) {
if (_is_valid_title(p, title)) {
BD_DEBUG(DBG_HDMV, "_jump_title(%d)\n", title);

/* discard suspended object */
Expand All @@ -371,7 +409,7 @@ static int _call_object(HDMV_VM *p, int object)

static int _call_title(HDMV_VM *p, int title)
{
if (title >= 0 && title <= 0xffff) {
if (_is_valid_title(p, title)) {
BD_DEBUG(DBG_HDMV, "_call_title(%d)\n", title);

_suspend_object(p, 1);
Expand Down Expand Up @@ -974,13 +1012,28 @@ int hdmv_vm_resume(HDMV_VM *p)
return result;
}

int hdmv_vm_suspend(HDMV_VM *p)
int hdmv_vm_suspend_pl(HDMV_VM *p)
{
int result = -1;
bd_mutex_lock(&p->mutex);

if (p->object && !p->ig_object) {
_suspend_object(p, 1);
if (p->object || p->ig_object) {
BD_DEBUG(DBG_HDMV, "hdmv_vm_suspend_pl(): HDMV VM is still running\n");

} else if (!p->suspended_object) {
BD_DEBUG(DBG_HDMV, "hdmv_vm_suspend_pl(): No suspended object\n");

} else if (!_suspended_at_play_pl(p)) {
BD_DEBUG(DBG_HDMV, "hdmv_vm_suspend_pl(): Object is not playing playlist\n");

} else if (!p->suspended_object->resume_intention_flag) {
BD_DEBUG(DBG_HDMV, "hdmv_vm_suspend_pl(): no resume intention flag\n");

p->suspended_object = NULL;
result = 0;

} else {
bd_psr_save_state(p->regs);
result = 0;
}

Expand Down
33 changes: 31 additions & 2 deletions mythtv/libs/libmythbluray/hdmv/hdmv_vm.h
Expand Up @@ -58,14 +58,15 @@ typedef struct hdmv_vm_event_s {
*/

struct bd_registers_s;
struct indx_root_s;

/*
*
*/

typedef struct hdmv_vm_s HDMV_VM;

BD_PRIVATE HDMV_VM *hdmv_vm_init(const char *disc_root, struct bd_registers_s *regs);
BD_PRIVATE HDMV_VM *hdmv_vm_init(const char *disc_root, struct bd_registers_s *regs, struct indx_root_s *indx);
BD_PRIVATE void hdmv_vm_free(HDMV_VM **p);

BD_PRIVATE int hdmv_vm_select_object(HDMV_VM *p, int object);
Expand All @@ -79,7 +80,35 @@ BD_PRIVATE int hdmv_vm_running(HDMV_VM *p);
#define HDMV_TITLE_SEARCH_MASK 0x02
BD_PRIVATE uint32_t hdmv_vm_get_uo_mask(HDMV_VM *p);

BD_PRIVATE int hdmv_vm_suspend(HDMV_VM *p);
/**
*
* Suspend playlist playback
*
* This function assumes playlist is currently playing and
* movie object execution is suspended at PLAY_PL instruction.
*
* If resume_intention_flag of current movie object is 1:
* Copy playback position PSRs to backup registers
* (suspend playlist playback at current position)
* If resume_intention_flag of current movie object is 0:
* Discard current movie object
*
* @param p HDMV_VM object
* @return 0 on success, -1 if error
*/
BD_PRIVATE int hdmv_vm_suspend_pl(HDMV_VM *p);

/**
*
* Resume HDMV execution
*
* Continue execution of movie object after playlist playback.
* Do not restore backup PSRs.
* This function is called when playlist playback ends.
*
* @param p HDMV_VM object
* @return 0 on success, -1 if error
*/
BD_PRIVATE int hdmv_vm_resume(HDMV_VM *p);

#endif // _HDMV_VM_H_
2 changes: 1 addition & 1 deletion mythtv/libs/libmythbluray/register.c
Expand Up @@ -291,7 +291,7 @@ void bd_psr_restore_state(BD_REGISTERS *p)
ev.ev_type = BD_PSR_RESTORE;

for (i = 4; i < 13; i++) {
if (i != 9 && old_psr[i] != p->psr[i]) {
if (i != 9) {

ev.psr_idx = i;
ev.old_val = old_psr[i];
Expand Down

0 comments on commit 4ec47f8

Please sign in to comment.