[libbluray-devel] commit: Preload IG stream (sub path) (hpi1 )

git at videolan.org git at videolan.org
Sun Oct 17 15:11:25 CEST 2010


libbluray | branch: master | hpi1 <hpi1 at anonymous.org> | Sat Oct 16 21:33:30 2010 +0300| [230290238060eafc3786a67d0d46687d86e0194c] | committer: hpi1 

Preload IG stream (sub path)

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

 src/libbluray/bluray.c |  125 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 125 insertions(+), 0 deletions(-)

diff --git a/src/libbluray/bluray.c b/src/libbluray/bluray.c
index 9669f4e..cf30e48 100644
--- a/src/libbluray/bluray.c
+++ b/src/libbluray/bluray.c
@@ -78,6 +78,12 @@ typedef struct {
 
 } BD_STREAM;
 
+typedef struct {
+    NAV_CLIP *clip;
+    uint64_t  clip_size;
+    uint8_t  *buf;
+} BD_PRELOAD;
+
 struct bluray {
 
     /* current disc */
@@ -92,6 +98,7 @@ struct bluray {
 
     /* streams */
     BD_STREAM      st0; /* main path */
+    BD_PRELOAD     st_ig; /* preloaded IG stream sub path */
 
     /* buffer for bd_read(): current aligned unit of main stream (st0) */
     uint8_t        int_buf[6144];
@@ -312,6 +319,58 @@ static int _read_block(BLURAY *bd, BD_STREAM *st, uint8_t *buf)
     return 0;
 }
 
+/*
+ * clip preload (BD_PRELOAD)
+ */
+
+static void _close_preload(BD_PRELOAD *p)
+{
+    X_FREE(p->buf);
+    memset(p, 0, sizeof(*p));
+}
+
+static int _preload_m2ts(BLURAY *bd, BD_PRELOAD *p)
+{
+    /* setup and open BD_STREAM */
+
+    BD_STREAM st;
+
+    memset(&st, 0, sizeof(st));
+    st.clip = p->clip;
+
+    if (!_open_m2ts(bd, &st)) {
+        return 0;
+    }
+
+    /* allocate buffer */
+    p->clip_size = st.clip_size;
+    p->buf       = realloc(p->buf, p->clip_size);
+
+    /* read clip to buffer */
+
+    uint8_t *buf = p->buf;
+    uint8_t *end = p->buf + p->clip_size;
+
+    for (; buf < end; buf += 6144) {
+        if (!_read_block(bd, &st, buf)) {
+            DEBUG(DBG_BLURAY|DBG_CRIT, "_preload_m2ts(): error loading %s at %"PRIu64"\n",
+                  st.clip->name, (uint64_t)(buf - p->buf));
+            _close_m2ts(&st);
+            _close_preload(p);
+            return 0;
+        }
+    }
+
+    /* */
+
+    DEBUG(DBG_BLURAY, "_preload_m2ts(): loaded %"PRIu64" bytes from %s\n",
+          st.clip_size, st.clip->name);
+
+    _close_m2ts(&st);
+
+    return 1;
+}
+
 static int64_t _seek_stream(BLURAY *bd, BD_STREAM *st,
                             NAV_CLIP *clip, uint32_t clip_pkt)
 {
@@ -515,6 +574,7 @@ void bd_close(BLURAY *bd)
     _libbdplus_close(bd);
 
     _close_m2ts(&bd->st0);
+    _close_preload(&bd->st_ig);
 
     if (bd->title_list != NULL) {
         nav_free_title_list(bd->title_list);
@@ -808,12 +868,74 @@ int bd_read(BLURAY *bd, unsigned char *buf, int len)
 }
 
 /*
+ * preloader for asynchronous sub paths
+ */
+
+static int _find_ig_stream(BLURAY *bd, uint16_t *pid, int *sub_path_idx)
+{
+    MPLS_PI  *pi        = &bd->title->pl->play_item[0];
+    unsigned  ig_stream = bd_psr_read(bd->regs, PSR_IG_STREAM_ID);
+    unsigned  ii;
+
+    for (ii = 0; ii < pi->stn.num_ig; ii++) {
+        if (ii + 1 == ig_stream) {
+            if (pi->stn.ig[ii].stream_type == 2) {
+                *sub_path_idx = pi->stn.ig[ii].subpath_id;
+            }
+            *pid = pi->stn.ig[ii].pid;
+
+            DEBUG(DBG_BLURAY, "_find_ig_stream(): current IG stream pid 0x%04x sub-path %d\n",
+                  *pid, *sub_path_idx);
+            return 1;
+        }
+    }
+
+    return 0;
+}
+
+static int _preload_ig_subpath(BLURAY *bd)
+{
+    int      ig_subpath = -1;
+    uint16_t ig_pid     = 0;
+
+    _find_ig_stream(bd, &ig_pid, &ig_subpath);
+
+    if (!bd->graphics_controller) {
+        return 0;
+    }
+
+    if (ig_subpath < 0) {
+        return 0;
+    }
+
+    bd->st_ig.clip = &bd->title->sub_path[ig_subpath].clip_list.clip[0];
+
+    if (!_preload_m2ts(bd, &bd->st_ig)) {
+        return 0;
+    }
+
+    gc_decode_ts(bd->graphics_controller, ig_pid, bd->st_ig.buf, bd->st_ig.clip_size / 6144, -1);
+
+    return 1;
+}
+
+static int _preload_subpaths(BLURAY *bd)
+{
+    if (bd->title->pl->sub_count <= 0) {
+        return 0;
+    }
+
+    return _preload_ig_subpath(bd);
+}
+
+/*
  * select title / angle
  */
 
 static void _close_playlist(BLURAY *bd)
 {
     _close_m2ts(&bd->st0);
+    _close_preload(&bd->st_ig);
 
     if (bd->title) {
         nav_title_close(bd->title);
@@ -845,6 +967,9 @@ static int _open_playlist(BLURAY *bd, const char *f_name)
     bd->st0.clip = nav_next_clip(bd->title, NULL);
     if (_open_m2ts(bd, &bd->st0)) {
         DEBUG(DBG_BLURAY, "Title %s selected! (%p)\n", f_name, bd);
+
+        _preload_subpaths(bd);
+
         return 1;
     }
     return 0;



More information about the libbluray-devel mailing list