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

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

Issue 23517002: MediaSourcePlayer implements IsTypeSupported(). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: comments Created 7 years, 3 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 | Annotate | Revision Log
OLDNEW
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 9
9 #include "base/android/build_info.h" 10 #include "base/android/build_info.h"
10 #include "base/android/jni_android.h" 11 #include "base/android/jni_android.h"
11 #include "base/android/jni_array.h" 12 #include "base/android/jni_array.h"
12 #include "base/android/jni_string.h" 13 #include "base/android/jni_string.h"
13 #include "base/basictypes.h" 14 #include "base/basictypes.h"
14 #include "base/lazy_instance.h" 15 #include "base/lazy_instance.h"
15 #include "base/logging.h" 16 #include "base/logging.h"
16 #include "base/safe_numerics.h" 17 #include "base/safe_numerics.h"
17 #include "base/strings/stringprintf.h" 18 #include "base/strings/stringprintf.h"
18 #include "jni/MediaCodecBridge_jni.h" 19 #include "jni/MediaCodecBridge_jni.h"
19 #include "media/base/bit_reader.h" 20 #include "media/base/bit_reader.h"
20 #include "media/base/decrypt_config.h" 21 #include "media/base/decrypt_config.h"
21 22
22 using base::android::AttachCurrentThread; 23 using base::android::AttachCurrentThread;
23 using base::android::ConvertUTF8ToJavaString; 24 using base::android::ConvertUTF8ToJavaString;
24 using base::android::ScopedJavaLocalRef; 25 using base::android::ScopedJavaLocalRef;
25 26
26 namespace media { 27 namespace media {
27 28
28 enum { kBufferFlagEndOfStream = 4 }; 29 enum { kBufferFlagEndOfStream = 4 };
29 30
30 static const char* AudioCodecToMimeType(const AudioCodec codec) { 31 static const std::string AudioCodecToMimeType(const AudioCodec codec) {
31 switch (codec) { 32 switch (codec) {
32 case kCodecMP3: 33 case kCodecMP3:
33 return "audio/mpeg"; 34 return "audio/mpeg";
34 case kCodecVorbis: 35 case kCodecVorbis:
35 return "audio/vorbis"; 36 return "audio/vorbis";
36 case kCodecAAC: 37 case kCodecAAC:
37 return "audio/mp4a-latm"; 38 return "audio/mp4a-latm";
38 default: 39 default:
39 return NULL; 40 return "";
ddorwin 2013/08/28 02:28:50 std::string()
xhwang 2013/08/28 18:19:15 Done.
40 } 41 }
41 } 42 }
42 43
43 static const char* VideoCodecToMimeType(const VideoCodec codec) { 44 static const std::string VideoCodecToMimeType(const VideoCodec codec) {
44 switch (codec) { 45 switch (codec) {
45 case kCodecH264: 46 case kCodecH264:
46 return "video/avc"; 47 return "video/avc";
47 case kCodecVP8: 48 case kCodecVP8:
48 return "video/x-vnd.on2.vp8"; 49 return "video/x-vnd.on2.vp8";
49 default: 50 default:
50 return NULL; 51 return "";
51 } 52 }
52 } 53 }
53 54
54 static ScopedJavaLocalRef<jintArray> ToJavaIntArray( 55 static ScopedJavaLocalRef<jintArray> ToJavaIntArray(
55 JNIEnv* env, scoped_ptr<jint[]> native_array, int size) { 56 JNIEnv* env, scoped_ptr<jint[]> native_array, int size) {
56 ScopedJavaLocalRef<jintArray> j_array(env, env->NewIntArray(size)); 57 ScopedJavaLocalRef<jintArray> j_array(env, env->NewIntArray(size));
57 env->SetIntArrayRegion(j_array.obj(), 0, size, native_array.get()); 58 env->SetIntArrayRegion(j_array.obj(), 0, size, native_array.get());
58 return j_array; 59 return j_array;
59 } 60 }
60 61
61 // static 62 // static
62 const base::TimeDelta MediaCodecBridge::kTimeOutInfinity = 63 const base::TimeDelta MediaCodecBridge::kTimeOutInfinity =
63 base::TimeDelta::FromMicroseconds(-1); 64 base::TimeDelta::FromMicroseconds(-1);
64 65
65 // static 66 // static
66 const base::TimeDelta MediaCodecBridge::kTimeOutNoWait = 67 const base::TimeDelta MediaCodecBridge::kTimeOutNoWait =
67 base::TimeDelta::FromMicroseconds(0); 68 base::TimeDelta::FromMicroseconds(0);
68 69
69 // static 70 // static
70 bool MediaCodecBridge::IsAvailable() { 71 bool MediaCodecBridge::IsAvailable() {
71 // MediaCodec is only available on JB and greater. 72 // MediaCodec is only available on JB and greater.
72 return base::android::BuildInfo::GetInstance()->sdk_int() >= 16; 73 return base::android::BuildInfo::GetInstance()->sdk_int() >= 16;
73 } 74 }
74 75
75 MediaCodecBridge::MediaCodecBridge(const char* mime) { 76 // static
77 bool MediaCodecBridge::IsDecoderSupported(const std::string& mime,
78 bool secure) {
79 JNIEnv* env = AttachCurrentThread();
80 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime);
81 return !Java_MediaCodecBridge_create(env, j_mime.obj(), secure).is_null();
82 }
83
84 // TODO(xhwang): Support creating secure MediaCodecBridge.
85 MediaCodecBridge::MediaCodecBridge(const std::string& mime) {
76 JNIEnv* env = AttachCurrentThread(); 86 JNIEnv* env = AttachCurrentThread();
77 CHECK(env); 87 CHECK(env);
78 DCHECK(mime);
79 88
80 ScopedJavaLocalRef<jstring> j_type = ConvertUTF8ToJavaString(env, mime); 89 DCHECK(!mime.empty());
81 j_media_codec_.Reset(Java_MediaCodecBridge_create( 90 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime);
82 env, j_type.obj())); 91 j_media_codec_.Reset(Java_MediaCodecBridge_create(env, j_mime.obj(), false));
83 } 92 }
84 93
85 MediaCodecBridge::~MediaCodecBridge() { 94 MediaCodecBridge::~MediaCodecBridge() {
86 JNIEnv* env = AttachCurrentThread(); 95 JNIEnv* env = AttachCurrentThread();
87 CHECK(env); 96 CHECK(env);
88 if (j_media_codec_.obj()) 97 if (j_media_codec_.obj())
89 Java_MediaCodecBridge_release(env, j_media_codec_.obj()); 98 Java_MediaCodecBridge_release(env, j_media_codec_.obj());
90 } 99 }
91 100
92 void MediaCodecBridge::StartInternal() { 101 void MediaCodecBridge::StartInternal() {
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 int size_to_copy = (buffer_capacity < size) ? buffer_capacity : size; 229 int size_to_copy = (buffer_capacity < size) ? buffer_capacity : size;
221 // TODO(qinmin): Handling the case that not all the data can be copied. 230 // TODO(qinmin): Handling the case that not all the data can be copied.
222 DCHECK(size_to_copy == size) << 231 DCHECK(size_to_copy == size) <<
223 "Failed to fill all the data into the input buffer. Size to fill: " 232 "Failed to fill all the data into the input buffer. Size to fill: "
224 << size << ". Size filled: " << size_to_copy; 233 << size << ". Size filled: " << size_to_copy;
225 if (size_to_copy > 0) 234 if (size_to_copy > 0)
226 memcpy(direct_buffer, data, size_to_copy); 235 memcpy(direct_buffer, data, size_to_copy);
227 return size_to_copy; 236 return size_to_copy;
228 } 237 }
229 238
230 AudioCodecBridge::AudioCodecBridge(const char* mime) 239 AudioCodecBridge::AudioCodecBridge(const std::string& mime)
231 : MediaCodecBridge(mime) { 240 : MediaCodecBridge(mime) {
232 } 241 }
233 242
234 bool AudioCodecBridge::Start( 243 bool AudioCodecBridge::Start(
235 const AudioCodec codec, int sample_rate, int channel_count, 244 const AudioCodec codec, int sample_rate, int channel_count,
236 const uint8* extra_data, size_t extra_data_size, bool play_audio, 245 const uint8* extra_data, size_t extra_data_size, bool play_audio,
237 jobject media_crypto) { 246 jobject media_crypto) {
238 JNIEnv* env = AttachCurrentThread(); 247 JNIEnv* env = AttachCurrentThread();
239 DCHECK(AudioCodecToMimeType(codec));
240 248
241 if (!media_codec()) 249 if (!media_codec())
242 return false; 250 return false;
243 251
252 std::string codec_string = AudioCodecToMimeType(codec);
253 DCHECK(!codec_string.empty());
ddorwin 2013/08/28 02:28:50 Who calls Start()? Are we sure invalid types won't
xhwang 2013/08/28 18:19:15 Good point. It comes from renderer. So we could hi
244 ScopedJavaLocalRef<jstring> j_mime = 254 ScopedJavaLocalRef<jstring> j_mime =
245 ConvertUTF8ToJavaString(env, AudioCodecToMimeType(codec)); 255 ConvertUTF8ToJavaString(env, codec_string);
246 ScopedJavaLocalRef<jobject> j_format( 256 ScopedJavaLocalRef<jobject> j_format(
247 Java_MediaCodecBridge_createAudioFormat( 257 Java_MediaCodecBridge_createAudioFormat(
248 env, j_mime.obj(), sample_rate, channel_count)); 258 env, j_mime.obj(), sample_rate, channel_count));
249 DCHECK(!j_format.is_null()); 259 DCHECK(!j_format.is_null());
250 260
251 if (!ConfigureMediaFormat(j_format.obj(), codec, extra_data, extra_data_size)) 261 if (!ConfigureMediaFormat(j_format.obj(), codec, extra_data, extra_data_size))
252 return false; 262 return false;
253 263
254 if (!Java_MediaCodecBridge_configureAudio( 264 if (!Java_MediaCodecBridge_configureAudio(
255 env, media_codec(), j_format.obj(), media_crypto, 0, play_audio)) { 265 env, media_codec(), j_format.obj(), media_crypto, 0, play_audio)) {
256 return false; 266 return false;
257 } 267 }
268
258 StartInternal(); 269 StartInternal();
259 return true; 270 return true;
260 } 271 }
261 272
262 bool AudioCodecBridge::ConfigureMediaFormat( 273 bool AudioCodecBridge::ConfigureMediaFormat(
263 jobject j_format, const AudioCodec codec, const uint8* extra_data, 274 jobject j_format, const AudioCodec codec, const uint8* extra_data,
264 size_t extra_data_size) { 275 size_t extra_data_size) {
265 if (extra_data_size == 0) 276 if (extra_data_size == 0)
266 return true; 277 return true;
267 278
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 base::android::ToJavaByteArray(env, buffer, numBytes); 386 base::android::ToJavaByteArray(env, buffer, numBytes);
376 Java_MediaCodecBridge_playOutputBuffer( 387 Java_MediaCodecBridge_playOutputBuffer(
377 env, media_codec(), byte_array.obj()); 388 env, media_codec(), byte_array.obj());
378 } 389 }
379 390
380 void AudioCodecBridge::SetVolume(double volume) { 391 void AudioCodecBridge::SetVolume(double volume) {
381 JNIEnv* env = AttachCurrentThread(); 392 JNIEnv* env = AttachCurrentThread();
382 Java_MediaCodecBridge_setVolume(env, media_codec(), volume); 393 Java_MediaCodecBridge_setVolume(env, media_codec(), volume);
383 } 394 }
384 395
385 VideoCodecBridge::VideoCodecBridge(const char* mime) 396 VideoCodecBridge::VideoCodecBridge(const std::string& mime)
386 : MediaCodecBridge(mime) { 397 : MediaCodecBridge(mime) {
387 } 398 }
388 399
389 bool VideoCodecBridge::Start( 400 bool VideoCodecBridge::Start(
390 const VideoCodec codec, const gfx::Size& size, jobject surface, 401 const VideoCodec codec, const gfx::Size& size, jobject surface,
391 jobject media_crypto) { 402 jobject media_crypto) {
392 JNIEnv* env = AttachCurrentThread(); 403 JNIEnv* env = AttachCurrentThread();
393 DCHECK(VideoCodecToMimeType(codec));
394 404
395 if (!media_codec()) 405 if (!media_codec())
396 return false; 406 return false;
397 407
408 std::string codec_string = VideoCodecToMimeType(codec);
409 DCHECK(!codec_string.empty());
398 ScopedJavaLocalRef<jstring> j_mime = 410 ScopedJavaLocalRef<jstring> j_mime =
399 ConvertUTF8ToJavaString(env, VideoCodecToMimeType(codec)); 411 ConvertUTF8ToJavaString(env, codec_string);
400 ScopedJavaLocalRef<jobject> j_format( 412 ScopedJavaLocalRef<jobject> j_format(
401 Java_MediaCodecBridge_createVideoFormat( 413 Java_MediaCodecBridge_createVideoFormat(
402 env, j_mime.obj(), size.width(), size.height())); 414 env, j_mime.obj(), size.width(), size.height()));
403 DCHECK(!j_format.is_null()); 415 DCHECK(!j_format.is_null());
404 if (!Java_MediaCodecBridge_configureVideo( 416 if (!Java_MediaCodecBridge_configureVideo(
405 env, media_codec(), j_format.obj(), surface, media_crypto, 0)) { 417 env, media_codec(), j_format.obj(), surface, media_crypto, 0)) {
406 return false; 418 return false;
407 } 419 }
408 StartInternal(); 420 StartInternal();
409 return true; 421 return true;
410 } 422 }
411 423
412 AudioCodecBridge* AudioCodecBridge::Create(const AudioCodec codec) { 424 AudioCodecBridge* AudioCodecBridge::Create(const AudioCodec codec) {
413 const char* mime = AudioCodecToMimeType(codec); 425 const std::string mime = AudioCodecToMimeType(codec);
414 return mime ? new AudioCodecBridge(mime) : NULL; 426 return mime.empty() ? NULL: new AudioCodecBridge(mime);
ddorwin 2013/08/28 02:28:50 space before ':' below too
xhwang 2013/08/28 18:19:15 Done.
415 } 427 }
416 428
417 VideoCodecBridge* VideoCodecBridge::Create(const VideoCodec codec) { 429 VideoCodecBridge* VideoCodecBridge::Create(const VideoCodec codec) {
418 const char* mime = VideoCodecToMimeType(codec); 430 const std::string mime = VideoCodecToMimeType(codec);
419 return mime ? new VideoCodecBridge(mime) : NULL; 431 return mime.empty() ? NULL: new VideoCodecBridge(mime);
420 } 432 }
421 433
422 bool MediaCodecBridge::RegisterMediaCodecBridge(JNIEnv* env) { 434 bool MediaCodecBridge::RegisterMediaCodecBridge(JNIEnv* env) {
423 return RegisterNativesImpl(env); 435 return RegisterNativesImpl(env);
424 } 436 }
425 437
426 } // namespace media 438 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698