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

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

Issue 1805163002: Cleanup MediaCodecUtil::GetDefaultCodecName(). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@better_known
Patch Set: Switch to faster getCodecInfos. Comments. 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
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";
52 if (mime == "video/avc")
53 return "avc1";
54 if (mime == "video/hevc")
55 return "hvc1";
56 if (mime == "video/x-vnd.on2.vp8")
57 return "vp8";
58 if (mime == "video/x-vnd.on2.vp9")
59 return "vp9";
60 if (mime == "audio/mp4a-latm")
61 return "mp4a";
62 if (mime == "audio/mpeg")
63 return "mp3";
64 if (mime == "audio/vorbis")
65 return "vorbis";
66 if (mime == "audio/opus")
67 return "opus";
68 return std::string();
69 }
70
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(); 50 JNIEnv* env = AttachCurrentThread();
77 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime_type); 51 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime_type);
78 ScopedJavaLocalRef<jstring> j_codec_name = 52 ScopedJavaLocalRef<jstring> j_codec_name =
79 Java_MediaCodecUtil_getDefaultCodecName(env, j_mime.obj(), direction); 53 Java_MediaCodecUtil_getDefaultCodecName(env, j_mime.obj(), direction);
80 return ConvertJavaStringToUTF8(env, j_codec_name.obj()); 54 return ConvertJavaStringToUTF8(env, j_codec_name.obj());
81 } 55 }
82 56
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 57 // static
127 bool MediaCodecUtil::IsMediaCodecAvailable() { 58 bool MediaCodecUtil::IsMediaCodecAvailable() {
128 // MediaCodec is only available on JB and greater. 59 // MediaCodec is only available on JB and greater.
129 if (base::android::BuildInfo::GetInstance()->sdk_int() < 16) 60 if (base::android::BuildInfo::GetInstance()->sdk_int() < 16)
130 return false; 61 return false;
131 // Blacklist some devices on Jellybean as for MediaCodec support is buggy. 62 // Blacklist some devices on Jellybean as for MediaCodec support is buggy.
132 // http://crbug.com/365494. 63 // http://crbug.com/365494.
133 if (base::android::BuildInfo::GetInstance()->sdk_int() == 16) { 64 if (base::android::BuildInfo::GetInstance()->sdk_int() == 16) {
134 std::string model(base::android::BuildInfo::GetInstance()->model()); 65 std::string model(base::android::BuildInfo::GetInstance()->model());
135 return model != "GT-I9100" && model != "GT-I9300" && model != "GT-N7000"; 66 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); 107 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime);
177 return Java_MediaCodecUtil_canDecode(env, j_mime.obj(), is_secure); 108 return Java_MediaCodecUtil_canDecode(env, j_mime.obj(), is_secure);
178 } 109 }
179 110
180 // static 111 // static
181 bool MediaCodecUtil::IsKnownUnaccelerated(const std::string& mime_type, 112 bool MediaCodecUtil::IsKnownUnaccelerated(const std::string& mime_type,
182 MediaCodecDirection direction) { 113 MediaCodecDirection direction) {
183 if (!IsMediaCodecAvailable()) 114 if (!IsMediaCodecAvailable())
184 return true; 115 return true;
185 116
186 std::string codec_name; 117 std::string codec_name = GetDefaultCodecName(mime_type, direction);
187 if (SupportsGetName()) { 118 DVLOG(1) << __FUNCTION__ << "Default codec for " << mime_type << " : "
188 codec_name = GetDefaultCodecName(mime_type, direction); 119 << codec_name << ", direction: " << direction;
189 } else { 120 if (!codec_name.size())
qinmin 2016/03/17 04:11:29 codec_name.empty()
190 std::string codec_type = AndroidMimeTypeToCodecType(mime_type); 121 return true;
191 std::vector<CodecsInfo> codecs_info = GetCodecsInfo(); 122
192 for (size_t i = 0; i < codecs_info.size(); ++i) {
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 123 // It would be nice if MediaCodecInfo externalized some notion of
203 // HW-acceleration but it doesn't. Android Media guidance is that the 124 // 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 125 // "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 126 // use. "OMX.SEC.*" codec is Samsung software implementation - report it
206 // as unaccelerated as well. MediaTek hardware vp8 is known slower than 127 // as unaccelerated as well. MediaTek hardware vp8 is known slower than
207 // the software implementation. http://crbug.com/446974. 128 // the software implementation. http://crbug.com/446974.
208 if (codec_name.length() > 0) { 129 return base::StartsWith(codec_name, "OMX.google.",
209 return base::StartsWith(codec_name, "OMX.google.", 130 base::CompareCase::SENSITIVE) ||
210 base::CompareCase::SENSITIVE) || 131 base::StartsWith(codec_name, "OMX.SEC.",
211 base::StartsWith(codec_name, "OMX.SEC.", 132 base::CompareCase::SENSITIVE) ||
212 base::CompareCase::SENSITIVE) || 133 (base::StartsWith(codec_name, "OMX.MTK.",
213 (base::StartsWith(codec_name, "OMX.MTK.", 134 base::CompareCase::SENSITIVE) &&
214 base::CompareCase::SENSITIVE) && 135 mime_type == "video/x-vnd.on2.vp8");
215 mime_type == "video/x-vnd.on2.vp8");
216 }
217 return true;
218 } 136 }
219 137
220 // static 138 // static
221 bool MediaCodecUtil::IsHLSPath(const GURL& url) { 139 bool MediaCodecUtil::IsHLSPath(const GURL& url) {
222 if (!url.SchemeIsHTTPOrHTTPS() && !url.SchemeIsFile()) 140 if (!url.SchemeIsHTTPOrHTTPS() && !url.SchemeIsFile())
223 return false; 141 return false;
224 142
225 std::string path = url.path(); 143 std::string path = url.path();
226 return base::EndsWith(path, ".m3u8", base::CompareCase::INSENSITIVE_ASCII); 144 return base::EndsWith(path, ".m3u8", base::CompareCase::INSENSITIVE_ASCII);
227 } 145 }
(...skipping 26 matching lines...) Expand all
254 } 172 }
255 173
256 // static 174 // static
257 bool MediaCodecUtil::IsVp8EncoderAvailable() { 175 bool MediaCodecUtil::IsVp8EncoderAvailable() {
258 // Currently the vp8 encoder and decoder blacklists cover the same devices, 176 // Currently the vp8 encoder and decoder blacklists cover the same devices,
259 // but we have a second method for clarity in future issues. 177 // but we have a second method for clarity in future issues.
260 return IsVp8DecoderAvailable(); 178 return IsVp8DecoderAvailable();
261 } 179 }
262 180
263 } // namespace media 181 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698