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

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

Issue 1897003002: Fix a bug that mime type isn't passed when checking Codec capabilities (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: nits Created 4 years, 8 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 | « no previous file | no next file » | 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 {
ddorwin 2016/04/18 22:09:09 nit: empty line at beginning and end of namespaces
qinmin 2016/04/19 23:27:11 Done.
27 const char kMP4AMimeType[] = "audio/mp4a-latm";
ddorwin 2016/04/18 22:09:09 I think we generally do kMp4a... (The MP4 examples
qinmin 2016/04/19 23:27:10 Done.
28 const char kOPUSMimeType[] = "audio/opus";
ddorwin 2016/04/18 22:09:09 Opus
qinmin 2016/04/19 23:27:10 Done.
29 const char kVORBISMimeType[] = "audio/vorbis";
ddorwin 2016/04/18 22:09:08 Vorbis
qinmin 2016/04/19 23:27:10 Done.
30 const char kAVCMimeType[] = "video/avc";
31 const char kHVCMimeType[] = "video/hevc";
ddorwin 2016/04/18 22:09:09 kHevc... I haven't seen HVC used as an acronym.
qinmin 2016/04/19 23:27:11 Done.
32 const char kVP8MimeType[] = "video/x-vnd.on2.vp8";
33 const char kVP9MimeType[] = "video/x-vnd.on2.vp9";
34 }
35
26 namespace media { 36 namespace media {
ddorwin 2016/04/18 22:09:09 nit: Put the anonymous namespace in this one. No i
qinmin 2016/04/19 23:27:10 Done.
27 37
28 static std::string CodecTypeToAndroidMimeType(const std::string& codec) { 38 static std::string CodecTypeToAndroidMimeType(const std::string& codec) {
29 // TODO(xhwang): Shall we handle more detailed strings like "mp4a.40.2"? 39 // TODO(xhwang): Shall we handle more detailed strings like "mp4a.40.2"?
30 if (codec == "avc1") 40 if (codec == "avc1")
31 return "video/avc"; 41 return kAVCMimeType;
32 if (codec == "hvc1") 42 if (codec == "hvc1")
33 return "video/hevc"; 43 return kHVCMimeType;
34 if (codec == "mp4a") 44 if (codec == "mp4a")
35 return "audio/mp4a-latm"; 45 return kMP4AMimeType;
36 if (codec == "vp8" || codec == "vp8.0") 46 if (codec == "vp8" || codec == "vp8.0")
37 return "video/x-vnd.on2.vp8"; 47 return kVP8MimeType;
38 if (codec == "vp9" || codec == "vp9.0") 48 if (codec == "vp9" || codec == "vp9.0")
39 return "video/x-vnd.on2.vp9"; 49 return kVP9MimeType;
40 if (codec == "vorbis") 50 if (codec == "vorbis")
41 return "audio/vorbis"; 51 return kVORBISMimeType;
42 if (codec == "opus") 52 if (codec == "opus")
43 return "audio/opus"; 53 return kOPUSMimeType;
54 DLOG(WARNING) << "Cannot convert codec to Android MIME type: " << codec;
44 return std::string(); 55 return std::string();
45 } 56 }
46 57
58 static bool IsMimeTypeSupported(const std::string& mime_type) {
ddorwin 2016/04/18 22:09:09 |android_mime_type|
qinmin 2016/04/19 23:27:10 Done. However, this function should checks whether
59 std::vector<std::string> supported{
ddorwin 2016/04/18 22:09:09 nit: space before '{' ?
qinmin 2016/04/19 23:27:10 I added the space initially, but "git cl media for
60 kMP4AMimeType, kOPUSMimeType, kVORBISMimeType, kAVCMimeType,
61 kHVCMimeType, kVP8MimeType, kVP9MimeType};
ddorwin 2016/04/18 22:09:09 Note: Initializer lists are in the process of bein
qinmin 2016/04/19 23:27:10 good to know, thanks
62 return std::find(supported.begin(), supported.end(), mime_type) !=
ddorwin 2016/04/18 22:09:09 This is a bit simpler if you use a base::hash_set
qinmin 2016/04/19 23:27:11 Since this is only used in DCHECK, i will leave th
63 supported.end();
64 }
65
47 static std::string GetDefaultCodecName(const std::string& mime_type, 66 static std::string GetDefaultCodecName(const std::string& mime_type,
48 MediaCodecDirection direction) { 67 MediaCodecDirection direction) {
49 DCHECK(MediaCodecUtil::IsMediaCodecAvailable()); 68 DCHECK(MediaCodecUtil::IsMediaCodecAvailable());
50 JNIEnv* env = AttachCurrentThread(); 69 JNIEnv* env = AttachCurrentThread();
51 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime_type); 70 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime_type);
52 ScopedJavaLocalRef<jstring> j_codec_name = 71 ScopedJavaLocalRef<jstring> j_codec_name =
53 Java_MediaCodecUtil_getDefaultCodecName(env, j_mime.obj(), direction); 72 Java_MediaCodecUtil_getDefaultCodecName(env, j_mime.obj(), direction);
54 return ConvertJavaStringToUTF8(env, j_codec_name.obj()); 73 return ConvertJavaStringToUTF8(env, j_codec_name.obj());
55 } 74 }
56 75
57 static bool IsDecoderSupportedByDevice(const std::string& mime_type) { 76 static bool IsDecoderSupportedByDevice(const std::string& android_mime_type) {
58 DCHECK(MediaCodecUtil::IsMediaCodecAvailable()); 77 DCHECK(MediaCodecUtil::IsMediaCodecAvailable());
78 DCHECK(IsMimeTypeSupported(android_mime_type));
59 JNIEnv* env = AttachCurrentThread(); 79 JNIEnv* env = AttachCurrentThread();
60 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime_type); 80 ScopedJavaLocalRef<jstring> j_mime =
81 ConvertUTF8ToJavaString(env, android_mime_type);
61 return Java_MediaCodecUtil_isDecoderSupportedForDevice(env, j_mime.obj()); 82 return Java_MediaCodecUtil_isDecoderSupportedForDevice(env, j_mime.obj());
62 } 83 }
63 84
64 // static 85 // static
65 bool MediaCodecUtil::IsMediaCodecAvailable() { 86 bool MediaCodecUtil::IsMediaCodecAvailable() {
66 // MediaCodec is only available on JB and greater. 87 // MediaCodec is only available on JB and greater.
67 if (base::android::BuildInfo::GetInstance()->sdk_int() < 16) 88 if (base::android::BuildInfo::GetInstance()->sdk_int() < 16)
68 return false; 89 return false;
69 // Blacklist some devices on Jellybean as for MediaCodec support is buggy. 90 // Blacklist some devices on Jellybean as for MediaCodec support is buggy.
70 // http://crbug.com/365494. 91 // http://crbug.com/365494.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 130
110 JNIEnv* env = AttachCurrentThread(); 131 JNIEnv* env = AttachCurrentThread();
111 std::string mime = CodecTypeToAndroidMimeType(codec); 132 std::string mime = CodecTypeToAndroidMimeType(codec);
112 if (mime.empty()) 133 if (mime.empty())
113 return false; 134 return false;
114 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime); 135 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime);
115 return Java_MediaCodecUtil_canDecode(env, j_mime.obj(), is_secure); 136 return Java_MediaCodecUtil_canDecode(env, j_mime.obj(), is_secure);
116 } 137 }
117 138
118 // static 139 // static
119 bool MediaCodecUtil::IsKnownUnaccelerated(const std::string& mime_type, 140 bool MediaCodecUtil::IsKnownUnaccelerated(const std::string& android_mime_type,
120 MediaCodecDirection direction) { 141 MediaCodecDirection direction) {
121 if (!IsMediaCodecAvailable()) 142 if (!IsMediaCodecAvailable())
122 return true; 143 return true;
123 144
124 std::string codec_name = GetDefaultCodecName(mime_type, direction); 145 DCHECK(IsMimeTypeSupported(android_mime_type));
ddorwin 2016/04/18 22:09:09 We can still do debug checks of input even regardl
qinmin 2016/04/19 23:27:11 Done.
125 DVLOG(1) << __FUNCTION__ << "Default codec for " << mime_type << " : " 146 std::string codec_name = GetDefaultCodecName(android_mime_type, direction);
147 DVLOG(1) << __FUNCTION__ << "Default codec for " << android_mime_type << " : "
126 << codec_name << ", direction: " << direction; 148 << codec_name << ", direction: " << direction;
127 if (!codec_name.size()) 149 if (!codec_name.size())
128 return true; 150 return true;
129 151
130 // MediaTek hardware vp8 is known slower than the software implementation. 152 // MediaTek hardware vp8 is known slower than the software implementation.
131 // MediaTek hardware vp9 is known crashy, see http://crbug.com/446974 and 153 // MediaTek hardware vp9 is known crashy, see http://crbug.com/446974 and
132 // http://crbug.com/597836. 154 // http://crbug.com/597836.
133 if (base::StartsWith(codec_name, "OMX.MTK.", base::CompareCase::SENSITIVE)) { 155 if (base::StartsWith(codec_name, "OMX.MTK.", base::CompareCase::SENSITIVE)) {
134 if (mime_type == "video/x-vnd.on2.vp8") 156 if (android_mime_type.compare(kVP8MimeType) == 0)
ddorwin 2016/04/18 22:09:09 Is there a reason you changed from just using ==?
qinmin 2016/04/19 23:27:11 They are essentially the same, personal preference
135 return true; 157 return true;
136 158
137 if (mime_type == "video/x-vnd.on2.vp9") 159 if (android_mime_type.compare(kVP9MimeType) == 0)
138 return base::android::BuildInfo::GetInstance()->sdk_int() < 21; 160 return base::android::BuildInfo::GetInstance()->sdk_int() < 21;
139 161
140 return false; 162 return false;
141 } 163 }
142 164
143 // It would be nice if MediaCodecInfo externalized some notion of 165 // It would be nice if MediaCodecInfo externalized some notion of
144 // HW-acceleration but it doesn't. Android Media guidance is that the 166 // HW-acceleration but it doesn't. Android Media guidance is that the
145 // "OMX.google" prefix is always used for SW decoders, so that's what we 167 // "OMX.google" prefix is always used for SW decoders, so that's what we
146 // use. "OMX.SEC.*" codec is Samsung software implementation - report it 168 // use. "OMX.SEC.*" codec is Samsung software implementation - report it
147 // as unaccelerated as well. 169 // as unaccelerated as well.
(...skipping 23 matching lines...) Expand all
171 return (spec.find("m3u8") != std::string::npos); 193 return (spec.find("m3u8") != std::string::npos);
172 } 194 }
173 195
174 // static 196 // static
175 bool MediaCodecUtil::RegisterMediaCodecUtil(JNIEnv* env) { 197 bool MediaCodecUtil::RegisterMediaCodecUtil(JNIEnv* env) {
176 return RegisterNativesImpl(env); 198 return RegisterNativesImpl(env);
177 } 199 }
178 200
179 // static 201 // static
180 bool MediaCodecUtil::IsVp8DecoderAvailable() { 202 bool MediaCodecUtil::IsVp8DecoderAvailable() {
181 return IsMediaCodecAvailable() && IsDecoderSupportedByDevice("vp8"); 203 return IsMediaCodecAvailable() && IsDecoderSupportedByDevice(kVP8MimeType);
182 } 204 }
183 205
184 // static 206 // static
185 bool MediaCodecUtil::IsVp8EncoderAvailable() { 207 bool MediaCodecUtil::IsVp8EncoderAvailable() {
186 // Currently the vp8 encoder and decoder blacklists cover the same devices, 208 // Currently the vp8 encoder and decoder blacklists cover the same devices,
187 // but we have a second method for clarity in future issues. 209 // but we have a second method for clarity in future issues.
188 return IsVp8DecoderAvailable(); 210 return IsVp8DecoderAvailable();
189 } 211 }
190 212
191 // static 213 // static
192 bool MediaCodecUtil::IsVp9DecoderAvailable() { 214 bool MediaCodecUtil::IsVp9DecoderAvailable() {
193 return IsMediaCodecAvailable() && IsDecoderSupportedByDevice("vp9"); 215 return IsMediaCodecAvailable() && IsDecoderSupportedByDevice(kVP9MimeType);
194 } 216 }
195 217
196 // static 218 // static
197 bool MediaCodecUtil::IsSurfaceViewOutputSupported() { 219 bool MediaCodecUtil::IsSurfaceViewOutputSupported() {
198 // Disable SurfaceView output for the Samsung Galaxy S3; it does not work 220 // Disable SurfaceView output for the Samsung Galaxy S3; it does not work
199 // well enough for even 360p24 H264 playback. http://crbug.com/602870. 221 // well enough for even 360p24 H264 playback. http://crbug.com/602870.
200 // 222 //
201 // Notably this is codec agnostic at present, so any devices added to 223 // Notably this is codec agnostic at present, so any devices added to
202 // the blacklist will avoid trying to play any codecs on SurfaceView. If 224 // the blacklist will avoid trying to play any codecs on SurfaceView. If
203 // needed in the future this can be expanded to be codec specific. 225 // needed in the future this can be expanded to be codec specific.
204 return !base::StartsWith(base::android::BuildInfo::GetInstance()->model(), 226 return !base::StartsWith(base::android::BuildInfo::GetInstance()->model(),
205 "GT-I9300", base::CompareCase::INSENSITIVE_ASCII); 227 "GT-I9300", base::CompareCase::INSENSITIVE_ASCII);
206 } 228 }
207 229
208 } // namespace media 230 } // namespace media
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698