[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