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 |