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

Side by Side Diff: media/base/android/media_codec_util.cc

Issue 1796393002: Remove Exynos from MediaCodec blacklist. Limit MediaTek blacklist. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 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
« no previous file with comments | « media/base/android/media_codec_util.h ('k') | media/base/mime_util_internal.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #include "media/base/android/media_codec_util.h" 5 #include "media/base/android/media_codec_util.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 10
11 #include "base/android/build_info.h" 11 #include "base/android/build_info.h"
12 #include "base/android/jni_android.h" 12 #include "base/android/jni_android.h"
13 #include "base/android/jni_array.h" 13 #include "base/android/jni_array.h"
14 #include "base/android/jni_string.h" 14 #include "base/android/jni_string.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/strings/string_util.h" 16 #include "base/strings/string_util.h"
17 #include "jni/MediaCodecUtil_jni.h" 17 #include "jni/MediaCodecUtil_jni.h"
18 #include "url/gurl.h" 18 #include "url/gurl.h"
19 19
20 using base::android::AttachCurrentThread; 20 using base::android::AttachCurrentThread;
21 using base::android::ConvertJavaStringToUTF8; 21 using base::android::ConvertJavaStringToUTF8;
22 using base::android::ConvertUTF8ToJavaString; 22 using base::android::ConvertUTF8ToJavaString;
23 using base::android::JavaIntArrayToIntVector; 23 using base::android::JavaIntArrayToIntVector;
24 using base::android::ScopedJavaLocalRef; 24 using base::android::ScopedJavaLocalRef;
25 25
26 namespace media { 26 namespace media {
27 27
28 // static 28 static std::string CodecTypeToAndroidMimeType(const std::string& codec) {
29 const std::string CodecTypeToAndroidMimeType(const std::string& codec) {
30 // TODO(xhwang): Shall we handle more detailed strings like "mp4a.40.2"? 29 // TODO(xhwang): Shall we handle more detailed strings like "mp4a.40.2"?
31 if (codec == "avc1") 30 if (codec == "avc1")
32 return "video/avc"; 31 return "video/avc";
33 if (codec == "hvc1") 32 if (codec == "hvc1")
34 return "video/hevc"; 33 return "video/hevc";
35 if (codec == "mp4a") 34 if (codec == "mp4a")
36 return "audio/mp4a-latm"; 35 return "audio/mp4a-latm";
37 if (codec == "vp8" || codec == "vp8.0") 36 if (codec == "vp8" || codec == "vp8.0")
38 return "video/x-vnd.on2.vp8"; 37 return "video/x-vnd.on2.vp8";
39 if (codec == "vp9" || codec == "vp9.0") 38 if (codec == "vp9" || codec == "vp9.0")
40 return "video/x-vnd.on2.vp9"; 39 return "video/x-vnd.on2.vp9";
41 if (codec == "vorbis") 40 if (codec == "vorbis")
42 return "audio/vorbis"; 41 return "audio/vorbis";
43 if (codec == "opus") 42 if (codec == "opus")
44 return "audio/opus"; 43 return "audio/opus";
45 return std::string(); 44 return std::string();
46 } 45 }
47 46
48 // TODO(qinmin): using a map to help all the conversions in this class. 47 static std::string GetDefaultCodecName(const std::string& mime_type,
49 const std::string AndroidMimeTypeToCodecType(const std::string& mime) { 48 MediaCodecDirection direction) {
50 if (mime == "video/mp4v-es") 49 DCHECK(MediaCodecUtil::IsMediaCodecAvailable());
51 return "mp4v"; 50 JNIEnv* env = AttachCurrentThread();
52 if (mime == "video/avc") 51
53 return "avc1"; 52 // MediaCodec::getName() is only supported on newer Android versions.
Tima Vaisburd 2016/03/15 03:26:42 It seems the whole body of this function belongs i
DaleCurtis 2016/03/15 17:30:37 You're right. I realize now my cleanup didn't go f
54 if (mime == "video/hevc") 53 if (base::android::BuildInfo::GetInstance()->sdk_int() >= 18) {
55 return "hvc1"; 54 ScopedJavaLocalRef<jstring> j_mime =
56 if (mime == "video/x-vnd.on2.vp8") 55 ConvertUTF8ToJavaString(env, mime_type);
57 return "vp8"; 56 ScopedJavaLocalRef<jstring> j_codec_name =
58 if (mime == "video/x-vnd.on2.vp9") 57 Java_MediaCodecUtil_getDefaultCodecName(env, j_mime.obj(), direction);
59 return "vp9"; 58 return ConvertJavaStringToUTF8(env, j_codec_name.obj());
60 if (mime == "audio/mp4a-latm") 59 }
61 return "mp4a"; 60
62 if (mime == "audio/mpeg") 61 ScopedJavaLocalRef<jobjectArray> j_codec_info_array =
63 return "mp3"; 62 Java_MediaCodecUtil_getCodecsInfo(env);
64 if (mime == "audio/vorbis") 63 const jsize len = env->GetArrayLength(j_codec_info_array.obj());
65 return "vorbis"; 64 for (jsize i = 0; i < len; ++i) {
66 if (mime == "audio/opus") 65 ScopedJavaLocalRef<jobject> j_info(
67 return "opus"; 66 env, env->GetObjectArrayElement(j_codec_info_array.obj(), i));
67 if (direction != static_cast<MediaCodecDirection>(
68 Java_CodecInfo_direction(env, j_info.obj()))) {
69 continue;
70 }
71
72 std::string current_mime_type;
73 ScopedJavaLocalRef<jstring> j_codec_type =
74 Java_CodecInfo_codecType(env, j_info.obj());
75 ConvertJavaStringToUTF8(env, j_codec_type.obj(), &current_mime_type);
76 if (mime_type != current_mime_type)
77 continue;
78
79 std::string current_codec_name;
80 ScopedJavaLocalRef<jstring> j_codec_name =
81 Java_CodecInfo_codecName(env, j_info.obj());
82 ConvertJavaStringToUTF8(env, j_codec_name.obj(), &current_codec_name);
83 return current_codec_name;
84 }
85
68 return std::string(); 86 return std::string();
69 } 87 }
70 88
71 std::string GetDefaultCodecName(const std::string& mime_type,
72 MediaCodecDirection direction) {
73 if (!MediaCodecUtil::IsMediaCodecAvailable())
74 return std::string();
75
76 JNIEnv* env = AttachCurrentThread();
77 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime_type);
78 ScopedJavaLocalRef<jstring> j_codec_name =
79 Java_MediaCodecUtil_getDefaultCodecName(env, j_mime.obj(), direction);
80 return ConvertJavaStringToUTF8(env, j_codec_name.obj());
81 }
82
83 bool SupportsGetName() {
84 // MediaCodec.getName() is only available on JB MR2 and greater.
85 return base::android::BuildInfo::GetInstance()->sdk_int() >= 18;
86 }
87
88 // Represents supported codecs on android.
89 // TODO(qinmin): Currently the codecs string only contains one codec. Do we
90 // need to support codecs separated by comma. (e.g. "vp8" -> "vp8, vp8.0")?
91 struct CodecsInfo {
92 std::string codecs; // E.g. "vp8" or "avc1".
93 std::string name; // E.g. "OMX.google.vp8.decoder".
94 MediaCodecDirection direction;
95 };
96
97 // Get a list of supported codecs.
98 std::vector<CodecsInfo> GetCodecsInfo() {
99 std::vector<CodecsInfo> codecs_info;
100 if (!MediaCodecUtil::IsMediaCodecAvailable())
101 return codecs_info;
102
103 JNIEnv* env = AttachCurrentThread();
104 std::string mime_type;
105 ScopedJavaLocalRef<jobjectArray> j_codec_info_array =
106 Java_MediaCodecUtil_getCodecsInfo(env);
107 jsize len = env->GetArrayLength(j_codec_info_array.obj());
108 for (jsize i = 0; i < len; ++i) {
109 ScopedJavaLocalRef<jobject> j_info(
110 env, env->GetObjectArrayElement(j_codec_info_array.obj(), i));
111 ScopedJavaLocalRef<jstring> j_codec_type =
112 Java_CodecInfo_codecType(env, j_info.obj());
113 ConvertJavaStringToUTF8(env, j_codec_type.obj(), &mime_type);
114 ScopedJavaLocalRef<jstring> j_codec_name =
115 Java_CodecInfo_codecName(env, j_info.obj());
116 CodecsInfo info;
117 info.codecs = AndroidMimeTypeToCodecType(mime_type);
118 ConvertJavaStringToUTF8(env, j_codec_name.obj(), &info.name);
119 info.direction = static_cast<MediaCodecDirection>(
120 Java_CodecInfo_direction(env, j_info.obj()));
121 codecs_info.push_back(info);
122 }
123 return codecs_info;
124 }
125
126 // static 89 // static
127 bool MediaCodecUtil::IsMediaCodecAvailable() { 90 bool MediaCodecUtil::IsMediaCodecAvailable() {
128 // MediaCodec is only available on JB and greater. 91 // MediaCodec is only available on JB and greater.
129 if (base::android::BuildInfo::GetInstance()->sdk_int() < 16) 92 if (base::android::BuildInfo::GetInstance()->sdk_int() < 16)
130 return false; 93 return false;
131 // Blacklist some devices on Jellybean as for MediaCodec support is buggy. 94 // Blacklist some devices on Jellybean as for MediaCodec support is buggy.
132 // http://crbug.com/365494. 95 // http://crbug.com/365494.
133 if (base::android::BuildInfo::GetInstance()->sdk_int() == 16) { 96 if (base::android::BuildInfo::GetInstance()->sdk_int() == 16) {
134 std::string model(base::android::BuildInfo::GetInstance()->model()); 97 std::string model(base::android::BuildInfo::GetInstance()->model());
135 return model != "GT-I9100" && model != "GT-I9300" && model != "GT-N7000"; 98 return model != "GT-I9100" && model != "GT-I9300" && model != "GT-N7000";
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime); 139 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime);
177 return Java_MediaCodecUtil_canDecode(env, j_mime.obj(), is_secure); 140 return Java_MediaCodecUtil_canDecode(env, j_mime.obj(), is_secure);
178 } 141 }
179 142
180 // static 143 // static
181 bool MediaCodecUtil::IsKnownUnaccelerated(const std::string& mime_type, 144 bool MediaCodecUtil::IsKnownUnaccelerated(const std::string& mime_type,
182 MediaCodecDirection direction) { 145 MediaCodecDirection direction) {
183 if (!IsMediaCodecAvailable()) 146 if (!IsMediaCodecAvailable())
184 return true; 147 return true;
185 148
186 std::string codec_name; 149 std::string codec_name = GetDefaultCodecName(mime_type, direction);
187 if (SupportsGetName()) { 150 DVLOG(1) << __FUNCTION__ << "Default codec for " << mime_type << " : "
188 codec_name = GetDefaultCodecName(mime_type, direction); 151 << codec_name << ", " << direction;
189 } else { 152
190 std::string codec_type = AndroidMimeTypeToCodecType(mime_type); 153 if (!codec_name.size())
191 std::vector<CodecsInfo> codecs_info = GetCodecsInfo(); 154 return true;
192 for (size_t i = 0; i < codecs_info.size(); ++i) { 155
193 if (codecs_info[i].codecs == codec_type &&
194 codecs_info[i].direction == direction) {
195 codec_name = codecs_info[i].name;
196 break;
197 }
198 }
199 }
200 DVLOG(1) << __PRETTY_FUNCTION__ << "Default codec for " << mime_type << " : "
201 << codec_name;
202 // It would be nice if MediaCodecInfo externalized some notion of 156 // It would be nice if MediaCodecInfo externalized some notion of
203 // HW-acceleration but it doesn't. Android Media guidance is that the 157 // HW-acceleration but it doesn't. Android Media guidance is that the
204 // "OMX.google" prefix is always used for SW decoders, so that's what we 158 // "OMX.google" prefix is always used for SW decoders, so that's what we
205 // use. "OMX.SEC.*" codec is Samsung software implementation - report it 159 // use. "OMX.SEC.*" codec is Samsung software implementation - report it
206 // as unaccelerated as well. Also temporary blacklist Exynos and MediaTek 160 // as unaccelerated as well. MediaTek hardware vp8 is known slower than
207 // devices while HW decoder video freezes and distortions are 161 // the software implementation. http://crbug.com/446974.
208 // investigated - http://crbug.com/446974. 162 return base::StartsWith(codec_name, "OMX.google.",
209 if (codec_name.length() > 0) { 163 base::CompareCase::SENSITIVE) ||
210 return (base::StartsWith(codec_name, "OMX.google.", 164 base::StartsWith(codec_name, "OMX.SEC.",
211 base::CompareCase::SENSITIVE) || 165 base::CompareCase::SENSITIVE) ||
212 base::StartsWith(codec_name, "OMX.SEC.", 166 (base::StartsWith(codec_name, "OMX.MTK.",
213 base::CompareCase::SENSITIVE) || 167 base::CompareCase::SENSITIVE) &&
214 base::StartsWith(codec_name, "OMX.MTK.", 168 mime_type == "video/x-vnd.on2.vp8");
Tima Vaisburd 2016/03/15 03:26:42 Limiting the blacklisting to specific codec is gre
DaleCurtis 2016/03/15 17:30:37 Kind of. This CL also needs the changes in the And
215 base::CompareCase::SENSITIVE) ||
216 base::StartsWith(codec_name, "OMX.Exynos.",
217 base::CompareCase::SENSITIVE));
218 }
219 return true;
220 } 169 }
221 170
222 // static 171 // static
223 bool MediaCodecUtil::IsHLSPath(const GURL& url) { 172 bool MediaCodecUtil::IsHLSPath(const GURL& url) {
224 if (!url.SchemeIsHTTPOrHTTPS() && !url.SchemeIsFile()) 173 if (!url.SchemeIsHTTPOrHTTPS() && !url.SchemeIsFile())
225 return false; 174 return false;
226 175
227 std::string path = url.path(); 176 std::string path = url.path();
228 return base::EndsWith(path, ".m3u8", base::CompareCase::INSENSITIVE_ASCII); 177 return base::EndsWith(path, ".m3u8", base::CompareCase::INSENSITIVE_ASCII);
229 } 178 }
230 179
231 // static 180 // static
232 bool MediaCodecUtil::IsHLSURL(const GURL& url) { 181 bool MediaCodecUtil::IsHLSURL(const GURL& url) {
233 if (!url.SchemeIsHTTPOrHTTPS() && !url.SchemeIsFile()) 182 if (!url.SchemeIsHTTPOrHTTPS() && !url.SchemeIsFile())
234 return false; 183 return false;
235 184
236 std::string spec = url.spec(); 185 std::string spec = url.spec();
237 if (base::EndsWith(spec, ".m3u8", base::CompareCase::INSENSITIVE_ASCII)) 186 if (base::EndsWith(spec, ".m3u8", base::CompareCase::INSENSITIVE_ASCII))
238 return true; 187 return true;
239 188
240 return (spec.find("m3u8") != std::string::npos); 189 return (spec.find("m3u8") != std::string::npos);
241 } 190 }
242 191
243 // static 192 // static
244 bool MediaCodecUtil::RegisterMediaCodecUtil(JNIEnv* env) { 193 bool MediaCodecUtil::RegisterMediaCodecUtil(JNIEnv* env) {
245 return RegisterNativesImpl(env); 194 return RegisterNativesImpl(env);
246 } 195 }
247 196
248 // static 197 // static
249 bool MediaCodecUtil::IsVp8DecoderAvailable() { 198 bool MediaCodecUtil::IsVp8CodecAvailable() {
Tima Vaisburd 2016/03/15 03:26:42 How is this renaming justified? We blacklist some
Tima Vaisburd 2016/03/15 03:26:42 A side remark unrelated to this CL: I'd expect som
DaleCurtis 2016/03/15 17:30:37 This allows the code in AndroidVideo_Encode_Accele
250 if (!IsMediaCodecAvailable()) 199 if (!IsMediaCodecAvailable())
251 return false; 200 return false;
252 201
253 JNIEnv* env = AttachCurrentThread(); 202 JNIEnv* env = AttachCurrentThread();
254 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, "vp8"); 203 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, "vp8");
255 return Java_MediaCodecUtil_isDecoderSupportedForDevice(env, j_mime.obj()); 204 return Java_MediaCodecUtil_isDecoderSupportedForDevice(env, j_mime.obj());
256 } 205 }
257 206
258 } // namespace media 207 } // namespace media
OLDNEW
« no previous file with comments | « media/base/android/media_codec_util.h ('k') | media/base/mime_util_internal.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698