Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(618)

Side by Side Diff: media/base/android/java/src/org/chromium/media/MediaCodecUtil.java

Issue 2106133003: [M52] Make AVDA fall back to software decoding if needed. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@2743
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.media; 5 package org.chromium.media;
6 6
7 import android.annotation.TargetApi; 7 import android.annotation.TargetApi;
8 import android.media.MediaCodec; 8 import android.media.MediaCodec;
9 import android.media.MediaCodecInfo; 9 import android.media.MediaCodecInfo;
10 import android.media.MediaCodecList; 10 import android.media.MediaCodecList;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 } 73 }
74 74
75 private boolean hasNewMediaCodecList() { 75 private boolean hasNewMediaCodecList() {
76 return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; 76 return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
77 } 77 }
78 78
79 private MediaCodecInfo[] mCodecList; 79 private MediaCodecInfo[] mCodecList;
80 } 80 }
81 81
82 /** 82 /**
83 * Return true if and only if name is a software codec.
84 * @param name The codec name, e.g. from MediaCodecInfo.getName().
85 */
86 public static boolean isSoftwareCodec(String name) {
87 // This is structured identically to libstagefright/OMXCodec.cpp .
88 if (name.startsWith("OMX.google.")) return true;
89
90 if (name.startsWith("OMX.")) return false;
91
92 return true;
93 }
94
95 /**
83 * Get a name of default android codec. 96 * Get a name of default android codec.
84 * @param mime MIME type of the media. 97 * @param mime MIME type of the media.
85 * @param direction Whether this is encoder or decoder. 98 * @param direction Whether this is encoder or decoder.
99 * @param requireSoftwareCodec Whether we require a software codec.
86 * @return name of the codec. 100 * @return name of the codec.
87 */ 101 */
88 @CalledByNative 102 @CalledByNative
89 private static String getDefaultCodecName(String mime, int direction) { 103 private static String getDefaultCodecName(
104 String mime, int direction, boolean requireSoftwareCodec) {
90 MediaCodecListHelper codecListHelper = new MediaCodecListHelper(); 105 MediaCodecListHelper codecListHelper = new MediaCodecListHelper();
91 int codecCount = codecListHelper.getCodecCount(); 106 int codecCount = codecListHelper.getCodecCount();
92 for (int i = 0; i < codecCount; ++i) { 107 for (int i = 0; i < codecCount; ++i) {
93 MediaCodecInfo info = codecListHelper.getCodecInfoAt(i); 108 MediaCodecInfo info = codecListHelper.getCodecInfoAt(i);
94 109
95 int codecDirection = info.isEncoder() ? MEDIA_CODEC_ENCODER : MEDIA_ CODEC_DECODER; 110 int codecDirection = info.isEncoder() ? MEDIA_CODEC_ENCODER : MEDIA_ CODEC_DECODER;
96 if (codecDirection != direction) continue; 111 if (codecDirection != direction) continue;
97 112
113 if (requireSoftwareCodec && !isSoftwareCodec(info.getName())) contin ue;
114
98 String[] supportedTypes = info.getSupportedTypes(); 115 String[] supportedTypes = info.getSupportedTypes();
99 for (int j = 0; j < supportedTypes.length; ++j) { 116 for (int j = 0; j < supportedTypes.length; ++j) {
100 if (supportedTypes[j].equalsIgnoreCase(mime)) return info.getNam e(); 117 if (supportedTypes[j].equalsIgnoreCase(mime)) return info.getNam e();
101 } 118 }
102 } 119 }
103 120
104 Log.e(TAG, "Decoder for type %s is not supported on this device", mime); 121 Log.e(TAG, "Decoder for type %s is not supported on this device", mime);
105 return ""; 122 return "";
106 } 123 }
107 124
(...skipping 21 matching lines...) Expand all
129 } 146 }
130 147
131 /** 148 /**
132 * Check if a given MIME type can be decoded. 149 * Check if a given MIME type can be decoded.
133 * @param mime MIME type of the media. 150 * @param mime MIME type of the media.
134 * @param secure Whether secure decoder is required. 151 * @param secure Whether secure decoder is required.
135 * @return true if system is able to decode, or false otherwise. 152 * @return true if system is able to decode, or false otherwise.
136 */ 153 */
137 @CalledByNative 154 @CalledByNative
138 private static boolean canDecode(String mime, boolean isSecure) { 155 private static boolean canDecode(String mime, boolean isSecure) {
139 CodecCreationInfo info = createDecoder(mime, isSecure); 156 // TODO(liberato): Should we insist on software here?
157 CodecCreationInfo info = createDecoder(mime, isSecure, false);
140 if (info.mediaCodec == null) return false; 158 if (info.mediaCodec == null) return false;
141 159
142 try { 160 try {
143 info.mediaCodec.release(); 161 info.mediaCodec.release();
144 } catch (IllegalStateException e) { 162 } catch (IllegalStateException e) {
145 Log.e(TAG, "Cannot release media codec", e); 163 Log.e(TAG, "Cannot release media codec", e);
146 } 164 }
147 return true; 165 return true;
148 } 166 }
149 167
150 /** 168 /**
151 * Creates MediaCodec decoder. 169 * Creates MediaCodec decoder.
152 * @param mime MIME type of the media. 170 * @param mime MIME type of the media.
153 * @param secure Whether secure decoder is required. 171 * @param secure Whether secure decoder is required.
172 * @param requireSoftwareCodec Whether a software decoder is required.
154 * @return CodecCreationInfo object 173 * @return CodecCreationInfo object
155 */ 174 */
156 static CodecCreationInfo createDecoder(String mime, boolean isSecure) { 175 static CodecCreationInfo createDecoder(
176 String mime, boolean isSecure, boolean requireSoftwareCodec) {
157 // Always return a valid CodecCreationInfo, its |mediaCodec| field will be null 177 // Always return a valid CodecCreationInfo, its |mediaCodec| field will be null
158 // if we cannot create the codec. 178 // if we cannot create the codec.
159 CodecCreationInfo result = new CodecCreationInfo(); 179 CodecCreationInfo result = new CodecCreationInfo();
160 180
161 assert result.mediaCodec == null; 181 assert result.mediaCodec == null;
162 182
163 // Creation of ".secure" codecs sometimes crash instead of throwing exce ptions 183 // Creation of ".secure" codecs sometimes crash instead of throwing exce ptions
164 // on pre-JBMR2 devices. 184 // on pre-JBMR2 devices.
165 if (isSecure && Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_M R2) return result; 185 if (isSecure && Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_M R2) return result;
166 186
167 // Do not create codec for blacklisted devices. 187 // Do not create codec for blacklisted devices.
168 if (!isDecoderSupportedForDevice(mime)) { 188 if (!isDecoderSupportedForDevice(mime)) {
169 Log.e(TAG, "Decoder for type %s is not supported on this device", mi me); 189 Log.e(TAG, "Decoder for type %s is not supported on this device", mi me);
170 return result; 190 return result;
171 } 191 }
172 192
173 try { 193 try {
174 // |isSecure| only applies to video decoders. 194 // |isSecure| only applies to video decoders.
175 if (mime.startsWith("video") && isSecure) { 195 if (mime.startsWith("video") && isSecure) {
176 String decoderName = getDefaultCodecName(mime, MEDIA_CODEC_DECOD ER); 196 String decoderName =
197 getDefaultCodecName(mime, MEDIA_CODEC_DECODER, requireSo ftwareCodec);
177 if (decoderName.equals("")) return null; 198 if (decoderName.equals("")) return null;
178 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 199 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
179 // To work around an issue that we cannot get the codec info from the secure 200 // To work around an issue that we cannot get the codec info from the secure
180 // decoder, create an insecure decoder first so that we can query its codec 201 // decoder, create an insecure decoder first so that we can query its codec
181 // info. http://b/15587335. 202 // info. http://b/15587335.
182 // Futhermore, it is impossible to create an insecure decode r if the secure 203 // Futhermore, it is impossible to create an insecure decode r if the secure
183 // one is already created. 204 // one is already created.
184 MediaCodec insecureCodec = MediaCodec.createByCodecName(deco derName); 205 MediaCodec insecureCodec = MediaCodec.createByCodecName(deco derName);
185 result.supportsAdaptivePlayback = 206 result.supportsAdaptivePlayback =
186 codecSupportsAdaptivePlayback(insecureCodec, mime); 207 codecSupportsAdaptivePlayback(insecureCodec, mime);
187 insecureCodec.release(); 208 insecureCodec.release();
188 } 209 }
189 result.mediaCodec = MediaCodec.createByCodecName(decoderName + " .secure"); 210 result.mediaCodec = MediaCodec.createByCodecName(decoderName + " .secure");
190 } else { 211 } else {
191 result.mediaCodec = MediaCodec.createDecoderByType(mime); 212 if (requireSoftwareCodec) {
213 String decoderName =
214 getDefaultCodecName(mime, MEDIA_CODEC_DECODER, requi reSoftwareCodec);
215 result.mediaCodec = MediaCodec.createByCodecName(decoderName );
216 } else {
217 result.mediaCodec = MediaCodec.createDecoderByType(mime);
218 }
192 result.supportsAdaptivePlayback = 219 result.supportsAdaptivePlayback =
193 codecSupportsAdaptivePlayback(result.mediaCodec, mime); 220 codecSupportsAdaptivePlayback(result.mediaCodec, mime);
194 } 221 }
195 } catch (Exception e) { 222 } catch (Exception e) {
196 Log.e(TAG, "Failed to create MediaCodec: %s, isSecure: %s", mime, is Secure, e); 223 Log.e(TAG, "Failed to create MediaCodec: %s, isSecure: %s, requireSo ftwareCodec: %s",
224 mime, isSecure, requireSoftwareCodec ? "yes" : "no", e);
197 result.mediaCodec = null; 225 result.mediaCodec = null;
198 } 226 }
199 return result; 227 return result;
200 } 228 }
201 229
202 /** 230 /**
203 * This is a way to blacklist misbehaving devices. 231 * This is a way to blacklist misbehaving devices.
204 * Some devices cannot decode certain codecs, while other codecs work fine. 232 * Some devices cannot decode certain codecs, while other codecs work fine.
205 * @param mime MIME type as passed to mediaCodec.createDecoderByType(mime). 233 * @param mime MIME type as passed to mediaCodec.createDecoderByType(mime).
206 * @return true if this codec is supported for decoder on this device. 234 * @return true if this codec is supported for decoder on this device.
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 MediaCodecInfo.CodecCapabilities capabilities = info.getCapabilities ForType(mime); 344 MediaCodecInfo.CodecCapabilities capabilities = info.getCapabilities ForType(mime);
317 return (capabilities != null) 345 return (capabilities != null)
318 && capabilities.isFeatureSupported( 346 && capabilities.isFeatureSupported(
319 MediaCodecInfo.CodecCapabilities.FEATURE_Adaptive Playback); 347 MediaCodecInfo.CodecCapabilities.FEATURE_Adaptive Playback);
320 } catch (IllegalArgumentException e) { 348 } catch (IllegalArgumentException e) {
321 Log.e(TAG, "Cannot retrieve codec information", e); 349 Log.e(TAG, "Cannot retrieve codec information", e);
322 } 350 }
323 return false; 351 return false;
324 } 352 }
325 } 353 }
OLDNEW
« no previous file with comments | « media/base/android/java/src/org/chromium/media/MediaCodecBridge.java ('k') | media/base/android/media_codec_bridge.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698