| OLD | NEW |
| 1 /* | 1 /* |
| 2 * libjingle | 2 * libjingle |
| 3 * Copyright 2015 Google Inc. | 3 * Copyright 2015 Google Inc. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
| 7 * | 7 * |
| 8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
| 9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 int32_t Reset() override; | 89 int32_t Reset() override; |
| 90 // rtc::MessageHandler implementation. | 90 // rtc::MessageHandler implementation. |
| 91 void OnMessage(rtc::Message* msg) override; | 91 void OnMessage(rtc::Message* msg) override; |
| 92 | 92 |
| 93 private: | 93 private: |
| 94 // CHECK-fail if not running on |codec_thread_|. | 94 // CHECK-fail if not running on |codec_thread_|. |
| 95 void CheckOnCodecThread(); | 95 void CheckOnCodecThread(); |
| 96 | 96 |
| 97 int32_t InitDecodeOnCodecThread(); | 97 int32_t InitDecodeOnCodecThread(); |
| 98 int32_t ReleaseOnCodecThread(); | 98 int32_t ReleaseOnCodecThread(); |
| 99 int32_t DecodeOnCodecThread(const EncodedImage& inputImage); | 99 int32_t DecodeOnCodecThread(const EncodedImage* inputImage); |
| 100 // Deliver any outputs pending in the MediaCodec to our |callback_| and return | 100 // Deliver any outputs pending in the MediaCodec to our |callback_| and return |
| 101 // true on success. | 101 // true on success. |
| 102 bool DeliverPendingOutputs(JNIEnv* jni, int dequeue_timeout_us); | 102 bool DeliverPendingOutputs(JNIEnv* jni, int dequeue_timeout_us); |
| 103 int32_t ProcessHWErrorOnCodecThread(); | 103 int32_t ProcessHWErrorOnCodecThread(); |
| 104 | 104 |
| 105 // Type of video codec. | 105 // Type of video codec. |
| 106 VideoCodecType codecType_; | 106 VideoCodecType codecType_; |
| 107 | 107 |
| 108 bool key_frame_required_; | 108 bool key_frame_required_; |
| 109 bool inited_; | 109 bool inited_; |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 ALOGE << "Decode() - complete frame is required"; | 482 ALOGE << "Decode() - complete frame is required"; |
| 483 return WEBRTC_VIDEO_CODEC_ERROR; | 483 return WEBRTC_VIDEO_CODEC_ERROR; |
| 484 } | 484 } |
| 485 key_frame_required_ = false; | 485 key_frame_required_ = false; |
| 486 } | 486 } |
| 487 if (inputImage._length == 0) { | 487 if (inputImage._length == 0) { |
| 488 return WEBRTC_VIDEO_CODEC_ERROR; | 488 return WEBRTC_VIDEO_CODEC_ERROR; |
| 489 } | 489 } |
| 490 | 490 |
| 491 return codec_thread_->Invoke<int32_t>(Bind( | 491 return codec_thread_->Invoke<int32_t>(Bind( |
| 492 &MediaCodecVideoDecoder::DecodeOnCodecThread, this, inputImage)); | 492 &MediaCodecVideoDecoder::DecodeOnCodecThread, this, &inputImage)); |
| 493 } | 493 } |
| 494 | 494 |
| 495 int32_t MediaCodecVideoDecoder::DecodeOnCodecThread( | 495 int32_t MediaCodecVideoDecoder::DecodeOnCodecThread( |
| 496 const EncodedImage& inputImage) { | 496 const EncodedImage* inputImage) { |
| 497 CheckOnCodecThread(); | 497 CheckOnCodecThread(); |
| 498 JNIEnv* jni = AttachCurrentThreadIfNeeded(); | 498 JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
| 499 ScopedLocalRefFrame local_ref_frame(jni); | 499 ScopedLocalRefFrame local_ref_frame(jni); |
| 500 | 500 |
| 501 // Try to drain the decoder and wait until output is not too | 501 // Try to drain the decoder and wait until output is not too |
| 502 // much behind the input. | 502 // much behind the input. |
| 503 if (frames_received_ > frames_decoded_ + max_pending_frames_) { | 503 if (frames_received_ > frames_decoded_ + max_pending_frames_) { |
| 504 ALOGV("Received: %d. Decoded: %d. Wait for output...", | 504 ALOGV("Received: %d. Decoded: %d. Wait for output...", |
| 505 frames_received_, frames_decoded_); | 505 frames_received_, frames_decoded_); |
| 506 if (!DeliverPendingOutputs(jni, kMediaCodecTimeoutMs * 1000)) { | 506 if (!DeliverPendingOutputs(jni, kMediaCodecTimeoutMs * 1000)) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 520 ALOGE << "dequeueInputBuffer error"; | 520 ALOGE << "dequeueInputBuffer error"; |
| 521 return ProcessHWErrorOnCodecThread(); | 521 return ProcessHWErrorOnCodecThread(); |
| 522 } | 522 } |
| 523 | 523 |
| 524 // Copy encoded data to Java ByteBuffer. | 524 // Copy encoded data to Java ByteBuffer. |
| 525 jobject j_input_buffer = input_buffers_[j_input_buffer_index]; | 525 jobject j_input_buffer = input_buffers_[j_input_buffer_index]; |
| 526 uint8_t* buffer = | 526 uint8_t* buffer = |
| 527 reinterpret_cast<uint8_t*>(jni->GetDirectBufferAddress(j_input_buffer)); | 527 reinterpret_cast<uint8_t*>(jni->GetDirectBufferAddress(j_input_buffer)); |
| 528 RTC_CHECK(buffer) << "Indirect buffer??"; | 528 RTC_CHECK(buffer) << "Indirect buffer??"; |
| 529 int64_t buffer_capacity = jni->GetDirectBufferCapacity(j_input_buffer); | 529 int64_t buffer_capacity = jni->GetDirectBufferCapacity(j_input_buffer); |
| 530 if (CheckException(jni) || buffer_capacity < inputImage._length) { | 530 if (CheckException(jni) || buffer_capacity < inputImage->_length) { |
| 531 ALOGE << "Input frame size "<< inputImage._length << | 531 ALOGE << "Input frame size "<< inputImage->_length << |
| 532 " is bigger than buffer size " << buffer_capacity; | 532 " is bigger than buffer size " << buffer_capacity; |
| 533 return ProcessHWErrorOnCodecThread(); | 533 return ProcessHWErrorOnCodecThread(); |
| 534 } | 534 } |
| 535 jlong timestamp_us = (frames_received_ * 1000000) / codec_.maxFramerate; | 535 jlong timestamp_us = (frames_received_ * 1000000) / codec_.maxFramerate; |
| 536 ALOGV("Decoder frame in # %d. Type: %d. Buffer # %d. TS: %lld. Size: %d", | 536 ALOGV("Decoder frame in # %d. Type: %d. Buffer # %d. TS: %lld. Size: %d", |
| 537 frames_received_, inputImage._frameType, j_input_buffer_index, | 537 frames_received_, inputImage->_frameType, j_input_buffer_index, |
| 538 timestamp_us / 1000, inputImage._length); | 538 timestamp_us / 1000, inputImage->_length); |
| 539 memcpy(buffer, inputImage._buffer, inputImage._length); | 539 memcpy(buffer, inputImage->_buffer, inputImage->_length); |
| 540 | 540 |
| 541 // Save input image timestamps for later output. | 541 // Save input image timestamps for later output. |
| 542 frames_received_++; | 542 frames_received_++; |
| 543 current_bytes_ += inputImage._length; | 543 current_bytes_ += inputImage->_length; |
| 544 timestamps_.push_back(inputImage._timeStamp); | 544 timestamps_.push_back(inputImage->_timeStamp); |
| 545 ntp_times_ms_.push_back(inputImage.ntp_time_ms_); | 545 ntp_times_ms_.push_back(inputImage->ntp_time_ms_); |
| 546 frame_rtc_times_ms_.push_back(GetCurrentTimeMs()); | 546 frame_rtc_times_ms_.push_back(GetCurrentTimeMs()); |
| 547 | 547 |
| 548 // Feed input to decoder. | 548 // Feed input to decoder. |
| 549 bool success = jni->CallBooleanMethod(*j_media_codec_video_decoder_, | 549 bool success = jni->CallBooleanMethod(*j_media_codec_video_decoder_, |
| 550 j_queue_input_buffer_method_, | 550 j_queue_input_buffer_method_, |
| 551 j_input_buffer_index, | 551 j_input_buffer_index, |
| 552 inputImage._length, | 552 inputImage->_length, |
| 553 timestamp_us); | 553 timestamp_us); |
| 554 if (CheckException(jni) || !success) { | 554 if (CheckException(jni) || !success) { |
| 555 ALOGE << "queueInputBuffer error"; | 555 ALOGE << "queueInputBuffer error"; |
| 556 return ProcessHWErrorOnCodecThread(); | 556 return ProcessHWErrorOnCodecThread(); |
| 557 } | 557 } |
| 558 | 558 |
| 559 // Try to drain the decoder | 559 // Try to drain the decoder |
| 560 if (!DeliverPendingOutputs(jni, 0)) { | 560 if (!DeliverPendingOutputs(jni, 0)) { |
| 561 ALOGE << "DeliverPendingOutputs error"; | 561 ALOGE << "DeliverPendingOutputs error"; |
| 562 return ProcessHWErrorOnCodecThread(); | 562 return ProcessHWErrorOnCodecThread(); |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 846 } | 846 } |
| 847 | 847 |
| 848 void MediaCodecVideoDecoderFactory::DestroyVideoDecoder( | 848 void MediaCodecVideoDecoderFactory::DestroyVideoDecoder( |
| 849 webrtc::VideoDecoder* decoder) { | 849 webrtc::VideoDecoder* decoder) { |
| 850 ALOGD << "Destroy video decoder."; | 850 ALOGD << "Destroy video decoder."; |
| 851 delete decoder; | 851 delete decoder; |
| 852 } | 852 } |
| 853 | 853 |
| 854 } // namespace webrtc_jni | 854 } // namespace webrtc_jni |
| 855 | 855 |
| OLD | NEW |