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/sdk_media_codec_bridge.h" | 5 #include "media/base/android/sdk_media_codec_bridge.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <limits> | 8 #include <limits> |
9 #include <memory> | 9 #include <memory> |
10 #include <utility> | 10 #include <utility> |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 return MediaCodecUtil::IsKnownUnaccelerated( | 357 return MediaCodecUtil::IsKnownUnaccelerated( |
358 AudioCodecToAndroidMimeType(codec), MEDIA_CODEC_DECODER); | 358 AudioCodecToAndroidMimeType(codec), MEDIA_CODEC_DECODER); |
359 } | 359 } |
360 | 360 |
361 AudioCodecBridge::AudioCodecBridge(const std::string& mime) | 361 AudioCodecBridge::AudioCodecBridge(const std::string& mime) |
362 // Audio codec doesn't care about security level and there is no need for | 362 // Audio codec doesn't care about security level and there is no need for |
363 // audio encoding yet. | 363 // audio encoding yet. |
364 : SdkMediaCodecBridge(mime, false, MEDIA_CODEC_DECODER, false) {} | 364 : SdkMediaCodecBridge(mime, false, MEDIA_CODEC_DECODER, false) {} |
365 | 365 |
366 bool AudioCodecBridge::ConfigureAndStart(const AudioDecoderConfig& config, | 366 bool AudioCodecBridge::ConfigureAndStart(const AudioDecoderConfig& config, |
367 bool play_audio, | |
368 jobject media_crypto) { | 367 jobject media_crypto) { |
369 const int channel_count = | 368 const int channel_count = |
370 ChannelLayoutToChannelCount(config.channel_layout()); | 369 ChannelLayoutToChannelCount(config.channel_layout()); |
371 const int64_t codec_delay_ns = base::Time::kNanosecondsPerSecond * | 370 const int64_t codec_delay_ns = base::Time::kNanosecondsPerSecond * |
372 config.codec_delay() / | 371 config.codec_delay() / |
373 config.samples_per_second(); | 372 config.samples_per_second(); |
374 const int64_t seek_preroll_ns = | 373 const int64_t seek_preroll_ns = |
375 1000LL * config.seek_preroll().InMicroseconds(); | 374 1000LL * config.seek_preroll().InMicroseconds(); |
376 | 375 |
377 return ConfigureAndStart(config.codec(), config.samples_per_second(), | 376 return ConfigureAndStart(config.codec(), config.samples_per_second(), |
378 channel_count, config.extra_data().data(), | 377 channel_count, config.extra_data().data(), |
379 config.extra_data().size(), codec_delay_ns, | 378 config.extra_data().size(), codec_delay_ns, |
380 seek_preroll_ns, play_audio, media_crypto); | 379 seek_preroll_ns, media_crypto); |
381 } | 380 } |
382 | 381 |
383 bool AudioCodecBridge::ConfigureAndStart(const AudioCodec& codec, | 382 bool AudioCodecBridge::ConfigureAndStart(const AudioCodec& codec, |
384 int sample_rate, | 383 int sample_rate, |
385 int channel_count, | 384 int channel_count, |
386 const uint8_t* extra_data, | 385 const uint8_t* extra_data, |
387 size_t extra_data_size, | 386 size_t extra_data_size, |
388 int64_t codec_delay_ns, | 387 int64_t codec_delay_ns, |
389 int64_t seek_preroll_ns, | 388 int64_t seek_preroll_ns, |
390 bool play_audio, | |
391 jobject media_crypto) { | 389 jobject media_crypto) { |
392 DVLOG(2) << __FUNCTION__ << ": " | 390 DVLOG(2) << __FUNCTION__ << ": " |
393 << " codec:" << GetCodecName(codec) | 391 << " codec:" << GetCodecName(codec) |
394 << " samples_per_second:" << sample_rate | 392 << " samples_per_second:" << sample_rate |
395 << " channel_count:" << channel_count | 393 << " channel_count:" << channel_count |
396 << " codec_delay_ns:" << codec_delay_ns | 394 << " codec_delay_ns:" << codec_delay_ns |
397 << " seek_preroll_ns:" << seek_preroll_ns | 395 << " seek_preroll_ns:" << seek_preroll_ns |
398 << " extra data size:" << extra_data_size | 396 << " extra data size:" << extra_data_size |
399 << " play audio:" << play_audio << " media_crypto:" << media_crypto; | 397 << " media_crypto:" << media_crypto; |
400 DCHECK(media_codec()); | 398 DCHECK(media_codec()); |
401 | 399 |
402 std::string codec_string = AudioCodecToAndroidMimeType(codec); | 400 std::string codec_string = AudioCodecToAndroidMimeType(codec); |
403 if (codec_string.empty()) | 401 if (codec_string.empty()) |
404 return false; | 402 return false; |
405 | 403 |
406 JNIEnv* env = AttachCurrentThread(); | 404 JNIEnv* env = AttachCurrentThread(); |
407 | 405 |
408 ScopedJavaLocalRef<jstring> j_mime = | 406 ScopedJavaLocalRef<jstring> j_mime = |
409 ConvertUTF8ToJavaString(env, codec_string); | 407 ConvertUTF8ToJavaString(env, codec_string); |
410 ScopedJavaLocalRef<jobject> j_format(Java_MediaCodecBridge_createAudioFormat( | 408 ScopedJavaLocalRef<jobject> j_format(Java_MediaCodecBridge_createAudioFormat( |
411 env, j_mime, sample_rate, channel_count)); | 409 env, j_mime, sample_rate, channel_count)); |
412 DCHECK(!j_format.is_null()); | 410 DCHECK(!j_format.is_null()); |
413 | 411 |
414 if (!ConfigureMediaFormat(j_format.obj(), codec, extra_data, extra_data_size, | 412 if (!ConfigureMediaFormat(j_format.obj(), codec, extra_data, extra_data_size, |
415 codec_delay_ns, seek_preroll_ns)) { | 413 codec_delay_ns, seek_preroll_ns)) { |
416 return false; | 414 return false; |
417 } | 415 } |
418 | 416 |
419 if (!Java_MediaCodecBridge_configureAudio(env, media_codec(), j_format, | 417 if (!Java_MediaCodecBridge_configureAudio(env, media_codec(), j_format, |
420 media_crypto, 0, play_audio)) { | 418 media_crypto, 0)) { |
421 return false; | 419 return false; |
422 } | 420 } |
423 | 421 |
424 return Start(); | 422 return Start(); |
425 } | 423 } |
426 | 424 |
427 bool AudioCodecBridge::ConfigureMediaFormat(jobject j_format, | 425 bool AudioCodecBridge::ConfigureMediaFormat(jobject j_format, |
428 const AudioCodec& codec, | 426 const AudioCodec& codec, |
429 const uint8_t* extra_data, | 427 const uint8_t* extra_data, |
430 size_t extra_data_size, | 428 size_t extra_data_size, |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
547 break; | 545 break; |
548 } | 546 } |
549 default: | 547 default: |
550 LOG(ERROR) << "Invalid header encountered for codec: " | 548 LOG(ERROR) << "Invalid header encountered for codec: " |
551 << AudioCodecToAndroidMimeType(codec); | 549 << AudioCodecToAndroidMimeType(codec); |
552 return false; | 550 return false; |
553 } | 551 } |
554 return true; | 552 return true; |
555 } | 553 } |
556 | 554 |
557 bool AudioCodecBridge::CreateAudioTrack(int sampling_rate, int channel_count) { | |
558 DVLOG(2) << __FUNCTION__ << ": samping_rate:" << sampling_rate | |
559 << " channel_count:" << channel_count; | |
560 | |
561 JNIEnv* env = AttachCurrentThread(); | |
562 return Java_MediaCodecBridge_createAudioTrack(env, media_codec(), | |
563 sampling_rate, channel_count); | |
564 } | |
565 | |
566 MediaCodecStatus AudioCodecBridge::PlayOutputBuffer(int index, | |
567 size_t size, | |
568 size_t offset, | |
569 bool postpone, | |
570 int64_t* playback_pos) { | |
571 DCHECK_LE(0, index); | |
572 int numBytes = base::checked_cast<int>(size); | |
573 | |
574 const uint8_t* buffer = nullptr; | |
575 size_t capacity = 0; | |
576 MediaCodecStatus status = | |
577 GetOutputBufferAddress(index, offset, &buffer, &capacity); | |
578 if (status != MEDIA_CODEC_OK) { | |
579 DLOG(ERROR) << __FUNCTION__ | |
580 << ": GetOutputBufferAddress() failed for index:" << index; | |
581 return status; | |
582 } | |
583 | |
584 numBytes = std::min(base::checked_cast<int>(capacity), numBytes); | |
585 CHECK_GE(numBytes, 0); | |
586 | |
587 JNIEnv* env = AttachCurrentThread(); | |
588 ScopedJavaLocalRef<jbyteArray> byte_array = | |
589 base::android::ToJavaByteArray(env, buffer, numBytes); | |
590 *playback_pos = Java_MediaCodecBridge_playOutputBuffer(env, media_codec(), | |
591 byte_array, postpone); | |
592 return status; | |
593 } | |
594 | |
595 void AudioCodecBridge::SetVolume(double volume) { | |
596 JNIEnv* env = AttachCurrentThread(); | |
597 Java_MediaCodecBridge_setVolume(env, media_codec(), volume); | |
598 } | |
599 | |
600 // static | 555 // static |
601 bool VideoCodecBridge::IsKnownUnaccelerated(const VideoCodec& codec, | 556 bool VideoCodecBridge::IsKnownUnaccelerated(const VideoCodec& codec, |
602 MediaCodecDirection direction) { | 557 MediaCodecDirection direction) { |
603 return MediaCodecUtil::IsKnownUnaccelerated( | 558 return MediaCodecUtil::IsKnownUnaccelerated( |
604 VideoCodecToAndroidMimeType(codec), direction); | 559 VideoCodecToAndroidMimeType(codec), direction); |
605 } | 560 } |
606 | 561 |
607 // static | 562 // static |
608 VideoCodecBridge* VideoCodecBridge::CreateDecoder(const VideoCodec& codec, | 563 VideoCodecBridge* VideoCodecBridge::CreateDecoder(const VideoCodec& codec, |
609 bool is_secure, | 564 bool is_secure, |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
695 if (adaptive_playback_supported_for_testing_ == 0) | 650 if (adaptive_playback_supported_for_testing_ == 0) |
696 return false; | 651 return false; |
697 else if (adaptive_playback_supported_for_testing_ > 0) | 652 else if (adaptive_playback_supported_for_testing_ > 0) |
698 return true; | 653 return true; |
699 JNIEnv* env = AttachCurrentThread(); | 654 JNIEnv* env = AttachCurrentThread(); |
700 return Java_MediaCodecBridge_isAdaptivePlaybackSupported(env, media_codec(), | 655 return Java_MediaCodecBridge_isAdaptivePlaybackSupported(env, media_codec(), |
701 width, height); | 656 width, height); |
702 } | 657 } |
703 | 658 |
704 } // namespace media | 659 } // namespace media |
OLD | NEW |