| 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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 74 return "video/x-vnd.on2.vp8"; | 74 return "video/x-vnd.on2.vp8"; |
| 75 case kCodecVP9: | 75 case kCodecVP9: |
| 76 return "video/x-vnd.on2.vp9"; | 76 return "video/x-vnd.on2.vp9"; |
| 77 default: | 77 default: |
| 78 return std::string(); | 78 return std::string(); |
| 79 } | 79 } |
| 80 } | 80 } |
| 81 | 81 |
| 82 SdkMediaCodecBridge::SdkMediaCodecBridge(const std::string& mime, | 82 SdkMediaCodecBridge::SdkMediaCodecBridge(const std::string& mime, |
| 83 bool is_secure, | 83 bool is_secure, |
| 84 MediaCodecDirection direction) { | 84 MediaCodecDirection direction, |
| 85 bool require_software_codec) { |
| 85 JNIEnv* env = AttachCurrentThread(); | 86 JNIEnv* env = AttachCurrentThread(); |
| 86 CHECK(env); | 87 CHECK(env); |
| 87 DCHECK(!mime.empty()); | 88 DCHECK(!mime.empty()); |
| 88 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime); | 89 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime); |
| 89 j_media_codec_.Reset( | 90 j_media_codec_.Reset(Java_MediaCodecBridge_create( |
| 90 Java_MediaCodecBridge_create(env, j_mime.obj(), is_secure, direction)); | 91 env, j_mime.obj(), is_secure, direction, require_software_codec)); |
| 91 } | 92 } |
| 92 | 93 |
| 93 SdkMediaCodecBridge::~SdkMediaCodecBridge() { | 94 SdkMediaCodecBridge::~SdkMediaCodecBridge() { |
| 94 JNIEnv* env = AttachCurrentThread(); | 95 JNIEnv* env = AttachCurrentThread(); |
| 95 CHECK(env); | 96 CHECK(env); |
| 96 if (j_media_codec_.obj()) | 97 if (j_media_codec_.obj()) |
| 97 Java_MediaCodecBridge_release(env, j_media_codec_.obj()); | 98 Java_MediaCodecBridge_release(env, j_media_codec_.obj()); |
| 98 } | 99 } |
| 99 | 100 |
| 100 MediaCodecStatus SdkMediaCodecBridge::Reset() { | 101 MediaCodecStatus SdkMediaCodecBridge::Reset() { |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 return MEDIA_CODEC_ERROR; | 327 return MEDIA_CODEC_ERROR; |
| 327 const size_t total_capacity = env->GetDirectBufferCapacity(j_buffer.obj()); | 328 const size_t total_capacity = env->GetDirectBufferCapacity(j_buffer.obj()); |
| 328 CHECK_GE(total_capacity, offset); | 329 CHECK_GE(total_capacity, offset); |
| 329 *addr = reinterpret_cast<const uint8_t*>( | 330 *addr = reinterpret_cast<const uint8_t*>( |
| 330 env->GetDirectBufferAddress(j_buffer.obj())) + | 331 env->GetDirectBufferAddress(j_buffer.obj())) + |
| 331 offset; | 332 offset; |
| 332 *capacity = total_capacity - offset; | 333 *capacity = total_capacity - offset; |
| 333 return MEDIA_CODEC_OK; | 334 return MEDIA_CODEC_OK; |
| 334 } | 335 } |
| 335 | 336 |
| 337 bool SdkMediaCodecBridge::IsSoftwareCodec() { |
| 338 JNIEnv* env = AttachCurrentThread(); |
| 339 return Java_MediaCodecBridge_isSoftwareCodec(env, j_media_codec_.obj()); |
| 340 } |
| 341 |
| 336 // static | 342 // static |
| 337 bool SdkMediaCodecBridge::RegisterSdkMediaCodecBridge(JNIEnv* env) { | 343 bool SdkMediaCodecBridge::RegisterSdkMediaCodecBridge(JNIEnv* env) { |
| 338 return RegisterNativesImpl(env); | 344 return RegisterNativesImpl(env); |
| 339 } | 345 } |
| 340 | 346 |
| 341 // static | 347 // static |
| 342 AudioCodecBridge* AudioCodecBridge::Create(const AudioCodec& codec) { | 348 AudioCodecBridge* AudioCodecBridge::Create(const AudioCodec& codec) { |
| 343 if (!MediaCodecUtil::IsMediaCodecAvailable()) | 349 if (!MediaCodecUtil::IsMediaCodecAvailable()) |
| 344 return nullptr; | 350 return nullptr; |
| 345 | 351 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 356 | 362 |
| 357 // static | 363 // static |
| 358 bool AudioCodecBridge::IsKnownUnaccelerated(const AudioCodec& codec) { | 364 bool AudioCodecBridge::IsKnownUnaccelerated(const AudioCodec& codec) { |
| 359 return MediaCodecUtil::IsKnownUnaccelerated( | 365 return MediaCodecUtil::IsKnownUnaccelerated( |
| 360 AudioCodecToAndroidMimeType(codec), MEDIA_CODEC_DECODER); | 366 AudioCodecToAndroidMimeType(codec), MEDIA_CODEC_DECODER); |
| 361 } | 367 } |
| 362 | 368 |
| 363 AudioCodecBridge::AudioCodecBridge(const std::string& mime) | 369 AudioCodecBridge::AudioCodecBridge(const std::string& mime) |
| 364 // Audio codec doesn't care about security level and there is no need for | 370 // Audio codec doesn't care about security level and there is no need for |
| 365 // audio encoding yet. | 371 // audio encoding yet. |
| 366 : SdkMediaCodecBridge(mime, false, MEDIA_CODEC_DECODER) {} | 372 : SdkMediaCodecBridge(mime, false, MEDIA_CODEC_DECODER, false) {} |
| 367 | 373 |
| 368 bool AudioCodecBridge::ConfigureAndStart(const AudioDecoderConfig& config, | 374 bool AudioCodecBridge::ConfigureAndStart(const AudioDecoderConfig& config, |
| 369 bool play_audio, | 375 bool play_audio, |
| 370 jobject media_crypto) { | 376 jobject media_crypto) { |
| 371 const int channel_count = | 377 const int channel_count = |
| 372 ChannelLayoutToChannelCount(config.channel_layout()); | 378 ChannelLayoutToChannelCount(config.channel_layout()); |
| 373 const int64_t codec_delay_ns = base::Time::kNanosecondsPerSecond * | 379 const int64_t codec_delay_ns = base::Time::kNanosecondsPerSecond * |
| 374 config.codec_delay() / | 380 config.codec_delay() / |
| 375 config.samples_per_second(); | 381 config.samples_per_second(); |
| 376 const int64_t seek_preroll_ns = | 382 const int64_t seek_preroll_ns = |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 602 } | 608 } |
| 603 | 609 |
| 604 // static | 610 // static |
| 605 bool VideoCodecBridge::IsKnownUnaccelerated(const VideoCodec& codec, | 611 bool VideoCodecBridge::IsKnownUnaccelerated(const VideoCodec& codec, |
| 606 MediaCodecDirection direction) { | 612 MediaCodecDirection direction) { |
| 607 return MediaCodecUtil::IsKnownUnaccelerated( | 613 return MediaCodecUtil::IsKnownUnaccelerated( |
| 608 VideoCodecToAndroidMimeType(codec), direction); | 614 VideoCodecToAndroidMimeType(codec), direction); |
| 609 } | 615 } |
| 610 | 616 |
| 611 // static | 617 // static |
| 612 VideoCodecBridge* VideoCodecBridge::CreateDecoder( | 618 VideoCodecBridge* VideoCodecBridge::CreateDecoder(const VideoCodec& codec, |
| 613 const VideoCodec& codec, | 619 bool is_secure, |
| 614 bool is_secure, | 620 const gfx::Size& size, |
| 615 const gfx::Size& size, | 621 jobject surface, |
| 616 jobject surface, | 622 jobject media_crypto, |
| 617 jobject media_crypto, | 623 bool allow_adaptive_playback, |
| 618 bool allow_adaptive_playback) { | 624 bool require_software_codec) { |
| 619 if (!MediaCodecUtil::IsMediaCodecAvailable()) | 625 if (!MediaCodecUtil::IsMediaCodecAvailable()) |
| 620 return nullptr; | 626 return nullptr; |
| 621 | 627 |
| 622 const std::string mime = VideoCodecToAndroidMimeType(codec); | 628 const std::string mime = VideoCodecToAndroidMimeType(codec); |
| 623 if (mime.empty()) | 629 if (mime.empty()) |
| 624 return nullptr; | 630 return nullptr; |
| 625 | 631 |
| 626 std::unique_ptr<VideoCodecBridge> bridge( | 632 std::unique_ptr<VideoCodecBridge> bridge(new VideoCodecBridge( |
| 627 new VideoCodecBridge(mime, is_secure, MEDIA_CODEC_DECODER)); | 633 mime, is_secure, MEDIA_CODEC_DECODER, require_software_codec)); |
| 628 if (!bridge->media_codec()) | 634 if (!bridge->media_codec()) |
| 629 return nullptr; | 635 return nullptr; |
| 630 | 636 |
| 631 JNIEnv* env = AttachCurrentThread(); | 637 JNIEnv* env = AttachCurrentThread(); |
| 632 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime); | 638 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime); |
| 633 ScopedJavaLocalRef<jobject> j_format( | 639 ScopedJavaLocalRef<jobject> j_format( |
| 634 Java_MediaCodecBridge_createVideoDecoderFormat( | 640 Java_MediaCodecBridge_createVideoDecoderFormat( |
| 635 env, j_mime.obj(), size.width(), size.height())); | 641 env, j_mime.obj(), size.width(), size.height())); |
| 636 DCHECK(!j_format.is_null()); | 642 DCHECK(!j_format.is_null()); |
| 637 if (!Java_MediaCodecBridge_configureVideo( | 643 if (!Java_MediaCodecBridge_configureVideo( |
| (...skipping 13 matching lines...) Expand all Loading... |
| 651 int i_frame_interval, | 657 int i_frame_interval, |
| 652 int color_format) { | 658 int color_format) { |
| 653 if (!MediaCodecUtil::IsMediaCodecAvailable()) | 659 if (!MediaCodecUtil::IsMediaCodecAvailable()) |
| 654 return nullptr; | 660 return nullptr; |
| 655 | 661 |
| 656 const std::string mime = VideoCodecToAndroidMimeType(codec); | 662 const std::string mime = VideoCodecToAndroidMimeType(codec); |
| 657 if (mime.empty()) | 663 if (mime.empty()) |
| 658 return nullptr; | 664 return nullptr; |
| 659 | 665 |
| 660 std::unique_ptr<VideoCodecBridge> bridge( | 666 std::unique_ptr<VideoCodecBridge> bridge( |
| 661 new VideoCodecBridge(mime, false, MEDIA_CODEC_ENCODER)); | 667 new VideoCodecBridge(mime, false, MEDIA_CODEC_ENCODER, false)); |
| 662 if (!bridge->media_codec()) | 668 if (!bridge->media_codec()) |
| 663 return nullptr; | 669 return nullptr; |
| 664 | 670 |
| 665 JNIEnv* env = AttachCurrentThread(); | 671 JNIEnv* env = AttachCurrentThread(); |
| 666 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime); | 672 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime); |
| 667 ScopedJavaLocalRef<jobject> j_format( | 673 ScopedJavaLocalRef<jobject> j_format( |
| 668 Java_MediaCodecBridge_createVideoEncoderFormat( | 674 Java_MediaCodecBridge_createVideoEncoderFormat( |
| 669 env, j_mime.obj(), size.width(), size.height(), bit_rate, frame_rate, | 675 env, j_mime.obj(), size.width(), size.height(), bit_rate, frame_rate, |
| 670 i_frame_interval, color_format)); | 676 i_frame_interval, color_format)); |
| 671 DCHECK(!j_format.is_null()); | 677 DCHECK(!j_format.is_null()); |
| 672 if (!Java_MediaCodecBridge_configureVideo(env, bridge->media_codec(), | 678 if (!Java_MediaCodecBridge_configureVideo(env, bridge->media_codec(), |
| 673 j_format.obj(), nullptr, nullptr, | 679 j_format.obj(), nullptr, nullptr, |
| 674 kConfigureFlagEncode, true)) { | 680 kConfigureFlagEncode, true)) { |
| 675 return nullptr; | 681 return nullptr; |
| 676 } | 682 } |
| 677 | 683 |
| 678 return bridge->Start() ? bridge.release() : nullptr; | 684 return bridge->Start() ? bridge.release() : nullptr; |
| 679 } | 685 } |
| 680 | 686 |
| 681 VideoCodecBridge::VideoCodecBridge(const std::string& mime, | 687 VideoCodecBridge::VideoCodecBridge(const std::string& mime, |
| 682 bool is_secure, | 688 bool is_secure, |
| 683 MediaCodecDirection direction) | 689 MediaCodecDirection direction, |
| 684 : SdkMediaCodecBridge(mime, is_secure, direction), | 690 bool require_software_codec) |
| 691 : SdkMediaCodecBridge(mime, is_secure, direction, require_software_codec), |
| 685 adaptive_playback_supported_for_testing_(-1) {} | 692 adaptive_playback_supported_for_testing_(-1) {} |
| 686 | 693 |
| 687 void VideoCodecBridge::SetVideoBitrate(int bps) { | 694 void VideoCodecBridge::SetVideoBitrate(int bps) { |
| 688 JNIEnv* env = AttachCurrentThread(); | 695 JNIEnv* env = AttachCurrentThread(); |
| 689 Java_MediaCodecBridge_setVideoBitrate(env, media_codec(), bps); | 696 Java_MediaCodecBridge_setVideoBitrate(env, media_codec(), bps); |
| 690 } | 697 } |
| 691 | 698 |
| 692 void VideoCodecBridge::RequestKeyFrameSoon() { | 699 void VideoCodecBridge::RequestKeyFrameSoon() { |
| 693 JNIEnv* env = AttachCurrentThread(); | 700 JNIEnv* env = AttachCurrentThread(); |
| 694 Java_MediaCodecBridge_requestKeyFrameSoon(env, media_codec()); | 701 Java_MediaCodecBridge_requestKeyFrameSoon(env, media_codec()); |
| 695 } | 702 } |
| 696 | 703 |
| 697 bool VideoCodecBridge::IsAdaptivePlaybackSupported(int width, int height) { | 704 bool VideoCodecBridge::IsAdaptivePlaybackSupported(int width, int height) { |
| 698 if (adaptive_playback_supported_for_testing_ == 0) | 705 if (adaptive_playback_supported_for_testing_ == 0) |
| 699 return false; | 706 return false; |
| 700 else if (adaptive_playback_supported_for_testing_ > 0) | 707 else if (adaptive_playback_supported_for_testing_ > 0) |
| 701 return true; | 708 return true; |
| 702 JNIEnv* env = AttachCurrentThread(); | 709 JNIEnv* env = AttachCurrentThread(); |
| 703 return Java_MediaCodecBridge_isAdaptivePlaybackSupported(env, media_codec(), | 710 return Java_MediaCodecBridge_isAdaptivePlaybackSupported(env, media_codec(), |
| 704 width, height); | 711 width, height); |
| 705 } | 712 } |
| 706 | 713 |
| 707 } // namespace media | 714 } // namespace media |
| OLD | NEW |