| 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 <utility> | 10 #include <utility> |
| 10 | 11 |
| 11 #include "base/android/build_info.h" | 12 #include "base/android/build_info.h" |
| 12 #include "base/android/jni_android.h" | 13 #include "base/android/jni_android.h" |
| 13 #include "base/android/jni_array.h" | 14 #include "base/android/jni_array.h" |
| 14 #include "base/android/jni_string.h" | 15 #include "base/android/jni_string.h" |
| 15 #include "base/logging.h" | 16 #include "base/logging.h" |
| 16 #include "base/numerics/safe_conversions.h" | 17 #include "base/numerics/safe_conversions.h" |
| 17 #include "base/strings/string_util.h" | 18 #include "base/strings/string_util.h" |
| 18 #include "jni/MediaCodecBridge_jni.h" | 19 #include "jni/MediaCodecBridge_jni.h" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 35 | 36 |
| 36 namespace media { | 37 namespace media { |
| 37 | 38 |
| 38 enum { | 39 enum { |
| 39 kBufferFlagSyncFrame = 1, // BUFFER_FLAG_SYNC_FRAME | 40 kBufferFlagSyncFrame = 1, // BUFFER_FLAG_SYNC_FRAME |
| 40 kBufferFlagEndOfStream = 4, // BUFFER_FLAG_END_OF_STREAM | 41 kBufferFlagEndOfStream = 4, // BUFFER_FLAG_END_OF_STREAM |
| 41 kConfigureFlagEncode = 1, // CONFIGURE_FLAG_ENCODE | 42 kConfigureFlagEncode = 1, // CONFIGURE_FLAG_ENCODE |
| 42 }; | 43 }; |
| 43 | 44 |
| 44 static ScopedJavaLocalRef<jintArray> | 45 static ScopedJavaLocalRef<jintArray> |
| 45 ToJavaIntArray(JNIEnv* env, scoped_ptr<jint[]> native_array, int size) { | 46 ToJavaIntArray(JNIEnv* env, std::unique_ptr<jint[]> native_array, int size) { |
| 46 ScopedJavaLocalRef<jintArray> j_array(env, env->NewIntArray(size)); | 47 ScopedJavaLocalRef<jintArray> j_array(env, env->NewIntArray(size)); |
| 47 env->SetIntArrayRegion(j_array.obj(), 0, size, native_array.get()); | 48 env->SetIntArrayRegion(j_array.obj(), 0, size, native_array.get()); |
| 48 return j_array; | 49 return j_array; |
| 49 } | 50 } |
| 50 | 51 |
| 51 static const std::string AudioCodecToAndroidMimeType(const AudioCodec& codec) { | 52 static const std::string AudioCodecToAndroidMimeType(const AudioCodec& codec) { |
| 52 switch (codec) { | 53 switch (codec) { |
| 53 case kCodecMP3: | 54 case kCodecMP3: |
| 54 return "audio/mpeg"; | 55 return "audio/mpeg"; |
| 55 case kCodecVorbis: | 56 case kCodecVorbis: |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 env, reinterpret_cast<const uint8_t*>(key_id.data()), key_id.size()); | 180 env, reinterpret_cast<const uint8_t*>(key_id.data()), key_id.size()); |
| 180 ScopedJavaLocalRef<jbyteArray> j_iv = base::android::ToJavaByteArray( | 181 ScopedJavaLocalRef<jbyteArray> j_iv = base::android::ToJavaByteArray( |
| 181 env, reinterpret_cast<const uint8_t*>(iv.data()), iv.size()); | 182 env, reinterpret_cast<const uint8_t*>(iv.data()), iv.size()); |
| 182 | 183 |
| 183 // MediaCodec.CryptoInfo documentations says passing NULL for |clear_array| | 184 // MediaCodec.CryptoInfo documentations says passing NULL for |clear_array| |
| 184 // to indicate that all data is encrypted. But it doesn't specify what | 185 // to indicate that all data is encrypted. But it doesn't specify what |
| 185 // |cypher_array| and |subsamples_size| should be in that case. Passing | 186 // |cypher_array| and |subsamples_size| should be in that case. Passing |
| 186 // one subsample here just to be on the safe side. | 187 // one subsample here just to be on the safe side. |
| 187 int new_subsamples_size = subsamples_size == 0 ? 1 : subsamples_size; | 188 int new_subsamples_size = subsamples_size == 0 ? 1 : subsamples_size; |
| 188 | 189 |
| 189 scoped_ptr<jint[]> native_clear_array(new jint[new_subsamples_size]); | 190 std::unique_ptr<jint[]> native_clear_array(new jint[new_subsamples_size]); |
| 190 scoped_ptr<jint[]> native_cypher_array(new jint[new_subsamples_size]); | 191 std::unique_ptr<jint[]> native_cypher_array(new jint[new_subsamples_size]); |
| 191 | 192 |
| 192 if (subsamples_size == 0) { | 193 if (subsamples_size == 0) { |
| 193 DCHECK(!subsamples); | 194 DCHECK(!subsamples); |
| 194 native_clear_array[0] = 0; | 195 native_clear_array[0] = 0; |
| 195 native_cypher_array[0] = data_size; | 196 native_cypher_array[0] = data_size; |
| 196 } else { | 197 } else { |
| 197 DCHECK_GT(subsamples_size, 0); | 198 DCHECK_GT(subsamples_size, 0); |
| 198 DCHECK(subsamples); | 199 DCHECK(subsamples); |
| 199 for (int i = 0; i < subsamples_size; ++i) { | 200 for (int i = 0; i < subsamples_size; ++i) { |
| 200 DCHECK(subsamples[i].clear_bytes <= std::numeric_limits<uint16_t>::max()); | 201 DCHECK(subsamples[i].clear_bytes <= std::numeric_limits<uint16_t>::max()); |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 | 342 |
| 342 // static | 343 // static |
| 343 AudioCodecBridge* AudioCodecBridge::Create(const AudioCodec& codec) { | 344 AudioCodecBridge* AudioCodecBridge::Create(const AudioCodec& codec) { |
| 344 if (!MediaCodecUtil::IsMediaCodecAvailable()) | 345 if (!MediaCodecUtil::IsMediaCodecAvailable()) |
| 345 return nullptr; | 346 return nullptr; |
| 346 | 347 |
| 347 const std::string mime = AudioCodecToAndroidMimeType(codec); | 348 const std::string mime = AudioCodecToAndroidMimeType(codec); |
| 348 if (mime.empty()) | 349 if (mime.empty()) |
| 349 return nullptr; | 350 return nullptr; |
| 350 | 351 |
| 351 scoped_ptr<AudioCodecBridge> bridge(new AudioCodecBridge(mime)); | 352 std::unique_ptr<AudioCodecBridge> bridge(new AudioCodecBridge(mime)); |
| 352 if (!bridge->media_codec()) | 353 if (!bridge->media_codec()) |
| 353 return nullptr; | 354 return nullptr; |
| 354 | 355 |
| 355 return bridge.release(); | 356 return bridge.release(); |
| 356 } | 357 } |
| 357 | 358 |
| 358 // static | 359 // static |
| 359 bool AudioCodecBridge::IsKnownUnaccelerated(const AudioCodec& codec) { | 360 bool AudioCodecBridge::IsKnownUnaccelerated(const AudioCodec& codec) { |
| 360 return MediaCodecUtil::IsKnownUnaccelerated( | 361 return MediaCodecUtil::IsKnownUnaccelerated( |
| 361 AudioCodecToAndroidMimeType(codec), MEDIA_CODEC_DECODER); | 362 AudioCodecToAndroidMimeType(codec), MEDIA_CODEC_DECODER); |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 604 jobject surface, | 605 jobject surface, |
| 605 jobject media_crypto, | 606 jobject media_crypto, |
| 606 bool allow_adaptive_playback) { | 607 bool allow_adaptive_playback) { |
| 607 if (!MediaCodecUtil::IsMediaCodecAvailable()) | 608 if (!MediaCodecUtil::IsMediaCodecAvailable()) |
| 608 return nullptr; | 609 return nullptr; |
| 609 | 610 |
| 610 const std::string mime = VideoCodecToAndroidMimeType(codec); | 611 const std::string mime = VideoCodecToAndroidMimeType(codec); |
| 611 if (mime.empty()) | 612 if (mime.empty()) |
| 612 return nullptr; | 613 return nullptr; |
| 613 | 614 |
| 614 scoped_ptr<VideoCodecBridge> bridge( | 615 std::unique_ptr<VideoCodecBridge> bridge( |
| 615 new VideoCodecBridge(mime, is_secure, MEDIA_CODEC_DECODER)); | 616 new VideoCodecBridge(mime, is_secure, MEDIA_CODEC_DECODER)); |
| 616 if (!bridge->media_codec()) | 617 if (!bridge->media_codec()) |
| 617 return nullptr; | 618 return nullptr; |
| 618 | 619 |
| 619 JNIEnv* env = AttachCurrentThread(); | 620 JNIEnv* env = AttachCurrentThread(); |
| 620 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime); | 621 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime); |
| 621 ScopedJavaLocalRef<jobject> j_format( | 622 ScopedJavaLocalRef<jobject> j_format( |
| 622 Java_MediaCodecBridge_createVideoDecoderFormat( | 623 Java_MediaCodecBridge_createVideoDecoderFormat( |
| 623 env, j_mime.obj(), size.width(), size.height())); | 624 env, j_mime.obj(), size.width(), size.height())); |
| 624 DCHECK(!j_format.is_null()); | 625 DCHECK(!j_format.is_null()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 638 int frame_rate, | 639 int frame_rate, |
| 639 int i_frame_interval, | 640 int i_frame_interval, |
| 640 int color_format) { | 641 int color_format) { |
| 641 if (!MediaCodecUtil::IsMediaCodecAvailable()) | 642 if (!MediaCodecUtil::IsMediaCodecAvailable()) |
| 642 return nullptr; | 643 return nullptr; |
| 643 | 644 |
| 644 const std::string mime = VideoCodecToAndroidMimeType(codec); | 645 const std::string mime = VideoCodecToAndroidMimeType(codec); |
| 645 if (mime.empty()) | 646 if (mime.empty()) |
| 646 return nullptr; | 647 return nullptr; |
| 647 | 648 |
| 648 scoped_ptr<VideoCodecBridge> bridge( | 649 std::unique_ptr<VideoCodecBridge> bridge( |
| 649 new VideoCodecBridge(mime, false, MEDIA_CODEC_ENCODER)); | 650 new VideoCodecBridge(mime, false, MEDIA_CODEC_ENCODER)); |
| 650 if (!bridge->media_codec()) | 651 if (!bridge->media_codec()) |
| 651 return nullptr; | 652 return nullptr; |
| 652 | 653 |
| 653 JNIEnv* env = AttachCurrentThread(); | 654 JNIEnv* env = AttachCurrentThread(); |
| 654 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime); | 655 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime); |
| 655 ScopedJavaLocalRef<jobject> j_format( | 656 ScopedJavaLocalRef<jobject> j_format( |
| 656 Java_MediaCodecBridge_createVideoEncoderFormat( | 657 Java_MediaCodecBridge_createVideoEncoderFormat( |
| 657 env, j_mime.obj(), size.width(), size.height(), bit_rate, frame_rate, | 658 env, j_mime.obj(), size.width(), size.height(), bit_rate, frame_rate, |
| 658 i_frame_interval, color_format)); | 659 i_frame_interval, color_format)); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 686 if (adaptive_playback_supported_for_testing_ == 0) | 687 if (adaptive_playback_supported_for_testing_ == 0) |
| 687 return false; | 688 return false; |
| 688 else if (adaptive_playback_supported_for_testing_ > 0) | 689 else if (adaptive_playback_supported_for_testing_ > 0) |
| 689 return true; | 690 return true; |
| 690 JNIEnv* env = AttachCurrentThread(); | 691 JNIEnv* env = AttachCurrentThread(); |
| 691 return Java_MediaCodecBridge_isAdaptivePlaybackSupported(env, media_codec(), | 692 return Java_MediaCodecBridge_isAdaptivePlaybackSupported(env, media_codec(), |
| 692 width, height); | 693 width, height); |
| 693 } | 694 } |
| 694 | 695 |
| 695 } // namespace media | 696 } // namespace media |
| OLD | NEW |