[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