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

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

Issue 2697643003: media: Clean up MediaCodecBridge and remove subclasses (Closed)
Patch Set: rebase 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
« no previous file with comments | « media/base/android/media_codec_util.h ('k') | media/base/android/mock_media_codec_bridge.h » ('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 #include <vector> 10 #include <vector>
(...skipping 17 matching lines...) Expand all
28 using base::android::JavaIntArrayToIntVector; 28 using base::android::JavaIntArrayToIntVector;
29 using base::android::JavaRef; 29 using base::android::JavaRef;
30 using base::android::ScopedJavaLocalRef; 30 using base::android::ScopedJavaLocalRef;
31 using base::android::SDK_VERSION_JELLY_BEAN_MR2; 31 using base::android::SDK_VERSION_JELLY_BEAN_MR2;
32 using base::android::SDK_VERSION_KITKAT; 32 using base::android::SDK_VERSION_KITKAT;
33 using base::android::SDK_VERSION_LOLLIPOP_MR1; 33 using base::android::SDK_VERSION_LOLLIPOP_MR1;
34 34
35 namespace media { 35 namespace media {
36 36
37 namespace { 37 namespace {
38 38 const char kMp3MimeType[] = "audio/mpeg";
39 const char kMp4aMimeType[] = "audio/mp4a-latm"; 39 const char kAacMimeType[] = "audio/mp4a-latm";
40 const char kOpusMimeType[] = "audio/opus"; 40 const char kOpusMimeType[] = "audio/opus";
41 const char kVorbisMimeType[] = "audio/vorbis"; 41 const char kVorbisMimeType[] = "audio/vorbis";
42 const char kAc3MimeType[] = "audio/ac3"; 42 const char kAc3MimeType[] = "audio/ac3";
43 const char kEac3MimeType[] = "audio/eac3"; 43 const char kEac3MimeType[] = "audio/eac3";
44 const char kAvcMimeType[] = "video/avc"; 44 const char kAvcMimeType[] = "video/avc";
45 const char kHevcMimeType[] = "video/hevc"; 45 const char kHevcMimeType[] = "video/hevc";
46 const char kVp8MimeType[] = "video/x-vnd.on2.vp8"; 46 const char kVp8MimeType[] = "video/x-vnd.on2.vp8";
47 const char kVp9MimeType[] = "video/x-vnd.on2.vp9"; 47 const char kVp9MimeType[] = "video/x-vnd.on2.vp9";
48
49 } // namespace 48 } // namespace
50 49
51 static std::string CodecTypeToAndroidMimeType(const std::string& codec) {
52 // TODO(xhwang): Shall we handle more detailed strings like "mp4a.40.2"?
53 if (codec == "avc1")
54 return kAvcMimeType;
55 if (codec == "hvc1")
56 return kHevcMimeType;
57 if (codec == "mp4a")
58 return kMp4aMimeType;
59 if (codec == "vp8" || codec == "vp8.0")
60 return kVp8MimeType;
61 if (codec == "vp9" || codec == "vp9.0")
62 return kVp9MimeType;
63 if (codec == "vorbis")
64 return kVorbisMimeType;
65 if (codec == "opus")
66 return kOpusMimeType;
67 if (codec == "ac3")
68 return kAc3MimeType;
69 if (codec == "eac3")
70 return kEac3MimeType;
71
72 DLOG(WARNING) << "Cannot convert codec to Android MIME type: " << codec;
73 return std::string();
74 }
75
76 static VideoCodec AndroidCodecToCodecEnum(const std::string& codec) {
77 if (codec == "AVC")
78 return kCodecH264;
79 if (codec == "VP8")
80 return kCodecVP8;
81 if (codec == "VP9")
82 return kCodecVP9;
83 if (codec == "HEVC")
84 return kCodecHEVC;
85 DLOG(WARNING) << "Unknown video codec name \"" << codec << "\"";
86 return kUnknownVideoCodec;
87 }
88
89 static CodecProfileLevel MediaCodecProfileLevelToChromiumProfileLevel( 50 static CodecProfileLevel MediaCodecProfileLevelToChromiumProfileLevel(
90 JNIEnv* env, 51 JNIEnv* env,
91 const jobject& j_codec_profile_level) { 52 const jobject& j_codec_profile_level) {
92 ScopedJavaLocalRef<jstring> codec = 53 VideoCodec codec = static_cast<VideoCodec>(
93 Java_CodecProfileLevelAdapter_getCodec(env, j_codec_profile_level); 54 Java_CodecProfileLevelAdapter_getCodec(env, j_codec_profile_level));
94 int profile = 55 VideoCodecProfile profile = static_cast<VideoCodecProfile>(
95 Java_CodecProfileLevelAdapter_getProfile(env, j_codec_profile_level); 56 Java_CodecProfileLevelAdapter_getProfile(env, j_codec_profile_level));
96 int level = 57 int level =
97 Java_CodecProfileLevelAdapter_getLevel(env, j_codec_profile_level); 58 Java_CodecProfileLevelAdapter_getLevel(env, j_codec_profile_level);
98 return {AndroidCodecToCodecEnum(ConvertJavaStringToUTF8(codec)), 59 return {codec, profile, level};
99 static_cast<VideoCodecProfile>(profile), level};
100 } 60 }
101 61
102 static bool IsSupportedAndroidMimeType(const std::string& mime_type) { 62 static bool IsSupportedAndroidMimeType(const std::string& mime_type) {
103 std::vector<std::string> supported{ 63 std::vector<std::string> supported{
104 kMp4aMimeType, kOpusMimeType, kVorbisMimeType, kAvcMimeType, 64 kMp3MimeType, kAacMimeType, kOpusMimeType, kVorbisMimeType,
105 kHevcMimeType, kVp8MimeType, kVp9MimeType}; 65 kAvcMimeType, kHevcMimeType, kVp8MimeType, kVp9MimeType};
106 return std::find(supported.begin(), supported.end(), mime_type) != 66 return std::find(supported.begin(), supported.end(), mime_type) !=
107 supported.end(); 67 supported.end();
108 } 68 }
109 69
110 static std::string GetDefaultCodecName(const std::string& mime_type, 70 static std::string GetDefaultCodecName(const std::string& mime_type,
111 MediaCodecDirection direction, 71 MediaCodecDirection direction,
112 bool require_software_codec) { 72 bool require_software_codec) {
113 DCHECK(MediaCodecUtil::IsMediaCodecAvailable()); 73 DCHECK(MediaCodecUtil::IsMediaCodecAvailable());
114 JNIEnv* env = AttachCurrentThread(); 74 JNIEnv* env = AttachCurrentThread();
115 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime_type); 75 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime_type);
116 ScopedJavaLocalRef<jstring> j_codec_name = 76 ScopedJavaLocalRef<jstring> j_codec_name =
117 Java_MediaCodecUtil_getDefaultCodecName(env, j_mime, direction, 77 Java_MediaCodecUtil_getDefaultCodecName(
118 require_software_codec); 78 env, j_mime, static_cast<int>(direction), require_software_codec);
119 return ConvertJavaStringToUTF8(env, j_codec_name.obj()); 79 return ConvertJavaStringToUTF8(env, j_codec_name.obj());
120 } 80 }
121 81
122 static bool IsDecoderSupportedByDevice(const std::string& android_mime_type) { 82 static bool IsDecoderSupportedByDevice(const std::string& android_mime_type) {
123 DCHECK(MediaCodecUtil::IsMediaCodecAvailable()); 83 DCHECK(MediaCodecUtil::IsMediaCodecAvailable());
124 DCHECK(IsSupportedAndroidMimeType(android_mime_type)); 84 DCHECK(IsSupportedAndroidMimeType(android_mime_type));
125 JNIEnv* env = AttachCurrentThread(); 85 JNIEnv* env = AttachCurrentThread();
126 ScopedJavaLocalRef<jstring> j_mime = 86 ScopedJavaLocalRef<jstring> j_mime =
127 ConvertUTF8ToJavaString(env, android_mime_type); 87 ConvertUTF8ToJavaString(env, android_mime_type);
128 return Java_MediaCodecUtil_isDecoderSupportedForDevice(env, j_mime); 88 return Java_MediaCodecUtil_isDecoderSupportedForDevice(env, j_mime);
129 } 89 }
130 90
131 static bool IsEncoderSupportedByDevice(const std::string& android_mime_type) { 91 static bool IsEncoderSupportedByDevice(const std::string& android_mime_type) {
132 DCHECK(MediaCodecUtil::IsMediaCodecAvailable()); 92 DCHECK(MediaCodecUtil::IsMediaCodecAvailable());
133 JNIEnv* env = AttachCurrentThread(); 93 JNIEnv* env = AttachCurrentThread();
134 ScopedJavaLocalRef<jstring> j_mime = 94 ScopedJavaLocalRef<jstring> j_mime =
135 ConvertUTF8ToJavaString(env, android_mime_type); 95 ConvertUTF8ToJavaString(env, android_mime_type);
136 return Java_MediaCodecUtil_isEncoderSupportedByDevice(env, j_mime); 96 return Java_MediaCodecUtil_isEncoderSupportedByDevice(env, j_mime);
137 } 97 }
138 98
139 // static 99 // static
100 std::string MediaCodecUtil::CodecToAndroidMimeType(AudioCodec codec) {
101 switch (codec) {
102 case kCodecMP3:
103 return kMp3MimeType;
104 case kCodecVorbis:
105 return kVorbisMimeType;
106 case kCodecOpus:
107 return kOpusMimeType;
108 case kCodecAAC:
109 return kAacMimeType;
110 case kCodecAC3:
111 return kAc3MimeType;
112 case kCodecEAC3:
113 return kEac3MimeType;
114 default:
115 return std::string();
116 }
117 }
118
119 // static
120 std::string MediaCodecUtil::CodecToAndroidMimeType(VideoCodec codec) {
121 switch (codec) {
122 case kCodecH264:
123 return kAvcMimeType;
124 case kCodecHEVC:
125 return kHevcMimeType;
126 case kCodecVP8:
127 return kVp8MimeType;
128 case kCodecVP9:
129 return kVp9MimeType;
130 default:
131 return std::string();
132 }
133 }
134
135 // static
140 bool MediaCodecUtil::IsMediaCodecAvailable() { 136 bool MediaCodecUtil::IsMediaCodecAvailable() {
141 return IsMediaCodecAvailableFor( 137 return IsMediaCodecAvailableFor(
142 base::android::BuildInfo::GetInstance()->sdk_int(), 138 base::android::BuildInfo::GetInstance()->sdk_int(),
143 base::android::BuildInfo::GetInstance()->model()); 139 base::android::BuildInfo::GetInstance()->model());
144 } 140 }
145 141
146 // static 142 // static
147 bool MediaCodecUtil::IsMediaCodecAvailableFor(int sdk, const char* model) { 143 bool MediaCodecUtil::IsMediaCodecAvailableFor(int sdk, const char* model) {
148 // We will blacklist the model on any sdk that is as old or older than 144 // We will blacklist the model on any sdk that is as old or older than
149 // |last_bad_sdk| for the given model. 145 // |last_bad_sdk| for the given model.
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 if (j_color_format_array.obj()) { 208 if (j_color_format_array.obj()) {
213 std::vector<int> formats; 209 std::vector<int> formats;
214 JavaIntArrayToIntVector(env, j_color_format_array.obj(), &formats); 210 JavaIntArrayToIntVector(env, j_color_format_array.obj(), &formats);
215 color_formats = std::set<int>(formats.begin(), formats.end()); 211 color_formats = std::set<int>(formats.begin(), formats.end());
216 } 212 }
217 213
218 return color_formats; 214 return color_formats;
219 } 215 }
220 216
221 // static 217 // static
222 bool MediaCodecUtil::CanDecode(const std::string& codec, bool is_secure) { 218 bool MediaCodecUtil::CanDecode(VideoCodec codec, bool is_secure) {
219 return CanDecodeInternal(CodecToAndroidMimeType(codec), is_secure);
220 }
221
222 // static
223 bool MediaCodecUtil::CanDecode(AudioCodec codec) {
224 return CanDecodeInternal(CodecToAndroidMimeType(codec), false);
225 }
226
227 // static
228 bool MediaCodecUtil::CanDecodeInternal(const std::string& mime,
229 bool is_secure) {
223 if (!IsMediaCodecAvailable()) 230 if (!IsMediaCodecAvailable())
224 return false; 231 return false;
232 if (mime.empty())
233 return false;
225 234
226 JNIEnv* env = AttachCurrentThread(); 235 JNIEnv* env = AttachCurrentThread();
227 std::string mime = CodecTypeToAndroidMimeType(codec);
228 if (mime.empty())
229 return false;
230 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime); 236 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime);
231 return Java_MediaCodecUtil_canDecode(env, j_mime, is_secure); 237 return Java_MediaCodecUtil_canDecode(env, j_mime, is_secure);
232 } 238 }
233 239
234 // static 240 // static
235 bool MediaCodecUtil::AddSupportedCodecProfileLevels( 241 bool MediaCodecUtil::AddSupportedCodecProfileLevels(
236 std::vector<CodecProfileLevel>* result) { 242 std::vector<CodecProfileLevel>* result) {
237 DCHECK(result); 243 DCHECK(result);
238 if (!IsMediaCodecAvailable()) 244 if (!IsMediaCodecAvailable())
239 return false; 245 return false;
240 JNIEnv* env = AttachCurrentThread(); 246 JNIEnv* env = AttachCurrentThread();
241 ScopedJavaLocalRef<jobjectArray> j_codec_profile_levels( 247 ScopedJavaLocalRef<jobjectArray> j_codec_profile_levels(
242 Java_MediaCodecUtil_getSupportedCodecProfileLevels(env)); 248 Java_MediaCodecUtil_getSupportedCodecProfileLevels(env));
243 int java_array_length = env->GetArrayLength(j_codec_profile_levels.obj()); 249 int java_array_length = env->GetArrayLength(j_codec_profile_levels.obj());
244 for (int i = 0; i < java_array_length; ++i) { 250 for (int i = 0; i < java_array_length; ++i) {
245 const jobject& java_codec_profile_level = 251 const jobject& java_codec_profile_level =
246 env->GetObjectArrayElement(j_codec_profile_levels.obj(), i); 252 env->GetObjectArrayElement(j_codec_profile_levels.obj(), i);
247 result->push_back(MediaCodecProfileLevelToChromiumProfileLevel( 253 result->push_back(MediaCodecProfileLevelToChromiumProfileLevel(
248 env, java_codec_profile_level)); 254 env, java_codec_profile_level));
249 } 255 }
250 return true; 256 return true;
251 } 257 }
252 258
253 // static 259 // static
254 bool MediaCodecUtil::IsKnownUnaccelerated(const std::string& android_mime_type, 260 bool MediaCodecUtil::IsKnownUnaccelerated(VideoCodec codec,
255 MediaCodecDirection direction) { 261 MediaCodecDirection direction) {
256 DCHECK(IsSupportedAndroidMimeType(android_mime_type));
257 if (!IsMediaCodecAvailable()) 262 if (!IsMediaCodecAvailable())
258 return true; 263 return true;
259 264
260 std::string codec_name = 265 std::string codec_name =
261 GetDefaultCodecName(android_mime_type, direction, false); 266 GetDefaultCodecName(CodecToAndroidMimeType(codec), direction, false);
262 DVLOG(1) << __func__ << "Default codec for " << android_mime_type << " : " 267 DVLOG(1) << __func__ << "Default codec for " << GetCodecName(codec) << " : "
263 << codec_name << ", direction: " << direction; 268 << codec_name << ", direction: " << static_cast<int>(direction);
264 if (codec_name.empty()) 269 if (codec_name.empty())
265 return true; 270 return true;
266 271
267 // MediaTek hardware vp8 is known slower than the software implementation. 272 // MediaTek hardware vp8 is known slower than the software implementation.
268 // MediaTek hardware vp9 is known crashy, see http://crbug.com/446974 and 273 // MediaTek hardware vp9 is known crashy, see http://crbug.com/446974 and
269 // http://crbug.com/597836. 274 // http://crbug.com/597836.
270 if (base::StartsWith(codec_name, "OMX.MTK.", base::CompareCase::SENSITIVE)) { 275 if (base::StartsWith(codec_name, "OMX.MTK.", base::CompareCase::SENSITIVE)) {
271 if (android_mime_type == kVp8MimeType) 276 if (codec == kCodecVP8)
272 return true; 277 return true;
273 278
274 if (android_mime_type == kVp9MimeType) 279 if (codec == kCodecVP9)
275 return base::android::BuildInfo::GetInstance()->sdk_int() < 21; 280 return base::android::BuildInfo::GetInstance()->sdk_int() < 21;
276 281
277 return false; 282 return false;
278 } 283 }
279 284
280 // It would be nice if MediaCodecInfo externalized some notion of 285 // It would be nice if MediaCodecInfo externalized some notion of
281 // HW-acceleration but it doesn't. Android Media guidance is that the 286 // HW-acceleration but it doesn't. Android Media guidance is that the
282 // "OMX.google" prefix is always used for SW decoders, so that's what we 287 // "OMX.google" prefix is always used for SW decoders, so that's what we
283 // use. "OMX.SEC.*" codec is Samsung software implementation - report it 288 // use. "OMX.SEC.*" codec is Samsung software implementation - report it
284 // as unaccelerated as well. 289 // as unaccelerated as well.
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 (sdk_int == 18 && ("OMX.SEC.avc.dec" == codec_name || 367 (sdk_int == 18 && ("OMX.SEC.avc.dec" == codec_name ||
363 "OMX.SEC.avc.dec.secure" == codec_name)) || 368 "OMX.SEC.avc.dec.secure" == codec_name)) ||
364 (sdk_int == 19 && 369 (sdk_int == 19 &&
365 base::StartsWith(base::android::BuildInfo::GetInstance()->model(), 370 base::StartsWith(base::android::BuildInfo::GetInstance()->model(),
366 "SM-G800", base::CompareCase::INSENSITIVE_ASCII) && 371 "SM-G800", base::CompareCase::INSENSITIVE_ASCII) &&
367 ("OMX.Exynos.avc.dec" == codec_name || 372 ("OMX.Exynos.avc.dec" == codec_name ||
368 "OMX.Exynos.avc.dec.secure" == codec_name)); 373 "OMX.Exynos.avc.dec.secure" == codec_name));
369 } 374 }
370 375
371 } // namespace media 376 } // namespace media
OLDNEW
« no previous file with comments | « media/base/android/media_codec_util.h ('k') | media/base/android/mock_media_codec_bridge.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698