Skip to content
Commits on Source (14)
- Add initial support for OpenJDK 11.
- Add initial support for UHD disc BD-J menus.
- Add support for compiling .jar file with Java 9+ compiler.
- Move AWT classes to separate .jar file.
- Update libudfread submodule repository URL.
- Improve main title selection.
- Improve error resilience and stability.
- Improve BD-J compability.
- Fix playback of some broken BD-J discs.
- Fix playback of discs without normal titles (only TopMenu / FirstPlay title).
2017-12-01: Version 1.0.2
- Add initial support for UHD BluRay discs (without BD-J menus).
......
......@@ -122,7 +122,7 @@ static void *_load_jvm_win32(const char **p_java_home)
HKEY hkey;
r = RegOpenKeyExW(HKEY_LOCAL_MACHINE, buf_loc, 0, KEY_READ, &hkey);
# if 0
# ifndef NO_JAVA9_SUPPORT
if (r != ERROR_SUCCESS) {
/* Try Java 9 */
wcscpy(buf_loc, L"SOFTWARE\\JavaSoft\\JRE\\");
......@@ -309,13 +309,14 @@ static void *_jvm_dlopen(const char *java_home, const char *jvm_dir, const char
}
BD_DEBUG(DBG_BDJ, "Opening %s ...\n", path);
void *h = dl_dlopen(path, NULL);
# ifdef NO_JAVA9_SUPPORT
/* ignore Java 9+ */
if (h && dl_dlsym(h, "JVM_DefineModule")) {
BD_DEBUG(DBG_CRIT | DBG_BDJ, "Ignoring JVM %s: looks like Java 9 or later\n", path);
dl_dlclose(h);
h = NULL;
}
# endif
X_FREE(path);
return h;
} else {
......@@ -883,6 +884,18 @@ static int _create_jvm(void *jvm_lib, const char *java_home, const char *jar_fil
/* Fix module graph */
option[n++].optionString = str_dup("--add-reads=java.base=java.desktop");
/* org.videolan.IxcRegistryImpl -> java.rmi.Remote */
option[n++].optionString = str_dup("--add-reads=java.base=java.rmi");
/* org.videolan.FontIndex -> java.xml. */
option[n++].optionString = str_dup("--add-reads=java.base=java.xml");
/* AWT needs to access logger and Xlet context */
option[n++].optionString = str_dup("--add-opens=java.base/org.videolan=java.desktop");
/* AWT needs to acess DVBGraphics */
option[n++].optionString = str_dup("--add-exports=java.base/org.dvb.ui=java.desktop");
/* org.havi.ui.HBackgroundImage needs to access sun.awt.image.FileImageSource */
option[n++].optionString = str_dup("--add-exports=java.desktop/sun.awt.image=java.base");
/* Export BluRay packages to Xlets */
for (size_t idx = 0; idx < num_java_base_exports; idx++) {
option[n++].optionString = str_printf("--add-exports=java.base/%s=ALL-UNNAMED", java_base_exports[idx]);
......
/*
* This file is part of libbluray
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*/
package java.io;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
public final class FileDescriptor {
/* for files used by JVM */
private int fd;
private long handle;
private int useCount;
public FileDescriptor() {
fd = -1;
handle = -1;
useCount = 0;
}
private FileDescriptor(int fd) {
this();
this.fd = fd;
}
public static final FileDescriptor in = new FileDescriptor(0);
public static final FileDescriptor out = new FileDescriptor(1);
public static final FileDescriptor err = new FileDescriptor(2);
public boolean valid() {
return (fd != -1) || (handle != -1);
}
public native void sync() throws SyncFailedException;
private static native void initIDs();
static {
initIDs();
}
int incrementAndGetUseCount() {
synchronized (this) {
useCount = useCount + 1;
return useCount;
}
}
int decrementAndGetUseCount() {
synchronized (this) {
useCount = useCount - 1;
return useCount;
}
}
/* Java 8 */
private List parents = null;
private boolean closed = false;
synchronized void attach(Closeable c) {
if (parents == null) {
parents = new ArrayList();
}
parents.add(c);
}
synchronized void closeAll(Closeable releaser) throws IOException {
if (!closed) {
IOException ex = null;
closed = true;
for (Iterator it = parents.iterator(); it.hasNext(); ) {
Closeable c = (Closeable)it.next();
try {
c.close();
} catch (IOException ioe) {
if (ex != null)
ex = ioe;
}
}
releaser.close();
if (ex != null) {
throw ex;
}
}
}
}
......@@ -18,6 +18,7 @@
package java.io;
import java.lang.reflect.InvocationTargetException;
import org.videolan.BDJLoader;
import org.videolan.BDJXletContext;
......@@ -46,17 +47,12 @@ public class FileInputStream extends InputStream
}
fd = new FileDescriptor();
fd.incrementAndGetUseCount();
fdAttach();
if (file.isAbsolute()) {
String cachedName = BDJLoader.getCachedFile(name);
if (cachedName != name) {
synchronized (FileInputStream.class) {
if (logger == null) {
logger = Logger.getLogger(FileInputStream.class.getName());
}
}
logger.info("Using cached " + cachedName + " for " + name);
getLogger().info("Using cached " + cachedName + " for " + name);
name = cachedName;
}
openImpl(name);
......@@ -66,12 +62,7 @@ public class FileInputStream extends InputStream
String home = BDJXletContext.getCurrentXletHome();
if (home == null) {
synchronized (FileInputStream.class) {
if (logger == null) {
logger = Logger.getLogger(FileInputStream.class.getName());
}
}
logger.error("no home found for " + name + " at " + Logger.dumpStack());
getLogger().error("Xlet home directory not found for " + name + " at " + Logger.dumpStack());
throw new FileNotFoundException(name);
}
openImpl(home + name);
......@@ -92,9 +83,9 @@ public class FileInputStream extends InputStream
if (security != null) {
security.checkRead(fdObj);
}
fdObj.incrementAndGetUseCount();
fd = fdObj;
available = 1024;
fdAttach();
}
/* open()/open0() wrapper to select correct native method at runtime */
......@@ -108,6 +99,7 @@ public class FileInputStream extends InputStream
}
private native int readBytes(byte b[], int off, int len) throws IOException;
/* OpenJDK < 10 */
private native int close0();
/* OpenJDK 6, OpenJDK 7, PhoneME, ... */
private native void open(String name) throws FileNotFoundException;
......@@ -156,7 +148,7 @@ public class FileInputStream extends InputStream
close(true);
}
public void close(boolean force) throws IOException {
private void close(boolean force) throws IOException {
synchronized (closeLock) {
if (closed) {
return;
......@@ -166,14 +158,7 @@ public class FileInputStream extends InputStream
available = 0;
if (fd != null) {
int n = fd.decrementAndGetUseCount();
if (n > 0 && !force) {
return;
}
}
close0();
fdClose(force);
}
public final FileDescriptor getFD() throws IOException {
......@@ -187,6 +172,15 @@ public class FileInputStream extends InputStream
public FileChannel getChannel() {}
*/
private static Logger getLogger() {
synchronized (FileInputStream.class) {
if (logger == null) {
logger = Logger.getLogger(FileInputStream.class.getName());
}
}
return logger;
}
private static native void initIDs();
static {
......@@ -200,4 +194,111 @@ public class FileInputStream extends InputStream
}
}
}
/*
* compat layer
*/
private boolean useFdCount = false;
private void fdAttach() {
/*
* Reflection fails at very early stage in JVM bootstrap.
* -> hide all errors in this function.
*/
try {
try {
fd.getClass().getDeclaredMethod("attach", new Class[] { Closeable.class })
.invoke(fd, new Object[] { (Object)this });
return;
} catch (NoSuchMethodException e) {
/* older RT libs */
}
try {
fd.getClass().getDeclaredMethod("incrementAndGetUseCount", new Class[0]).invoke((Object)fd, new Object[0]);
useFdCount = true;
return;
} catch (NoSuchMethodException e) {
getLogger().error("internal error in FileDescriptor usage");
}
} catch (Throwable t) {
if (logger != null)
logger.error("" + t);
}
}
private void closeImpl() throws IOException {
/* OpenJDK 10+ */
try {
fd.getClass().getDeclaredMethod("close", new Class[0])
.invoke(fd, new Object[0]);
return;
} catch (InvocationTargetException ite) {
Throwable t = ite.getTargetException();
getLogger().error("" + t);
if (t instanceof IOException) {
throw (IOException)t;
}
throw new IOException();
} catch (IllegalAccessException iae) {
getLogger().error("internal error in FileDescriptor usage: " + iae);
return;
} catch (NoSuchMethodException no_jdk10) {
/* JDK < 10 */
}
/* JDK < 10 */
try {
close0();
} catch (UnsatisfiedLinkError no_close0) {
getLogger().error("internal error in FileDescriptor usage: " + no_close0);
}
}
private void fdClose(boolean force) throws IOException {
try {
if (useFdCount) {
try {
Integer i = (Integer) fd.getClass().getDeclaredMethod("decrementAndGetUseCount", new Class[0]).invoke((Object)fd, new Object[0]);
if (i.intValue() > 0 && !force) {
return;
}
closeImpl();
} catch (NoSuchMethodException no_method) {
getLogger().error("internal error in FileDescriptor usage: " + no_method);
}
return;
}
try {
fd.getClass().getDeclaredMethod("closeAll", new Class[] { Closeable.class })
.invoke(fd, new Object[] { (Object)
new Closeable() {
public void close() throws IOException {
closeImpl();
}
}});
return;
} catch (NoSuchMethodException no_closeAll) {
getLogger().error("internal error in FileDescriptor usage: " + no_closeAll);
}
} catch (IllegalAccessException iae) {
getLogger().error("internal error in FileDescriptor usage: " + iae);
return;
} catch (InvocationTargetException ite) {
Throwable t = ite.getTargetException();
getLogger().error("" + t);
if (t instanceof IOException) {
throw (IOException)t;
}
throw new IOException();
}
}
}
......@@ -65,7 +65,7 @@ public class BDJClassFileTransformer
ClassReader cr = new ClassReader(b);
ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES/* | ClassWriter.COMPUTE_MAXS*/);
ClassVisitor cv = new RemappingClassAdapter(cw, m);
cr.accept(cv, ClassReader.SKIP_DEBUG);
cr.accept(cv, ClassReader.SKIP_DEBUG | ClassReader.EXPAND_FRAMES);
return cw.toByteArray();
} catch (Exception e) {
logger.error("Failed renaming class: " + e);
......@@ -87,7 +87,7 @@ public class BDJClassFileTransformer
ClassReader cr = new ClassReader(r);
ClassWriter cw = new ClassWriter(cr, 0/*ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS*/);
ClassVisitor cv = new MyClassVisitor(cw);
cr.accept(cv, ClassReader.SKIP_DEBUG);
cr.accept(cv, ClassReader.SKIP_DEBUG | ClassReader.EXPAND_FRAMES);
return cw.toByteArray();
} catch (Exception e) {
logger.error("Failed transforming class: " + e);
......
......@@ -217,6 +217,31 @@ final class BDJSecurityManager extends SecurityManager {
}
}
/*
* Allow package access (Java 11)
*/
private static String pkgPrefixes[] = {
"javax.media" ,
"javax.tv",
"javax.microedition",
"org.davic",
"org.dvb",
"org.havi",
"org.bluray",
"org.blurayx",
"com.aacsla.bluray",
};
public void checkPackageAccess(String pkg) {
for (int i = 0; i < pkgPrefixes.length; i++)
if (pkg.startsWith(pkgPrefixes[i]))
return;
super.checkPackageAccess(pkg);
}
/*
*
*/
......
......@@ -53,6 +53,8 @@ public class Libbluray {
/* hook system properties: make "user.dir" point to current Xlet home directory */
private static boolean booted;
private static void hookProperties() {
java.util.Properties p = new java.util.Properties(System.getProperties()) {
public String getProperty(String key) {
......@@ -61,7 +63,9 @@ public class Libbluray {
if (ctx != null) {
return ctx.getXletHome();
}
System.err.println("getProperty(user.dir): no context ! " + Logger.dumpStack());
if (booted) {
System.err.println("getProperty(user.dir): no context ! " + Logger.dumpStack());
}
}
return super.getProperty(key);
}
......@@ -268,6 +272,7 @@ public class Libbluray {
boolean p5 = (profile & 0x10) != 0;
boolean p6 = ((profile & 0x1f) == 0) && (version >= 0x0300);
resetProfile();
if (!p6) {
System.setProperty("bluray.profile.1", "YES");
System.setProperty("bluray.p1.version.major", "1");
......@@ -338,6 +343,8 @@ public class Libbluray {
loadAdapter(System.getProperty("org.videolan.loader.adapter"));
loadAdapter(pkg);
booted = true;
}
/* called only from native code */
......@@ -380,6 +387,7 @@ public class Libbluray {
}
classLoaderAdapter = null;
loaderAdapter = null;
booted = false;
}
/*
......@@ -566,7 +574,7 @@ public class Libbluray {
*/
public static void writeGPR(int num, int value) {
int ret = writeGPRN(nativePointer, num, value);
int ret = writeRegN(nativePointer, 0, num, value, 0xffffffff);
if (ret == -1)
throw new IllegalArgumentException("Invalid GPR");
......@@ -577,7 +585,7 @@ public class Libbluray {
}
public static void writePSR(int num, int value, int psr_value_mask) {
int ret = writePSRN(nativePointer, num, value, psr_value_mask);
int ret = writeRegN(nativePointer, 1, num, value, psr_value_mask);
if (ret == -1)
throw new IllegalArgumentException("Invalid PSR");
......@@ -587,14 +595,14 @@ public class Libbluray {
if (num < 0 || (num >= 4096))
throw new IllegalArgumentException("Invalid GPR");
return readGPRN(nativePointer, num);
return readRegN(nativePointer, 0, num);
}
public static int readPSR(int num) {
if (num < 0 || (num >= 128))
throw new IllegalArgumentException("Invalid PSR");
return readPSRN(nativePointer, num);
return readRegN(nativePointer, 1, num);
}
/*
......@@ -788,11 +796,9 @@ public class Libbluray {
private static native void setKeyInterestN(long np, int mask);
private static native long tellTimeN(long np);
private static native int selectRateN(long np, float rate, int reason);
private static native int writeGPRN(long np, int num, int value);
private static native int writePSRN(long np, int num, int value, int psr_value_mask);
private static native int readGPRN(long np, int num);
private static native int writeRegN(long np, int is_psr, int num, int value, int psr_value_mask);
private static native int readRegN(long np, int is_psr, int num);
private static native int setVirtualPackageN(long np, String vpPath, boolean psrBackup);
private static native int readPSRN(long np, int num);
private static native int cacheBdRomFileN(long np, String path, String cachePath);
private static native String[] listBdFilesN(long np, String path, boolean onlyBdRom);
private static native Bdjo getBdjoN(long np, String name);
......
......@@ -349,46 +349,29 @@ JNIEXPORT jint JNICALL Java_org_videolan_Libbluray_selectRateN(JNIEnv * env,
return 1;
}
JNIEXPORT jint JNICALL Java_org_videolan_Libbluray_writeGPRN(JNIEnv * env,
jclass cls, jlong np, jint num, jint value) {
JNIEXPORT jint JNICALL Java_org_videolan_Libbluray_readRegN(JNIEnv * env,
jclass cls, jlong np, jint is_psr, jint num) {
BLURAY* bd = (BLURAY*)(intptr_t)np;
int value = bd_reg_read(bd, is_psr, num);
BD_DEBUG(DBG_JNI, "writeGPRN(%d,%d)\n", (int)num, (int)value);
return bd_reg_write(bd, 0, num, value, ~0);
}
JNIEXPORT jint JNICALL Java_org_videolan_Libbluray_readGPRN(JNIEnv * env,
jclass cls, jlong np, jint num) {
BLURAY* bd = (BLURAY*)(intptr_t)np;
int value = bd_reg_read(bd, 0, num);
BD_DEBUG(DBG_JNI, "readGPRN(%d) -> %d\n", (int)num, (int)value);
BD_DEBUG(DBG_JNI, "readRegN(%s_%d) -> %d\n", is_psr ? "PSR" : "GPR", (int)num, (int)value);
return value;
}
JNIEXPORT jint JNICALL Java_org_videolan_Libbluray_writePSRN(JNIEnv * env,
jclass cls, jlong np, jint num, jint value, jint mask) {
JNIEXPORT jint JNICALL Java_org_videolan_Libbluray_writeRegN(JNIEnv * env,
jclass cls, jlong np, jint is_psr, jint num, jint value, jint mask) {
BLURAY* bd = (BLURAY*)(intptr_t)np;
if ((uint32_t)mask == 0xffffffff) {
BD_DEBUG(DBG_JNI, "writePSRN(%d,%d)\n", (int)num, (int)value);
BD_DEBUG(DBG_JNI, "writeRegN(%s_%d,%d)\n",
is_psr ? "PSR" : "GPR", (int)num, (int)value);
} else {
BD_DEBUG(DBG_JNI, "writePSRN(%d,0x%x,0x%08x)\n", (int)num, (int)value, (int)mask);
BD_DEBUG(DBG_JNI, "writeRegN(%s_%d,0x%x,0x%08x)\n",
is_psr ? "PSR" : "GPR", (int)num, (int)value, (int)mask);
}
return bd_reg_write(bd, 1, num, value, mask);
}
JNIEXPORT jint JNICALL Java_org_videolan_Libbluray_readPSRN(JNIEnv * env,
jclass cls, jlong np, jint num) {
BLURAY* bd = (BLURAY*)(intptr_t)np;
int value = bd_reg_read(bd, 1, num);
BD_DEBUG(DBG_JNI, "readPSRN(%d) -> %d\n", (int)num, (int)value);
return value;
return bd_reg_write(bd, is_psr, num, value, mask);
}
JNIEXPORT jint JNICALL Java_org_videolan_Libbluray_cacheBdRomFileN(JNIEnv * env,
......@@ -724,24 +707,14 @@ Java_org_videolan_Libbluray_methods[] =
VC(Java_org_videolan_Libbluray_selectRateN),
},
{
CC("writeGPRN"),
CC("(JII)I"),
VC(Java_org_videolan_Libbluray_writeGPRN),
CC("writeRegN"),
CC("(JIIII)I"),
VC(Java_org_videolan_Libbluray_writeRegN),
},
{
CC("writePSRN"),
CC("(JIII)I"),
VC(Java_org_videolan_Libbluray_writePSRN),
},
{
CC("readGPRN"),
CC("(JI)I"),
VC(Java_org_videolan_Libbluray_readGPRN),
},
{
CC("readPSRN"),
CC("(JI)I"),
VC(Java_org_videolan_Libbluray_readPSRN),
CC("readRegN"),
CC("(JII)I"),
VC(Java_org_videolan_Libbluray_readRegN),
},
{
CC("cacheBdRomFileN"),
......
......@@ -206,35 +206,19 @@ JNIEXPORT jint JNICALL Java_org_videolan_Libbluray_selectRateN
/*
* Class: org_videolan_Libbluray
* Method: writeGPRN
* Signature: (JII)I
*/
JNIEXPORT jint JNICALL Java_org_videolan_Libbluray_writeGPRN
(JNIEnv *, jclass, jlong, jint, jint);
/*
* Class: org_videolan_Libbluray
* Method: writePSRN
* Signature: (JIII)I
*/
JNIEXPORT jint JNICALL Java_org_videolan_Libbluray_writePSRN
(JNIEnv *, jclass, jlong, jint, jint, jint);
/*
* Class: org_videolan_Libbluray
* Method: readGPRN
* Signature: (JI)I
* Method: writeRegN
* Signature: (JIIII)I
*/
JNIEXPORT jint JNICALL Java_org_videolan_Libbluray_readGPRN
(JNIEnv *, jclass, jlong, jint);
JNIEXPORT jint JNICALL Java_org_videolan_Libbluray_writeRegN
(JNIEnv *, jclass, jlong, jint, jint, jint, jint);
/*
* Class: org_videolan_Libbluray
* Method: readPSRN
* Signature: (JI)I
* Method: readRegN
* Signature: (JII)I
*/
JNIEXPORT jint JNICALL Java_org_videolan_Libbluray_readPSRN
(JNIEnv *, jclass, jlong, jint);
JNIEXPORT jint JNICALL Java_org_videolan_Libbluray_readRegN
(JNIEnv *, jclass, jlong, jint, jint);
/*
* Class: org_videolan_Libbluray
......
/*
* This file is part of libbluray
* Copyright (C) 2009-2010 John Stebbins
* Copyright (C) 2010-2016 Petri Hintukainen
* Copyright (C) 2010-2019 Petri Hintukainen <phintuka@users.sourceforge.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -601,7 +601,7 @@ _extrapolate_title(NAV_TITLE *title)
static void _fill_clip(NAV_TITLE *title,
const MPLS_CLIP *mpls_clip,
uint8_t connection_condition, uint32_t in_time, uint32_t out_time,
unsigned pi_angle_count,
unsigned pi_angle_count, unsigned still_mode, unsigned still_time,
NAV_CLIP *clip,
unsigned ref, uint32_t *pos, uint32_t *time)
......@@ -610,6 +610,8 @@ static void _fill_clip(NAV_TITLE *title,
clip->title = title;
clip->ref = ref;
clip->still_mode = still_mode;
clip->still_time = still_time;
if (title->angle >= pi_angle_count) {
clip->angle = 0;
......@@ -741,7 +743,7 @@ NAV_TITLE* nav_title_open(BD_DISC *disc, const char *playlist, unsigned angle)
clip = &title->clip_list.clip[ii];
_fill_clip(title, pi->clip, pi->connection_condition, pi->in_time, pi->out_time, pi->angle_count,
clip, ii, &pos, &time);
pi->still_mode, pi->still_time, clip, ii, &pos, &time);
}
}
......@@ -775,7 +777,7 @@ NAV_TITLE* nav_title_open(BD_DISC *disc, const char *playlist, unsigned angle)
NAV_CLIP *clip = &sub_path->clip_list.clip[ii];
_fill_clip(title, pi->clip, pi->connection_condition, pi->in_time, pi->out_time, 0,
clip, ii, &pos, &time);
0, 0, clip, ii, &pos, &time);
}
}
}
......@@ -1047,7 +1049,7 @@ NAV_CLIP* nav_set_angle(NAV_TITLE *title, NAV_CLIP *clip, unsigned angle)
cl = &title->clip_list.clip[ii];
_fill_clip(title, pi->clip, pi->connection_condition, pi->in_time, pi->out_time, pi->angle_count,
cl, ii, &pos, &time);
pi->still_mode, pi->still_time, cl, ii, &pos, &time);
}
_extrapolate_title(title);
return clip;
......
......@@ -85,6 +85,9 @@ struct nav_clip_s
uint32_t stc_spn; /* start packet of clip STC sequence */
uint8_t still_mode;
uint16_t still_time;
struct clpi_cl *cl;
};
......
......@@ -2,7 +2,7 @@
* This file is part of libbluray
* Copyright (C) 2009-2010 Obliter0n
* Copyright (C) 2009-2010 John Stebbins
* Copyright (C) 2010-2017 Petri Hintukainen
* Copyright (C) 2010-2019 Petri Hintukainen <phintuka@users.sourceforge.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -1062,12 +1062,17 @@ static void _fill_disc_info(BLURAY *bd, BD_ENC_INFO *enc_info)
bd->disc_info.top_menu = titles[0];
}
/* no BD-J menu support for profile 6 */
if (bd->disc_info.num_bdj_titles) {
// XXX actually, should check from bdjo files ...
if (index->indx_version >= ('0' << 24 | '3' << 16 | '0' << 8 | '0')) {
BD_DEBUG(DBG_CRIT | DBG_BLURAY, "WARNING: BluRay profile 6 BD-J menus are not supported\n");
bd->disc_info.no_menu_support = 1;
/* increase player profile and version when 3D or UHD disc is detected */
if (index->indx_version >= ('0' << 24 | '3' << 16 | '0' << 8 | '0')) {
BD_DEBUG(DBG_CRIT | DBG_BLURAY, "WARNING: BluRay profile 6 BD-J menu support is experimental\n");
/* Switch to UHD profile */
psr_init_UHD(bd->regs, 1);
}
if (((index->indx_version >> 16) & 0xff) == '2') {
if (index->app_info.content_exist_flag) {
/* Switch to 3D profile */
psr_init_3D(bd->regs, index->app_info.initial_output_mode_preference, 0);
}
}
......@@ -1934,16 +1939,14 @@ static int _bd_read(BLURAY *bd, unsigned char *buf, int len)
return out_len;
}
MPLS_PI *pi = &st->clip->title->pl->play_item[st->clip->ref];
// handle still mode clips
if (pi->still_mode == BLURAY_STILL_INFINITE) {
if (st->clip->still_mode == BLURAY_STILL_INFINITE) {
_queue_event(bd, BD_EVENT_STILL_TIME, 0);
return 0;
}
if (pi->still_mode == BLURAY_STILL_TIME) {
if (st->clip->still_mode == BLURAY_STILL_TIME) {
if (bd->event_queue) {
_queue_event(bd, BD_EVENT_STILL_TIME, pi->still_time);
_queue_event(bd, BD_EVENT_STILL_TIME, st->clip->still_time);
return 0;
}
}
......@@ -2063,9 +2066,7 @@ int bd_read_skip_still(BLURAY *bd)
bd_mutex_lock(&bd->mutex);
if (st->clip) {
MPLS_PI *pi = &st->clip->title->pl->play_item[st->clip->ref];
if (pi->still_mode == BLURAY_STILL_TIME) {
if (st->clip->still_mode == BLURAY_STILL_TIME) {
st->clip = nav_next_clip(bd->title, st->clip);
if (st->clip) {
ret = _open_m2ts(bd, st);
......