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

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

Issue 2084143002: Make AVDA fall back to software decoding if needed. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: symbolic constants, coments. Created 4 years, 6 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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 * Get a name of default android codec. 83 * Get a name of default android codec.
84 * @param mime MIME type of the media. 84 * @param mime MIME type of the media.
85 * @param direction Whether this is encoder or decoder. 85 * @param direction Whether this is encoder or decoder.
86 * @param requireSoftware Whether we require a software codec.
DaleCurtis 2016/06/21 21:17:56 requireSoftwareCodec is probably a better name.
liberato (no reviews please) 2016/06/22 17:56:13 Done.
86 * @return name of the codec. 87 * @return name of the codec.
87 */ 88 */
88 @CalledByNative 89 @CalledByNative
89 private static String getDefaultCodecName(String mime, int direction) { 90 private static String getDefaultCodecName(String mime, int direction, boolea n requireSoftware) {
90 MediaCodecListHelper codecListHelper = new MediaCodecListHelper(); 91 MediaCodecListHelper codecListHelper = new MediaCodecListHelper();
91 int codecCount = codecListHelper.getCodecCount(); 92 int codecCount = codecListHelper.getCodecCount();
92 for (int i = 0; i < codecCount; ++i) { 93 for (int i = 0; i < codecCount; ++i) {
93 MediaCodecInfo info = codecListHelper.getCodecInfoAt(i); 94 MediaCodecInfo info = codecListHelper.getCodecInfoAt(i);
94 95
95 int codecDirection = info.isEncoder() ? MEDIA_CODEC_ENCODER : MEDIA_ CODEC_DECODER; 96 int codecDirection = info.isEncoder() ? MEDIA_CODEC_ENCODER : MEDIA_ CODEC_DECODER;
96 if (codecDirection != direction) continue; 97 if (codecDirection != direction) continue;
97 98
99 if (requireSoftware && !info.getName().startsWith("OMX.google")) con tinue;
DaleCurtis 2016/06/21 21:17:56 Does this exist on Samsung phones? The samsung one
liberato (no reviews please) 2016/06/22 17:56:13 according to this: http://androidxref.com/6.0.1_r
100
98 String[] supportedTypes = info.getSupportedTypes(); 101 String[] supportedTypes = info.getSupportedTypes();
99 for (int j = 0; j < supportedTypes.length; ++j) { 102 for (int j = 0; j < supportedTypes.length; ++j) {
100 if (supportedTypes[j].equalsIgnoreCase(mime)) return info.getNam e(); 103 if (supportedTypes[j].equalsIgnoreCase(mime)) return info.getNam e();
101 } 104 }
102 } 105 }
103 106
104 Log.e(TAG, "Decoder for type %s is not supported on this device", mime); 107 Log.e(TAG, "Decoder for type %s is not supported on this device", mime);
105 return ""; 108 return "";
106 } 109 }
107 110
(...skipping 21 matching lines...) Expand all
129 } 132 }
130 133
131 /** 134 /**
132 * Check if a given MIME type can be decoded. 135 * Check if a given MIME type can be decoded.
133 * @param mime MIME type of the media. 136 * @param mime MIME type of the media.
134 * @param secure Whether secure decoder is required. 137 * @param secure Whether secure decoder is required.
135 * @return true if system is able to decode, or false otherwise. 138 * @return true if system is able to decode, or false otherwise.
136 */ 139 */
137 @CalledByNative 140 @CalledByNative
138 private static boolean canDecode(String mime, boolean isSecure) { 141 private static boolean canDecode(String mime, boolean isSecure) {
139 CodecCreationInfo info = createDecoder(mime, isSecure); 142 // TODO(liberato): Should we insist on software here?
143 CodecCreationInfo info = createDecoder(mime, isSecure, false);
140 if (info.mediaCodec == null) return false; 144 if (info.mediaCodec == null) return false;
141 145
142 try { 146 try {
143 info.mediaCodec.release(); 147 info.mediaCodec.release();
144 } catch (IllegalStateException e) { 148 } catch (IllegalStateException e) {
145 Log.e(TAG, "Cannot release media codec", e); 149 Log.e(TAG, "Cannot release media codec", e);
146 } 150 }
147 return true; 151 return true;
148 } 152 }
149 153
150 /** 154 /**
151 * Creates MediaCodec decoder. 155 * Creates MediaCodec decoder.
152 * @param mime MIME type of the media. 156 * @param mime MIME type of the media.
153 * @param secure Whether secure decoder is required. 157 * @param secure Whether secure decoder is required.
158 * @param requireSoftware Whether a software decoder is required.
154 * @return CodecCreationInfo object 159 * @return CodecCreationInfo object
155 */ 160 */
156 static CodecCreationInfo createDecoder(String mime, boolean isSecure) { 161 static CodecCreationInfo createDecoder(String mime, boolean isSecure, boolea n requireSoftware) {
157 // Always return a valid CodecCreationInfo, its |mediaCodec| field will be null 162 // Always return a valid CodecCreationInfo, its |mediaCodec| field will be null
158 // if we cannot create the codec. 163 // if we cannot create the codec.
159 CodecCreationInfo result = new CodecCreationInfo(); 164 CodecCreationInfo result = new CodecCreationInfo();
160 165
161 assert result.mediaCodec == null; 166 assert result.mediaCodec == null;
162 167
163 // Creation of ".secure" codecs sometimes crash instead of throwing exce ptions 168 // Creation of ".secure" codecs sometimes crash instead of throwing exce ptions
164 // on pre-JBMR2 devices. 169 // on pre-JBMR2 devices.
165 if (isSecure && Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_M R2) return result; 170 if (isSecure && Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_M R2) return result;
166 171
167 // Do not create codec for blacklisted devices. 172 // Do not create codec for blacklisted devices.
168 if (!isDecoderSupportedForDevice(mime)) { 173 if (!isDecoderSupportedForDevice(mime)) {
169 Log.e(TAG, "Decoder for type %s is not supported on this device", mi me); 174 Log.e(TAG, "Decoder for type %s is not supported on this device", mi me);
170 return result; 175 return result;
171 } 176 }
172 177
173 try { 178 try {
174 // |isSecure| only applies to video decoders. 179 // |isSecure| only applies to video decoders.
175 if (mime.startsWith("video") && isSecure) { 180 if (mime.startsWith("video") && isSecure) {
176 String decoderName = getDefaultCodecName(mime, MEDIA_CODEC_DECOD ER); 181 String decoderName =
182 getDefaultCodecName(mime, MEDIA_CODEC_DECODER, requireSo ftware);
177 if (decoderName.equals("")) return null; 183 if (decoderName.equals("")) return null;
178 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 184 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 185 // 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 186 // decoder, create an insecure decoder first so that we can query its codec
181 // info. http://b/15587335. 187 // info. http://b/15587335.
182 // Futhermore, it is impossible to create an insecure decode r if the secure 188 // Futhermore, it is impossible to create an insecure decode r if the secure
183 // one is already created. 189 // one is already created.
184 MediaCodec insecureCodec = MediaCodec.createByCodecName(deco derName); 190 MediaCodec insecureCodec = MediaCodec.createByCodecName(deco derName);
185 result.supportsAdaptivePlayback = 191 result.supportsAdaptivePlayback =
186 codecSupportsAdaptivePlayback(insecureCodec, mime); 192 codecSupportsAdaptivePlayback(insecureCodec, mime);
187 insecureCodec.release(); 193 insecureCodec.release();
188 } 194 }
189 result.mediaCodec = MediaCodec.createByCodecName(decoderName + " .secure"); 195 result.mediaCodec = MediaCodec.createByCodecName(decoderName + " .secure");
190 } else { 196 } else {
191 result.mediaCodec = MediaCodec.createDecoderByType(mime); 197 if (requireSoftware) {
198 String decoderName =
199 getDefaultCodecName(mime, MEDIA_CODEC_DECODER, requi reSoftware);
200 result.mediaCodec = MediaCodec.createByCodecName(decoderName );
201 } else {
202 result.mediaCodec = MediaCodec.createDecoderByType(mime);
203 }
192 result.supportsAdaptivePlayback = 204 result.supportsAdaptivePlayback =
193 codecSupportsAdaptivePlayback(result.mediaCodec, mime); 205 codecSupportsAdaptivePlayback(result.mediaCodec, mime);
194 } 206 }
195 } catch (Exception e) { 207 } catch (Exception e) {
196 Log.e(TAG, "Failed to create MediaCodec: %s, isSecure: %s", mime, is Secure, e); 208 Log.e(TAG, "Failed to create MediaCodec: %s, isSecure: %s, requireSo ftware: %d", mime,
209 isSecure, requireSoftware, e);
197 result.mediaCodec = null; 210 result.mediaCodec = null;
198 } 211 }
199 return result; 212 return result;
200 } 213 }
201 214
202 /** 215 /**
203 * This is a way to blacklist misbehaving devices. 216 * This is a way to blacklist misbehaving devices.
204 * Some devices cannot decode certain codecs, while other codecs work fine. 217 * Some devices cannot decode certain codecs, while other codecs work fine.
205 * @param mime MIME type as passed to mediaCodec.createDecoderByType(mime). 218 * @param mime MIME type as passed to mediaCodec.createDecoderByType(mime).
206 * @return true if this codec is supported for decoder on this device. 219 * @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); 329 MediaCodecInfo.CodecCapabilities capabilities = info.getCapabilities ForType(mime);
317 return (capabilities != null) 330 return (capabilities != null)
318 && capabilities.isFeatureSupported( 331 && capabilities.isFeatureSupported(
319 MediaCodecInfo.CodecCapabilities.FEATURE_Adaptive Playback); 332 MediaCodecInfo.CodecCapabilities.FEATURE_Adaptive Playback);
320 } catch (IllegalArgumentException e) { 333 } catch (IllegalArgumentException e) {
321 Log.e(TAG, "Cannot retrieve codec information", e); 334 Log.e(TAG, "Cannot retrieve codec information", e);
322 } 335 }
323 return false; 336 return false;
324 } 337 }
325 } 338 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698