[Android] [RFC] [PATCH] android: Allow enabling the android mediacodec decoder

Martin Storsjö martin at martin.st
Mon Oct 8 17:51:07 CEST 2012


This changes the hw decoding setting into a combo box, just like
the audio output. On devices prior to 4.1, you only have the
options Off and IOMX there, while you get MediaCodec as an
alternative on 4.1. (This is only to not confuse users, the code
falls back cleanly if ran on older android versions.)

This is useful for being able to switch between the different
codepaths, until the MediaCodec code has received wider testing.
In practice, the MediaCodec API is a thin wrapper on top of IOMX,
so normally the decoders there will have the same quirks, more or
less.
---
 vlc-android/jni/libvlcjni.c                        |   14 +++++++---
 vlc-android/res/values/strings.xml                 |   21 +++++++++++++++
 vlc-android/res/xml/preferences.xml                |    8 +++---
 vlc-android/src/org/videolan/vlc/LibVLC.java       |   28 +++++++++++++++-----
 .../org/videolan/vlc/gui/PreferencesActivity.java  |   22 ++++++++-------
 5 files changed, 70 insertions(+), 23 deletions(-)

diff --git a/vlc-android/jni/libvlcjni.c b/vlc-android/jni/libvlcjni.c
index 42ca612..9d0049a 100644
--- a/vlc-android/jni/libvlcjni.c
+++ b/vlc-android/jni/libvlcjni.c
@@ -46,6 +46,10 @@
 #define AOUT_AUDIOTRACK_JAVA 1
 #define AOUT_OPENSLES        2
 
