| 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 <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 bool SdkMediaCodecBridge::Start() { | 105 bool SdkMediaCodecBridge::Start() { |
| 106 JNIEnv* env = AttachCurrentThread(); | 106 JNIEnv* env = AttachCurrentThread(); |
| 107 return Java_MediaCodecBridge_start(env, j_media_codec_.obj()); | 107 return Java_MediaCodecBridge_start(env, j_media_codec_.obj()); |
| 108 } | 108 } |
| 109 | 109 |
| 110 void SdkMediaCodecBridge::Stop() { | 110 void SdkMediaCodecBridge::Stop() { |
| 111 JNIEnv* env = AttachCurrentThread(); | 111 JNIEnv* env = AttachCurrentThread(); |
| 112 Java_MediaCodecBridge_stop(env, j_media_codec_.obj()); | 112 Java_MediaCodecBridge_stop(env, j_media_codec_.obj()); |
| 113 } | 113 } |
| 114 | 114 |
| 115 void SdkMediaCodecBridge::GetOutputFormat(int* width, int* height) { | 115 MediaCodecStatus SdkMediaCodecBridge::GetOutputSize(gfx::Size* size) { |
| 116 JNIEnv* env = AttachCurrentThread(); | 116 JNIEnv* env = AttachCurrentThread(); |
| 117 | 117 ScopedJavaLocalRef<jobject> result = |
| 118 *width = Java_MediaCodecBridge_getOutputWidth(env, j_media_codec_.obj()); | 118 Java_MediaCodecBridge_getOutputFormat(env, j_media_codec_.obj()); |
| 119 *height = Java_MediaCodecBridge_getOutputHeight(env, j_media_codec_.obj()); | 119 MediaCodecStatus status = static_cast<MediaCodecStatus>( |
| 120 Java_GetOutputFormatResult_status(env, result.obj())); |
| 121 if (status == MEDIA_CODEC_OK) { |
| 122 size->SetSize(Java_GetOutputFormatResult_width(env, result.obj()), |
| 123 Java_GetOutputFormatResult_height(env, result.obj())); |
| 124 } |
| 125 return status; |
| 120 } | 126 } |
| 121 | 127 |
| 122 int SdkMediaCodecBridge::GetOutputSamplingRate() { | 128 MediaCodecStatus SdkMediaCodecBridge::GetOutputSamplingRate( |
| 129 int* sampling_rate) { |
| 123 JNIEnv* env = AttachCurrentThread(); | 130 JNIEnv* env = AttachCurrentThread(); |
| 124 | 131 ScopedJavaLocalRef<jobject> result = |
| 125 return Java_MediaCodecBridge_getOutputSamplingRate(env, j_media_codec_.obj()); | 132 Java_MediaCodecBridge_getOutputFormat(env, j_media_codec_.obj()); |
| 133 MediaCodecStatus status = static_cast<MediaCodecStatus>( |
| 134 Java_GetOutputFormatResult_status(env, result.obj())); |
| 135 if (status == MEDIA_CODEC_OK) |
| 136 *sampling_rate = Java_GetOutputFormatResult_sampleRate(env, result.obj()); |
| 137 return status; |
| 126 } | 138 } |
| 127 | 139 |
| 128 MediaCodecStatus SdkMediaCodecBridge::QueueInputBuffer( | 140 MediaCodecStatus SdkMediaCodecBridge::QueueInputBuffer( |
| 129 int index, | 141 int index, |
| 130 const uint8_t* data, | 142 const uint8_t* data, |
| 131 size_t data_size, | 143 size_t data_size, |
| 132 const base::TimeDelta& presentation_time) { | 144 const base::TimeDelta& presentation_time) { |
| 133 DVLOG(3) << __PRETTY_FUNCTION__ << index << ": " << data_size; | 145 DVLOG(3) << __PRETTY_FUNCTION__ << index << ": " << data_size; |
| 134 if (data_size > | 146 if (data_size > |
| 135 base::checked_cast<size_t>(std::numeric_limits<int32_t>::max())) { | 147 base::checked_cast<size_t>(std::numeric_limits<int32_t>::max())) { |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 267 | 279 |
| 268 void SdkMediaCodecBridge::ReleaseOutputBuffer(int index, bool render) { | 280 void SdkMediaCodecBridge::ReleaseOutputBuffer(int index, bool render) { |
| 269 DVLOG(3) << __PRETTY_FUNCTION__ << ": " << index; | 281 DVLOG(3) << __PRETTY_FUNCTION__ << ": " << index; |
| 270 JNIEnv* env = AttachCurrentThread(); | 282 JNIEnv* env = AttachCurrentThread(); |
| 271 CHECK(env); | 283 CHECK(env); |
| 272 | 284 |
| 273 Java_MediaCodecBridge_releaseOutputBuffer(env, j_media_codec_.obj(), index, | 285 Java_MediaCodecBridge_releaseOutputBuffer(env, j_media_codec_.obj(), index, |
| 274 render); | 286 render); |
| 275 } | 287 } |
| 276 | 288 |
| 277 void SdkMediaCodecBridge::GetInputBuffer(int input_buffer_index, | 289 MediaCodecStatus SdkMediaCodecBridge::GetInputBuffer(int input_buffer_index, |
| 278 uint8_t** data, | 290 uint8_t** data, |
| 279 size_t* capacity) { | 291 size_t* capacity) { |
| 280 JNIEnv* env = AttachCurrentThread(); | 292 JNIEnv* env = AttachCurrentThread(); |
| 281 ScopedJavaLocalRef<jobject> j_buffer(Java_MediaCodecBridge_getInputBuffer( | 293 ScopedJavaLocalRef<jobject> j_buffer(Java_MediaCodecBridge_getInputBuffer( |
| 282 env, j_media_codec_.obj(), input_buffer_index)); | 294 env, j_media_codec_.obj(), input_buffer_index)); |
| 295 if (j_buffer.is_null()) |
| 296 return MEDIA_CODEC_ERROR; |
| 297 |
| 283 *data = static_cast<uint8_t*>(env->GetDirectBufferAddress(j_buffer.obj())); | 298 *data = static_cast<uint8_t*>(env->GetDirectBufferAddress(j_buffer.obj())); |
| 284 *capacity = | 299 *capacity = |
| 285 base::checked_cast<size_t>(env->GetDirectBufferCapacity(j_buffer.obj())); | 300 base::checked_cast<size_t>(env->GetDirectBufferCapacity(j_buffer.obj())); |
| 301 return MEDIA_CODEC_OK; |
| 286 } | 302 } |
| 287 | 303 |
| 288 void SdkMediaCodecBridge::CopyFromOutputBuffer(int index, | 304 MediaCodecStatus SdkMediaCodecBridge::CopyFromOutputBuffer(int index, |
| 289 size_t offset, | 305 size_t offset, |
| 290 void* dst, | 306 void* dst, |
| 291 size_t num) { | 307 size_t num) { |
| 292 void* src_data = nullptr; | 308 void* src_data = nullptr; |
| 293 const size_t src_capacity = GetOutputBufferAddress(index, offset, &src_data); | 309 size_t src_capacity = 0; |
| 294 CHECK_GE(src_capacity, num); | 310 MediaCodecStatus status = |
| 295 memcpy(dst, src_data, num); | 311 GetOutputBufferAddress(index, offset, &src_data, &src_capacity); |
| 312 if (status == MEDIA_CODEC_OK) { |
| 313 CHECK_GE(src_capacity, num); |
| 314 memcpy(dst, src_data, num); |
| 315 } |
| 316 return status; |
| 296 } | 317 } |
| 297 | 318 |
| 298 size_t SdkMediaCodecBridge::GetOutputBufferAddress(int index, | 319 MediaCodecStatus SdkMediaCodecBridge::GetOutputBufferAddress(int index, |
| 299 size_t offset, | 320 size_t offset, |
| 300 void** addr) { | 321 void** addr, |
| 322 size_t* capacity) { |
| 301 JNIEnv* env = AttachCurrentThread(); | 323 JNIEnv* env = AttachCurrentThread(); |
| 302 ScopedJavaLocalRef<jobject> j_buffer( | 324 ScopedJavaLocalRef<jobject> j_buffer( |
| 303 Java_MediaCodecBridge_getOutputBuffer(env, j_media_codec_.obj(), index)); | 325 Java_MediaCodecBridge_getOutputBuffer(env, j_media_codec_.obj(), index)); |
| 326 if (j_buffer.is_null()) |
| 327 return MEDIA_CODEC_ERROR; |
| 304 const size_t total_capacity = env->GetDirectBufferCapacity(j_buffer.obj()); | 328 const size_t total_capacity = env->GetDirectBufferCapacity(j_buffer.obj()); |
| 305 CHECK_GE(total_capacity, offset); | 329 CHECK_GE(total_capacity, offset); |
| 306 *addr = | 330 *addr = |
| 307 reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(j_buffer.obj())) + | 331 reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(j_buffer.obj())) + |
| 308 offset; | 332 offset; |
| 309 return total_capacity - offset; | 333 *capacity = total_capacity - offset; |
| 334 return MEDIA_CODEC_OK; |
| 310 } | 335 } |
| 311 | 336 |
| 312 // static | 337 // static |
| 313 bool SdkMediaCodecBridge::RegisterSdkMediaCodecBridge(JNIEnv* env) { | 338 bool SdkMediaCodecBridge::RegisterSdkMediaCodecBridge(JNIEnv* env) { |
| 314 return RegisterNativesImpl(env); | 339 return RegisterNativesImpl(env); |
| 315 } | 340 } |
| 316 | 341 |
| 317 // static | 342 // static |
| 318 AudioCodecBridge* AudioCodecBridge::Create(const AudioCodec& codec) { | 343 AudioCodecBridge* AudioCodecBridge::Create(const AudioCodec& codec) { |
| 319 if (!MediaCodecUtil::IsMediaCodecAvailable()) | 344 if (!MediaCodecUtil::IsMediaCodecAvailable()) |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 521 break; | 546 break; |
| 522 } | 547 } |
| 523 default: | 548 default: |
| 524 LOG(ERROR) << "Invalid header encountered for codec: " | 549 LOG(ERROR) << "Invalid header encountered for codec: " |
| 525 << AudioCodecToAndroidMimeType(codec); | 550 << AudioCodecToAndroidMimeType(codec); |
| 526 return false; | 551 return false; |
| 527 } | 552 } |
| 528 return true; | 553 return true; |
| 529 } | 554 } |
| 530 | 555 |
| 531 int64_t AudioCodecBridge::PlayOutputBuffer(int index, | 556 MediaCodecStatus AudioCodecBridge::PlayOutputBuffer(int index, |
| 532 size_t size, | 557 size_t size, |
| 533 size_t offset, | 558 size_t offset, |
| 534 bool postpone) { | 559 bool postpone, |
| 560 int64_t* playback_pos) { |
| 535 DCHECK_LE(0, index); | 561 DCHECK_LE(0, index); |
| 536 int numBytes = base::checked_cast<int>(size); | 562 int numBytes = base::checked_cast<int>(size); |
| 537 | 563 |
| 538 void* buffer = nullptr; | 564 void* buffer = nullptr; |
| 539 int capacity = GetOutputBufferAddress(index, offset, &buffer); | 565 size_t capacity = 0; |
| 540 numBytes = std::min(capacity, numBytes); | 566 MediaCodecStatus status = |
| 567 GetOutputBufferAddress(index, offset, &buffer, &capacity); |
| 568 if (status == MEDIA_CODEC_ERROR) |
| 569 return status; |
| 570 |
| 571 numBytes = std::min(base::checked_cast<int>(capacity), numBytes); |
| 541 CHECK_GE(numBytes, 0); | 572 CHECK_GE(numBytes, 0); |
| 542 | 573 |
| 543 JNIEnv* env = AttachCurrentThread(); | 574 JNIEnv* env = AttachCurrentThread(); |
| 544 ScopedJavaLocalRef<jbyteArray> byte_array = base::android::ToJavaByteArray( | 575 ScopedJavaLocalRef<jbyteArray> byte_array = base::android::ToJavaByteArray( |
| 545 env, static_cast<uint8_t*>(buffer), numBytes); | 576 env, static_cast<uint8_t*>(buffer), numBytes); |
| 546 return Java_MediaCodecBridge_playOutputBuffer(env, media_codec(), | 577 *playback_pos = Java_MediaCodecBridge_playOutputBuffer( |
| 547 byte_array.obj(), postpone); | 578 env, media_codec(), byte_array.obj(), postpone); |
| 579 return status; |
| 548 } | 580 } |
| 549 | 581 |
| 550 void AudioCodecBridge::SetVolume(double volume) { | 582 void AudioCodecBridge::SetVolume(double volume) { |
| 551 JNIEnv* env = AttachCurrentThread(); | 583 JNIEnv* env = AttachCurrentThread(); |
| 552 Java_MediaCodecBridge_setVolume(env, media_codec(), volume); | 584 Java_MediaCodecBridge_setVolume(env, media_codec(), volume); |
| 553 } | 585 } |
| 554 | 586 |
| 555 // static | 587 // static |
| 556 bool VideoCodecBridge::IsKnownUnaccelerated(const VideoCodec& codec, | 588 bool VideoCodecBridge::IsKnownUnaccelerated(const VideoCodec& codec, |
| 557 MediaCodecDirection direction) { | 589 MediaCodecDirection direction) { |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 649 if (adaptive_playback_supported_for_testing_ == 0) | 681 if (adaptive_playback_supported_for_testing_ == 0) |
| 650 return false; | 682 return false; |
| 651 else if (adaptive_playback_supported_for_testing_ > 0) | 683 else if (adaptive_playback_supported_for_testing_ > 0) |
| 652 return true; | 684 return true; |
| 653 JNIEnv* env = AttachCurrentThread(); | 685 JNIEnv* env = AttachCurrentThread(); |
| 654 return Java_MediaCodecBridge_isAdaptivePlaybackSupported(env, media_codec(), | 686 return Java_MediaCodecBridge_isAdaptivePlaybackSupported(env, media_codec(), |
| 655 width, height); | 687 width, height); |
| 656 } | 688 } |
| 657 | 689 |
| 658 } // namespace media | 690 } // namespace media |
| OLD | NEW |