[libbluray-devel] Finetune seeks (avoid skipping PAT/PMT/PCR)

hpi1 git at videolan.org
Mon Nov 2 12:46:21 CET 2015


libbluray | branch: master | hpi1 <hpi1 at anonymous.org> | Mon Nov  2 11:55:26 2015 +0200| [6134c31b48bbb36992980a575e03b98b3bbd18d6] | committer: hpi1

Finetune seeks (avoid skipping PAT/PMT/PCR)

Rewind few packets after seek if previous packets are PAT/PMT/PCR.

Seek points are aligned to video packets.
Sometimes playlist is seeked before playback starts, and
application misses initial PAT/PMT/PCR. This may be fatal with
still images.

Fixes seeking to ~ beginning of playlist. In middle of the stream
PAT/PMT/PCR are muxed at ~ constant intervals, and rewind would be
more complex to implement. PAT/PMT are not allowed to change in
middle of HDMV stream.

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

 src/libbluray/bluray.c             |   18 ++++++++++++++++++
 src/libbluray/decoders/hdmv_pids.h |    7 +++++++
 2 files changed, 25 insertions(+)

diff --git a/src/libbluray/bluray.c b/src/libbluray/bluray.c
index ccb293e..5a4ffe6 100644
--- a/src/libbluray/bluray.c
+++ b/src/libbluray/bluray.c
@@ -42,6 +42,7 @@
 #include "hdmv/hdmv_vm.h"
 #include "hdmv/mobj_parse.h"
 #include "decoders/graphics_controller.h"
+#include "decoders/hdmv_pids.h"
 #include "decoders/m2ts_filter.h"
 #include "decoders/overlay.h"
 #include "disc/disc.h"
@@ -93,6 +94,7 @@ typedef struct {
     /* */
     uint8_t         eof_hit;
     uint8_t         encrypted_block_cnt;
+    uint8_t         seek_flag;  /* used to fine-tune first read after seek */
 
     M2TS_FILTER    *m2ts_filter;
 } BD_STREAM;
@@ -849,6 +851,7 @@ static int64_t _seek_stream(BLURAY *bd, BD_STREAM *st,
     }
 
     st->int_buf_off = 6144;
+    st->seek_flag = 1;
 
     return st->clip_pos;
 }
@@ -1958,6 +1961,19 @@ static int _bd_read(BLURAY *bd, unsigned char *buf, int len)
                     /* fatal error */
                     return -1;
                 }
+
+                /* finetune seek point (avoid skipping PAT/PMT/PCR) */
+                if (BD_UNLIKELY(st->seek_flag)) {
+                    st->seek_flag = 0;
+
+                    /* rewind if previous packets contain PAT/PMT/PCR */
+                    while (st->int_buf_off >= 192 && TS_PID(bd->int_buf + st->int_buf_off - 192) <= HDMV_PID_PCR) {
+                        st->clip_pos -= 192;
+                        st->int_buf_off -= 192;
+                        bd->s_pos -= 192;
+                    }
+                }
+
             }
             if (size > (unsigned int)6144 - st->int_buf_off) {
                 size = 6144 - st->int_buf_off;
@@ -2282,6 +2298,8 @@ static int _open_playlist(BLURAY *bd, const char *f_name, unsigned angle)
 
         _preload_subpaths(bd);
 
+        bd->st0.seek_flag = 1;
+
         return 1;
     }
     return 0;
diff --git a/src/libbluray/decoders/hdmv_pids.h b/src/libbluray/decoders/hdmv_pids.h
index ac5bc6a..45a55f3 100644
--- a/src/libbluray/decoders/hdmv_pids.h
+++ b/src/libbluray/decoders/hdmv_pids.h
@@ -61,5 +61,12 @@
 #define IS_HDMV_PID_IG(pid)     ((pid) >= HDMV_PID_IG_FIRST && (pid) <= HDMV_PID_IG_LAST)
 #define IS_HDMV_PID_TEXTST(pid) ((pid) == HDMV_PID_TEXTST)
 
+/*
+ * Extract PID from HDMV MPEG-TS packet
+ */
+
+#define TS_PID(buf)                             \
+  ((((buf)[4+1] & 0x1f) << 8) | (buf)[4+2])
+
 
 #endif // _HDMV_PIDS_H_



More information about the libbluray-devel mailing list