| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 2015 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #include <algorithm> | 11 #include <algorithm> |
| 12 #include <deque> |
| 12 #include <memory> | 13 #include <memory> |
| 13 #include <vector> | 14 #include <vector> |
| 14 | 15 |
| 15 // NOTICE: androidmediadecoder_jni.h must be included before | 16 // NOTICE: androidmediadecoder_jni.h must be included before |
| 16 // androidmediacodeccommon.h to avoid build errors. | 17 // androidmediacodeccommon.h to avoid build errors. |
| 17 #include "webrtc/sdk/android/src/jni/androidmediadecoder_jni.h" | 18 #include "webrtc/sdk/android/src/jni/androidmediadecoder_jni.h" |
| 18 | 19 |
| 19 #include "third_party/libyuv/include/libyuv/convert.h" | 20 #include "third_party/libyuv/include/libyuv/convert.h" |
| 20 #include "third_party/libyuv/include/libyuv/convert_from.h" | 21 #include "third_party/libyuv/include/libyuv/convert_from.h" |
| 21 #include "third_party/libyuv/include/libyuv/video_common.h" | 22 #include "third_party/libyuv/include/libyuv/video_common.h" |
| 22 #include "webrtc/sdk/android/src/jni/androidmediacodeccommon.h" | |
| 23 #include "webrtc/sdk/android/src/jni/classreferenceholder.h" | |
| 24 #include "webrtc/sdk/android/src/jni/native_handle_impl.h" | |
| 25 #include "webrtc/sdk/android/src/jni/surfacetexturehelper_jni.h" | |
| 26 #include "webrtc/base/bind.h" | 23 #include "webrtc/base/bind.h" |
| 27 #include "webrtc/base/checks.h" | 24 #include "webrtc/base/checks.h" |
| 28 #include "webrtc/base/logging.h" | 25 #include "webrtc/base/logging.h" |
| 29 #include "webrtc/base/scoped_ref_ptr.h" | 26 #include "webrtc/base/scoped_ref_ptr.h" |
| 30 #include "webrtc/base/thread.h" | 27 #include "webrtc/base/thread.h" |
| 31 #include "webrtc/base/timeutils.h" | 28 #include "webrtc/base/timeutils.h" |
| 29 #include "webrtc/common_video/h264/h264_bitstream_parser.h" |
| 32 #include "webrtc/common_video/include/i420_buffer_pool.h" | 30 #include "webrtc/common_video/include/i420_buffer_pool.h" |
| 33 #include "webrtc/modules/video_coding/include/video_codec_interface.h" | 31 #include "webrtc/modules/video_coding/include/video_codec_interface.h" |
| 32 #include "webrtc/modules/video_coding/utility/vp8_header_parser.h" |
| 33 #include "webrtc/sdk/android/src/jni/androidmediacodeccommon.h" |
| 34 #include "webrtc/sdk/android/src/jni/classreferenceholder.h" |
| 35 #include "webrtc/sdk/android/src/jni/native_handle_impl.h" |
| 36 #include "webrtc/sdk/android/src/jni/surfacetexturehelper_jni.h" |
| 34 #include "webrtc/system_wrappers/include/logcat_trace_context.h" | 37 #include "webrtc/system_wrappers/include/logcat_trace_context.h" |
| 35 | 38 |
| 36 using rtc::Bind; | 39 using rtc::Bind; |
| 37 using rtc::Thread; | 40 using rtc::Thread; |
| 38 using rtc::ThreadManager; | 41 using rtc::ThreadManager; |
| 39 | 42 |
| 40 using webrtc::CodecSpecificInfo; | 43 using webrtc::CodecSpecificInfo; |
| 41 using webrtc::DecodedImageCallback; | 44 using webrtc::DecodedImageCallback; |
| 42 using webrtc::EncodedImage; | 45 using webrtc::EncodedImage; |
| 43 using webrtc::VideoFrame; | 46 using webrtc::VideoFrame; |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 int frames_received_; // Number of frames received by decoder. | 128 int frames_received_; // Number of frames received by decoder. |
| 126 int frames_decoded_; // Number of frames decoded by decoder. | 129 int frames_decoded_; // Number of frames decoded by decoder. |
| 127 // Number of decoded frames for which log information is displayed. | 130 // Number of decoded frames for which log information is displayed. |
| 128 int frames_decoded_logged_; | 131 int frames_decoded_logged_; |
| 129 int64_t start_time_ms_; // Start time for statistics. | 132 int64_t start_time_ms_; // Start time for statistics. |
| 130 int current_frames_; // Number of frames in the current statistics interval. | 133 int current_frames_; // Number of frames in the current statistics interval. |
| 131 int current_bytes_; // Encoded bytes in the current statistics interval. | 134 int current_bytes_; // Encoded bytes in the current statistics interval. |
| 132 int current_decoding_time_ms_; // Overall decoding time in the current second | 135 int current_decoding_time_ms_; // Overall decoding time in the current second |
| 133 int current_delay_time_ms_; // Overall delay time in the current second. | 136 int current_delay_time_ms_; // Overall delay time in the current second. |
| 134 uint32_t max_pending_frames_; // Maximum number of pending input frames. | 137 uint32_t max_pending_frames_; // Maximum number of pending input frames. |
| 138 webrtc::H264BitstreamParser h264_bitstream_parser_; |
| 139 std::deque<rtc::Optional<uint8_t>> pending_frame_qps_; |
| 135 | 140 |
| 136 // State that is constant for the lifetime of this object once the ctor | 141 // State that is constant for the lifetime of this object once the ctor |
| 137 // returns. | 142 // returns. |
| 138 std::unique_ptr<Thread> | 143 std::unique_ptr<Thread> |
| 139 codec_thread_; // Thread on which to operate MediaCodec. | 144 codec_thread_; // Thread on which to operate MediaCodec. |
| 140 ScopedGlobalRef<jclass> j_media_codec_video_decoder_class_; | 145 ScopedGlobalRef<jclass> j_media_codec_video_decoder_class_; |
| 141 ScopedGlobalRef<jobject> j_media_codec_video_decoder_; | 146 ScopedGlobalRef<jobject> j_media_codec_video_decoder_; |
| 142 jmethodID j_init_decode_method_; | 147 jmethodID j_init_decode_method_; |
| 143 jmethodID j_reset_method_; | 148 jmethodID j_reset_method_; |
| 144 jmethodID j_release_method_; | 149 jmethodID j_release_method_; |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 316 | 321 |
| 317 key_frame_required_ = true; | 322 key_frame_required_ = true; |
| 318 frames_received_ = 0; | 323 frames_received_ = 0; |
| 319 frames_decoded_ = 0; | 324 frames_decoded_ = 0; |
| 320 frames_decoded_logged_ = kMaxDecodedLogFrames; | 325 frames_decoded_logged_ = kMaxDecodedLogFrames; |
| 321 start_time_ms_ = rtc::TimeMillis(); | 326 start_time_ms_ = rtc::TimeMillis(); |
| 322 current_frames_ = 0; | 327 current_frames_ = 0; |
| 323 current_bytes_ = 0; | 328 current_bytes_ = 0; |
| 324 current_decoding_time_ms_ = 0; | 329 current_decoding_time_ms_ = 0; |
| 325 current_delay_time_ms_ = 0; | 330 current_delay_time_ms_ = 0; |
| 331 pending_frame_qps_.clear(); |
| 326 } | 332 } |
| 327 | 333 |
| 328 int32_t MediaCodecVideoDecoder::InitDecodeOnCodecThread() { | 334 int32_t MediaCodecVideoDecoder::InitDecodeOnCodecThread() { |
| 329 CheckOnCodecThread(); | 335 CheckOnCodecThread(); |
| 330 JNIEnv* jni = AttachCurrentThreadIfNeeded(); | 336 JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
| 331 ScopedLocalRefFrame local_ref_frame(jni); | 337 ScopedLocalRefFrame local_ref_frame(jni); |
| 332 ALOGD << "InitDecodeOnCodecThread Type: " << (int)codecType_ << ". " | 338 ALOGD << "InitDecodeOnCodecThread Type: " << (int)codecType_ << ". " |
| 333 << codec_.width << " x " << codec_.height << ". Fps: " << | 339 << codec_.width << " x " << codec_.height << ". Fps: " << |
| 334 (int)codec_.maxFramerate; | 340 (int)codec_.maxFramerate; |
| 335 | 341 |
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 646 ALOGD << "Decoder frame in # " << frames_received_ << | 652 ALOGD << "Decoder frame in # " << frames_received_ << |
| 647 ". Type: " << inputImage._frameType << | 653 ". Type: " << inputImage._frameType << |
| 648 ". Buffer # " << j_input_buffer_index << | 654 ". Buffer # " << j_input_buffer_index << |
| 649 ". TS: " << presentation_timestamp_us / 1000 << | 655 ". TS: " << presentation_timestamp_us / 1000 << |
| 650 ". Size: " << inputImage._length; | 656 ". Size: " << inputImage._length; |
| 651 } | 657 } |
| 652 | 658 |
| 653 // Save input image timestamps for later output. | 659 // Save input image timestamps for later output. |
| 654 frames_received_++; | 660 frames_received_++; |
| 655 current_bytes_ += inputImage._length; | 661 current_bytes_ += inputImage._length; |
| 662 rtc::Optional<uint8_t> qp; |
| 663 if (codecType_ == kVideoCodecVP8) { |
| 664 int qp_int; |
| 665 if (webrtc::vp8::GetQp(inputImage._buffer, inputImage._length, &qp_int)) { |
| 666 qp = rtc::Optional<uint8_t>(qp_int); |
| 667 } |
| 668 } else if (codecType_ == kVideoCodecH264) { |
| 669 h264_bitstream_parser_.ParseBitstream(inputImage._buffer, |
| 670 inputImage._length); |
| 671 int qp_int; |
| 672 if (h264_bitstream_parser_.GetLastSliceQp(&qp_int)) { |
| 673 qp = rtc::Optional<uint8_t>(qp_int); |
| 674 } |
| 675 } |
| 676 pending_frame_qps_.push_back(qp); |
| 656 | 677 |
| 657 // Feed input to decoder. | 678 // Feed input to decoder. |
| 658 bool success = jni->CallBooleanMethod( | 679 bool success = jni->CallBooleanMethod( |
| 659 *j_media_codec_video_decoder_, | 680 *j_media_codec_video_decoder_, |
| 660 j_queue_input_buffer_method_, | 681 j_queue_input_buffer_method_, |
| 661 j_input_buffer_index, | 682 j_input_buffer_index, |
| 662 inputImage._length, | 683 inputImage._length, |
| 663 presentation_timestamp_us, | 684 presentation_timestamp_us, |
| 664 static_cast<int64_t> (inputImage._timeStamp), | 685 static_cast<int64_t> (inputImage._timeStamp), |
| 665 inputImage.ntp_time_ms_); | 686 inputImage.ntp_time_ms_); |
| 666 if (CheckException(jni) || !success) { | 687 if (CheckException(jni) || !success) { |
| 667 ALOGE << "queueInputBuffer error"; | 688 ALOGE << "queueInputBuffer error"; |
| 668 return ProcessHWErrorOnCodecThread(); | 689 return ProcessHWErrorOnCodecThread(); |
| 669 } | 690 } |
| 670 | 691 |
| 671 // Try to drain the decoder | 692 // Try to drain the decoder |
| 672 if (!DeliverPendingOutputs(jni, 0)) { | 693 if (!DeliverPendingOutputs(jni, 0)) { |
| 673 ALOGE << "DeliverPendingOutputs error"; | 694 ALOGE << "DeliverPendingOutputs error"; |
| 674 return ProcessHWErrorOnCodecThread(); | 695 return ProcessHWErrorOnCodecThread(); |
| 675 } | 696 } |
| 676 | 697 |
| 677 return WEBRTC_VIDEO_CODEC_OK; | 698 return WEBRTC_VIDEO_CODEC_OK; |
| 678 } | 699 } |
| 679 | 700 |
| 680 bool MediaCodecVideoDecoder::DeliverPendingOutputs( | 701 bool MediaCodecVideoDecoder::DeliverPendingOutputs( |
| 681 JNIEnv* jni, int dequeue_timeout_ms) { | 702 JNIEnv* jni, int dequeue_timeout_ms) { |
| 703 CheckOnCodecThread(); |
| 682 if (frames_received_ <= frames_decoded_) { | 704 if (frames_received_ <= frames_decoded_) { |
| 683 // No need to query for output buffers - decoder is drained. | 705 // No need to query for output buffers - decoder is drained. |
| 684 return true; | 706 return true; |
| 685 } | 707 } |
| 686 // Get decoder output. | 708 // Get decoder output. |
| 687 jobject j_decoder_output_buffer = | 709 jobject j_decoder_output_buffer = |
| 688 jni->CallObjectMethod(*j_media_codec_video_decoder_, | 710 jni->CallObjectMethod(*j_media_codec_video_decoder_, |
| 689 use_surface_ ? j_dequeue_texture_buffer_method_ | 711 use_surface_ ? j_dequeue_texture_buffer_method_ |
| 690 : j_dequeue_byte_buffer_method_, | 712 : j_dequeue_byte_buffer_method_, |
| 691 dequeue_timeout_ms); | 713 dequeue_timeout_ms); |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 854 current_decoding_time_ms_ = 0; | 876 current_decoding_time_ms_ = 0; |
| 855 current_delay_time_ms_ = 0; | 877 current_delay_time_ms_ = 0; |
| 856 } | 878 } |
| 857 | 879 |
| 858 // If the frame was dropped, frame_buffer is left as nullptr. | 880 // If the frame was dropped, frame_buffer is left as nullptr. |
| 859 if (frame_buffer) { | 881 if (frame_buffer) { |
| 860 VideoFrame decoded_frame(frame_buffer, 0, 0, webrtc::kVideoRotation_0); | 882 VideoFrame decoded_frame(frame_buffer, 0, 0, webrtc::kVideoRotation_0); |
| 861 decoded_frame.set_timestamp(output_timestamps_ms); | 883 decoded_frame.set_timestamp(output_timestamps_ms); |
| 862 decoded_frame.set_ntp_time_ms(output_ntp_timestamps_ms); | 884 decoded_frame.set_ntp_time_ms(output_ntp_timestamps_ms); |
| 863 | 885 |
| 864 const int32_t callback_status = | 886 rtc::Optional<uint8_t> qp = pending_frame_qps_.front(); |
| 865 callback_->Decoded(decoded_frame, decode_time_ms); | 887 pending_frame_qps_.pop_front(); |
| 866 if (callback_status > 0) { | 888 callback_->Decoded(decoded_frame, rtc::Optional<int32_t>(decode_time_ms), |
| 867 ALOGE << "callback error"; | 889 qp); |
| 868 } | |
| 869 } | 890 } |
| 870 return true; | 891 return true; |
| 871 } | 892 } |
| 872 | 893 |
| 873 int32_t MediaCodecVideoDecoder::RegisterDecodeCompleteCallback( | 894 int32_t MediaCodecVideoDecoder::RegisterDecodeCompleteCallback( |
| 874 DecodedImageCallback* callback) { | 895 DecodedImageCallback* callback) { |
| 875 callback_ = callback; | 896 callback_ = callback; |
| 876 return WEBRTC_VIDEO_CODEC_OK; | 897 return WEBRTC_VIDEO_CODEC_OK; |
| 877 } | 898 } |
| 878 | 899 |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 980 webrtc::VideoDecoder* decoder) { | 1001 webrtc::VideoDecoder* decoder) { |
| 981 ALOGD << "Destroy video decoder."; | 1002 ALOGD << "Destroy video decoder."; |
| 982 delete decoder; | 1003 delete decoder; |
| 983 } | 1004 } |
| 984 | 1005 |
| 985 const char* MediaCodecVideoDecoder::ImplementationName() const { | 1006 const char* MediaCodecVideoDecoder::ImplementationName() const { |
| 986 return "MediaCodec"; | 1007 return "MediaCodec"; |
| 987 } | 1008 } |
| 988 | 1009 |
| 989 } // namespace webrtc_jni | 1010 } // namespace webrtc_jni |
| OLD | NEW |