[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