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

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

Issue 2697643003: media: Clean up MediaCodecBridge and remove subclasses (Closed)
Patch Set: Created 3 years, 10 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 #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
(...skipping 10 matching lines...) Expand all
21 #include "url/gurl.h" 21 #include "url/gurl.h"
22 22
23 using base::android::AttachCurrentThread; 23 using base::android::AttachCurrentThread;
24 using base::android::ConvertJavaStringToUTF8; 24 using base::android::ConvertJavaStringToUTF8;
25 using base::android::ConvertUTF8ToJavaString; 25 using base::android::ConvertUTF8ToJavaString;
26 using base::android::JavaIntArrayToIntVector; 26 using base::android::JavaIntArrayToIntVector;
27 using base::android::JavaRef; 27 using base::android::JavaRef;
28 using base::android::ScopedJavaLocalRef; 28 using base::android::ScopedJavaLocalRef;
29 29
30 namespace media { 30 namespace media {
31
32 namespace { 31 namespace {
33 32
34 const char kMp4aMimeType[] = "audio/mp4a-latm"; 33 const char kMp3MimeType[] = "audio/mpeg";
34 const char kAacMimeType[] = "audio/mp4a-latm";
35 const char kOpusMimeType[] = "audio/opus"; 35 const char kOpusMimeType[] = "audio/opus";
36 const char kVorbisMimeType[] = "audio/vorbis"; 36 const char kVorbisMimeType[] = "audio/vorbis";
37 const char kAc3MimeType[] = "audio/ac3"; 37 const char kAc3MimeType[] = "audio/ac3";
38 const char kEac3MimeType[] = "audio/eac3"; 38 const char kEac3MimeType[] = "audio/eac3";
39 const char kAvcMimeType[] = "video/avc"; 39 const char kAvcMimeType[] = "video/avc";
40 const char kHevcMimeType[] = "video/hevc"; 40 const char kHevcMimeType[] = "video/hevc";
41 const char kVp8MimeType[] = "video/x-vnd.on2.vp8"; 41 const char kVp8MimeType[] = "video/x-vnd.on2.vp8";
42 const char kVp9MimeType[] = "video/x-vnd.on2.vp9"; 42 const char kVp9MimeType[] = "video/x-vnd.on2.vp9";
43 43
44 } // namespace 44 } // namespace
45 45
46 static std::string CodecTypeToAndroidMimeType(const std::string& codec) {
47 // TODO(xhwang): Shall we handle more detailed strings like "mp4a.40.2"?
48 if (codec == "avc1")
49 return kAvcMimeType;
50 if (codec == "hvc1")
51 return kHevcMimeType;
52 if (codec == "mp4a")
53 return kMp4aMimeType;
54 if (codec == "vp8" || codec == "vp8.0")
55 return kVp8MimeType;
56 if (codec == "vp9" || codec == "vp9.0")
57 return kVp9MimeType;
58 if (codec == "vorbis")
59 return kVorbisMimeType;
60 if (codec == "opus")
61 return kOpusMimeType;
62 if (codec == "ac3")
63 return kAc3MimeType;
64 if (codec == "eac3")
65 return kEac3MimeType;
66
67 DLOG(WARNING) << "Cannot convert codec to Android MIME type: " << codec;
68 return std::string();
69 }
70
71 static VideoCodec AndroidCodecToCodecEnum(const std::string& codec) { 46 static VideoCodec AndroidCodecToCodecEnum(const std::string& codec) {
72 if (codec == "AVC") 47 if (codec == "AVC")
73 return kCodecH264; 48 return kCodecH264;
74 if (codec == "VP8") 49 if (codec == "VP8")
75 return kCodecVP8; 50 return kCodecVP8;
76 if (codec == "VP9") 51 if (codec == "VP9")
77 return kCodecVP9; 52 return kCodecVP9;
78 if (codec == "HEVC") 53 if (codec == "HEVC")
79 return kCodecHEVC; 54 return kCodecHEVC;
80 DLOG(WARNING) << "Unknown video codec name \"" << codec << "\""; 55 DLOG(WARNING) << "Unknown video codec name \"" << codec << "\"";
81 return kUnknownVideoCodec; 56 return kUnknownVideoCodec;
82 } 57 }
83 58
84 static CodecProfileLevel MediaCodecProfileLevelToChromiumProfileLevel( 59 static CodecProfileLevel MediaCodecProfileLevelToChromiumProfileLevel(
85 JNIEnv* env, 60 JNIEnv* env,
86 const jobject& j_codec_profile_level) { 61 const jobject& j_codec_profile_level) {
87 ScopedJavaLocalRef<jstring> codec = 62 ScopedJavaLocalRef<jstring> codec =
88 Java_CodecProfileLevelAdapter_getCodec(env, j_codec_profile_level); 63 Java_CodecProfileLevelAdapter_getCodec(env, j_codec_profile_level);
89 int profile = 64 int profile =
90 Java_CodecProfileLevelAdapter_getProfile(env, j_codec_profile_level); 65 Java_CodecProfileLevelAdapter_getProfile(env, j_codec_profile_level);
91 int level = 66 int level =
92 Java_CodecProfileLevelAdapter_getLevel(env, j_codec_profile_level); 67 Java_CodecProfileLevelAdapter_getLevel(env, j_codec_profile_level);
93 return {AndroidCodecToCodecEnum(ConvertJavaStringToUTF8(codec)), 68 return {AndroidCodecToCodecEnum(ConvertJavaStringToUTF8(codec)),
94 static_cast<VideoCodecProfile>(profile), level}; 69 static_cast<VideoCodecProfile>(profile), level};
95 } 70 }
96 71
97 static bool IsSupportedAndroidMimeType(const std::string& mime_type) { 72 static bool IsSupportedAndroidMimeType(const std::string& mime_type) {
98 std::vector<std::string> supported{ 73 std::vector<std::string> supported{
99 kMp4aMimeType, kOpusMimeType, kVorbisMimeType, kAvcMimeType, 74 kMp3MimeType, kAacMimeType, kOpusMimeType, kVorbisMimeType,
watk 2017/02/14 01:40:51 I added mp3 here. Seems like it was missing before
100 kHevcMimeType, kVp8MimeType, kVp9MimeType}; 75 kAvcMimeType, kHevcMimeType, kVp8MimeType, kVp9MimeType};
101 return std::find(supported.begin(), supported.end(), mime_type) != 76 return std::find(supported.begin(), supported.end(), mime_type) !=
102 supported.end(); 77 supported.end();
103 } 78 }
104 79
105 static std::string GetDefaultCodecName(const std::string& mime_type, 80 static std::string GetDefaultCodecName(const std::string& mime_type,
106 MediaCodecDirection direction, 81 MediaCodecDirection direction,
107 bool require_software_codec) { 82 bool require_software_codec) {
108 DCHECK(MediaCodecUtil::IsMediaCodecAvailable()); 83 DCHECK(MediaCodecUtil::IsMediaCodecAvailable());
109 JNIEnv* env = AttachCurrentThread(); 84 JNIEnv* env = AttachCurrentThread();
110 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime_type); 85 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime_type);
111 ScopedJavaLocalRef<jstring> j_codec_name = 86 ScopedJavaLocalRef<jstring> j_codec_name =
112 Java_MediaCodecUtil_getDefaultCodecName(env, j_mime, direction, 87 Java_MediaCodecUtil_getDefaultCodecName(
113 require_software_codec); 88 env, j_mime, static_cast<int>(direction), require_software_codec);
114 return ConvertJavaStringToUTF8(env, j_codec_name.obj()); 89 return ConvertJavaStringToUTF8(env, j_codec_name.obj());
115 } 90 }
116 91
117 static bool IsDecoderSupportedByDevice(const std::string& android_mime_type) { 92 static bool IsDecoderSupportedByDevice(const std::string& android_mime_type) {
118 DCHECK(MediaCodecUtil::IsMediaCodecAvailable()); 93 DCHECK(MediaCodecUtil::IsMediaCodecAvailable());
119 DCHECK(IsSupportedAndroidMimeType(android_mime_type)); 94 DCHECK(IsSupportedAndroidMimeType(android_mime_type));
120 JNIEnv* env = AttachCurrentThread(); 95 JNIEnv* env = AttachCurrentThread();
121 ScopedJavaLocalRef<jstring> j_mime = 96 ScopedJavaLocalRef<jstring> j_mime =
122 ConvertUTF8ToJavaString(env, android_mime_type); 97 ConvertUTF8ToJavaString(env, android_mime_type);
123 return Java_MediaCodecUtil_isDecoderSupportedForDevice(env, j_mime); 98 return Java_MediaCodecUtil_isDecoderSupportedForDevice(env, j_mime);
124 } 99 }
125 100
126 static bool IsEncoderSupportedByDevice(const std::string& android_mime_type) { 101 static bool IsEncoderSupportedByDevice(const std::string& android_mime_type) {
127 DCHECK(MediaCodecUtil::IsMediaCodecAvailable()); 102 DCHECK(MediaCodecUtil::IsMediaCodecAvailable());
128 JNIEnv* env = AttachCurrentThread(); 103 JNIEnv* env = AttachCurrentThread();
129 ScopedJavaLocalRef<jstring> j_mime = 104 ScopedJavaLocalRef<jstring> j_mime =
130 ConvertUTF8ToJavaString(env, android_mime_type); 105 ConvertUTF8ToJavaString(env, android_mime_type);
131 return Java_MediaCodecUtil_isEncoderSupportedByDevice(env, j_mime); 106 return Java_MediaCodecUtil_isEncoderSupportedByDevice(env, j_mime);
132 } 107 }
133 108
134 // static 109 // static
110 std::string MediaCodecUtil::CodecToAndroidMimeType(AudioCodec codec) {
111 switch (codec) {
112 case kCodecMP3:
113 return kMp3MimeType;
114 case kCodecVorbis:
115 return kVorbisMimeType;
116 case kCodecOpus:
117 return kOpusMimeType;
118 case kCodecAAC:
119 return kAacMimeType;
120 case kCodecAC3:
121 return kAc3MimeType;
122 case kCodecEAC3:
123 return kEac3MimeType;
124 default:
125 return std::string();
126 }
127 }
128
129 // static
130 std::string MediaCodecUtil::CodecToAndroidMimeType(VideoCodec codec) {
131 switch (codec) {
132 case kCodecH264:
133 return kAvcMimeType;
134 case kCodecHEVC:
135 return kHevcMimeType;
136 case kCodecVP8:
137 return kVp8MimeType;
138 case kCodecVP9:
139 return kVp9MimeType;
140 default:
141 return std::string();
142 }
143 }
144
145 // static
135 bool MediaCodecUtil::IsMediaCodecAvailable() { 146 bool MediaCodecUtil::IsMediaCodecAvailable() {
136 // Blacklist some devices on Jellybean as MediaCodec is buggy. 147 // Blacklist some devices on Jellybean as MediaCodec is buggy.
137 // http://crbug.com/365494, http://crbug.com/615872 148 // http://crbug.com/365494, http://crbug.com/615872
138 // Blacklist Lenovo A6600 / A6800 on KitKat, which tends to crash a lot. 149 // Blacklist Lenovo A6600 / A6800 on KitKat, which tends to crash a lot.
139 // See crbug.com/628059 . We include < K since they don't exist. 150 // See crbug.com/628059 . We include < K since they don't exist.
140 // Blacklist Samsung Galaxy Star Pro (GT-S7262) (crbug.com/634920). 151 // Blacklist Samsung Galaxy Star Pro (GT-S7262) (crbug.com/634920).
141 // GT-S5282 and GT-I8552 are for crbug.com/634920 . 152 // GT-S5282 and GT-I8552 are for crbug.com/634920 .
142 if (base::android::BuildInfo::GetInstance()->sdk_int() <= 19) { 153 if (base::android::BuildInfo::GetInstance()->sdk_int() <= 19) {
143 std::string model(base::android::BuildInfo::GetInstance()->model()); 154 std::string model(base::android::BuildInfo::GetInstance()->model());
144 return model != "GT-I9100" && model != "GT-I9300" && model != "GT-N7000" && 155 return model != "GT-I9100" && model != "GT-I9300" && model != "GT-N7000" &&
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 if (j_color_format_array.obj()) { 187 if (j_color_format_array.obj()) {
177 std::vector<int> formats; 188 std::vector<int> formats;
178 JavaIntArrayToIntVector(env, j_color_format_array.obj(), &formats); 189 JavaIntArrayToIntVector(env, j_color_format_array.obj(), &formats);
179 color_formats = std::set<int>(formats.begin(), formats.end()); 190 color_formats = std::set<int>(formats.begin(), formats.end());
180 } 191 }
181 192
182 return color_formats; 193 return color_formats;
183 } 194 }
184 195
185 // static 196 // static
186 bool MediaCodecUtil::CanDecode(const std::string& codec, bool is_secure) { 197 bool MediaCodecUtil::CanDecode(const std::string& mime, bool is_secure) {
187 if (!IsMediaCodecAvailable()) 198 if (!IsMediaCodecAvailable())
188 return false; 199 return false;
200 if (mime.empty())
201 return false;
189 202
190 JNIEnv* env = AttachCurrentThread(); 203 JNIEnv* env = AttachCurrentThread();
191 std::string mime = CodecTypeToAndroidMimeType(codec);
192 if (mime.empty())
193 return false;
194 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime); 204 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime);
195 return Java_MediaCodecUtil_canDecode(env, j_mime, is_secure); 205 return Java_MediaCodecUtil_canDecode(env, j_mime, is_secure);
196 } 206 }
197 207
198 // static 208 // static
199 bool MediaCodecUtil::AddSupportedCodecProfileLevels( 209 bool MediaCodecUtil::AddSupportedCodecProfileLevels(
200 std::vector<CodecProfileLevel>* result) { 210 std::vector<CodecProfileLevel>* result) {
201 DCHECK(result); 211 DCHECK(result);
202 if (!IsMediaCodecAvailable()) 212 if (!IsMediaCodecAvailable())
203 return false; 213 return false;
204 JNIEnv* env = AttachCurrentThread(); 214 JNIEnv* env = AttachCurrentThread();
205 ScopedJavaLocalRef<jobjectArray> j_codec_profile_levels( 215 ScopedJavaLocalRef<jobjectArray> j_codec_profile_levels(
206 Java_MediaCodecUtil_getSupportedCodecProfileLevels(env)); 216 Java_MediaCodecUtil_getSupportedCodecProfileLevels(env));
207 int java_array_length = env->GetArrayLength(j_codec_profile_levels.obj()); 217 int java_array_length = env->GetArrayLength(j_codec_profile_levels.obj());
208 for (int i = 0; i < java_array_length; ++i) { 218 for (int i = 0; i < java_array_length; ++i) {
209 const jobject& java_codec_profile_level = 219 const jobject& java_codec_profile_level =
210 env->GetObjectArrayElement(j_codec_profile_levels.obj(), i); 220 env->GetObjectArrayElement(j_codec_profile_levels.obj(), i);
211 result->push_back(MediaCodecProfileLevelToChromiumProfileLevel( 221 result->push_back(MediaCodecProfileLevelToChromiumProfileLevel(
212 env, java_codec_profile_level)); 222 env, java_codec_profile_level));
213 } 223 }
214 return true; 224 return true;
215 } 225 }
216 226
217 // static 227 // static
218 bool MediaCodecUtil::IsKnownUnaccelerated(const std::string& android_mime_type, 228 bool MediaCodecUtil::IsKnownUnaccelerated(VideoCodec codec,
219 MediaCodecDirection direction) { 229 MediaCodecDirection direction) {
220 DCHECK(IsSupportedAndroidMimeType(android_mime_type));
221 if (!IsMediaCodecAvailable()) 230 if (!IsMediaCodecAvailable())
222 return true; 231 return true;
223 232
224 std::string codec_name = 233 std::string codec_name =
225 GetDefaultCodecName(android_mime_type, direction, false); 234 GetDefaultCodecName(CodecToAndroidMimeType(codec), direction, false);
226 DVLOG(1) << __func__ << "Default codec for " << android_mime_type << " : " 235 DVLOG(1) << __func__ << "Default codec for " << GetCodecName(codec) << " : "
227 << codec_name << ", direction: " << direction; 236 << codec_name << ", direction: " << static_cast<int>(direction);
228 if (codec_name.empty()) 237 if (codec_name.empty())
229 return true; 238 return true;
230 239
231 // MediaTek hardware vp8 is known slower than the software implementation. 240 // MediaTek hardware vp8 is known slower than the software implementation.
232 // MediaTek hardware vp9 is known crashy, see http://crbug.com/446974 and 241 // MediaTek hardware vp9 is known crashy, see http://crbug.com/446974 and
233 // http://crbug.com/597836. 242 // http://crbug.com/597836.
234 if (base::StartsWith(codec_name, "OMX.MTK.", base::CompareCase::SENSITIVE)) { 243 if (base::StartsWith(codec_name, "OMX.MTK.", base::CompareCase::SENSITIVE)) {
235 if (android_mime_type == kVp8MimeType) 244 if (codec == kCodecVP8)
236 return true; 245 return true;
237 246
238 if (android_mime_type == kVp9MimeType) 247 if (codec == kCodecVP9)
239 return base::android::BuildInfo::GetInstance()->sdk_int() < 21; 248 return base::android::BuildInfo::GetInstance()->sdk_int() < 21;
240 249
241 return false; 250 return false;
242 } 251 }
243 252
244 // It would be nice if MediaCodecInfo externalized some notion of 253 // It would be nice if MediaCodecInfo externalized some notion of
245 // HW-acceleration but it doesn't. Android Media guidance is that the 254 // HW-acceleration but it doesn't. Android Media guidance is that the
246 // "OMX.google" prefix is always used for SW decoders, so that's what we 255 // "OMX.google" prefix is always used for SW decoders, so that's what we
247 // use. "OMX.SEC.*" codec is Samsung software implementation - report it 256 // use. "OMX.SEC.*" codec is Samsung software implementation - report it
248 // as unaccelerated as well. 257 // as unaccelerated as well.
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 (sdk_int == 18 && ("OMX.SEC.avc.dec" == codec_name || 335 (sdk_int == 18 && ("OMX.SEC.avc.dec" == codec_name ||
327 "OMX.SEC.avc.dec.secure" == codec_name)) || 336 "OMX.SEC.avc.dec.secure" == codec_name)) ||
328 (sdk_int == 19 && 337 (sdk_int == 19 &&
329 base::StartsWith(base::android::BuildInfo::GetInstance()->model(), 338 base::StartsWith(base::android::BuildInfo::GetInstance()->model(),
330 "SM-G800", base::CompareCase::INSENSITIVE_ASCII) && 339 "SM-G800", base::CompareCase::INSENSITIVE_ASCII) &&
331 ("OMX.Exynos.avc.dec" == codec_name || 340 ("OMX.Exynos.avc.dec" == codec_name ||
332 "OMX.Exynos.avc.dec.secure" == codec_name)); 341 "OMX.Exynos.avc.dec.secure" == codec_name));
333 } 342 }
334 343
335 } // namespace media 344 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698