OLD | NEW |
---|---|
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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_bridge.h" | 5 #include "media/base/android/media_codec_bridge.h" |
6 | 6 |
7 #include <jni.h> | 7 #include <jni.h> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/android/build_info.h" | 10 #include "base/android/build_info.h" |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
107 return base::android::BuildInfo::GetInstance()->sdk_int() >= 16; | 107 return base::android::BuildInfo::GetInstance()->sdk_int() >= 16; |
108 } | 108 } |
109 | 109 |
110 // static | 110 // static |
111 bool MediaCodecBridge::SupportsSetParameters() { | 111 bool MediaCodecBridge::SupportsSetParameters() { |
112 // MediaCodec.setParameters() is only available starting with K. | 112 // MediaCodec.setParameters() is only available starting with K. |
113 return base::android::BuildInfo::GetInstance()->sdk_int() >= 19; | 113 return base::android::BuildInfo::GetInstance()->sdk_int() >= 19; |
114 } | 114 } |
115 | 115 |
116 // static | 116 // static |
117 bool MediaCodecBridge::SupportsGetName() { | |
118 // MediaCodec.getName() is only available on JB MR2 and greater. | |
119 return base::android::BuildInfo::GetInstance()->sdk_int() >= 18; | |
120 } | |
121 | |
122 // static | |
117 std::vector<MediaCodecBridge::CodecsInfo> MediaCodecBridge::GetCodecsInfo() { | 123 std::vector<MediaCodecBridge::CodecsInfo> MediaCodecBridge::GetCodecsInfo() { |
118 std::vector<CodecsInfo> codecs_info; | 124 std::vector<CodecsInfo> codecs_info; |
119 if (!IsAvailable()) | 125 if (!IsAvailable()) |
120 return codecs_info; | 126 return codecs_info; |
121 | 127 |
122 JNIEnv* env = AttachCurrentThread(); | 128 JNIEnv* env = AttachCurrentThread(); |
123 std::string mime_type; | 129 std::string mime_type; |
124 ScopedJavaLocalRef<jobjectArray> j_codec_info_array = | 130 ScopedJavaLocalRef<jobjectArray> j_codec_info_array = |
125 Java_MediaCodecBridge_getCodecsInfo(env); | 131 Java_MediaCodecBridge_getCodecsInfo(env); |
126 jsize len = env->GetArrayLength(j_codec_info_array.obj()); | 132 jsize len = env->GetArrayLength(j_codec_info_array.obj()); |
127 for (jsize i = 0; i < len; ++i) { | 133 for (jsize i = 0; i < len; ++i) { |
128 ScopedJavaLocalRef<jobject> j_info( | 134 ScopedJavaLocalRef<jobject> j_info( |
129 env, env->GetObjectArrayElement(j_codec_info_array.obj(), i)); | 135 env, env->GetObjectArrayElement(j_codec_info_array.obj(), i)); |
130 ScopedJavaLocalRef<jstring> j_codec_type = | 136 ScopedJavaLocalRef<jstring> j_codec_type = |
131 Java_CodecInfo_codecType(env, j_info.obj()); | 137 Java_CodecInfo_codecType(env, j_info.obj()); |
132 ConvertJavaStringToUTF8(env, j_codec_type.obj(), &mime_type); | 138 ConvertJavaStringToUTF8(env, j_codec_type.obj(), &mime_type); |
133 ScopedJavaLocalRef<jstring> j_codec_name = | 139 ScopedJavaLocalRef<jstring> j_codec_name = |
134 Java_CodecInfo_codecName(env, j_info.obj()); | 140 Java_CodecInfo_codecName(env, j_info.obj()); |
135 CodecsInfo info; | 141 CodecsInfo info; |
136 info.codecs = AndroidMimeTypeToCodecType(mime_type); | 142 info.codecs = AndroidMimeTypeToCodecType(mime_type); |
137 ConvertJavaStringToUTF8(env, j_codec_name.obj(), &info.name); | 143 ConvertJavaStringToUTF8(env, j_codec_name.obj(), &info.name); |
138 info.direction = static_cast<MediaCodecDirection>( | 144 info.direction = static_cast<MediaCodecDirection>( |
139 Java_CodecInfo_direction(env, j_info.obj())); | 145 Java_CodecInfo_direction(env, j_info.obj())); |
140 codecs_info.push_back(info); | 146 codecs_info.push_back(info); |
141 } | 147 } |
142 return codecs_info; | 148 return codecs_info; |
143 } | 149 } |
144 | 150 |
145 // static | 151 // static |
152 std::string MediaCodecBridge::GetDefaultCodecName( | |
153 const std::string& mime_type, | |
154 MediaCodecDirection direction) { | |
155 if (!IsAvailable()) | |
156 return std::string(); | |
157 | |
158 JNIEnv* env = AttachCurrentThread(); | |
159 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime_type); | |
160 ScopedJavaLocalRef<jstring> j_codec_name = | |
161 Java_MediaCodecBridge_getDefaultCodecName(env, j_mime.obj(), direction); | |
162 return ConvertJavaStringToUTF8(env, j_codec_name.obj()); | |
163 } | |
164 | |
165 // static | |
146 bool MediaCodecBridge::CanDecode(const std::string& codec, bool is_secure) { | 166 bool MediaCodecBridge::CanDecode(const std::string& codec, bool is_secure) { |
147 if (!IsAvailable()) | 167 if (!IsAvailable()) |
148 return false; | 168 return false; |
149 | 169 |
150 JNIEnv* env = AttachCurrentThread(); | 170 JNIEnv* env = AttachCurrentThread(); |
151 std::string mime = CodecTypeToAndroidMimeType(codec); | 171 std::string mime = CodecTypeToAndroidMimeType(codec); |
152 if (mime.empty()) | 172 if (mime.empty()) |
153 return false; | 173 return false; |
154 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime); | 174 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime); |
155 ScopedJavaLocalRef<jobject> j_media_codec_bridge = | 175 ScopedJavaLocalRef<jobject> j_media_codec_bridge = |
156 Java_MediaCodecBridge_create(env, j_mime.obj(), is_secure, false); | 176 Java_MediaCodecBridge_create(env, j_mime.obj(), is_secure, false); |
157 if (!j_media_codec_bridge.is_null()) { | 177 if (!j_media_codec_bridge.is_null()) { |
158 Java_MediaCodecBridge_release(env, j_media_codec_bridge.obj()); | 178 Java_MediaCodecBridge_release(env, j_media_codec_bridge.obj()); |
159 return true; | 179 return true; |
160 } | 180 } |
161 return false; | 181 return false; |
162 } | 182 } |
163 | 183 |
164 // static | 184 // static |
165 bool MediaCodecBridge::IsKnownUnaccelerated(const std::string& mime_type, | 185 bool MediaCodecBridge::IsKnownUnaccelerated(const std::string& mime_type, |
166 MediaCodecDirection direction) { | 186 MediaCodecDirection direction) { |
167 if (!IsAvailable()) | 187 if (!IsAvailable()) |
168 return true; | 188 return true; |
169 | 189 |
170 std::string codec_type = AndroidMimeTypeToCodecType(mime_type); | 190 std::string codec_name; |
171 std::vector<media::MediaCodecBridge::CodecsInfo> codecs_info = | 191 if (SupportsGetName()) { |
172 MediaCodecBridge::GetCodecsInfo(); | 192 codec_name = GetDefaultCodecName(mime_type, direction); |
173 for (size_t i = 0; i < codecs_info.size(); ++i) { | 193 } else { |
174 if (codecs_info[i].codecs == codec_type && | 194 std::string codec_type = AndroidMimeTypeToCodecType(mime_type); |
175 codecs_info[i].direction == direction) { | 195 std::vector<media::MediaCodecBridge::CodecsInfo> codecs_info = |
176 // It would be nice if MediaCodecInfo externalized some notion of | 196 MediaCodecBridge::GetCodecsInfo(); |
177 // HW-acceleration but it doesn't. Android Media guidance is that the | 197 for (size_t i = 0; i < codecs_info.size(); ++i) { |
178 // prefix below is always used for SW decoders, so that's what we use. | 198 if (codecs_info[i].codecs == codec_type && |
179 if (!StartsWithASCII(codecs_info[i].name, "OMX.google.", true)) | 199 codecs_info[i].direction == direction) { |
180 return false; | 200 codec_name = codecs_info[i].name; |
201 break; | |
202 } | |
181 } | 203 } |
182 } | 204 } |
205 DVLOG(1) << __PRETTY_FUNCTION__ << "Default codec for " << mime_type << | |
206 " : " << codec_name; | |
207 // It would be nice if MediaCodecInfo externalized some notion of | |
208 // HW-acceleration but it doesn't. Android Media guidance is that the | |
209 // "OMX.google" prefix is always used for SW decoders, so that's what we | |
210 // use. "OMX.SEC.*" codec is Samsung software implementation - report it | |
211 // as unaccelerated as well. | |
212 if (codec_name.length() > 0) | |
qinmin
2014/09/30 18:14:24
nit: {} needed for if statement that spans multipl
| |
213 return (StartsWithASCII(codec_name, "OMX.google.", true) || | |
214 StartsWithASCII(codec_name, "OMX.SEC.", true)); | |
183 return true; | 215 return true; |
184 } | 216 } |
185 | 217 |
186 MediaCodecBridge::MediaCodecBridge(const std::string& mime, | 218 MediaCodecBridge::MediaCodecBridge(const std::string& mime, |
187 bool is_secure, | 219 bool is_secure, |
188 MediaCodecDirection direction) { | 220 MediaCodecDirection direction) { |
189 JNIEnv* env = AttachCurrentThread(); | 221 JNIEnv* env = AttachCurrentThread(); |
190 CHECK(env); | 222 CHECK(env); |
191 DCHECK(!mime.empty()); | 223 DCHECK(!mime.empty()); |
192 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime); | 224 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime); |
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
738 JNIEnv* env = AttachCurrentThread(); | 770 JNIEnv* env = AttachCurrentThread(); |
739 return Java_MediaCodecBridge_isAdaptivePlaybackSupported( | 771 return Java_MediaCodecBridge_isAdaptivePlaybackSupported( |
740 env, media_codec(), width, height); | 772 env, media_codec(), width, height); |
741 } | 773 } |
742 | 774 |
743 bool MediaCodecBridge::RegisterMediaCodecBridge(JNIEnv* env) { | 775 bool MediaCodecBridge::RegisterMediaCodecBridge(JNIEnv* env) { |
744 return RegisterNativesImpl(env); | 776 return RegisterNativesImpl(env); |
745 } | 777 } |
746 | 778 |
747 } // namespace media | 779 } // namespace media |
OLD | NEW |