[libbluray-devel] Separated HDMV suspend from suspension during playlist playback
hpi1
git at videolan.org
Thu Jun 23 17:24:22 CEST 2011
libbluray | branch: master | hpi1 <hpi1 at anonymous.org> | Thu Jun 23 18:08:57 2011 +0300| [1086a6ccbd00b2bd4ed856f54a3e96c341aba5de] | committer: hpi1
Separated HDMV suspend from suspension during playlist playback
> http://git.videolan.org/gitweb.cgi/libbluray.git/?a=commit;h=1086a6ccbd00b2bd4ed856f54a3e96c341aba5de
---
src/libbluray/hdmv/hdmv_vm.c | 120 ++++++++++++++++++++++++++++++++++++------
1 files changed, 104 insertions(+), 16 deletions(-)
diff --git a/src/libbluray/hdmv/hdmv_vm.c b/src/libbluray/hdmv/hdmv_vm.c
index 6e29235..715ed3a 100644
--- a/src/libbluray/hdmv/hdmv_vm.c
+++ b/src/libbluray/hdmv/hdmv_vm.c
@@ -56,6 +56,10 @@ struct hdmv_vm_s {
MOBJ_OBJECTS *movie_objects; /* disc movie objects */
MOBJ_OBJECT *ig_object; /* current object from IG stream */
+ /* object currently playing playlist */
+ MOBJ_OBJECT *playing_object;
+ int playing_pc;
+
/* suspended object */
MOBJ_OBJECT *suspended_object;
int suspended_pc;
@@ -299,6 +303,38 @@ static int _suspended_at_play_pl(HDMV_VM *p)
return play_pl;
}
+static int _suspend_for_play_pl(HDMV_VM *p)
+{
+ if (p->playing_object) {
+ BD_DEBUG(DBG_HDMV|DBG_CRIT, "_suspend_for_play_pl(): object already playing playlist !\n");
+ return -1;
+ }
+
+ p->playing_object = p->object;
+ p->playing_pc = p->pc;
+
+ p->object = NULL;
+
+ return 0;
+}
+
+static int _resume_from_play_pl(HDMV_VM *p)
+{
+ if (!p->playing_object) {
+ BD_DEBUG(DBG_HDMV|DBG_CRIT, "_resume_from_play_pl(): object not playing playlist !\n");
+ return -1;
+ }
+
+ p->object = p->playing_object;
+ p->pc = p->playing_pc + 1;
+
+ p->playing_object = NULL;
+
+ _free_ig_object(p);
+
+ return 0;
+}
+
static void _suspend_object(HDMV_VM *p, int psr_backup)
{
BD_DEBUG(DBG_HDMV, "_suspend_object()\n");
@@ -312,10 +348,31 @@ static void _suspend_object(HDMV_VM *p, int psr_backup)
bd_psr_save_state(p->regs);
}
- p->suspended_object = p->object;
- p->suspended_pc = p->pc;
+ if (p->ig_object) {
+ if (!p->playing_object) {
+ BD_DEBUG(DBG_HDMV|DBG_CRIT, "_suspend_object: IG object tries to suspend, no playing object !\n");
+ return;
+ }
+ p->suspended_object = p->playing_object;
+ p->suspended_pc = p->playing_pc;
+
+ p->playing_object = NULL;
+
+ } else {
+
+ if (p->playing_object) {
+ BD_DEBUG(DBG_HDMV|DBG_CRIT, "_suspend_object: Movie object tries to suspend, also playing object present !\n");
+ return;
+ }
+
+ p->suspended_object = p->object;
+ p->suspended_pc = p->pc;
+
+ }
p->object = NULL;
+
+ _free_ig_object(p);
}
static int _resume_object(HDMV_VM *p, int psr_restore)
@@ -325,19 +382,33 @@ static int _resume_object(HDMV_VM *p, int psr_restore)
return -1;
}
+ p->object = NULL;
+ p->playing_object = NULL;
_free_ig_object(p);
- p->object = p->suspended_object;
- p->pc = p->suspended_pc + 1;
-
if (psr_restore) {
+ /* check if suspended in play_pl */
+ if (_suspended_at_play_pl(p)) {
+ BD_DEBUG(DBG_HDMV, "resuming playlist playback\n");
+ p->playing_object = p->suspended_object;
+ p->playing_pc = p->suspended_pc;
+ p->suspended_object = NULL;
+ bd_psr_restore_state(p->regs);
+
+ return 0;
+ }
bd_psr_restore_state(p->regs);
}
- BD_DEBUG(DBG_HDMV, "resuming object %p at %d\n", p->object, p->pc + 1);
+ p->object = p->suspended_object;
+ p->pc = p->suspended_pc + 1;
p->suspended_object = NULL;
+ BD_DEBUG(DBG_HDMV, "resuming object %p at %d\n", p->object, p->pc);
+
+ _queue_event(p, HDMV_EVENT_PLAY_STOP, 0);
+
return 0;
}
@@ -370,8 +441,12 @@ static int _jump_object(HDMV_VM *p, int object)
BD_DEBUG(DBG_HDMV, "_jump_object(): jumping to object %d\n", object);
+ _queue_event(p, HDMV_EVENT_PLAY_STOP, 0);
+
_free_ig_object(p);
+ p->playing_object = NULL;
+
p->pc = 0;
p->object = &p->movie_objects->objects[object];
@@ -387,6 +462,7 @@ static int _jump_title(HDMV_VM *p, int title)
/* discard suspended object */
p->suspended_object = NULL;
+ p->playing_object = NULL;
bd_psr_reset_backup_registers(p->regs);
_queue_event(p, HDMV_EVENT_TITLE, title);
@@ -402,6 +478,7 @@ static int _call_object(HDMV_VM *p, int object)
{
BD_DEBUG(DBG_HDMV, "_call_object(%d)\n", object);
+ _queue_event(p, HDMV_EVENT_PLAY_STOP, 0);
_suspend_object(p, 1);
return _jump_object(p, object);
@@ -415,6 +492,7 @@ static int _call_title(HDMV_VM *p, int title)
_suspend_object(p, 1);
_queue_event(p, HDMV_EVENT_TITLE, title);
+
return 0;
}
@@ -448,7 +526,7 @@ static int _play_at(HDMV_VM *p, int playlist, int playitem, int playmark)
if (playlist >= 0) {
_queue_event(p, HDMV_EVENT_PLAY_PL, playlist);
- _suspend_object(p, 0);
+ _suspend_for_play_pl(p);
}
if (playitem >= 0) {
@@ -471,6 +549,7 @@ static int _play_stop(HDMV_VM *p)
BD_DEBUG(DBG_HDMV, "_play_stop()\n");
_queue_event(p, HDMV_EVENT_PLAY_STOP, 0);
+
return 0;
}
@@ -992,7 +1071,7 @@ uint32_t hdmv_vm_get_uo_mask(HDMV_VM *p)
bd_mutex_lock(&p->mutex);
- if ((o = p->object ? p->object : p->suspended_object)) {
+ if ((o = p->object ? p->object : (p->playing_object ? p->playing_object : p->suspended_object))) {
mask |= o->menu_call_mask;
mask |= o->title_search_mask << 1;
}
@@ -1006,7 +1085,7 @@ int hdmv_vm_resume(HDMV_VM *p)
int result;
bd_mutex_lock(&p->mutex);
- result = _resume_object(p, 0);
+ result = _resume_from_play_pl(p);
bd_mutex_unlock(&p->mutex);
return result;
@@ -1020,19 +1099,21 @@ int hdmv_vm_suspend_pl(HDMV_VM *p)
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 (!p->playing_object) {
+ BD_DEBUG(DBG_HDMV, "hdmv_vm_suspend_pl(): No playing 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) {
+ } else if (!p->playing_object->resume_intention_flag) {
BD_DEBUG(DBG_HDMV, "hdmv_vm_suspend_pl(): no resume intention flag\n");
- p->suspended_object = NULL;
+ p->playing_object = NULL;
result = 0;
} else {
+ p->suspended_object = p->playing_object;
+ p->suspended_pc = p->playing_pc;
+
+ p->playing_object = NULL;
+
bd_psr_save_state(p->regs);
result = 0;
}
@@ -1061,6 +1142,13 @@ static int _vm_run(HDMV_VM *p, HDMV_EVENT *ev)
while (--max_loop > 0) {
+ /* suspended ? */
+ if (!p->object) {
+ BD_DEBUG(DBG_HDMV, "hdmv_vm_run(): object suspended\n");
+ _get_event(p, ev);
+ return 0;
+ }
+
/* terminated ? */
if (p->pc >= p->object->num_cmds) {
BD_DEBUG(DBG_HDMV, "terminated with PC=%d\n", p->pc);
More information about the libbluray-devel
mailing list