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

Side by Side Diff: webrtc/api/android/jni/androidmediaencoder_jni.cc

Issue 2398963003: Move usage of QualityScaler to ViEEncoder. (Closed)
Patch Set: Fix flaky test Created 4 years, 1 month 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
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
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 const int64_t frame_input_time_ms); 158 const int64_t frame_input_time_ms);
159 bool EncodeByteBufferOnCodecThread(JNIEnv* jni, 159 bool EncodeByteBufferOnCodecThread(JNIEnv* jni,
160 bool key_frame, const webrtc::VideoFrame& frame, int input_buffer_index); 160 bool key_frame, const webrtc::VideoFrame& frame, int input_buffer_index);
161 bool EncodeTextureOnCodecThread(JNIEnv* jni, 161 bool EncodeTextureOnCodecThread(JNIEnv* jni,
162 bool key_frame, const webrtc::VideoFrame& frame); 162 bool key_frame, const webrtc::VideoFrame& frame);
163 163
164 int32_t RegisterEncodeCompleteCallbackOnCodecThread( 164 int32_t RegisterEncodeCompleteCallbackOnCodecThread(
165 webrtc::EncodedImageCallback* callback); 165 webrtc::EncodedImageCallback* callback);
166 int32_t ReleaseOnCodecThread(); 166 int32_t ReleaseOnCodecThread();
167 int32_t SetRatesOnCodecThread(uint32_t new_bit_rate, uint32_t frame_rate); 167 int32_t SetRatesOnCodecThread(uint32_t new_bit_rate, uint32_t frame_rate);
168 void OnDroppedFrameOnCodecThread();
169 168
170 // Helper accessors for MediaCodecVideoEncoder$OutputBufferInfo members. 169 // Helper accessors for MediaCodecVideoEncoder$OutputBufferInfo members.
171 int GetOutputBufferInfoIndex(JNIEnv* jni, jobject j_output_buffer_info); 170 int GetOutputBufferInfoIndex(JNIEnv* jni, jobject j_output_buffer_info);
172 jobject GetOutputBufferInfoBuffer(JNIEnv* jni, jobject j_output_buffer_info); 171 jobject GetOutputBufferInfoBuffer(JNIEnv* jni, jobject j_output_buffer_info);
173 bool GetOutputBufferInfoIsKeyFrame(JNIEnv* jni, jobject j_output_buffer_info); 172 bool GetOutputBufferInfoIsKeyFrame(JNIEnv* jni, jobject j_output_buffer_info);
174 jlong GetOutputBufferInfoPresentationTimestampUs( 173 jlong GetOutputBufferInfoPresentationTimestampUs(
175 JNIEnv* jni, jobject j_output_buffer_info); 174 JNIEnv* jni, jobject j_output_buffer_info);
176 175
177 // Deliver any outputs pending in the MediaCodec to our |callback_| and return 176 // Deliver any outputs pending in the MediaCodec to our |callback_| and return
178 // true on success. 177 // true on success.
179 bool DeliverPendingOutputs(JNIEnv* jni); 178 bool DeliverPendingOutputs(JNIEnv* jni);
180 179
181 // Search for H.264 start codes. 180 // Search for H.264 start codes.
182 int32_t NextNaluPosition(uint8_t *buffer, size_t buffer_size); 181 int32_t NextNaluPosition(uint8_t *buffer, size_t buffer_size);
183 182
183 QualityScaler::Settings GetQPThresholds() const override;
184
184 // Displays encoder statistics. 185 // Displays encoder statistics.
185 void LogStatistics(bool force_log); 186 void LogStatistics(bool force_log);
186 187
187 // Type of video codec. 188 // Type of video codec.
188 VideoCodecType codecType_; 189 VideoCodecType codecType_;
189 190
190 // Valid all the time since RegisterEncodeCompleteCallback() Invoke()s to 191 // Valid all the time since RegisterEncodeCompleteCallback() Invoke()s to
191 // |codec_thread_| synchronously. 192 // |codec_thread_| synchronously.
192 webrtc::EncodedImageCallback* callback_; 193 webrtc::EncodedImageCallback* callback_;
193 194
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 // |input_frame_infos_|. 260 // |input_frame_infos_|.
260 int64_t output_render_time_ms_; // Last output frame render time from 261 int64_t output_render_time_ms_; // Last output frame render time from
261 // |input_frame_infos_|. 262 // |input_frame_infos_|.
262 webrtc::VideoRotation output_rotation_; // Last output frame rotation from 263 webrtc::VideoRotation output_rotation_; // Last output frame rotation from
263 // |input_frame_infos_|. 264 // |input_frame_infos_|.
264 // Frame size in bytes fed to MediaCodec. 265 // Frame size in bytes fed to MediaCodec.
265 int yuv_size_; 266 int yuv_size_;
266 // True only when between a callback_->OnEncodedImage() call return a positive 267 // True only when between a callback_->OnEncodedImage() call return a positive
267 // value and the next Encode() call being ignored. 268 // value and the next Encode() call being ignored.
268 bool drop_next_input_frame_; 269 bool drop_next_input_frame_;
270 bool scale_;
269 // Global references; must be deleted in Release(). 271 // Global references; must be deleted in Release().
270 std::vector<jobject> input_buffers_; 272 std::vector<jobject> input_buffers_;
271 QualityScaler quality_scaler_;
272 // Dynamic resolution change, off by default.
273 bool scale_;
274
275 // H264 bitstream parser, used to extract QP from encoded bitstreams.
276 webrtc::H264BitstreamParser h264_bitstream_parser_; 273 webrtc::H264BitstreamParser h264_bitstream_parser_;
277 274
278 // VP9 variables to populate codec specific structure. 275 // VP9 variables to populate codec specific structure.
279 webrtc::GofInfoVP9 gof_; // Contains each frame's temporal information for 276 webrtc::GofInfoVP9 gof_; // Contains each frame's temporal information for
280 // non-flexible VP9 mode. 277 // non-flexible VP9 mode.
281 uint8_t tl0_pic_idx_; 278 uint8_t tl0_pic_idx_;
282 size_t gof_idx_; 279 size_t gof_idx_;
283 280
284 // EGL context - owned by factory, should not be allocated/destroyed 281 // EGL context - owned by factory, should not be allocated/destroyed
285 // by MediaCodecVideoEncoder. 282 // by MediaCodecVideoEncoder.
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 scale_ = false; 402 scale_ = false;
406 if (codecType_ == kVideoCodecVP8) { 403 if (codecType_ == kVideoCodecVP8) {
407 scale_ = codec_settings->codecSpecific.VP8.automaticResizeOn; 404 scale_ = codec_settings->codecSpecific.VP8.automaticResizeOn;
408 } else if (codecType_ != kVideoCodecVP9) { 405 } else if (codecType_ != kVideoCodecVP9) {
409 scale_ = true; 406 scale_ = true;
410 } 407 }
411 408
412 ALOGD << "InitEncode request: " << init_width << " x " << init_height; 409 ALOGD << "InitEncode request: " << init_width << " x " << init_height;
413 ALOGD << "Encoder automatic resize " << (scale_ ? "enabled" : "disabled"); 410 ALOGD << "Encoder automatic resize " << (scale_ ? "enabled" : "disabled");
414 411
415 if (scale_) {
416 if (codecType_ == kVideoCodecVP8 || codecType_ == kVideoCodecH264) {
417 quality_scaler_.Init(codecType_, codec_settings->startBitrate,
418 codec_settings->width, codec_settings->height,
419 codec_settings->maxFramerate);
420 } else {
421 // When adding codec support to additional hardware codecs, also configure
422 // their QP thresholds for scaling.
423 RTC_NOTREACHED() << "Unsupported codec without configured QP thresholds.";
424 scale_ = false;
425 }
426 QualityScaler::Resolution res = quality_scaler_.GetScaledResolution();
427 init_width = res.width;
428 init_height = res.height;
429 ALOGD << "Scaled resolution: " << init_width << " x " << init_height;
430 }
431
432 return codec_thread_->Invoke<int32_t>( 412 return codec_thread_->Invoke<int32_t>(
433 RTC_FROM_HERE, 413 RTC_FROM_HERE,
434 Bind(&MediaCodecVideoEncoder::InitEncodeOnCodecThread, this, init_width, 414 Bind(&MediaCodecVideoEncoder::InitEncodeOnCodecThread, this, init_width,
435 init_height, codec_settings->startBitrate, 415 init_height, codec_settings->startBitrate,
436 codec_settings->maxFramerate, 416 codec_settings->maxFramerate,
437 codec_settings->expect_encode_from_texture)); 417 codec_settings->expect_encode_from_texture));
438 } 418 }
439 419
440 int32_t MediaCodecVideoEncoder::Encode( 420 int32_t MediaCodecVideoEncoder::Encode(
441 const webrtc::VideoFrame& frame, 421 const webrtc::VideoFrame& frame,
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
701 << ". TS: " << (int)(current_timestamp_us_ / 1000) 681 << ". TS: " << (int)(current_timestamp_us_ / 1000)
702 << ". Q: " << input_frame_infos_.size() << ". Fps: " << last_set_fps_ 682 << ". Q: " << input_frame_infos_.size() << ". Fps: " << last_set_fps_
703 << ". Kbps: " << last_set_bitrate_kbps_; 683 << ". Kbps: " << last_set_bitrate_kbps_;
704 } 684 }
705 685
706 if (drop_next_input_frame_) { 686 if (drop_next_input_frame_) {
707 ALOGW << "Encoder drop frame - failed callback."; 687 ALOGW << "Encoder drop frame - failed callback.";
708 drop_next_input_frame_ = false; 688 drop_next_input_frame_ = false;
709 current_timestamp_us_ += rtc::kNumMicrosecsPerSec / last_set_fps_; 689 current_timestamp_us_ += rtc::kNumMicrosecsPerSec / last_set_fps_;
710 frames_dropped_media_encoder_++; 690 frames_dropped_media_encoder_++;
711 OnDroppedFrameOnCodecThread();
712 return WEBRTC_VIDEO_CODEC_OK; 691 return WEBRTC_VIDEO_CODEC_OK;
713 } 692 }
714 693
715 RTC_CHECK(frame_types->size() == 1) << "Unexpected stream count"; 694 RTC_CHECK(frame_types->size() == 1) << "Unexpected stream count";
716 695
717 // Check if we accumulated too many frames in encoder input buffers and drop 696 // Check if we accumulated too many frames in encoder input buffers and drop
718 // frame if so. 697 // frame if so.
719 if (input_frame_infos_.size() > MAX_ENCODER_Q_SIZE) { 698 if (input_frame_infos_.size() > MAX_ENCODER_Q_SIZE) {
720 ALOGD << "Already " << input_frame_infos_.size() 699 ALOGD << "Already " << input_frame_infos_.size()
721 << " frames in the queue, dropping" 700 << " frames in the queue, dropping"
722 << ". TS: " << (int)(current_timestamp_us_ / 1000) 701 << ". TS: " << (int)(current_timestamp_us_ / 1000)
723 << ". Fps: " << last_set_fps_ 702 << ". Fps: " << last_set_fps_
724 << ". Consecutive drops: " << consecutive_full_queue_frame_drops_; 703 << ". Consecutive drops: " << consecutive_full_queue_frame_drops_;
725 current_timestamp_us_ += rtc::kNumMicrosecsPerSec / last_set_fps_; 704 current_timestamp_us_ += rtc::kNumMicrosecsPerSec / last_set_fps_;
726 consecutive_full_queue_frame_drops_++; 705 consecutive_full_queue_frame_drops_++;
727 if (consecutive_full_queue_frame_drops_ >= 706 if (consecutive_full_queue_frame_drops_ >=
728 ENCODER_STALL_FRAMEDROP_THRESHOLD) { 707 ENCODER_STALL_FRAMEDROP_THRESHOLD) {
729 ALOGE << "Encoder got stuck."; 708 ALOGE << "Encoder got stuck.";
730 return ProcessHWErrorOnEncodeOnCodecThread(); 709 return ProcessHWErrorOnEncodeOnCodecThread();
731 } 710 }
732 frames_dropped_media_encoder_++; 711 frames_dropped_media_encoder_++;
733 OnDroppedFrameOnCodecThread();
734 return WEBRTC_VIDEO_CODEC_OK; 712 return WEBRTC_VIDEO_CODEC_OK;
735 } 713 }
736 consecutive_full_queue_frame_drops_ = 0; 714 consecutive_full_queue_frame_drops_ = 0;
737 715
738 rtc::scoped_refptr<webrtc::VideoFrameBuffer> input_buffer( 716 rtc::scoped_refptr<webrtc::VideoFrameBuffer> input_buffer(
739 frame.video_frame_buffer()); 717 frame.video_frame_buffer());
740 if (scale_) {
741 // Check framerate before spatial resolution change.
742 quality_scaler_.OnEncodeFrame(frame.width(), frame.height());
743 const webrtc::QualityScaler::Resolution scaled_resolution =
744 quality_scaler_.GetScaledResolution();
745 if (scaled_resolution.width != frame.width() ||
746 scaled_resolution.height != frame.height()) {
747 if (input_buffer->native_handle() != nullptr) {
748 input_buffer = static_cast<AndroidTextureBuffer*>(input_buffer.get())
749 ->CropScaleAndRotate(frame.width(), frame.height(),
750 0, 0,
751 scaled_resolution.width,
752 scaled_resolution.height,
753 webrtc::kVideoRotation_0);
754 } else {
755 input_buffer = quality_scaler_.GetScaledBuffer(input_buffer);
756 }
757 }
758 }
759 718
760 VideoFrame input_frame(input_buffer, frame.timestamp(), 719 VideoFrame input_frame(input_buffer, frame.timestamp(),
761 frame.render_time_ms(), frame.rotation()); 720 frame.render_time_ms(), frame.rotation());
762 721
763 if (!MaybeReconfigureEncoderOnCodecThread(input_frame)) { 722 if (!MaybeReconfigureEncoderOnCodecThread(input_frame)) {
764 ALOGE << "Failed to reconfigure encoder."; 723 ALOGE << "Failed to reconfigure encoder.";
765 return WEBRTC_VIDEO_CODEC_ERROR; 724 return WEBRTC_VIDEO_CODEC_ERROR;
766 } 725 }
767 726
768 const bool key_frame = 727 const bool key_frame =
769 frame_types->front() != webrtc::kVideoFrameDelta || send_key_frame; 728 frame_types->front() != webrtc::kVideoFrameDelta || send_key_frame;
770 bool encode_status = true; 729 bool encode_status = true;
771 if (!input_frame.video_frame_buffer()->native_handle()) { 730 if (!input_frame.video_frame_buffer()->native_handle()) {
772 int j_input_buffer_index = jni->CallIntMethod(*j_media_codec_video_encoder_, 731 int j_input_buffer_index = jni->CallIntMethod(*j_media_codec_video_encoder_,
773 j_dequeue_input_buffer_method_); 732 j_dequeue_input_buffer_method_);
774 if (CheckException(jni)) { 733 if (CheckException(jni)) {
775 ALOGE << "Exception in dequeu input buffer."; 734 ALOGE << "Exception in dequeu input buffer.";
776 return ProcessHWErrorOnEncodeOnCodecThread(); 735 return ProcessHWErrorOnEncodeOnCodecThread();
777 } 736 }
778 if (j_input_buffer_index == -1) { 737 if (j_input_buffer_index == -1) {
779 // Video codec falls behind - no input buffer available. 738 // Video codec falls behind - no input buffer available.
780 ALOGW << "Encoder drop frame - no input buffers available"; 739 ALOGW << "Encoder drop frame - no input buffers available";
781 if (frames_received_ > 1) { 740 if (frames_received_ > 1) {
782 current_timestamp_us_ += rtc::kNumMicrosecsPerSec / last_set_fps_; 741 current_timestamp_us_ += rtc::kNumMicrosecsPerSec / last_set_fps_;
783 frames_dropped_media_encoder_++; 742 frames_dropped_media_encoder_++;
784 OnDroppedFrameOnCodecThread();
785 } else { 743 } else {
786 // Input buffers are not ready after codec initialization, HW is still 744 // Input buffers are not ready after codec initialization, HW is still
787 // allocating thme - this is expected and should not result in drop 745 // allocating thme - this is expected and should not result in drop
788 // frame report. 746 // frame report.
789 frames_received_ = 0; 747 frames_received_ = 0;
790 } 748 }
791 return WEBRTC_VIDEO_CODEC_OK; // TODO(fischman): see webrtc bug 2887. 749 return WEBRTC_VIDEO_CODEC_OK; // TODO(fischman): see webrtc bug 2887.
792 } else if (j_input_buffer_index == -2) { 750 } else if (j_input_buffer_index == -2) {
793 return ProcessHWErrorOnEncodeOnCodecThread(); 751 return ProcessHWErrorOnEncodeOnCodecThread();
794 } 752 }
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
955 uint32_t frame_rate) { 913 uint32_t frame_rate) {
956 RTC_DCHECK(codec_thread_checker_.CalledOnValidThread()); 914 RTC_DCHECK(codec_thread_checker_.CalledOnValidThread());
957 if (sw_fallback_required_) 915 if (sw_fallback_required_)
958 return WEBRTC_VIDEO_CODEC_OK; 916 return WEBRTC_VIDEO_CODEC_OK;
959 frame_rate = (frame_rate < MAX_ALLOWED_VIDEO_FPS) ? 917 frame_rate = (frame_rate < MAX_ALLOWED_VIDEO_FPS) ?
960 frame_rate : MAX_ALLOWED_VIDEO_FPS; 918 frame_rate : MAX_ALLOWED_VIDEO_FPS;
961 if (last_set_bitrate_kbps_ == new_bit_rate && 919 if (last_set_bitrate_kbps_ == new_bit_rate &&
962 last_set_fps_ == frame_rate) { 920 last_set_fps_ == frame_rate) {
963 return WEBRTC_VIDEO_CODEC_OK; 921 return WEBRTC_VIDEO_CODEC_OK;
964 } 922 }
965 if (scale_) {
966 quality_scaler_.ReportFramerate(frame_rate);
967 }
968 JNIEnv* jni = AttachCurrentThreadIfNeeded(); 923 JNIEnv* jni = AttachCurrentThreadIfNeeded();
969 ScopedLocalRefFrame local_ref_frame(jni); 924 ScopedLocalRefFrame local_ref_frame(jni);
970 if (new_bit_rate > 0) { 925 if (new_bit_rate > 0) {
971 last_set_bitrate_kbps_ = new_bit_rate; 926 last_set_bitrate_kbps_ = new_bit_rate;
972 } 927 }
973 if (frame_rate > 0) { 928 if (frame_rate > 0) {
974 last_set_fps_ = frame_rate; 929 last_set_fps_ = frame_rate;
975 } 930 }
976 bool ret = jni->CallBooleanMethod(*j_media_codec_video_encoder_, 931 bool ret = jni->CallBooleanMethod(*j_media_codec_video_encoder_,
977 j_set_rates_method_, 932 j_set_rates_method_,
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1069 std::unique_ptr<webrtc::EncodedImage> image( 1024 std::unique_ptr<webrtc::EncodedImage> image(
1070 new webrtc::EncodedImage(payload, payload_size, payload_size)); 1025 new webrtc::EncodedImage(payload, payload_size, payload_size));
1071 image->_encodedWidth = width_; 1026 image->_encodedWidth = width_;
1072 image->_encodedHeight = height_; 1027 image->_encodedHeight = height_;
1073 image->_timeStamp = output_timestamp_; 1028 image->_timeStamp = output_timestamp_;
1074 image->capture_time_ms_ = output_render_time_ms_; 1029 image->capture_time_ms_ = output_render_time_ms_;
1075 image->rotation_ = output_rotation_; 1030 image->rotation_ = output_rotation_;
1076 image->_frameType = 1031 image->_frameType =
1077 (key_frame ? webrtc::kVideoFrameKey : webrtc::kVideoFrameDelta); 1032 (key_frame ? webrtc::kVideoFrameKey : webrtc::kVideoFrameDelta);
1078 image->_completeFrame = true; 1033 image->_completeFrame = true;
1079 image->adapt_reason_.quality_resolution_downscales =
1080 scale_ ? quality_scaler_.downscale_shift() : -1;
1081
1082 webrtc::CodecSpecificInfo info; 1034 webrtc::CodecSpecificInfo info;
1083 memset(&info, 0, sizeof(info)); 1035 memset(&info, 0, sizeof(info));
1084 info.codecType = codecType_; 1036 info.codecType = codecType_;
1085 if (codecType_ == kVideoCodecVP8) { 1037 if (codecType_ == kVideoCodecVP8) {
1086 info.codecSpecific.VP8.pictureId = picture_id_; 1038 info.codecSpecific.VP8.pictureId = picture_id_;
1087 info.codecSpecific.VP8.nonReference = false; 1039 info.codecSpecific.VP8.nonReference = false;
1088 info.codecSpecific.VP8.simulcastIdx = 0; 1040 info.codecSpecific.VP8.simulcastIdx = 0;
1089 info.codecSpecific.VP8.temporalIdx = webrtc::kNoTemporalIdx; 1041 info.codecSpecific.VP8.temporalIdx = webrtc::kNoTemporalIdx;
1090 info.codecSpecific.VP8.layerSync = false; 1042 info.codecSpecific.VP8.layerSync = false;
1091 info.codecSpecific.VP8.tl0PicIdx = webrtc::kNoTl0PicIdx; 1043 info.codecSpecific.VP8.tl0PicIdx = webrtc::kNoTl0PicIdx;
(...skipping 26 matching lines...) Expand all
1118 1070
1119 // Generate a header describing a single fragment. 1071 // Generate a header describing a single fragment.
1120 webrtc::RTPFragmentationHeader header; 1072 webrtc::RTPFragmentationHeader header;
1121 memset(&header, 0, sizeof(header)); 1073 memset(&header, 0, sizeof(header));
1122 if (codecType_ == kVideoCodecVP8 || codecType_ == kVideoCodecVP9) { 1074 if (codecType_ == kVideoCodecVP8 || codecType_ == kVideoCodecVP9) {
1123 header.VerifyAndAllocateFragmentationHeader(1); 1075 header.VerifyAndAllocateFragmentationHeader(1);
1124 header.fragmentationOffset[0] = 0; 1076 header.fragmentationOffset[0] = 0;
1125 header.fragmentationLength[0] = image->_length; 1077 header.fragmentationLength[0] = image->_length;
1126 header.fragmentationPlType[0] = 0; 1078 header.fragmentationPlType[0] = 0;
1127 header.fragmentationTimeDiff[0] = 0; 1079 header.fragmentationTimeDiff[0] = 0;
1128 if (codecType_ == kVideoCodecVP8 && scale_) { 1080 if (codecType_ == kVideoCodecVP8) {
1129 int qp; 1081 int qp;
1130 if (webrtc::vp8::GetQp(payload, payload_size, &qp)) { 1082 if (webrtc::vp8::GetQp(payload, payload_size, &qp)) {
1131 current_acc_qp_ += qp; 1083 current_acc_qp_ += qp;
1132 quality_scaler_.ReportQP(qp);
1133 image->qp_ = qp; 1084 image->qp_ = qp;
1134 } 1085 }
1135 } 1086 }
1136 } else if (codecType_ == kVideoCodecH264) { 1087 } else if (codecType_ == kVideoCodecH264) {
1137 if (scale_) { 1088 h264_bitstream_parser_.ParseBitstream(payload, payload_size);
1138 h264_bitstream_parser_.ParseBitstream(payload, payload_size); 1089 int qp;
1139 int qp; 1090 if (h264_bitstream_parser_.GetLastSliceQp(&qp)) {
1140 if (h264_bitstream_parser_.GetLastSliceQp(&qp)) { 1091 current_acc_qp_ += qp;
1141 current_acc_qp_ += qp; 1092 image->qp_ = qp;
1142 quality_scaler_.ReportQP(qp);
1143 }
1144 } 1093 }
1145 // For H.264 search for start codes. 1094 // For H.264 search for start codes.
1146 int32_t scPositions[MAX_NALUS_PERFRAME + 1] = {}; 1095 int32_t scPositions[MAX_NALUS_PERFRAME + 1] = {};
1147 int32_t scPositionsLength = 0; 1096 int32_t scPositionsLength = 0;
1148 int32_t scPosition = 0; 1097 int32_t scPosition = 0;
1149 while (scPositionsLength < MAX_NALUS_PERFRAME) { 1098 while (scPositionsLength < MAX_NALUS_PERFRAME) {
1150 int32_t naluPosition = NextNaluPosition( 1099 int32_t naluPosition = NextNaluPosition(
1151 payload + scPosition, payload_size - scPosition); 1100 payload + scPosition, payload_size - scPosition);
1152 if (naluPosition < 0) { 1101 if (naluPosition < 0) {
1153 break; 1102 break;
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1234 ". QP: " << (current_acc_qp_ / current_frames_divider) << 1183 ". QP: " << (current_acc_qp_ / current_frames_divider) <<
1235 " for last " << statistic_time_ms << " ms."; 1184 " for last " << statistic_time_ms << " ms.";
1236 stat_start_time_ms_ = rtc::TimeMillis(); 1185 stat_start_time_ms_ = rtc::TimeMillis();
1237 current_frames_ = 0; 1186 current_frames_ = 0;
1238 current_bytes_ = 0; 1187 current_bytes_ = 0;
1239 current_acc_qp_ = 0; 1188 current_acc_qp_ = 0;
1240 current_encoding_time_ms_ = 0; 1189 current_encoding_time_ms_ = 0;
1241 } 1190 }
1242 } 1191 }
1243 1192
1193 QualityScaler::Settings MediaCodecVideoEncoder::GetQPThresholds() const {
1194 return QualityScaler::Settings(scale_);
1195 }
1196
1244 int32_t MediaCodecVideoEncoder::NextNaluPosition( 1197 int32_t MediaCodecVideoEncoder::NextNaluPosition(
1245 uint8_t *buffer, size_t buffer_size) { 1198 uint8_t *buffer, size_t buffer_size) {
1246 if (buffer_size < H264_SC_LENGTH) { 1199 if (buffer_size < H264_SC_LENGTH) {
1247 return -1; 1200 return -1;
1248 } 1201 }
1249 uint8_t *head = buffer; 1202 uint8_t *head = buffer;
1250 // Set end buffer pointer to 4 bytes before actual buffer end so we can 1203 // Set end buffer pointer to 4 bytes before actual buffer end so we can
1251 // access head[1], head[2] and head[3] in a loop without buffer overrun. 1204 // access head[1], head[2] and head[3] in a loop without buffer overrun.
1252 uint8_t *end = buffer + buffer_size - H264_SC_LENGTH; 1205 uint8_t *end = buffer + buffer_size - H264_SC_LENGTH;
1253 1206
(...skipping 13 matching lines...) Expand all
1267 if (head[3] != 0x01) { // got 000000xx 1220 if (head[3] != 0x01) { // got 000000xx
1268 head++; // xx != 1, continue searching. 1221 head++; // xx != 1, continue searching.
1269 continue; 1222 continue;
1270 } 1223 }
1271 return (int32_t)(head - buffer); 1224 return (int32_t)(head - buffer);
1272 } 1225 }
1273 return -1; 1226 return -1;
1274 } 1227 }
1275 1228
1276 void MediaCodecVideoEncoder::OnDroppedFrame() { 1229 void MediaCodecVideoEncoder::OnDroppedFrame() {
1277 // Methods running on the codec thread should call OnDroppedFrameOnCodecThread
1278 // directly.
1279 RTC_DCHECK(!codec_thread_checker_.CalledOnValidThread()); 1230 RTC_DCHECK(!codec_thread_checker_.CalledOnValidThread());
1280 codec_thread_->Invoke<void>(
1281 RTC_FROM_HERE,
1282 Bind(&MediaCodecVideoEncoder::OnDroppedFrameOnCodecThread, this));
1283 }
1284
1285 void MediaCodecVideoEncoder::OnDroppedFrameOnCodecThread() {
1286 RTC_DCHECK(codec_thread_checker_.CalledOnValidThread());
1287 // Report dropped frame to quality_scaler_.
1288 if (scale_)
1289 quality_scaler_.ReportDroppedFrame();
1290 } 1231 }
1291 1232
1292 const char* MediaCodecVideoEncoder::ImplementationName() const { 1233 const char* MediaCodecVideoEncoder::ImplementationName() const {
1293 return "MediaCodec"; 1234 return "MediaCodec";
1294 } 1235 }
1295 1236
1296 MediaCodecVideoEncoderFactory::MediaCodecVideoEncoderFactory() 1237 MediaCodecVideoEncoderFactory::MediaCodecVideoEncoderFactory()
1297 : egl_context_(nullptr) { 1238 : egl_context_(nullptr) {
1298 JNIEnv* jni = AttachCurrentThreadIfNeeded(); 1239 JNIEnv* jni = AttachCurrentThreadIfNeeded();
1299 ScopedLocalRefFrame local_ref_frame(jni); 1240 ScopedLocalRefFrame local_ref_frame(jni);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1370 return supported_codecs_; 1311 return supported_codecs_;
1371 } 1312 }
1372 1313
1373 void MediaCodecVideoEncoderFactory::DestroyVideoEncoder( 1314 void MediaCodecVideoEncoderFactory::DestroyVideoEncoder(
1374 webrtc::VideoEncoder* encoder) { 1315 webrtc::VideoEncoder* encoder) {
1375 ALOGD << "Destroy video encoder."; 1316 ALOGD << "Destroy video encoder.";
1376 delete encoder; 1317 delete encoder;
1377 } 1318 }
1378 1319
1379 } // namespace webrtc_jni 1320 } // namespace webrtc_jni
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698