Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(15)

Side by Side Diff: webrtc/sdk/android/src/jni/androidmediadecoder_jni.cc

Issue 2653183004: Add QP for MediaCodec decoder. (Closed)
Patch Set: Rebase 2 Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/sdk/android/src/jni/DEPS ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « webrtc/sdk/android/src/jni/DEPS ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698