[Android] libvlc: Media: set default HWDecoders options

Thomas Guillem git at videolan.org
Mon Jun 8 16:06:43 CEST 2015


vlc-ports/android | branch: master | Thomas Guillem <thomas at gllm.fr> | Mon Jun  8 16:05:13 2015 +0200| [3339fcd038341af20a126e8617ab73280161b840] | committer: Thomas Guillem

libvlc: Media: set default HWDecoders options

> http://git.videolan.org/gitweb.cgi/vlc-ports/android.git/?a=commit;h=3339fcd038341af20a126e8617ab73280161b840
---

 libvlc/src/org/videolan/libvlc/Media.java          |   60 +++++++++++++++++
 libvlc/src/org/videolan/libvlc/MediaPlayer.java    |    1 +
 .../org/videolan/vlc/MediaWrapperListPlayer.java   |    4 +-
 .../src/org/videolan/vlc/util/VLCOptions.java      |   68 ++++----------------
 4 files changed, 74 insertions(+), 59 deletions(-)

diff --git a/libvlc/src/org/videolan/libvlc/Media.java b/libvlc/src/org/videolan/libvlc/Media.java
index 9413405..ef66944 100644
--- a/libvlc/src/org/videolan/libvlc/Media.java
+++ b/libvlc/src/org/videolan/libvlc/Media.java
@@ -22,6 +22,9 @@ package org.videolan.libvlc;
 
 import android.net.Uri;
 
