[libbluray-devel] HDMV: support state serialization and restore

hpi1 git at videolan.org
Wed Apr 22 13:03:33 CEST 2015


libbluray | branch: master | hpi1 <hpi1 at anonymous.org> | Wed Apr 22 13:52:04 2015 +0300| [f8de9a561108acb3ddc237789f55c682099d58f8] | committer: hpi1

HDMV: support state serialization and restore

> http://git.videolan.org/gitweb.cgi/libbluray.git/?a=commit;h=f8de9a561108acb3ddc237789f55c682099d58f8
---

 src/libbluray/hdmv/hdmv_vm.c |   86 ++++++++++++++++++++++++++++++++++++++++++
 src/libbluray/hdmv/hdmv_vm.h |   11 ++++++
 src/libbluray/register.c     |   51 +++++++++++++++++++++++++
 src/libbluray/register.h     |    9 +++++
 4 files changed, 157 insertions(+)

diff --git a/src/libbluray/hdmv/hdmv_vm.c b/src/libbluray/hdmv/hdmv_vm.c
index 2fb99b1..6583562 100644
--- a/src/libbluray/hdmv/hdmv_vm.c
+++ b/src/libbluray/hdmv/hdmv_vm.c
@@ -72,6 +72,92 @@ struct hdmv_vm_s {
 };
 
 /*
+ * save / restore VM state
+ */
+
+static int _save_state(HDMV_VM *p, uint32_t *s)
+{
+    memset(s, 0, sizeof(*s) * HDMV_STATE_SIZE);
+
+    if (p->ig_object) {
+        BD_DEBUG(DBG_HDMV | DBG_CRIT, "_save_state() failed: button object running\n");
+        return -1;
+    }
+    if (p->object) {
+        BD_DEBUG(DBG_HDMV | DBG_CRIT, "_save_state() failed: movie object running\n");
+        return -1;
+    }
+    if (p->event[0].event != HDMV_EVENT_NONE) {
+        BD_DEBUG(DBG_HDMV | DBG_CRIT, "_save_state() failed: unprocessed events\n");
+        return -1;
+    }
+
+    if (p->playing_object) {
+        s[0] = (uint32_t)(p->playing_object - p->movie_objects->objects);
+        s[1] = p->playing_pc;
+    } else {
+        s[0] = (uint32_t)-1;
+    }
+
+    if (p->suspended_object) {
+        s[2] = (uint32_t)(p->suspended_object - p->movie_objects->objects);
+        s[3] = p->suspended_pc;
+    } else {
+        s[2] = (uint32_t)-1;
+    }
+
+    /* nv timer ? */
+
+    return 0;
+}
+
+static int _restore_state(HDMV_VM *p, const uint32_t *s)
+{
+    if (s[0] == (uint32_t)-1) {
+        p->playing_object = NULL;
+    } else if (s[0] >= p->movie_objects->num_objects) {
+        BD_DEBUG(DBG_HDMV | DBG_CRIT, "_restore_state() failed: invalid playing object index\n");
+        return -1;
+    } else {
+        p->playing_object = &p->movie_objects->objects[s[0]];
+    }
+    p->playing_pc = s[1];
+
+    if (s[2] == (uint32_t)-1) {
+        p->suspended_object = NULL;
+    } else if (s[2] >= p->movie_objects->num_objects) {
+        BD_DEBUG(DBG_HDMV | DBG_CRIT, "_restore_state() failed: invalid suspended object index\n");
+        return -1;
+    } else {
+        p->suspended_object = &p->movie_objects->objects[s[2]];
+    }
+    p->suspended_pc = s[3];
+
+    p->object = NULL;
+    p->ig_object = NULL;
+    memset(p->event, 0, sizeof(p->event));
+
+    return 0;
+}
+
+int hdmv_vm_save_state(HDMV_VM *p, uint32_t *s)
+{
+    int result;
+    bd_mutex_lock(&p->mutex);
+    result = _save_state(p, s);
+    bd_mutex_unlock(&p->mutex);
+    return result;
+}
+
+void hdmv_vm_restore_state(HDMV_VM *p, const uint32_t *s)
+{
+    bd_mutex_lock(&p->mutex);
+    _restore_state(p, s);
+    bd_mutex_unlock(&p->mutex);
+}
+
+
+/*
  * registers: PSR and GPR access
  */
 
