libbluray | branch: master | hpi1 <[email protected]> | 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_ */ _______________________________________________ libbluray-devel mailing list [email protected] https://mailman.videolan.org/listinfo/libbluray-devel