+#define HWDEC_OFF        0
+#define HWDEC_IOMX       1
+#define HWDEC_MEDIACODEC 2
+
 static jint getInt(JNIEnv *env, jobject thiz, const char* field) {
     jclass clazz = (*env)->GetObjectClass(env, thiz);
     jfieldID fieldMP = (*env)->GetFieldID(env, clazz,
@@ -149,8 +153,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, "getHwdec", "()I");
+        int hwdec = (*env)->CallIntMethod(env, thiz, methodId);
+        if (hwdec != HWDEC_OFF) {
             /*
              * Set higher caching values if using iomx decoding, since some omx
              * decoders have a very high latency, and if the preroll data isn't
@@ -162,7 +167,10 @@ libvlc_media_t *new_media(jlong instance, JNIEnv *env, jobject thiz, jstring fil
              */
             libvlc_media_add_option(p_md, ":file-caching=1500");
             libvlc_media_add_option(p_md, ":network-caching=1500");
-            libvlc_media_add_option(p_md, ":codec=iomx,all");
+            if (hwdec == HWDEC_MEDIACODEC)
+                libvlc_media_add_option(p_md, ":codec=mediacodec,iomx,all");
+            else
+                libvlc_media_add_option(p_md, ":codec=iomx,all");
         }
         if (noVideo)
             libvlc_media_add_option(p_md, ":no-video");
diff --git a/vlc-android/res/values/strings.xml b/vlc-android/res/values/strings.xml
index 6cf1773..ddc77eb 100644
--- a/vlc-android/res/values/strings.xml
+++ b/vlc-android/res/values/strings.xml
@@ -177,5 +177,26 @@
         <item>1</item>
         <item>2</item>
     </string-array>
+    <string name="hwdec_mediacodec">MediaCodec</string>
+    <string name="hwdec_iomx">IOMX</string>
+    <string name="hwdec_off">Off</string>
+    <string-array name="hwdec">
+        <item>@string/hwdec_mediacodec</item>
+        <item>@string/hwdec_iomx</item>
+        <item>@string/hwdec_off</item>
+    </string-array>
+    <string-array name="hwdec_values">
+        <item>2</item>
+        <item>1</item>
+        <item>0</item>
+    </string-array>
+    <string-array name="hwdec_ics">
+        <item>@string/hwdec_iomx</item>
+        <item>@string/hwdec_off</item>
+    </string-array>
+    <string-array name="hwdec_values_ics">
+        <item>1</item>
+        <item>0</item>
+    </string-array>
 
 </resources>
\ No newline at end of file
diff --git a/vlc-android/res/xml/preferences.xml b/vlc-android/res/xml/preferences.xml
index 4d35c7d..7df451e 100644
--- a/vlc-android/res/xml/preferences.xml
+++ b/vlc-android/res/xml/preferences.xml
@@ -14,10 +14,10 @@
         </PreferenceScreen>
     </PreferenceCategory>
     <PreferenceCategory android:title="@string/main_prefs_category">
-        <CheckBoxPreference
-            android:key="enable_iomx"
-            android:title="@string/enable_iomx">
-        </CheckBoxPreference>
+        <ListPreference
+            android:key="hwdec"
+            android:defaultValue="@string/hwdec_off"
+            android:title="@string/enable_iomx" />
         <CheckBoxPreference
             android:key="enable_headset_detection"
             android:title="@string/detect_headset"
diff --git a/vlc-android/src/org/videolan/vlc/LibVLC.java b/vlc-android/src/org/videolan/vlc/LibVLC.java
index 873574e..9b35019 100644
--- a/vlc-android/src/org/videolan/vlc/LibVLC.java
+++ b/vlc-android/src/org/videolan/vlc/LibVLC.java
@@ -37,8 +37,12 @@ public class LibVLC {
     private static final int AOUT_AUDIOTRACK_JAVA = 0;
     private static final int AOUT_OPENSLES = 2;
 
+    private static final int HWDEC_OFF = 0;
+    private static final int HWDEC_IOMX = 1;
+    private static final int HWDEC_MEDIACODEC = 2;
+
     private static LibVLC sInstance;
-    private static boolean sUseIomx = false;
+    private static int sHwdec = HWDEC_OFF;
     private static int sAout = AOUT_AUDIOTRACK_JAVA;
 
     /** libVLC instance C pointer */
@@ -141,12 +145,12 @@ public class LibVLC {
     /**
      *
      */
-    public boolean useIOMX() {
-        return sUseIomx;
+    public int getHwdec() {
+        return sHwdec;
     }
 
-    public static synchronized void setIOMX(boolean enable) {
-        sUseIomx = enable;
+    public static synchronized void setHwdec(Integer pref) {
+        sHwdec = pref;
     }
 
     public int getAout() {
@@ -155,7 +159,19 @@ public class LibVLC {
 
     public static synchronized void useIOMX(Context context) {
         SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
-        sUseIomx = pref.getBoolean("enable_iomx", false);
+        if (pref.contains("hwdec")) {
+            try {
+                sHwdec = Integer.parseInt(pref.getString("hwdec", String.valueOf(HWDEC_OFF)));
+            } catch (NumberFormatException nfe) {
+                sHwdec = HWDEC_OFF;
+            }
+        } else {
+            boolean iomx = pref.getBoolean("enable_iomx", false);
+            sHwdec = iomx ? HWDEC_IOMX : HWDEC_OFF;
+            SharedPreferences.Editor edit = pref.edit();
+            edit.putString("hwdec", String.valueOf(sHwdec));
+            edit.commit();
+        }
         try {
             sAout = Integer.parseInt(pref.getString("aout", String.valueOf(AOUT_AUDIOTRACK_JAVA)));
         } catch (NumberFormatException nfe) {
diff --git a/vlc-android/src/org/videolan/vlc/gui/PreferencesActivity.java b/vlc-android/src/org/videolan/vlc/gui/PreferencesActivity.java
index 8ad7cb2..21bab82 100644
--- a/vlc-android/src/org/videolan/vlc/gui/PreferencesActivity.java
+++ b/vlc-android/src/org/videolan/vlc/gui/PreferencesActivity.java
@@ -106,16 +106,18 @@ public class PreferencesActivity extends PreferenceActivity {
                 });
 
         // HW decoding
-        CheckBoxPreference checkboxHW = (CheckBoxPreference) findPreference("enable_iomx");
-        checkboxHW.setOnPreferenceClickListener(
-                new OnPreferenceClickListener() {
-                    @Override
-                    public boolean onPreferenceClick(Preference preference) {
-                        CheckBoxPreference checkboxHW = (CheckBoxPreference) preference;
-                        LibVLC.setIOMX(checkboxHW.isChecked());
-                        return true;
-                    }
-                });
+        ListPreference hwdecPref = (ListPreference) findPreference("hwdec");
+        int hwdecEntriesId = Util.isJellyBeanOrLater() ? R.array.hwdec : R.array.hwdec_ics;
+        int hwdecEntriesIdValues = Util.isJellyBeanOrLater() ? R.array.hwdec_values : R.array.hwdec_values_ics;
+        hwdecPref.setEntries(hwdecEntriesId);
+        hwdecPref.setEntryValues(hwdecEntriesIdValues);
+        hwdecPref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
+            @Override
+            public boolean onPreferenceChange(Preference preference, Object newValue) {
+                LibVLC.setHwdec(Integer.valueOf((String) newValue));
+                return true;
+            }
+        });
 
         // Headset detection option
         CheckBoxPreference checkboxHS = (CheckBoxPreference) findPreference("enable_headset_detection");
-- 
1.7.10



More information about the Android mailing list