| 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/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 #include <string> |
| 9 | 9 |
| 10 #include "base/android/build_info.h" | 10 #include "base/android/build_info.h" |
| 11 #include "base/android/jni_android.h" | 11 #include "base/android/jni_android.h" |
| 12 #include "base/android/jni_array.h" | 12 #include "base/android/jni_array.h" |
| 13 #include "base/android/jni_string.h" | 13 #include "base/android/jni_string.h" |
| 14 #include "base/basictypes.h" | 14 #include "base/basictypes.h" |
| 15 #include "base/lazy_instance.h" | 15 #include "base/lazy_instance.h" |
| 16 #include "base/logging.h" | 16 #include "base/logging.h" |
| 17 #include "base/safe_numerics.h" | 17 #include "base/numerics/safe_conversions.h" |
| 18 #include "base/strings/string_util.h" | 18 #include "base/strings/string_util.h" |
| 19 #include "base/strings/stringprintf.h" | 19 #include "base/strings/stringprintf.h" |
| 20 #include "jni/MediaCodecBridge_jni.h" | 20 #include "jni/MediaCodecBridge_jni.h" |
| 21 #include "media/base/bit_reader.h" | 21 #include "media/base/bit_reader.h" |
| 22 #include "media/base/decrypt_config.h" | 22 #include "media/base/decrypt_config.h" |
| 23 | 23 |
| 24 using base::android::AttachCurrentThread; | 24 using base::android::AttachCurrentThread; |
| 25 using base::android::ConvertJavaStringToUTF8; | 25 using base::android::ConvertJavaStringToUTF8; |
| 26 using base::android::ConvertUTF8ToJavaString; | 26 using base::android::ConvertUTF8ToJavaString; |
| 27 using base::android::ScopedJavaLocalRef; | 27 using base::android::ScopedJavaLocalRef; |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 *width = Java_MediaCodecBridge_getOutputWidth(env, j_media_codec_.obj()); | 218 *width = Java_MediaCodecBridge_getOutputWidth(env, j_media_codec_.obj()); |
| 219 *height = Java_MediaCodecBridge_getOutputHeight(env, j_media_codec_.obj()); | 219 *height = Java_MediaCodecBridge_getOutputHeight(env, j_media_codec_.obj()); |
| 220 } | 220 } |
| 221 | 221 |
| 222 MediaCodecStatus MediaCodecBridge::QueueInputBuffer( | 222 MediaCodecStatus MediaCodecBridge::QueueInputBuffer( |
| 223 int index, | 223 int index, |
| 224 const uint8* data, | 224 const uint8* data, |
| 225 size_t data_size, | 225 size_t data_size, |
| 226 const base::TimeDelta& presentation_time) { | 226 const base::TimeDelta& presentation_time) { |
| 227 DVLOG(3) << __PRETTY_FUNCTION__ << index << ": " << data_size; | 227 DVLOG(3) << __PRETTY_FUNCTION__ << index << ": " << data_size; |
| 228 if (data_size > base::checked_numeric_cast<size_t>(kint32max)) | 228 if (data_size > base::checked_cast<size_t>(kint32max)) |
| 229 return MEDIA_CODEC_ERROR; | 229 return MEDIA_CODEC_ERROR; |
| 230 if (data && !FillInputBuffer(index, data, data_size)) | 230 if (data && !FillInputBuffer(index, data, data_size)) |
| 231 return MEDIA_CODEC_ERROR; | 231 return MEDIA_CODEC_ERROR; |
| 232 JNIEnv* env = AttachCurrentThread(); | 232 JNIEnv* env = AttachCurrentThread(); |
| 233 return static_cast<MediaCodecStatus>( | 233 return static_cast<MediaCodecStatus>( |
| 234 Java_MediaCodecBridge_queueInputBuffer(env, | 234 Java_MediaCodecBridge_queueInputBuffer(env, |
| 235 j_media_codec_.obj(), | 235 j_media_codec_.obj(), |
| 236 index, | 236 index, |
| 237 0, | 237 0, |
| 238 data_size, | 238 data_size, |
| 239 presentation_time.InMicroseconds(), | 239 presentation_time.InMicroseconds(), |
| 240 0)); | 240 0)); |
| 241 } | 241 } |
| 242 | 242 |
| 243 MediaCodecStatus MediaCodecBridge::QueueSecureInputBuffer( | 243 MediaCodecStatus MediaCodecBridge::QueueSecureInputBuffer( |
| 244 int index, | 244 int index, |
| 245 const uint8* data, | 245 const uint8* data, |
| 246 size_t data_size, | 246 size_t data_size, |
| 247 const uint8* key_id, | 247 const uint8* key_id, |
| 248 int key_id_size, | 248 int key_id_size, |
| 249 const uint8* iv, | 249 const uint8* iv, |
| 250 int iv_size, | 250 int iv_size, |
| 251 const SubsampleEntry* subsamples, | 251 const SubsampleEntry* subsamples, |
| 252 int subsamples_size, | 252 int subsamples_size, |
| 253 const base::TimeDelta& presentation_time) { | 253 const base::TimeDelta& presentation_time) { |
| 254 DVLOG(3) << __PRETTY_FUNCTION__ << index << ": " << data_size; | 254 DVLOG(3) << __PRETTY_FUNCTION__ << index << ": " << data_size; |
| 255 if (data_size > base::checked_numeric_cast<size_t>(kint32max)) | 255 if (data_size > base::checked_cast<size_t>(kint32max)) |
| 256 return MEDIA_CODEC_ERROR; | 256 return MEDIA_CODEC_ERROR; |
| 257 if (data && !FillInputBuffer(index, data, data_size)) | 257 if (data && !FillInputBuffer(index, data, data_size)) |
| 258 return MEDIA_CODEC_ERROR; | 258 return MEDIA_CODEC_ERROR; |
| 259 | 259 |
| 260 JNIEnv* env = AttachCurrentThread(); | 260 JNIEnv* env = AttachCurrentThread(); |
| 261 ScopedJavaLocalRef<jbyteArray> j_key_id = | 261 ScopedJavaLocalRef<jbyteArray> j_key_id = |
| 262 base::android::ToJavaByteArray(env, key_id, key_id_size); | 262 base::android::ToJavaByteArray(env, key_id, key_id_size); |
| 263 ScopedJavaLocalRef<jbyteArray> j_iv = | 263 ScopedJavaLocalRef<jbyteArray> j_iv = |
| 264 base::android::ToJavaByteArray(env, iv, iv_size); | 264 base::android::ToJavaByteArray(env, iv, iv_size); |
| 265 | 265 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 size_t* offset, | 342 size_t* offset, |
| 343 size_t* size, | 343 size_t* size, |
| 344 base::TimeDelta* presentation_time, | 344 base::TimeDelta* presentation_time, |
| 345 bool* end_of_stream, | 345 bool* end_of_stream, |
| 346 bool* key_frame) { | 346 bool* key_frame) { |
| 347 JNIEnv* env = AttachCurrentThread(); | 347 JNIEnv* env = AttachCurrentThread(); |
| 348 ScopedJavaLocalRef<jobject> result = | 348 ScopedJavaLocalRef<jobject> result = |
| 349 Java_MediaCodecBridge_dequeueOutputBuffer( | 349 Java_MediaCodecBridge_dequeueOutputBuffer( |
| 350 env, j_media_codec_.obj(), timeout.InMicroseconds()); | 350 env, j_media_codec_.obj(), timeout.InMicroseconds()); |
| 351 *index = Java_DequeueOutputResult_index(env, result.obj()); | 351 *index = Java_DequeueOutputResult_index(env, result.obj()); |
| 352 *offset = base::checked_numeric_cast<size_t>( | 352 *offset = base::checked_cast<size_t>( |
| 353 Java_DequeueOutputResult_offset(env, result.obj())); | 353 Java_DequeueOutputResult_offset(env, result.obj())); |
| 354 *size = base::checked_numeric_cast<size_t>( | 354 *size = base::checked_cast<size_t>( |
| 355 Java_DequeueOutputResult_numBytes(env, result.obj())); | 355 Java_DequeueOutputResult_numBytes(env, result.obj())); |
| 356 if (presentation_time) { | 356 if (presentation_time) { |
| 357 *presentation_time = base::TimeDelta::FromMicroseconds( | 357 *presentation_time = base::TimeDelta::FromMicroseconds( |
| 358 Java_DequeueOutputResult_presentationTimeMicroseconds(env, | 358 Java_DequeueOutputResult_presentationTimeMicroseconds(env, |
| 359 result.obj())); | 359 result.obj())); |
| 360 } | 360 } |
| 361 int flags = Java_DequeueOutputResult_flags(env, result.obj()); | 361 int flags = Java_DequeueOutputResult_flags(env, result.obj()); |
| 362 if (end_of_stream) | 362 if (end_of_stream) |
| 363 *end_of_stream = flags & kBufferFlagEndOfStream; | 363 *end_of_stream = flags & kBufferFlagEndOfStream; |
| 364 if (key_frame) | 364 if (key_frame) |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 401 return Java_MediaCodecBridge_getOutputBuffers(env, j_media_codec_.obj()); | 401 return Java_MediaCodecBridge_getOutputBuffers(env, j_media_codec_.obj()); |
| 402 } | 402 } |
| 403 | 403 |
| 404 void MediaCodecBridge::GetInputBuffer(int input_buffer_index, | 404 void MediaCodecBridge::GetInputBuffer(int input_buffer_index, |
| 405 uint8** data, | 405 uint8** data, |
| 406 size_t* capacity) { | 406 size_t* capacity) { |
| 407 JNIEnv* env = AttachCurrentThread(); | 407 JNIEnv* env = AttachCurrentThread(); |
| 408 ScopedJavaLocalRef<jobject> j_buffer(Java_MediaCodecBridge_getInputBuffer( | 408 ScopedJavaLocalRef<jobject> j_buffer(Java_MediaCodecBridge_getInputBuffer( |
| 409 env, j_media_codec_.obj(), input_buffer_index)); | 409 env, j_media_codec_.obj(), input_buffer_index)); |
| 410 *data = static_cast<uint8*>(env->GetDirectBufferAddress(j_buffer.obj())); | 410 *data = static_cast<uint8*>(env->GetDirectBufferAddress(j_buffer.obj())); |
| 411 *capacity = base::checked_numeric_cast<size_t>( | 411 *capacity = base::checked_cast<size_t>( |
| 412 env->GetDirectBufferCapacity(j_buffer.obj())); | 412 env->GetDirectBufferCapacity(j_buffer.obj())); |
| 413 } | 413 } |
| 414 | 414 |
| 415 bool MediaCodecBridge::CopyFromOutputBuffer(int index, | 415 bool MediaCodecBridge::CopyFromOutputBuffer(int index, |
| 416 size_t offset, | 416 size_t offset, |
| 417 void* dst, | 417 void* dst, |
| 418 int dst_size) { | 418 int dst_size) { |
| 419 JNIEnv* env = AttachCurrentThread(); | 419 JNIEnv* env = AttachCurrentThread(); |
| 420 ScopedJavaLocalRef<jobject> j_buffer( | 420 ScopedJavaLocalRef<jobject> j_buffer( |
| 421 Java_MediaCodecBridge_getOutputBuffer(env, j_media_codec_.obj(), index)); | 421 Java_MediaCodecBridge_getOutputBuffer(env, j_media_codec_.obj(), index)); |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 583 default: | 583 default: |
| 584 LOG(ERROR) << "Invalid header encountered for codec: " | 584 LOG(ERROR) << "Invalid header encountered for codec: " |
| 585 << AudioCodecToAndroidMimeType(codec); | 585 << AudioCodecToAndroidMimeType(codec); |
| 586 return false; | 586 return false; |
| 587 } | 587 } |
| 588 return true; | 588 return true; |
| 589 } | 589 } |
| 590 | 590 |
| 591 void AudioCodecBridge::PlayOutputBuffer(int index, size_t size) { | 591 void AudioCodecBridge::PlayOutputBuffer(int index, size_t size) { |
| 592 DCHECK_LE(0, index); | 592 DCHECK_LE(0, index); |
| 593 int numBytes = base::checked_numeric_cast<int>(size); | 593 int numBytes = base::checked_cast<int>(size); |
| 594 JNIEnv* env = AttachCurrentThread(); | 594 JNIEnv* env = AttachCurrentThread(); |
| 595 ScopedJavaLocalRef<jobject> buf = | 595 ScopedJavaLocalRef<jobject> buf = |
| 596 Java_MediaCodecBridge_getOutputBuffer(env, media_codec(), index); | 596 Java_MediaCodecBridge_getOutputBuffer(env, media_codec(), index); |
| 597 uint8* buffer = static_cast<uint8*>(env->GetDirectBufferAddress(buf.obj())); | 597 uint8* buffer = static_cast<uint8*>(env->GetDirectBufferAddress(buf.obj())); |
| 598 | 598 |
| 599 ScopedJavaLocalRef<jbyteArray> byte_array = | 599 ScopedJavaLocalRef<jbyteArray> byte_array = |
| 600 base::android::ToJavaByteArray(env, buffer, numBytes); | 600 base::android::ToJavaByteArray(env, buffer, numBytes); |
| 601 Java_MediaCodecBridge_playOutputBuffer(env, media_codec(), byte_array.obj()); | 601 Java_MediaCodecBridge_playOutputBuffer(env, media_codec(), byte_array.obj()); |
| 602 } | 602 } |
| 603 | 603 |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 708 void VideoCodecBridge::RequestKeyFrameSoon() { | 708 void VideoCodecBridge::RequestKeyFrameSoon() { |
| 709 JNIEnv* env = AttachCurrentThread(); | 709 JNIEnv* env = AttachCurrentThread(); |
| 710 Java_MediaCodecBridge_requestKeyFrameSoon(env, media_codec()); | 710 Java_MediaCodecBridge_requestKeyFrameSoon(env, media_codec()); |
| 711 } | 711 } |
| 712 | 712 |
| 713 bool MediaCodecBridge::RegisterMediaCodecBridge(JNIEnv* env) { | 713 bool MediaCodecBridge::RegisterMediaCodecBridge(JNIEnv* env) { |
| 714 return RegisterNativesImpl(env); | 714 return RegisterNativesImpl(env); |
| 715 } | 715 } |
| 716 | 716 |
| 717 } // namespace media | 717 } // namespace media |
| OLD | NEW |