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 <memory> | 12 #include <memory> |
13 #include <vector> | 13 #include <vector> |
14 #include <deque> | |
magjed_webrtc
2017/02/16 20:22:20
sort the list
sakal
2017/02/17 09:23:43
Done.
| |
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/androidmediacodeccommon.h" |
23 #include "webrtc/sdk/android/src/jni/classreferenceholder.h" | 24 #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/native_handle_impl.h" |
25 #include "webrtc/sdk/android/src/jni/surfacetexturehelper_jni.h" | 26 #include "webrtc/sdk/android/src/jni/surfacetexturehelper_jni.h" |
26 #include "webrtc/base/bind.h" | 27 #include "webrtc/base/bind.h" |
27 #include "webrtc/base/checks.h" | 28 #include "webrtc/base/checks.h" |
28 #include "webrtc/base/logging.h" | 29 #include "webrtc/base/logging.h" |
29 #include "webrtc/base/scoped_ref_ptr.h" | 30 #include "webrtc/base/scoped_ref_ptr.h" |
30 #include "webrtc/base/thread.h" | 31 #include "webrtc/base/thread.h" |
31 #include "webrtc/base/timeutils.h" | 32 #include "webrtc/base/timeutils.h" |
33 #include "webrtc/common_video/h264/h264_bitstream_parser.h" | |
32 #include "webrtc/common_video/include/i420_buffer_pool.h" | 34 #include "webrtc/common_video/include/i420_buffer_pool.h" |
35 #include "webrtc/modules/video_coding/utility/vp8_header_parser.h" | |
magjed_webrtc
2017/02/16 20:22:20
sort the list
sakal
2017/02/17 09:23:43
Done.
| |
33 #include "webrtc/modules/video_coding/include/video_codec_interface.h" | 36 #include "webrtc/modules/video_coding/include/video_codec_interface.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; |
(...skipping 82 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<int> pending_frame_qps_; | |
magjed_webrtc
2017/02/16 20:22:20
Why not a regular queue? You don't need it to be d
sakal
2017/02/17 09:23:43
queue type doesn't have clear method that is requi
| |
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 int qp = -1; | |
magjed_webrtc
2017/02/16 20:22:20
Use a 'rtc::Optional<uint8_t> qp' directly instead
sakal
2017/02/17 09:23:43
Done.
| |
663 if (codecType_ == kVideoCodecVP8) { | |
664 webrtc::vp8::GetQp(inputImage._buffer, inputImage._length, &qp); | |
665 } else if (codecType_ == kVideoCodecH264) { | |
666 h264_bitstream_parser_.ParseBitstream(inputImage._buffer, | |
667 inputImage._length); | |
668 h264_bitstream_parser_.GetLastSliceQp(&qp); | |
669 } | |
670 pending_frame_qps_.push_back(qp); | |
656 | 671 |
657 // Feed input to decoder. | 672 // Feed input to decoder. |
658 bool success = jni->CallBooleanMethod( | 673 bool success = jni->CallBooleanMethod( |
659 *j_media_codec_video_decoder_, | 674 *j_media_codec_video_decoder_, |
660 j_queue_input_buffer_method_, | 675 j_queue_input_buffer_method_, |
661 j_input_buffer_index, | 676 j_input_buffer_index, |
662 inputImage._length, | 677 inputImage._length, |
663 presentation_timestamp_us, | 678 presentation_timestamp_us, |
664 static_cast<int64_t> (inputImage._timeStamp), | 679 static_cast<int64_t> (inputImage._timeStamp), |
665 inputImage.ntp_time_ms_); | 680 inputImage.ntp_time_ms_); |
666 if (CheckException(jni) || !success) { | 681 if (CheckException(jni) || !success) { |
667 ALOGE << "queueInputBuffer error"; | 682 ALOGE << "queueInputBuffer error"; |
668 return ProcessHWErrorOnCodecThread(); | 683 return ProcessHWErrorOnCodecThread(); |
669 } | 684 } |
670 | 685 |
671 // Try to drain the decoder | 686 // Try to drain the decoder |
672 if (!DeliverPendingOutputs(jni, 0)) { | 687 if (!DeliverPendingOutputs(jni, 0)) { |
673 ALOGE << "DeliverPendingOutputs error"; | 688 ALOGE << "DeliverPendingOutputs error"; |
674 return ProcessHWErrorOnCodecThread(); | 689 return ProcessHWErrorOnCodecThread(); |
675 } | 690 } |
676 | 691 |
677 return WEBRTC_VIDEO_CODEC_OK; | 692 return WEBRTC_VIDEO_CODEC_OK; |
678 } | 693 } |
679 | 694 |
680 bool MediaCodecVideoDecoder::DeliverPendingOutputs( | 695 bool MediaCodecVideoDecoder::DeliverPendingOutputs( |
681 JNIEnv* jni, int dequeue_timeout_ms) { | 696 JNIEnv* jni, int dequeue_timeout_ms) { |
697 CheckOnCodecThread(); | |
682 if (frames_received_ <= frames_decoded_) { | 698 if (frames_received_ <= frames_decoded_) { |
683 // No need to query for output buffers - decoder is drained. | 699 // No need to query for output buffers - decoder is drained. |
684 return true; | 700 return true; |
685 } | 701 } |
686 // Get decoder output. | 702 // Get decoder output. |
687 jobject j_decoder_output_buffer = | 703 jobject j_decoder_output_buffer = |
688 jni->CallObjectMethod(*j_media_codec_video_decoder_, | 704 jni->CallObjectMethod(*j_media_codec_video_decoder_, |
689 use_surface_ ? j_dequeue_texture_buffer_method_ | 705 use_surface_ ? j_dequeue_texture_buffer_method_ |
690 : j_dequeue_byte_buffer_method_, | 706 : j_dequeue_byte_buffer_method_, |
691 dequeue_timeout_ms); | 707 dequeue_timeout_ms); |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
854 current_decoding_time_ms_ = 0; | 870 current_decoding_time_ms_ = 0; |
855 current_delay_time_ms_ = 0; | 871 current_delay_time_ms_ = 0; |
856 } | 872 } |
857 | 873 |
858 // If the frame was dropped, frame_buffer is left as nullptr. | 874 // If the frame was dropped, frame_buffer is left as nullptr. |
859 if (frame_buffer) { | 875 if (frame_buffer) { |
860 VideoFrame decoded_frame(frame_buffer, 0, 0, webrtc::kVideoRotation_0); | 876 VideoFrame decoded_frame(frame_buffer, 0, 0, webrtc::kVideoRotation_0); |
861 decoded_frame.set_timestamp(output_timestamps_ms); | 877 decoded_frame.set_timestamp(output_timestamps_ms); |
862 decoded_frame.set_ntp_time_ms(output_ntp_timestamps_ms); | 878 decoded_frame.set_ntp_time_ms(output_ntp_timestamps_ms); |
863 | 879 |
864 const int32_t callback_status = | 880 int qp = pending_frame_qps_.front(); |
865 callback_->Decoded(decoded_frame, decode_time_ms); | 881 pending_frame_qps_.pop_front(); |
866 if (callback_status > 0) { | 882 callback_->Decoded( |
magjed_webrtc
2017/02/16 20:22:20
Why did you remove the return value check?
sakal
2017/02/17 09:23:43
The new callback doesn't include a return value be
| |
867 ALOGE << "callback error"; | 883 decoded_frame, rtc::Optional<int32_t>(decode_time_ms), |
868 } | 884 qp != -1 ? rtc::Optional<uint8_t>(qp) : rtc::Optional<uint8_t>()); |
869 } | 885 } |
870 return true; | 886 return true; |
871 } | 887 } |
872 | 888 |
873 int32_t MediaCodecVideoDecoder::RegisterDecodeCompleteCallback( | 889 int32_t MediaCodecVideoDecoder::RegisterDecodeCompleteCallback( |
874 DecodedImageCallback* callback) { | 890 DecodedImageCallback* callback) { |
875 callback_ = callback; | 891 callback_ = callback; |
876 return WEBRTC_VIDEO_CODEC_OK; | 892 return WEBRTC_VIDEO_CODEC_OK; |
877 } | 893 } |
878 | 894 |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
980 webrtc::VideoDecoder* decoder) { | 996 webrtc::VideoDecoder* decoder) { |
981 ALOGD << "Destroy video decoder."; | 997 ALOGD << "Destroy video decoder."; |
982 delete decoder; | 998 delete decoder; |
983 } | 999 } |
984 | 1000 |
985 const char* MediaCodecVideoDecoder::ImplementationName() const { | 1001 const char* MediaCodecVideoDecoder::ImplementationName() const { |
986 return "MediaCodec"; | 1002 return "MediaCodec"; |
987 } | 1003 } |
988 | 1004 |
989 } // namespace webrtc_jni | 1005 } // namespace webrtc_jni |
OLD | NEW |