| 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 |