[libbluray-devel] BD-J: select initial playback location with playlist

hpi1 git at videolan.org
Mon Apr 14 11:14:23 CEST 2014


libbluray | branch: master | hpi1 <hpi1 at anonymous.org> | Sun Apr 13 22:00:15 2014 +0300| [55e0d3149a6a5f35a3ce2aa928204e1bc1ee9a28] | committer: hpi1

BD-J: select initial playback location with playlist

Fixes problems when playlist is first selected and then playback is seeked to start location.
- application may have read stream from incorrect position before seek happens.
- previous playlist may be truncated because of select + seek
  (seek discards all data queued in application buffers).

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

 src/libbluray/bdj/java/org/videolan/Libbluray.java |   14 ++++++--
 .../videolan/media/content/playlist/Handler.java   |   22 +++++++-----
 src/libbluray/bdj/native/org_videolan_Libbluray.c  |   13 ++++---
 src/libbluray/bdj/native/org_videolan_Libbluray.h  |    4 +--
 src/libbluray/bluray.c                             |   38 ++++++++++++++++++++
 src/libbluray/bluray_internal.h                    |    2 ++
 6 files changed, 76 insertions(+), 17 deletions(-)

diff --git a/src/libbluray/bdj/java/org/videolan/Libbluray.java b/src/libbluray/bdj/java/org/videolan/Libbluray.java
index 7d06b81..c61d52e 100644
--- a/src/libbluray/bdj/java/org/videolan/Libbluray.java
+++ b/src/libbluray/bdj/java/org/videolan/Libbluray.java
@@ -206,11 +206,19 @@ public class Libbluray {
         return result;
     }
 
