From f3113e7055bb2474d52f192a8fbacf752d35de22 Mon Sep 17 00:00:00 2001 From: Oliver Woodman Date: Mon, 26 Oct 2015 15:32:49 +0000 Subject: [PATCH] Use MediaCodecUtil.IsSizeAndRateSupportedV21 where available. --- .../chunk/VideoFormatSelectorUtil.java | 13 ++-- .../exoplayer/dash/DashChunkSource.java | 45 +------------- .../android/exoplayer/util/MimeTypes.java | 61 +++++++++++++++++++ 3 files changed, 72 insertions(+), 47 deletions(-) diff --git a/library/src/main/java/com/google/android/exoplayer/chunk/VideoFormatSelectorUtil.java b/library/src/main/java/com/google/android/exoplayer/chunk/VideoFormatSelectorUtil.java index f9a4aae6b7..92d4da5ad5 100644 --- a/library/src/main/java/com/google/android/exoplayer/chunk/VideoFormatSelectorUtil.java +++ b/library/src/main/java/com/google/android/exoplayer/chunk/VideoFormatSelectorUtil.java @@ -17,6 +17,7 @@ package com.google.android.exoplayer.chunk; import com.google.android.exoplayer.MediaCodecUtil; import com.google.android.exoplayer.MediaCodecUtil.DecoderQueryException; +import com.google.android.exoplayer.util.MimeTypes; import com.google.android.exoplayer.util.Util; import android.annotation.TargetApi; @@ -138,7 +139,7 @@ public final class VideoFormatSelectorUtil { * whether HD formats should be filtered and a maximum decodable frame size in pixels. */ private static boolean isFormatPlayable(Format format, String[] allowedContainerMimeTypes, - boolean filterHdFormats, int maxDecodableFrameSize) { + boolean filterHdFormats, int maxDecodableFrameSize) throws DecoderQueryException { if (allowedContainerMimeTypes != null && !Util.contains(allowedContainerMimeTypes, format.mimeType)) { // Filtering format based on its container mime type. @@ -149,9 +150,13 @@ public final class VideoFormatSelectorUtil { return false; } if (format.width > 0 && format.height > 0) { - // TODO: Use MediaCodecUtil.isSizeAndRateSupportedV21 on API levels >= 21 if we know the - // mimeType of the media samples within the container. Remove the assumption that we're - // dealing with H.264. + String videoMediaMimeType = MimeTypes.getVideoMediaMimeType(format.codecs); + if (Util.SDK_INT >= 21 && !MimeTypes.VIDEO_UNKNOWN.equals(videoMediaMimeType)) { + float frameRate = (format.frameRate > 0) ? format.frameRate : 30.0f; + return MediaCodecUtil.isSizeAndRateSupportedV21(videoMediaMimeType, false, + format.width, format.height, frameRate); + } + //Assuming that the media is H.264 if (format.width * format.height > maxDecodableFrameSize) { // Filtering stream that device cannot play return false; diff --git a/library/src/main/java/com/google/android/exoplayer/dash/DashChunkSource.java b/library/src/main/java/com/google/android/exoplayer/dash/DashChunkSource.java index 48f8d95d91..36265aa5ab 100644 --- a/library/src/main/java/com/google/android/exoplayer/dash/DashChunkSource.java +++ b/library/src/main/java/com/google/android/exoplayer/dash/DashChunkSource.java @@ -52,7 +52,6 @@ import com.google.android.exoplayer.util.MimeTypes; import com.google.android.exoplayer.util.SystemClock; import android.os.Handler; -import android.text.TextUtils; import android.util.Log; import android.util.SparseArray; @@ -628,9 +627,9 @@ public class DashChunkSource implements ChunkSource, Output { private static String getMediaMimeType(Format format) { String formatMimeType = format.mimeType; if (MimeTypes.isAudio(formatMimeType)) { - return getAudioMediaMimeType(format); + return MimeTypes.getAudioMediaMimeType(format.codecs); } else if (MimeTypes.isVideo(formatMimeType)) { - return getVideoMediaMimeType(format); + return MimeTypes.getVideoMediaMimeType(format.codecs); } else if (mimeTypeIsRawText(formatMimeType)) { return formatMimeType; } else if (MimeTypes.APPLICATION_MP4.equals(formatMimeType) && "stpp".equals(format.codecs)) { @@ -640,46 +639,6 @@ public class DashChunkSource implements ChunkSource, Output { } } - private static String getVideoMediaMimeType(Format format) { - String codecs = format.codecs; - if (TextUtils.isEmpty(codecs)) { - Log.w(TAG, "Codecs attribute missing: " + format.id); - return MimeTypes.VIDEO_UNKNOWN; - } else if (codecs.startsWith("avc1") || codecs.startsWith("avc3")) { - return MimeTypes.VIDEO_H264; - } else if (codecs.startsWith("hev1") || codecs.startsWith("hvc1")) { - return MimeTypes.VIDEO_H265; - } else if (codecs.startsWith("vp9")) { - return MimeTypes.VIDEO_VP9; - } else if (codecs.startsWith("vp8")) { - return MimeTypes.VIDEO_VP8; - } - Log.w(TAG, "Failed to parse mime from codecs: " + format.id + ", " + codecs); - return MimeTypes.VIDEO_UNKNOWN; - } - - private static String getAudioMediaMimeType(Format format) { - String codecs = format.codecs; - if (TextUtils.isEmpty(codecs)) { - Log.w(TAG, "Codecs attribute missing: " + format.id); - return MimeTypes.AUDIO_UNKNOWN; - } else if (codecs.startsWith("mp4a")) { - return MimeTypes.AUDIO_AAC; - } else if (codecs.startsWith("ac-3") || codecs.startsWith("dac3")) { - return MimeTypes.AUDIO_AC3; - } else if (codecs.startsWith("ec-3") || codecs.startsWith("dec3")) { - return MimeTypes.AUDIO_EC3; - } else if (codecs.startsWith("dtsc") || codecs.startsWith("dtse")) { - return MimeTypes.AUDIO_DTS; - } else if (codecs.startsWith("dtsh") || codecs.startsWith("dtsl")) { - return MimeTypes.AUDIO_DTS_HD; - } else if (codecs.startsWith("opus")) { - return MimeTypes.AUDIO_OPUS; - } - Log.w(TAG, "Failed to parse mime from codecs: " + format.id + ", " + codecs); - return MimeTypes.AUDIO_UNKNOWN; - } - /* package */ static boolean mimeTypeIsWebm(String mimeType) { return mimeType.startsWith(MimeTypes.VIDEO_WEBM) || mimeType.startsWith(MimeTypes.AUDIO_WEBM) || mimeType.startsWith(MimeTypes.APPLICATION_WEBM); diff --git a/library/src/main/java/com/google/android/exoplayer/util/MimeTypes.java b/library/src/main/java/com/google/android/exoplayer/util/MimeTypes.java index 15cf132217..d89a7179df 100644 --- a/library/src/main/java/com/google/android/exoplayer/util/MimeTypes.java +++ b/library/src/main/java/com/google/android/exoplayer/util/MimeTypes.java @@ -15,6 +15,8 @@ */ package com.google.android.exoplayer.util; +import android.text.TextUtils; + /** * Defines common MIME types and helper methods. */ @@ -52,6 +54,7 @@ public final class MimeTypes { public static final String AUDIO_VORBIS = BASE_TYPE_AUDIO + "/vorbis"; public static final String AUDIO_OPUS = BASE_TYPE_AUDIO + "/opus"; + public static final String TEXT_UNKNOWN = BASE_TYPE_TEXT + "/x-unknown"; public static final String TEXT_VTT = BASE_TYPE_TEXT + "/vtt"; public static final String APPLICATION_MP4 = BASE_TYPE_APPLICATION + "/mp4"; @@ -119,4 +122,62 @@ public final class MimeTypes { return mimeType.substring(0, indexOfSlash); } + /** + * Returns the video mimeType type of {@code codecs}. + * + * @param codecs The codecs for which the video mimeType is required. + * @return The video mimeType. + */ + public static String getVideoMediaMimeType(String codecs) { + if (codecs == null) { + return MimeTypes.VIDEO_UNKNOWN; + } + String[] codecList = codecs.split(","); + for (String codec : codecList) { + codec = codec.trim(); + if (codec.startsWith("avc1") || codec.startsWith("avc3")) { + return MimeTypes.VIDEO_H264; + } else if (codec.startsWith("hev1") || codec.startsWith("hvc1")) { + return MimeTypes.VIDEO_H265; + } else if (codec.startsWith("vp9")) { + return MimeTypes.VIDEO_VP9; + } else if (codec.startsWith("vp8")) { + return MimeTypes.VIDEO_VP8; + } + } + return MimeTypes.VIDEO_UNKNOWN; + } + + /** + * Returns the audio mimeType type of {@code codecs}. + * + * @param codecs The codecs for which the audio mimeType is required. + * @return The audio mimeType. + */ + public static String getAudioMediaMimeType(String codecs) { + if (codecs == null) { + return MimeTypes.AUDIO_UNKNOWN; + } + String[] codecList = codecs.split(","); + for (String codec : codecList) { + codec = codec.trim(); + if (codec.startsWith("mp4a")) { + return MimeTypes.AUDIO_AAC; + } else if (codec.startsWith("ac-3") || codec.startsWith("dac3")) { + return MimeTypes.AUDIO_AC3; + } else if (codec.startsWith("ec-3") || codec.startsWith("dec3")) { + return MimeTypes.AUDIO_EC3; + } else if (codec.startsWith("dtsc") || codec.startsWith("dtse")) { + return MimeTypes.AUDIO_DTS; + } else if (codec.startsWith("dtsh") || codec.startsWith("dtsl")) { + return MimeTypes.AUDIO_DTS_HD; + } else if (codec.startsWith("opus")) { + return MimeTypes.AUDIO_OPUS; + } else if (codec.startsWith("vorbis")) { + return MimeTypes.AUDIO_VORBIS; + } + } + return MimeTypes.AUDIO_UNKNOWN; + } + }