diff --git a/src/libbluray/hdmv/hdmv_vm.h b/src/libbluray/hdmv/hdmv_vm.h
index 06ea2ed..c7d95f1 100644
--- a/src/libbluray/hdmv/hdmv_vm.h
+++ b/src/libbluray/hdmv/hdmv_vm.h
@@ -119,4 +119,15 @@ BD_PRIVATE int      hdmv_vm_suspend_pl(HDMV_VM *p);
  */
 BD_PRIVATE int      hdmv_vm_resume(HDMV_VM *p);
 
+
+/*
+ * save / restore VM state
+ */
+
+/* VM state size */
+#define HDMV_STATE_SIZE 10  /* * sizeof(uint32_t) */
+
+BD_PRIVATE int hdmv_vm_save_state(HDMV_VM *p, uint32_t *s);
+BD_PRIVATE void hdmv_vm_restore_state(HDMV_VM *p, const uint32_t *s);
+
 #endif // _HDMV_VM_H_
diff --git a/src/libbluray/register.c b/src/libbluray/register.c
index 964933e..0e20496 100644
--- a/src/libbluray/register.c
+++ b/src/libbluray/register.c
@@ -475,3 +475,54 @@ int bd_psr_write_bits(BD_REGISTERS *p, int reg, uint32_t val, uint32_t mask)
 
     return result;
 }
+
+/*
+ * save / restore registers between playback sessions
+ */
+
+void registers_save(BD_REGISTERS *p, uint32_t *psr, uint32_t *gpr)
+{
+    bd_psr_lock(p);
+
+    memcpy(gpr, p->gpr, sizeof(p->gpr));
+    memcpy(psr, p->psr, sizeof(p->psr));
+
+    bd_psr_unlock(p);
+}
+
+void registers_restore(BD_REGISTERS *p, const uint32_t *psr, const uint32_t *gpr)
+{
+    uint32_t new_psr[13];
+
+    bd_psr_lock(p);
+
+    memcpy(p->gpr, gpr, sizeof(p->gpr));
+    memcpy(p->psr, psr, sizeof(p->psr));
+
+    memcpy(new_psr, p->psr, sizeof(new_psr[0]) * 13);
+
+    /* generate restore events */
+    if (p->num_cb) {
+        BD_PSR_EVENT ev;
+        unsigned     i, j;
+
+        ev.ev_type = BD_PSR_RESTORE;
+        ev.old_val = 0; /* not used with BD_PSR_RESTORE */
+
+        for (i = 4; i < 13; i++) {
+            if (i != PSR_NAV_TIMER) {
+
+                p->psr[i] = new_psr[i];
+
+                ev.psr_idx = i;
+                ev.new_val = new_psr[i];
+
+                for (j = 0; j < p->num_cb; j++) {
+                    p->cb[j].cb(p->cb[j].handle, &ev);
+                }
+            }
+        }
+    }
+
+    bd_psr_unlock(p);
+}
diff --git a/src/libbluray/register.h b/src/libbluray/register.h
index 3e564ff..c936aca 100644
--- a/src/libbluray/register.h
+++ b/src/libbluray/register.h
@@ -264,4 +264,13 @@ void bd_psr_register_cb(BD_REGISTERS *, void (*callback)(void*,BD_PSR_EVENT*), v
 void bd_psr_unregister_cb(BD_REGISTERS *, void (*callback)(void*,BD_PSR_EVENT*), void *cb_handle);
 
 
+/*
+ * save / restore registers between playback sessions
+ *
+ * When state is restored, restore events will be generated and playback state is restored.
+ */
+
+BD_PRIVATE void registers_save(BD_REGISTERS *p, uint32_t *psr, uint32_t *gpr);
+BD_PRIVATE void registers_restore(BD_REGISTERS *p, const uint32_t *psr, const uint32_t *gpr);
+
 #endif /* _BD_REGISTER_H_ */



More information about the libbluray-devel mailing list