[Android] [PATCH] Replace HW acceleration checkbox by a list allowing the user to choose which mode to use

Felix Abecassis felix.abecassis at gmail.com
Tue Jan 21 19:18:55 CET 2014


There are currently 4 modes:
- Automatic: let VLC decide whether hardware acceleration should be used (default).
- Disabled: software decoding only.
- Decoding Acceleration: MediaCodec or OMX decoding.
- Full Acceleration: MediaCodec opaque direct rendering (decoding + display acceleration).
---
 vlc-android/jni/libvlcjni.c                          | 13 +++++++++++--
 vlc-android/res/values/strings.xml                   | 20 ++++++++++++++++++--
 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, 68 insertions(+), 25 deletions(-)

diff --git a/vlc-android/jni/libvlcjni.c b/vlc-android/jni/libvlcjni.c
index cba3bc0..8e003a5 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 HW_ACCELERATION_DISABLED 0
+#define HW_ACCELERATION_DECODING 1
+#define HW_ACCELERATION_FULL     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, "getHardwareAcceleration", "()I");
+        int hardwareAcceleration = (*env)->CallIntMethod(env, thiz, methodId);
+        if (hardwareAcceleration == HW_ACCELERATION_DECODING || hardwareAcceleration == HW_ACCELERATION_FULL) {
             /*
              * 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, "getHardwareAcceleration", "()I");
+    int hardwareAcceleration = (*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",
+        (hardwareAcceleration == HW_ACCELERATION_FULL) ? "" : "--no-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..51ef4ac 100644
--- a/vlc-android/res/values/strings.xml
+++ b/vlc-android/res/values/strings.xml
@@ -193,8 +193,11 @@
     <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="hardware_acceleration">Hardware Acceleration</string>
+    <string name="hardware_acceleration_summary">Disabled: better stability.\nDecoding: may improve performance.\nFull: may improve performance further.</string>
+    <string name="hardware_acceleration_disabled">Disabled</string>
+    <string name="hardware_acceleration_decoding">Decoding Acceleration</string>
+    <string name="hardware_acceleration_full">Full Acceleration</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 +237,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="hardware_acceleration_list">
+        <item>@string/automatic</item>
+        <item>@string/hardware_acceleration_disabled</item>
+        <item>@string/hardware_acceleration_decoding</item>
+        <item>@string/hardware_acceleration_full</item>
+    </string-array>
+    <string-array name="hardware_acceleration_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 f1dccce..bd7cb5f 100644
--- a/vlc-android/res/xml/preferences.xml
+++ b/vlc-android/res/xml/preferences.xml
@@ -57,10 +57,13 @@
             android:key="enable_frame_skip"
             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" />
+        <ListPreference
+            android:defaultValue="-1"
+            android:entries="@array/hardware_acceleration_list"
+            android:entryValues="@array/hardware_acceleration_values"
+            android:key="hardware_acceleration"
+            android:title="@string/hardware_acceleration"
+            android:summary="@string/hardware_acceleration_summary" />
         <CheckBoxPreference
             android:defaultValue="false"
             android:key="enable_time_stretching_audio"
diff --git a/vlc-android/src/org/videolan/libvlc/LibVLC.java b/vlc-android/src/org/videolan/libvlc/LibVLC.java
index bcde3a5..033afef 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 hardwareAcceleration = -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 getHardwareAcceleration() {
+        return this.hardwareAcceleration;
     }
 
-    public void setIomx(boolean iomx) {
-        this.iomx = iomx;
+    public void setHardwareAcceleration(int hardwareAcceleration) {
+        if (hardwareAcceleration < 0) {
+            // Automatic mode: activate MediaCodec opaque direct rendering for 4.3 and above.
+            if (LibVlcUtil.isJellyBeanMR2OrLater())
+                this.hardwareAcceleration = 2;
+            else
+                this.hardwareAcceleration = 0;
+        }
+        else
+            this.hardwareAcceleration = hardwareAcceleration;
     }
 
     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..b941522 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.getHardwareAcceleration() == 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 9c14bd0..4a6206f 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("subtitle_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 hardwareAcceleration;
+        try {
+            hardwareAcceleration = Integer.parseInt(pref.getString("hardware_acceleration", "-1"));
+        }
+        catch(NumberFormatException nfe) {
+            hardwareAcceleration = -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.setHardwareAcceleration(hardwareAcceleration);
     }
 
     /** 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 9e7d15a..5522594 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("hardware_acceleration")
                 || key.equalsIgnoreCase("subtitle_text_encoding")
                 || key.equalsIgnoreCase("aout")
                 || key.equalsIgnoreCase("vout")
-- 
1.8.3.2



More information about the Android mailing list