[Android] [PATCH 2/2] Replace HW acceleration option by a list allowing the user to choose which decoder to use.
Felix Abecassis
felix.abecassis at gmail.com
Thu Jan 16 12:28:21 CET 2014
There are currently 4 modes:
- Automatic: let VLC decide which decoder should be used (default).
- SW: software decoder.
- HW: MediaCodec or OMX decoding.
- HW+: MediaCodec opaque direct rendering.
---
vlc-android/jni/libvlcjni.c | 13 +++++++++++--
vlc-android/res/values/strings.xml | 17 +++++++++++++++--
vlc-android/res/xml/preferences.xml | 11 +++++++----
vlc-android/src/org/videolan/libvlc/LibVLC.java | 18 +++++++++++++-----
vlc-android/src/org/videolan/libvlc/MediaList.java | 20 ++++++++++----------
vlc-android/src/org/videolan/vlc/Util.java | 9 ++++++++-
.../org/videolan/vlc/gui/PreferencesActivity.java | 2 +-
7 files changed, 65 insertions(+), 25 deletions(-)
diff --git a/vlc-android/jni/libvlcjni.c b/vlc-android/jni/libvlcjni.c
index cba3bc0..4dd4540 100644
--- a/vlc-android/jni/libvlcjni.c
+++ b/vlc-android/jni/libvlcjni.c
@@ -42,6 +42,10 @@
#define VOUT_ANDROID_SURFACE 0
#define VOUT_OPENGLES2 1
+#define DECODER_SW 0
+#define DECODER_HW 1
+#define DECODER_HW_DR 2
+
#define LOG_TAG "VLC/JNI/main"
#include "log.h"
@@ -57,8 +61,9 @@ libvlc_media_t *new_media(jlong instance, JNIEnv *env, jobject thiz, jstring fil
if (!noOmx) {
jclass cls = (*env)->GetObjectClass(env, thiz);
- jmethodID methodId = (*env)->GetMethodID(env, cls, "useIOMX", "()Z");
- if ((*env)->CallBooleanMethod(env, thiz, methodId)) {
+ jmethodID methodId = (*env)->GetMethodID(env, cls, "getDecoderType", "()I");
+ int decoderType = (*env)->CallIntMethod(env, thiz, methodId);
+ if (decoderType == DECODER_HW || decoderType == DECODER_HW_DR) {
/*
* Set higher caching values if using iomx decoding, since some omx
* decoders have a very high latency, and if the preroll data isn't
@@ -248,6 +253,9 @@ void Java_org_videolan_libvlc_LibVLC_nativeInit(JNIEnv *env, jobject thiz)
methodId = (*env)->GetMethodID(env, cls, "isVerboseMode", "()Z");
verbosity = (*env)->CallBooleanMethod(env, thiz, methodId);
+ methodId = (*env)->GetMethodID(env, cls, "getDecoderType", "()I");
+ int decoderType = (*env)->CallIntMethod(env, thiz, methodId);
+
/* Don't add any invalid options, otherwise it causes LibVLC to crash */
const char *argv[] = {
"-I", "dummy",
@@ -271,6 +279,7 @@ void Java_org_videolan_libvlc_LibVLC_nativeInit(JNIEnv *env, jobject thiz)
use_opensles ? "--aout=opensles" : "--aout=android_audiotrack",
use_opengles2 ? "--vout=gles2" : "--vout=androidsurface",
"--androidsurface-chroma", chromastr != NULL && chromastr[0] != 0 ? chromastr : "RV32",
+ (decoderType == DECODER_HW_DR) ? "--mediacodec-dr" : "",
};
libvlc_instance_t *instance = libvlc_new(sizeof(argv) / sizeof(*argv), argv);
diff --git a/vlc-android/res/values/strings.xml b/vlc-android/res/values/strings.xml
index e7182e2..45a0c3a 100644
--- a/vlc-android/res/values/strings.xml
+++ b/vlc-android/res/values/strings.xml
@@ -193,8 +193,8 @@
<string name="performance_prefs_category">Performance</string>
<string name="chroma_format">Force video chroma</string>
<string name="chroma_format_summary">RGB 32-bit: default chroma\nRGB 16-bit: better performance but lower quality\nYUV: best performance but does not work on all devices. Android 2.3 and later only.</string>
- <string name="enable_iomx">Hardware accelerated decoding</string>
- <string name="enable_iomx_summary">Improves performance, but may not work with all devices.</string>
+ <string name="decoder_type">Decoder</string>
+ <string name="decoder_type_summary">SW: better stability.\nHW: improve performance for large videos.\nHW+: improve performance further.</string>
<string name="enable_time_stretching_audio">Time-stretching audio</string>
<string name="enable_time_stretching_audio_summary">Speed up and slow down audio without changing the pitch (requires a fast device).</string>
<string name="enable_frame_skip">Enable frame skip</string>
@@ -234,6 +234,19 @@
<string name="set_locale_popup">Quit and reset VLC for changes to take effect.</string>
<string name="quit">Quit application</string>
+ <string-array name="decoder_type_list" translatable="false">
+ <item>@string/automatic</item>
+ <item>SW</item>
+ <item>HW</item>
+ <item>HW+</item>
+ </string-array>
+ <string-array name="decoder_type_values" translatable="false">
+ <item>-1</item>
+ <item>0</item>
+ <item>1</item>
+ <item>2</item>
+ </string-array>
+
<string-array name="deblocking_list">
<item>@string/automatic</item>
<item>@string/deblocking_always</item>
diff --git a/vlc-android/res/xml/preferences.xml b/vlc-android/res/xml/preferences.xml
index 0c7b564..9235df7 100644
--- a/vlc-android/res/xml/preferences.xml
+++ b/vlc-android/res/xml/preferences.xml
@@ -9,6 +9,13 @@
</PreferenceCategory>
<PreferenceCategory android:title="@string/main_prefs_category" >
+ <ListPreference
+ android:defaultValue="-1"
+ android:entries="@array/decoder_type_list"
+ android:entryValues="@array/decoder_type_values"
+ android:key="decoder_type"
+ android:title="@string/decoder_type"
+ android:summary="@string/decoder_type_summary" />
<ListPreference
android:defaultValue="0"
android:entries="@array/screen_orientation_list"
@@ -58,10 +65,6 @@
android:summary="@string/enable_frame_skip_summary"
android:title="@string/enable_frame_skip" />
<CheckBoxPreference
- android:key="enable_iomx"
- android:summary="@string/enable_iomx_summary"
- android:title="@string/enable_iomx" />
- <CheckBoxPreference
android:defaultValue="false"
android:key="enable_time_stretching_audio"
android:summary="@string/enable_time_stretching_audio_summary"
diff --git a/vlc-android/src/org/videolan/libvlc/LibVLC.java b/vlc-android/src/org/videolan/libvlc/LibVLC.java
index bcde3a5..5f3b5ed 100644
--- a/vlc-android/src/org/videolan/libvlc/LibVLC.java
+++ b/vlc-android/src/org/videolan/libvlc/LibVLC.java
@@ -58,7 +58,7 @@ public class LibVLC {
//private WakeLock mWakeLock;
/** Settings */
- private boolean iomx = false;
+ private int decoderType = -1;
private String subtitlesEncoding = "";
private int aout = LibVlcUtil.isGingerbreadOrLater() ? AOUT_OPENSLES : AOUT_AUDIOTRACK_JAVA;
private int vout = VOUT_ANDROID_SURFACE;
@@ -216,12 +216,20 @@ public class LibVLC {
* those get/is* are called from native code to get settings values.
*/
- public boolean useIOMX() {
- return iomx;
+ public int getDecoderType() {
+ return this.decoderType;
}
- public void setIomx(boolean iomx) {
- this.iomx = iomx;
+ public void setDecoderType(int decoderType) {
+ if (decoderType < 0) {
+ // Automatic mode: activate MediaCodec opaque direct rendering for 4.3 and above.
+ if (LibVlcUtil.isJellyBeanMR2OrLater())
+ this.decoderType = 2;
+ else
+ this.decoderType = 0;
+ }
+ else
+ this.decoderType = decoderType;
}
public String getSubtitlesEncoding() {
diff --git a/vlc-android/src/org/videolan/libvlc/MediaList.java b/vlc-android/src/org/videolan/libvlc/MediaList.java
index 5990737..720d652 100644
--- a/vlc-android/src/org/videolan/libvlc/MediaList.java
+++ b/vlc-android/src/org/videolan/libvlc/MediaList.java
@@ -36,13 +36,13 @@ public class MediaList {
private class MediaHolder {
Media m;
boolean noVideo; // default false
- boolean noOmx; // default false
+ boolean noHardwareAcceleration; // default false
public MediaHolder(Media media) {
- m = media; noVideo = false; noOmx = false;
+ m = media; noVideo = false; noHardwareAcceleration = false;
}
- public MediaHolder(Media m_, boolean noVideo_, boolean noOmx_) {
- m = m_; noVideo = noVideo_; noOmx = noOmx_;
+ public MediaHolder(Media m_, boolean noVideo_, boolean noHardwareAcceleration_) {
+ m = m_; noVideo = noVideo_; noHardwareAcceleration = noHardwareAcceleration_;
}
}
@@ -74,8 +74,8 @@ public class MediaList {
public void add(Media media, boolean noVideo) {
add(media, noVideo, false);
}
- public void add(Media media, boolean noVideo, boolean noOmx) {
- mInternalList.add(new MediaHolder(media, noVideo, noOmx));
+ public void add(Media media, boolean noVideo, boolean noHardwareAcceleration) {
+ mInternalList.add(new MediaHolder(media, noVideo, noHardwareAcceleration));
signal_list_event(EventHandler.CustomMediaListItemAdded, mInternalList.size() - 1, media.getLocation());
}
@@ -164,17 +164,17 @@ public class MediaList {
}
public String[] getMediaOptions(int position) {
- boolean noOmx = !mLibVLC.useIOMX();
+ boolean noHardwareAcceleration = mLibVLC.getDecoderType() == 0;
boolean noVideo = false;
if (isValid(position))
{
- if (!noOmx)
- noOmx = mInternalList.get(position).noOmx;
+ if (!noHardwareAcceleration)
+ noHardwareAcceleration = mInternalList.get(position).noHardwareAcceleration;
noVideo = mInternalList.get(position).noVideo;
}
ArrayList<String> options = new ArrayList<String>();
- if (!noOmx) {
+ if (!noHardwareAcceleration) {
/*
* Set higher caching values if using iomx decoding, since some omx
* decoders have a very high latency, and if the preroll data isn't
diff --git a/vlc-android/src/org/videolan/vlc/Util.java b/vlc-android/src/org/videolan/vlc/Util.java
index db19fb8..96b141d 100644
--- a/vlc-android/src/org/videolan/vlc/Util.java
+++ b/vlc-android/src/org/videolan/vlc/Util.java
@@ -115,7 +115,6 @@ public class Util {
if (instance == null)
return;
- instance.setIomx(pref.getBoolean("enable_iomx", false));
instance.setSubtitlesEncoding(pref.getString("subtitles_text_encoding", ""));
instance.setTimeStretching(pref.getBoolean("enable_time_stretching_audio", false));
instance.setFrameSkip(pref.getBoolean("enable_frame_skip", false));
@@ -146,6 +145,13 @@ public class Util {
catch(NumberFormatException nfe) {
deblocking = -1;
}
+ int decoderType;
+ try {
+ decoderType = Integer.parseInt(pref.getString("decoder_type", "-1"));
+ }
+ catch(NumberFormatException nfe) {
+ decoderType = -1;
+ }
int networkCaching = pref.getInt("network_caching_value", 0);
if(networkCaching > 60000)
networkCaching = 60000;
@@ -155,6 +161,7 @@ public class Util {
instance.setVout(vout);
instance.setDeblocking(deblocking);
instance.setNetworkCaching(networkCaching);
+ instance.setDecoderType(decoderType);
}
/** Print an on-screen message to alert the user */
diff --git a/vlc-android/src/org/videolan/vlc/gui/PreferencesActivity.java b/vlc-android/src/org/videolan/vlc/gui/PreferencesActivity.java
index 20e6ae0..bd27c1e 100644
--- a/vlc-android/src/org/videolan/vlc/gui/PreferencesActivity.java
+++ b/vlc-android/src/org/videolan/vlc/gui/PreferencesActivity.java
@@ -227,7 +227,7 @@ public class PreferencesActivity extends PreferenceActivity implements OnSharedP
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
- if(key.equalsIgnoreCase("enable_iomx")
+ if(key.equalsIgnoreCase("decoder_type")
|| key.equalsIgnoreCase("subtitles_text_encoding")
|| key.equalsIgnoreCase("aout")
|| key.equalsIgnoreCase("vout")
--
1.8.3.2
More information about the Android
mailing list