+import org.videolan.libvlc.util.AndroidUtil;
+import org.videolan.libvlc.util.HWDecoderUtil;
+
 import java.io.FileDescriptor;
 
 public class Media extends VLCObject {
@@ -224,6 +227,7 @@ public class Media extends VLCObject {
     private long mDuration;
     private int mState = State.NothingSpecial;
     private int mType = Type.Unknown;
+    private boolean mCodecOptionSet = false;
 
     /**
      * Create a Media from libVLC and a local path starting with '/'.
@@ -512,12 +516,68 @@ public class Media extends VLCObject {
         return mNativeMetas != null ? mNativeMetas[id] : null;
     }
 
+    private static String getMediaCodecModule() {
+        return AndroidUtil.isLolliPopOrLater() ? "mediacodec_ndk" : "mediacodec_jni";
+    }
+
+
+    /**
+     * Add or remove hw acceleration media options
+     *
+     * @param enabled
+     * @param force force hw acceleration even for unknown devices
+     */
+    public void setHWDecoderEnabled(boolean enabled, boolean force) {
+        final HWDecoderUtil.Decoder decoder = enabled ?
+                HWDecoderUtil.getDecoderFromDevice() :
+                HWDecoderUtil.Decoder.NONE;
+
+        if (decoder == HWDecoderUtil.Decoder.NONE ||
+                (decoder == HWDecoderUtil.Decoder.UNKNOWN && !force)) {
+            addOption(":codec=all");
+            return;
+        }
+
+        /*
+         * Set higher caching values if using iomx decoding, since some omx
+         * decoders have a very high latency, and if the preroll data isn't
+         * enough to make the decoder output a frame, the playback timing gets
+         * started too soon, and every decoded frame appears to be too late.
+         * On Nexus One, the decoder latency seems to be 25 input packets
+         * for 320x170 H.264, a few packets less on higher resolutions.
+         * On Nexus S, the decoder latency seems to be about 7 packets.
+         */
+        addOption(":file-caching=1500");
+        addOption(":network-caching=1500");
+
+        final StringBuilder sb = new StringBuilder(":codec=");
+        if (decoder == HWDecoderUtil.Decoder.MEDIACODEC)
+            sb.append(getMediaCodecModule()).append(",");
+        else if (decoder == HWDecoderUtil.Decoder.OMX)
+            sb.append("iomx,");
+        else
+            sb.append(getMediaCodecModule()).append(",iomx,");
+        sb.append("all");
+
+        addOption(sb.toString());
+    }
+
+    /**
+     * Enable HWDecoder options if not already set
+     */
+    protected void setDefaultMediaPlayerOptions() {
+        if (!mCodecOptionSet)
+            setHWDecoderEnabled(true, false);
+    }
+
     /**
      * Add an option to this Media. This Media should be alive (not released).
      *
      * @param option ":option" or ":option=value"
      */
     public synchronized void addOption(String option) {
+        if (!mCodecOptionSet && option.startsWith(":codec="))
+            mCodecOptionSet = true;
         nativeAddOption(option);
     }
 
diff --git a/libvlc/src/org/videolan/libvlc/MediaPlayer.java b/libvlc/src/org/videolan/libvlc/MediaPlayer.java
index 213bef0..205cbac 100644
--- a/libvlc/src/org/videolan/libvlc/MediaPlayer.java
+++ b/libvlc/src/org/videolan/libvlc/MediaPlayer.java
@@ -84,6 +84,7 @@ public class MediaPlayer extends VLCObject {
             if (media.isReleased())
                 throw new IllegalArgumentException("Media is released");
             media.retain();
+            media.setDefaultMediaPlayerOptions();
         }
         mMedia = media;
         nativeSetMedia(mMedia);
diff --git a/vlc-android/src/org/videolan/vlc/MediaWrapperListPlayer.java b/vlc-android/src/org/videolan/vlc/MediaWrapperListPlayer.java
index 601d6a0..345d123 100644
--- a/vlc-android/src/org/videolan/vlc/MediaWrapperListPlayer.java
+++ b/vlc-android/src/org/videolan/vlc/MediaWrapperListPlayer.java
@@ -64,12 +64,10 @@ public class MediaWrapperListPlayer {
         if (mrl == null)
             return;
         final MediaWrapper mw = mMediaList.getMedia(position);
-        String[] options = VLCOptions.getMediaOptions(context, flags | (mw != null ? mw.getFlags() : 0));
         mPlayerIndex = position;
 
         final Media media = new Media(VLCInstance.get(), mw.getUri());
-        for (String option : options)
-            media.addOption(option);
+        VLCOptions.setMediaOptions(media, context, flags | (mw != null ? mw.getFlags() : 0));
         VLCInstance.getMainMediaPlayer().setMedia(media);
         media.release();
         VLCInstance.getMainMediaPlayer().setEqualizer(VLCOptions.getEqualizer());
diff --git a/vlc-android/src/org/videolan/vlc/util/VLCOptions.java b/vlc-android/src/org/videolan/vlc/util/VLCOptions.java
index 7dcb94e..eb08268 100644
--- a/vlc-android/src/org/videolan/vlc/util/VLCOptions.java
+++ b/vlc-android/src/org/videolan/vlc/util/VLCOptions.java
@@ -25,6 +25,7 @@ import android.content.SharedPreferences;
 import android.preference.PreferenceManager;
 import android.util.Log;
 
+import org.videolan.libvlc.Media;
 import org.videolan.libvlc.util.VLCUtil;
 import org.videolan.libvlc.util.AndroidUtil;
 import org.videolan.libvlc.util.HWDecoderUtil;
@@ -189,43 +190,12 @@ public class VLCOptions {
         }
     }
 
-    private static String getHardwareAccelerationOption(HWDecoderUtil.Decoder decoder, int hardwareAcceleration) {
-        if (hardwareAcceleration == HW_ACCELERATION_DISABLED) {
-            Log.d(TAG, "HWDec disabled: by user");
-            return "all";
-        } else {
-            // OMX, MEDIACODEC or ALL
-            String codecList;
-            if (decoder == HWDecoderUtil.Decoder.ALL)
-                codecList = DEFAULT_CODEC_LIST;
-            else {
-                final StringBuilder sb = new StringBuilder();
-                if (decoder == HWDecoderUtil.Decoder.MEDIACODEC)
-                    sb.append("mediacodec_ndk,mediacodec_jni,");
-                else if (decoder == HWDecoderUtil.Decoder.OMX)
-                    sb.append("iomx,");
-                sb.append("all");
-                codecList = sb.toString();
-            }
-            Log.d(TAG, "HWDec enabled: device working with: " + codecList);
-            return codecList;
-        }
-    }
-
-    public static String[] getMediaOptions(Context context, boolean noHardwareAcceleration, boolean noVideo) {
-        final int flag = (noHardwareAcceleration ? MEDIA_NO_HWACCEL : 0) |
-                (noVideo ? MEDIA_NO_VIDEO : 0);
-        return getMediaOptions(context, flag);
-    }
-
-    public static String[] getMediaOptions(Context context, int flags) {
+    public static void setMediaOptions(Media media, Context context, int flags) {
         boolean noHardwareAcceleration = (flags & MEDIA_NO_HWACCEL) != 0;
         boolean noVideo = (flags & MEDIA_NO_VIDEO) != 0;
         final boolean paused = (flags & MEDIA_PAUSED) != 0;
         int hardwareAcceleration = HW_ACCELERATION_DISABLED;
 
-        final HWDecoderUtil.Decoder decoder = HWDecoderUtil.getDecoderFromDevice();
-
         if (!noHardwareAcceleration) {
             try {
                 final SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
@@ -233,34 +203,20 @@ public class VLCOptions {
             } catch (NumberFormatException nfe) {
             }
         }
-        hardwareAcceleration = getHardwareAcceleration(decoder, hardwareAcceleration);
-
-        ArrayList<String> options = new ArrayList<String>();
-
-        if (hardwareAcceleration != HW_ACCELERATION_DISABLED) {
-            /*
-             * Set higher caching values if using iomx decoding, since some omx
-             * decoders have a very high latency, and if the preroll data isn't
-             * enough to make the decoder output a frame, the playback timing gets
-             * started too soon, and every decoded frame appears to be too late.
-             * On Nexus One, the decoder latency seems to be 25 input packets
-             * for 320x170 H.264, a few packets less on higher resolutions.
-             * On Nexus S, the decoder latency seems to be about 7 packets.
-             */
-            options.add(":file-caching=1500");
-            options.add(":network-caching=1500");
-            if (hardwareAcceleration != HW_ACCELERATION_FULL) {
-                options.add(":no-mediacodec-dr");
-                options.add(":no-omxil-dr");
+        if (hardwareAcceleration == HW_ACCELERATION_DISABLED)
+            media.setHWDecoderEnabled(false, false);
+        else if (hardwareAcceleration == HW_ACCELERATION_FULL || hardwareAcceleration == HW_ACCELERATION_DECODING) {
+            media.setHWDecoderEnabled(true, true);
+            if (hardwareAcceleration == HW_ACCELERATION_DECODING) {
+                media.addOption(":no-mediacodec-dr");
+                media.addOption(":no-omxil-dr");
             }
-        }
-        options.add(":codec=" + getHardwareAccelerationOption(decoder, hardwareAcceleration));
+        } /* else automatic: use default options */
 
         if (noVideo)
-            options.add(":no-video");
+            media.addOption(":no-video");
         if (paused)
-            options.add(":start-paused");
-        return options.toArray(new String[options.size()]);
+            media.addOption(":start-paused");
     }
 
     // Equalizer



More information about the Android mailing list