[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