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

Side by Side Diff: talk/app/webrtc/java/jni/androidmediaencoder_jni.cc

Issue 1592883004: Use high QP threshold for HW VP8 encoder frame downscaling. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc@master
Patch Set: Created 4 years, 11 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 | « no previous file | 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 * libjingle 2 * libjingle
3 * Copyright 2015 Google Inc. 3 * Copyright 2015 Google Inc.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright notice, 8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer. 9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice, 10 * 2. Redistributions in binary form must reproduce the above copyright notice,
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 #define MAX_VIDEO_WIDTH 1280 70 #define MAX_VIDEO_WIDTH 1280
71 #define MAX_VIDEO_HEIGHT 1280 71 #define MAX_VIDEO_HEIGHT 1280
72 // Maximum supported HW video encoder fps. 72 // Maximum supported HW video encoder fps.
73 #define MAX_VIDEO_FPS 30 73 #define MAX_VIDEO_FPS 30
74 // Maximum allowed fps value in SetRates() call. 74 // Maximum allowed fps value in SetRates() call.
75 #define MAX_ALLOWED_VIDEO_FPS 60 75 #define MAX_ALLOWED_VIDEO_FPS 60
76 // Maximum allowed frames in encoder input queue. 76 // Maximum allowed frames in encoder input queue.
77 #define MAX_ENCODER_Q_SIZE 2 77 #define MAX_ENCODER_Q_SIZE 2
78 // Maximum allowed latency in ms. 78 // Maximum allowed latency in ms.
79 #define MAX_ENCODER_LATENCY_MS 70 79 #define MAX_ENCODER_LATENCY_MS 70
80 80 // Maximum amount of dropped frames caused by full encoder queue - exceeding
81 // this threshold means that encoder probably got stuck and need to be reset.
82 #define MAX_DROPPED_FRAMES 60
pbos-webrtc 2016/01/18 10:33:07 ENCODER_STALL_FRAMEDROP_THRESHOLD maybe, something
jackychen_ 2016/01/19 02:21:01 In the comment, "reset the encoder when it drops m
AlexG 2016/01/19 22:13:41 Done.
AlexG 2016/01/19 22:13:41 Done.
81 83
82 // Logging macros. 84 // Logging macros.
83 #define TAG_ENCODER "MediaCodecVideoEncoder" 85 #define TAG_ENCODER "MediaCodecVideoEncoder"
84 #ifdef TRACK_BUFFER_TIMING 86 #ifdef TRACK_BUFFER_TIMING
85 #define ALOGV(...) 87 #define ALOGV(...)
86 __android_log_print(ANDROID_LOG_VERBOSE, TAG_ENCODER, __VA_ARGS__) 88 __android_log_print(ANDROID_LOG_VERBOSE, TAG_ENCODER, __VA_ARGS__)
87 #else 89 #else
88 #define ALOGV(...) 90 #define ALOGV(...)
89 #endif 91 #endif
90 #define ALOGD LOG_TAG(rtc::LS_INFO, TAG_ENCODER) 92 #define ALOGD LOG_TAG(rtc::LS_INFO, TAG_ENCODER)
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 bool inited_; 216 bool inited_;
215 bool use_surface_; 217 bool use_surface_;
216 uint16_t picture_id_; 218 uint16_t picture_id_;
217 enum libyuv::FourCC encoder_fourcc_; // Encoder color space format. 219 enum libyuv::FourCC encoder_fourcc_; // Encoder color space format.
218 int last_set_bitrate_kbps_; // Last-requested bitrate in kbps. 220 int last_set_bitrate_kbps_; // Last-requested bitrate in kbps.
219 int last_set_fps_; // Last-requested frame rate. 221 int last_set_fps_; // Last-requested frame rate.
220 int64_t current_timestamp_us_; // Current frame timestamps in us. 222 int64_t current_timestamp_us_; // Current frame timestamps in us.
221 int frames_received_; // Number of frames received by encoder. 223 int frames_received_; // Number of frames received by encoder.
222 int frames_encoded_; // Number of frames encoded by encoder. 224 int frames_encoded_; // Number of frames encoded by encoder.
223 int frames_dropped_; // Number of frames dropped by encoder. 225 int frames_dropped_; // Number of frames dropped by encoder.
226 int frames_dropped_q_full_; // Number of dropped frames caused by full queue.
pbos-webrtc 2016/01/18 10:33:07 consecutive_full_queue_frame_drops_
AlexG 2016/01/19 22:13:41 Done.
224 int frames_in_queue_; // Number of frames in encoder queue. 227 int frames_in_queue_; // Number of frames in encoder queue.
225 int64_t start_time_ms_; // Start time for statistics. 228 int64_t start_time_ms_; // Start time for statistics.
226 int current_frames_; // Number of frames in the current statistics interval. 229 int current_frames_; // Number of frames in the current statistics interval.
227 int current_bytes_; // Encoded bytes in the current statistics interval. 230 int current_bytes_; // Encoded bytes in the current statistics interval.
228 int current_acc_qp_; // Accumulated QP in the current statistics interval. 231 int current_acc_qp_; // Accumulated QP in the current statistics interval.
229 int current_encoding_time_ms_; // Overall encoding time in the current second 232 int current_encoding_time_ms_; // Overall encoding time in the current second
230 int64_t last_input_timestamp_ms_; // Timestamp of last received yuv frame. 233 int64_t last_input_timestamp_ms_; // Timestamp of last received yuv frame.
231 int64_t last_output_timestamp_ms_; // Timestamp of last encoded frame. 234 int64_t last_output_timestamp_ms_; // Timestamp of last encoded frame.
232 std::vector<int32_t> timestamps_; // Video frames timestamp queue. 235 std::vector<int32_t> timestamps_; // Video frames timestamp queue.
233 std::vector<int64_t> render_times_ms_; // Video frames render time queue. 236 std::vector<int64_t> render_times_ms_; // Video frames render time queue.
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 scale_ = (codecType_ != kVideoCodecVP9) && (webrtc::field_trial::FindFullName( 366 scale_ = (codecType_ != kVideoCodecVP9) && (webrtc::field_trial::FindFullName(
364 "WebRTC-MediaCodecVideoEncoder-AutomaticResize") == "Enabled"); 367 "WebRTC-MediaCodecVideoEncoder-AutomaticResize") == "Enabled");
365 ALOGD << "Encoder automatic resize " << (scale_ ? "enabled" : "disabled"); 368 ALOGD << "Encoder automatic resize " << (scale_ ? "enabled" : "disabled");
366 if (scale_) { 369 if (scale_) {
367 if (codecType_ == kVideoCodecVP8) { 370 if (codecType_ == kVideoCodecVP8) {
368 // QP is obtained from VP8-bitstream for HW, so the QP corresponds to the 371 // QP is obtained from VP8-bitstream for HW, so the QP corresponds to the
369 // (internal) range: [0, 127]. And we cannot change QP_max in HW, so it is 372 // (internal) range: [0, 127]. And we cannot change QP_max in HW, so it is
370 // always = 127. Note that in SW, QP is that of the user-level range [0, 373 // always = 127. Note that in SW, QP is that of the user-level range [0,
371 // 63]. 374 // 63].
372 const int kMaxQp = 127; 375 const int kMaxQp = 127;
373 // TODO(pbos): Investigate whether high-QP thresholds make sense for VP8. 376 const int kBadQpThreshold = kMaxQp - kMaxQp / 4;
pbos-webrtc 2016/01/18 10:33:07 I think this should just be hard-coded as another
AlexG 2016/01/19 22:13:41 Done.
374 // This effectively disables high QP as VP8 QP can't go above this 377 quality_scaler_.Init(
375 // threshold. 378 kMaxQp / kLowQpThresholdDenominator, kBadQpThreshold, false);
376 const int kDisabledBadQpThreshold = kMaxQp + 1;
377 quality_scaler_.Init(kMaxQp / kLowQpThresholdDenominator,
378 kDisabledBadQpThreshold, true);
379 } else if (codecType_ == kVideoCodecH264) { 379 } else if (codecType_ == kVideoCodecH264) {
380 // H264 QP is in the range [0, 51]. 380 // H264 QP is in the range [0, 51].
381 const int kMaxQp = 51; 381 const int kMaxQp = 51;
382 const int kBadQpThreshold = 40; 382 const int kBadQpThreshold = 40;
383 quality_scaler_.Init(kMaxQp / kLowQpThresholdDenominator, kBadQpThreshold, 383 quality_scaler_.Init(
384 false); 384 kMaxQp / kLowQpThresholdDenominator, kBadQpThreshold, false);
385 } else { 385 } else {
386 // When adding codec support to additional hardware codecs, also configure 386 // When adding codec support to additional hardware codecs, also configure
387 // their QP thresholds for scaling. 387 // their QP thresholds for scaling.
388 RTC_NOTREACHED() << "Unsupported codec without configured QP thresholds."; 388 RTC_NOTREACHED() << "Unsupported codec without configured QP thresholds.";
389 } 389 }
390 quality_scaler_.SetMinResolution(kMinWidth, kMinHeight); 390 quality_scaler_.SetMinResolution(kMinWidth, kMinHeight);
391 quality_scaler_.ReportFramerate(codec_settings->maxFramerate); 391 quality_scaler_.ReportFramerate(codec_settings->maxFramerate);
392 } 392 }
393 return codec_thread_->Invoke<int32_t>( 393 return codec_thread_->Invoke<int32_t>(
394 Bind(&MediaCodecVideoEncoder::InitEncodeOnCodecThread, 394 Bind(&MediaCodecVideoEncoder::InitEncodeOnCodecThread,
(...skipping 27 matching lines...) Expand all
422 Bind(&MediaCodecVideoEncoder::ReleaseOnCodecThread, this)); 422 Bind(&MediaCodecVideoEncoder::ReleaseOnCodecThread, this));
423 } 423 }
424 424
425 int32_t MediaCodecVideoEncoder::SetChannelParameters(uint32_t /* packet_loss */, 425 int32_t MediaCodecVideoEncoder::SetChannelParameters(uint32_t /* packet_loss */,
426 int64_t /* rtt */) { 426 int64_t /* rtt */) {
427 return WEBRTC_VIDEO_CODEC_OK; 427 return WEBRTC_VIDEO_CODEC_OK;
428 } 428 }
429 429
430 int32_t MediaCodecVideoEncoder::SetRates(uint32_t new_bit_rate, 430 int32_t MediaCodecVideoEncoder::SetRates(uint32_t new_bit_rate,
431 uint32_t frame_rate) { 431 uint32_t frame_rate) {
432 if (scale_)
433 quality_scaler_.ReportFramerate(frame_rate);
434
435 return codec_thread_->Invoke<int32_t>( 432 return codec_thread_->Invoke<int32_t>(
436 Bind(&MediaCodecVideoEncoder::SetRatesOnCodecThread, 433 Bind(&MediaCodecVideoEncoder::SetRatesOnCodecThread,
437 this, 434 this,
438 new_bit_rate, 435 new_bit_rate,
439 frame_rate)); 436 frame_rate));
440 } 437 }
441 438
442 void MediaCodecVideoEncoder::OnMessage(rtc::Message* msg) { 439 void MediaCodecVideoEncoder::OnMessage(rtc::Message* msg) {
443 RTC_DCHECK(codec_thread_checker_.CalledOnValidThread()); 440 RTC_DCHECK(codec_thread_checker_.CalledOnValidThread());
444 JNIEnv* jni = AttachCurrentThreadIfNeeded(); 441 JNIEnv* jni = AttachCurrentThreadIfNeeded();
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 } 488 }
492 489
493 width_ = width; 490 width_ = width;
494 height_ = height; 491 height_ = height;
495 last_set_bitrate_kbps_ = kbps; 492 last_set_bitrate_kbps_ = kbps;
496 last_set_fps_ = (fps < MAX_VIDEO_FPS) ? fps : MAX_VIDEO_FPS; 493 last_set_fps_ = (fps < MAX_VIDEO_FPS) ? fps : MAX_VIDEO_FPS;
497 yuv_size_ = width_ * height_ * 3 / 2; 494 yuv_size_ = width_ * height_ * 3 / 2;
498 frames_received_ = 0; 495 frames_received_ = 0;
499 frames_encoded_ = 0; 496 frames_encoded_ = 0;
500 frames_dropped_ = 0; 497 frames_dropped_ = 0;
498 frames_dropped_q_full_ = 0;
501 frames_in_queue_ = 0; 499 frames_in_queue_ = 0;
502 current_timestamp_us_ = 0; 500 current_timestamp_us_ = 0;
503 start_time_ms_ = GetCurrentTimeMs(); 501 start_time_ms_ = GetCurrentTimeMs();
504 current_frames_ = 0; 502 current_frames_ = 0;
505 current_bytes_ = 0; 503 current_bytes_ = 0;
506 current_acc_qp_ = 0; 504 current_acc_qp_ = 0;
507 current_encoding_time_ms_ = 0; 505 current_encoding_time_ms_ = 0;
508 last_input_timestamp_ms_ = -1; 506 last_input_timestamp_ms_ = -1;
509 last_output_timestamp_ms_ = -1; 507 last_output_timestamp_ms_ = -1;
510 output_timestamp_ = 0; 508 output_timestamp_ = 0;
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
607 RTC_CHECK(frame_types->size() == 1) << "Unexpected stream count"; 605 RTC_CHECK(frame_types->size() == 1) << "Unexpected stream count";
608 606
609 // Check if we accumulated too many frames in encoder input buffers 607 // Check if we accumulated too many frames in encoder input buffers
610 // or the encoder latency exceeds 70 ms and drop frame if so. 608 // or the encoder latency exceeds 70 ms and drop frame if so.
611 if (frames_in_queue_ > 0 && last_input_timestamp_ms_ >= 0) { 609 if (frames_in_queue_ > 0 && last_input_timestamp_ms_ >= 0) {
612 int encoder_latency_ms = last_input_timestamp_ms_ - 610 int encoder_latency_ms = last_input_timestamp_ms_ -
613 last_output_timestamp_ms_; 611 last_output_timestamp_ms_;
614 if (frames_in_queue_ > MAX_ENCODER_Q_SIZE || 612 if (frames_in_queue_ > MAX_ENCODER_Q_SIZE ||
615 encoder_latency_ms > MAX_ENCODER_LATENCY_MS) { 613 encoder_latency_ms > MAX_ENCODER_LATENCY_MS) {
616 ALOGD << "Drop frame - encoder is behind by " << encoder_latency_ms << 614 ALOGD << "Drop frame - encoder is behind by " << encoder_latency_ms <<
617 " ms. Q size: " << frames_in_queue_; 615 " ms. Q size: " << frames_in_queue_ << ". Consecutive drops: " <<
616 frames_dropped_q_full_;
618 current_timestamp_us_ += rtc::kNumMicrosecsPerSec / last_set_fps_; 617 current_timestamp_us_ += rtc::kNumMicrosecsPerSec / last_set_fps_;
618 frames_dropped_q_full_++;
619 if (frames_dropped_q_full_ >= MAX_DROPPED_FRAMES) {
620 ALOGE << "Encoder got stuck. Reset.";
621 ResetCodecOnCodecThread();
622 return WEBRTC_VIDEO_CODEC_ERROR;
623 }
619 OnDroppedFrame(); 624 OnDroppedFrame();
620 return WEBRTC_VIDEO_CODEC_OK; 625 return WEBRTC_VIDEO_CODEC_OK;
621 } 626 }
622 } 627 }
628 frames_dropped_q_full_ = 0;
623 629
624 VideoFrame input_frame = frame; 630 VideoFrame input_frame = frame;
625 if (scale_) { 631 if (scale_) {
626 // Check framerate before spatial resolution change. 632 // Check framerate before spatial resolution change.
627 quality_scaler_.OnEncodeFrame(frame); 633 quality_scaler_.OnEncodeFrame(frame);
628 const webrtc::QualityScaler::Resolution scaled_resolution = 634 const webrtc::QualityScaler::Resolution scaled_resolution =
629 quality_scaler_.GetScaledResolution(); 635 quality_scaler_.GetScaledResolution();
630 if (scaled_resolution.width != frame.width() || 636 if (scaled_resolution.width != frame.width() ||
631 scaled_resolution.height != frame.height()) { 637 scaled_resolution.height != frame.height()) {
632 if (frame.native_handle() != nullptr) { 638 if (frame.native_handle() != nullptr) {
(...skipping 22 matching lines...) Expand all
655 bool encode_status = true; 661 bool encode_status = true;
656 if (!input_frame.native_handle()) { 662 if (!input_frame.native_handle()) {
657 int j_input_buffer_index = jni->CallIntMethod(*j_media_codec_video_encoder_, 663 int j_input_buffer_index = jni->CallIntMethod(*j_media_codec_video_encoder_,
658 j_dequeue_input_buffer_method_); 664 j_dequeue_input_buffer_method_);
659 CHECK_EXCEPTION(jni); 665 CHECK_EXCEPTION(jni);
660 if (j_input_buffer_index == -1) { 666 if (j_input_buffer_index == -1) {
661 // Video codec falls behind - no input buffer available. 667 // Video codec falls behind - no input buffer available.
662 ALOGW << "Encoder drop frame - no input buffers available"; 668 ALOGW << "Encoder drop frame - no input buffers available";
663 current_timestamp_us_ += rtc::kNumMicrosecsPerSec / last_set_fps_; 669 current_timestamp_us_ += rtc::kNumMicrosecsPerSec / last_set_fps_;
664 frame_rtc_times_ms_.erase(frame_rtc_times_ms_.begin()); 670 frame_rtc_times_ms_.erase(frame_rtc_times_ms_.begin());
671 OnDroppedFrame();
665 return WEBRTC_VIDEO_CODEC_OK; // TODO(fischman): see webrtc bug 2887. 672 return WEBRTC_VIDEO_CODEC_OK; // TODO(fischman): see webrtc bug 2887.
666 } 673 }
667 if (j_input_buffer_index == -2) { 674 if (j_input_buffer_index == -2) {
668 ResetCodecOnCodecThread(); 675 ResetCodecOnCodecThread();
669 return WEBRTC_VIDEO_CODEC_ERROR; 676 return WEBRTC_VIDEO_CODEC_ERROR;
670 } 677 }
671 encode_status = EncodeByteBufferOnCodecThread(jni, key_frame, input_frame, 678 encode_status = EncodeByteBufferOnCodecThread(jni, key_frame, input_frame,
672 j_input_buffer_index); 679 j_input_buffer_index);
673 } else { 680 } else {
674 encode_status = EncodeTextureOnCodecThread(jni, key_frame, input_frame); 681 encode_status = EncodeTextureOnCodecThread(jni, key_frame, input_frame);
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
808 815
809 int32_t MediaCodecVideoEncoder::SetRatesOnCodecThread(uint32_t new_bit_rate, 816 int32_t MediaCodecVideoEncoder::SetRatesOnCodecThread(uint32_t new_bit_rate,
810 uint32_t frame_rate) { 817 uint32_t frame_rate) {
811 RTC_DCHECK(codec_thread_checker_.CalledOnValidThread()); 818 RTC_DCHECK(codec_thread_checker_.CalledOnValidThread());
812 frame_rate = (frame_rate < MAX_ALLOWED_VIDEO_FPS) ? 819 frame_rate = (frame_rate < MAX_ALLOWED_VIDEO_FPS) ?
813 frame_rate : MAX_ALLOWED_VIDEO_FPS; 820 frame_rate : MAX_ALLOWED_VIDEO_FPS;
814 if (last_set_bitrate_kbps_ == new_bit_rate && 821 if (last_set_bitrate_kbps_ == new_bit_rate &&
815 last_set_fps_ == frame_rate) { 822 last_set_fps_ == frame_rate) {
816 return WEBRTC_VIDEO_CODEC_OK; 823 return WEBRTC_VIDEO_CODEC_OK;
817 } 824 }
825 if (scale_) {
826 quality_scaler_.ReportFramerate(frame_rate);
827 }
818 JNIEnv* jni = AttachCurrentThreadIfNeeded(); 828 JNIEnv* jni = AttachCurrentThreadIfNeeded();
819 ScopedLocalRefFrame local_ref_frame(jni); 829 ScopedLocalRefFrame local_ref_frame(jni);
820 if (new_bit_rate > 0) { 830 if (new_bit_rate > 0) {
821 last_set_bitrate_kbps_ = new_bit_rate; 831 last_set_bitrate_kbps_ = new_bit_rate;
822 } 832 }
823 if (frame_rate > 0) { 833 if (frame_rate > 0) {
824 last_set_fps_ = frame_rate; 834 last_set_fps_ = frame_rate;
825 } 835 }
826 bool ret = jni->CallBooleanMethod(*j_media_codec_video_encoder_, 836 bool ret = jni->CallBooleanMethod(*j_media_codec_video_encoder_,
827 j_set_rates_method_, 837 j_set_rates_method_,
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
1206 } 1216 }
1207 1217
1208 void MediaCodecVideoEncoderFactory::DestroyVideoEncoder( 1218 void MediaCodecVideoEncoderFactory::DestroyVideoEncoder(
1209 webrtc::VideoEncoder* encoder) { 1219 webrtc::VideoEncoder* encoder) {
1210 ALOGD << "Destroy video encoder."; 1220 ALOGD << "Destroy video encoder.";
1211 delete encoder; 1221 delete encoder;
1212 } 1222 }
1213 1223
1214 } // namespace webrtc_jni 1224 } // namespace webrtc_jni
1215 1225
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698