-    public static boolean selectPlaylist(int playlist) {
+    public static boolean selectPlaylist(int playlist, int playitem, int playmark, long time) {
         if (playlist < 0)
             throw new IllegalArgumentException("Playlist cannot be negative");
 
-        return selectPlaylistN(nativePointer, playlist) == 1 ? true : false;
+        return selectPlaylistN(nativePointer, playlist, playitem, playmark, time) == 1 ? true : false;
+    }
+
+    public static boolean selectPlaylist(int playlist) {
+        return selectPlaylist(playlist, -1, -1, -1);
+    }
+
+    public static void stopPlaylist() {
+        selectPlaylistN(nativePointer, -1, -1, -1, -1);
     }
 
     public static boolean selectTitle(TitleImpl title) {
@@ -483,7 +491,7 @@ public class Libbluray {
     private static native int getCurrentChapterN(long np);
     private static native long seekMarkN(long np, int mark);
     private static native long seekPlayItemN(long np, int clip);
-    private static native int selectPlaylistN(long np, int playlist);
+    private static native int selectPlaylistN(long np, int playlist, int playitem, int playmark, long time);
     private static native int selectTitleN(long np, int title);
     private static native int selectAngleN(long np, int angle);
     private static native void seamlessAngleChangeN(long np, int angle);
diff --git a/src/libbluray/bdj/java/org/videolan/media/content/playlist/Handler.java b/src/libbluray/bdj/java/org/videolan/media/content/playlist/Handler.java
index 09e6951..c01b5d5 100644
--- a/src/libbluray/bdj/java/org/videolan/media/content/playlist/Handler.java
+++ b/src/libbluray/bdj/java/org/videolan/media/content/playlist/Handler.java
@@ -90,17 +90,23 @@ public class Handler extends BDHandler {
     protected ControllerErrorEvent doPrefetch() {
         synchronized (this) {
             try {
-                if (!Libbluray.selectPlaylist(locator.getPlayListId()))
-                    return new ConnectionErrorEvent(this);
-
+                int pl = locator.getPlayListId();
+                long time = -1;
+                int pi = -1, mark = -1;
                 if (baseMediaTime != 0) {
-                    Libbluray.seekTime((long)(baseMediaTime * FROM_NAROSECONDS));
-                } else if (locator.getMarkId() >= 0) {
-                    ((PlaybackControlImpl)controls[9]).skipToMark(locator.getMarkId());
-                } else if (locator.getPlayItemId() >= 0) {
-                    ((PlaybackControlImpl)controls[9]).skipToPlayItem(locator.getPlayItemId());
+                    time = (long)(baseMediaTime * FROM_NAROSECONDS);
+                } /*else*/ if (locator.getMarkId() > 0) {
+                    mark = locator.getMarkId();
+                } /*else*/ if (locator.getPlayItemId() > 0) {
+                    pi = locator.getPlayItemId();
+                }
+
+                if (!Libbluray.selectPlaylist(pl, pi, mark, time)) {
+                    return new ConnectionErrorEvent(this);
                 }
 
+                updateTime(new Time(Libbluray.tellTime() * TO_SECONDS));
+
                 int stream;
                 stream = locator.getPrimaryAudioStreamNumber();
                 if (stream > 0)
diff --git a/src/libbluray/bdj/native/org_videolan_Libbluray.c b/src/libbluray/bdj/native/org_videolan_Libbluray.c
index 908cdd2..211ea97 100644
--- a/src/libbluray/bdj/native/org_videolan_Libbluray.c
+++ b/src/libbluray/bdj/native/org_videolan_Libbluray.c
@@ -296,12 +296,17 @@ JNIEXPORT jlong JNICALL Java_org_videolan_Libbluray_seekPlayItemN(JNIEnv * env,
 }
 
 JNIEXPORT jint JNICALL Java_org_videolan_Libbluray_selectPlaylistN(
-        JNIEnv * env, jclass cls, jlong np, jint playlist) {
+        JNIEnv * env, jclass cls, jlong np, jint playlist, jint playitem, jint playmark, jlong time) {
     BDJAVA* bdj = (BDJAVA*)(intptr_t)np;
 
-    BD_DEBUG(DBG_JNI, "selectPlaylistN(%05d.mpls)\n", (int)playlist);
+    if (!bdj || !bdj->bd) {
+        return 0;
+    }
 
-    return bd_select_playlist(bdj->bd, playlist);
+    BD_DEBUG(DBG_JNI, "selectPlaylistN(pl=%d, pi=%d, pm=%d, time=%ld)\n",
+             (int)playlist, (int)playitem, (int)playmark, (long)time);
+
+    return bd_play_playlist_at(bdj->bd, playlist, playitem, playmark, time);
 }
 
 JNIEXPORT jint JNICALL Java_org_videolan_Libbluray_selectTitleN(JNIEnv * env,
@@ -604,7 +609,7 @@ Java_org_videolan_Libbluray_methods[] =
     },
     {
         CC("selectPlaylistN"),
-        CC("(JI)I"),
+        CC("(JIIIJ)I"),
         VC(Java_org_videolan_Libbluray_selectPlaylistN),
     },
     {
diff --git a/src/libbluray/bdj/native/org_videolan_Libbluray.h b/src/libbluray/bdj/native/org_videolan_Libbluray.h
index ea39982..5be0cf2 100644
--- a/src/libbluray/bdj/native/org_videolan_Libbluray.h
+++ b/src/libbluray/bdj/native/org_videolan_Libbluray.h
@@ -199,10 +199,10 @@ JNIEXPORT jlong JNICALL Java_org_videolan_Libbluray_seekPlayItemN
 /*
  * Class:     org_videolan_Libbluray
  * Method:    selectPlaylistN
- * Signature: (JI)I
+ * Signature: (JIIIJ)I
  */
 JNIEXPORT jint JNICALL Java_org_videolan_Libbluray_selectPlaylistN
-  (JNIEnv *, jclass, jlong, jint);
+  (JNIEnv *, jclass, jlong, jint, jint, jint, jlong);
 
 /*
  * Class:     org_videolan_Libbluray
diff --git a/src/libbluray/bluray.c b/src/libbluray/bluray.c
index ddd960c..28bc521 100644
--- a/src/libbluray/bluray.c
+++ b/src/libbluray/bluray.c
@@ -2169,6 +2169,44 @@ int bd_select_playlist(BLURAY *bd, uint32_t playlist)
     return result;
 }
 
+#ifdef USING_BDJAVA
+static int _play_playlist_at(BLURAY *bd, int playlist, int playitem, int playmark, int64_t time)
+{
+    if (playlist < 0) {
+        _close_playlist(bd);
+        return 1;
+    }
+
+    if (!bd_select_playlist(bd, playlist)) {
+        return 0;
+    }
+
+    if (playitem > 0) {
+        bd_seek_playitem(bd, playitem);
+    }
+    if (playmark >= 0) {
+        bd_seek_mark(bd, playmark);
+    }
+    if (time >= 0) {
+        bd_seek_time(bd, time);
+    }
+
+    return 1;
+}
+
+int bd_play_playlist_at(BLURAY *bd, int playlist, int playitem, int playmark, int64_t time)
+{
+    int result;
+
+    /* select + seek should be atomic (= player can't read data between select and seek to start position) */
+    bd_mutex_lock(&bd->mutex);
+    result = _play_playlist_at(bd, playlist, playitem, playmark, time);
+    bd_mutex_unlock(&bd->mutex);
+
+    return result;
+}
+#endif /* USING_BDJAVA */
+
 // Select a title for playback
 // The title index is an index into the list
 // established by bd_get_titles()
diff --git a/src/libbluray/bluray_internal.h b/src/libbluray/bluray_internal.h
index 1d000d9..70112d2 100644
--- a/src/libbluray/bluray_internal.h
+++ b/src/libbluray/bluray_internal.h
@@ -36,4 +36,6 @@ BD_PRIVATE int bd_reg_write(BLURAY *bd, int psr, int reg, uint32_t value, uint32
 
 BD_PRIVATE void bd_select_rate(BLURAY *bd, float rate, int reason);
 
+BD_PRIVATE int bd_play_playlist_at(BLURAY *bd, int playlist, int playitem, int playmark, int64_t time);
+
 #endif  /* _BLURAY_INTERNAL_H_ */



More information about the libbluray-devel mailing list