OLD | NEW |
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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 #define MAX_VIDEO_WIDTH 1280 | 71 #define MAX_VIDEO_WIDTH 1280 |
72 #define MAX_VIDEO_HEIGHT 1280 | 72 #define MAX_VIDEO_HEIGHT 1280 |
73 // Maximum supported HW video encoder fps. | 73 // Maximum supported HW video encoder fps. |
74 #define MAX_VIDEO_FPS 30 | 74 #define MAX_VIDEO_FPS 30 |
75 // Maximum allowed fps value in SetRates() call. | 75 // Maximum allowed fps value in SetRates() call. |
76 #define MAX_ALLOWED_VIDEO_FPS 60 | 76 #define MAX_ALLOWED_VIDEO_FPS 60 |
77 // Maximum allowed frames in encoder input queue. | 77 // Maximum allowed frames in encoder input queue. |
78 #define MAX_ENCODER_Q_SIZE 2 | 78 #define MAX_ENCODER_Q_SIZE 2 |
79 // Maximum allowed latency in ms. | 79 // Maximum allowed latency in ms. |
80 #define MAX_ENCODER_LATENCY_MS 70 | 80 #define MAX_ENCODER_LATENCY_MS 70 |
81 | 81 // Maximum amount of dropped frames caused by full encoder queue - exceeding |
| 82 // this threshold means that encoder probably got stuck and need to be reset. |
| 83 #define ENCODER_STALL_FRAMEDROP_THRESHOLD 60 |
82 | 84 |
83 // Logging macros. | 85 // Logging macros. |
84 #define TAG_ENCODER "MediaCodecVideoEncoder" | 86 #define TAG_ENCODER "MediaCodecVideoEncoder" |
85 #ifdef TRACK_BUFFER_TIMING | 87 #ifdef TRACK_BUFFER_TIMING |
86 #define ALOGV(...) | 88 #define ALOGV(...) |
87 __android_log_print(ANDROID_LOG_VERBOSE, TAG_ENCODER, __VA_ARGS__) | 89 __android_log_print(ANDROID_LOG_VERBOSE, TAG_ENCODER, __VA_ARGS__) |
88 #else | 90 #else |
89 #define ALOGV(...) | 91 #define ALOGV(...) |
90 #endif | 92 #endif |
91 #define ALOGD LOG_TAG(rtc::LS_INFO, TAG_ENCODER) | 93 #define ALOGD LOG_TAG(rtc::LS_INFO, TAG_ENCODER) |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 int height_; // Frame height in pixels. | 222 int height_; // Frame height in pixels. |
221 bool inited_; | 223 bool inited_; |
222 bool use_surface_; | 224 bool use_surface_; |
223 uint16_t picture_id_; | 225 uint16_t picture_id_; |
224 enum libyuv::FourCC encoder_fourcc_; // Encoder color space format. | 226 enum libyuv::FourCC encoder_fourcc_; // Encoder color space format. |
225 int last_set_bitrate_kbps_; // Last-requested bitrate in kbps. | 227 int last_set_bitrate_kbps_; // Last-requested bitrate in kbps. |
226 int last_set_fps_; // Last-requested frame rate. | 228 int last_set_fps_; // Last-requested frame rate. |
227 int64_t current_timestamp_us_; // Current frame timestamps in us. | 229 int64_t current_timestamp_us_; // Current frame timestamps in us. |
228 int frames_received_; // Number of frames received by encoder. | 230 int frames_received_; // Number of frames received by encoder. |
229 int frames_encoded_; // Number of frames encoded by encoder. | 231 int frames_encoded_; // Number of frames encoded by encoder. |
230 int frames_dropped_; // Number of frames dropped by encoder. | 232 int frames_dropped_media_encoder_; // Number of frames dropped by encoder. |
| 233 // Number of dropped frames caused by full queue. |
| 234 int consecutive_full_queue_frame_drops_; |
231 int frames_in_queue_; // Number of frames in encoder queue. | 235 int frames_in_queue_; // Number of frames in encoder queue. |
232 int64_t start_time_ms_; // Start time for statistics. | 236 int64_t start_time_ms_; // Start time for statistics. |
233 int current_frames_; // Number of frames in the current statistics interval. | 237 int current_frames_; // Number of frames in the current statistics interval. |
234 int current_bytes_; // Encoded bytes in the current statistics interval. | 238 int current_bytes_; // Encoded bytes in the current statistics interval. |
235 int current_acc_qp_; // Accumulated QP in the current statistics interval. | 239 int current_acc_qp_; // Accumulated QP in the current statistics interval. |
236 int current_encoding_time_ms_; // Overall encoding time in the current second | 240 int current_encoding_time_ms_; // Overall encoding time in the current second |
237 int64_t last_input_timestamp_ms_; // Timestamp of last received yuv frame. | 241 int64_t last_input_timestamp_ms_; // Timestamp of last received yuv frame. |
238 int64_t last_output_timestamp_ms_; // Timestamp of last encoded frame. | 242 int64_t last_output_timestamp_ms_; // Timestamp of last encoded frame. |
239 std::vector<int32_t> timestamps_; // Video frames timestamp queue. | 243 std::vector<int32_t> timestamps_; // Video frames timestamp queue. |
240 std::vector<int64_t> render_times_ms_; // Video frames render time queue. | 244 std::vector<int64_t> render_times_ms_; // Video frames render time queue. |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
378 scale_ = (codecType_ != kVideoCodecVP9) && (webrtc::field_trial::FindFullName( | 382 scale_ = (codecType_ != kVideoCodecVP9) && (webrtc::field_trial::FindFullName( |
379 "WebRTC-MediaCodecVideoEncoder-AutomaticResize") == "Enabled"); | 383 "WebRTC-MediaCodecVideoEncoder-AutomaticResize") == "Enabled"); |
380 ALOGD << "Encoder automatic resize " << (scale_ ? "enabled" : "disabled"); | 384 ALOGD << "Encoder automatic resize " << (scale_ ? "enabled" : "disabled"); |
381 if (scale_) { | 385 if (scale_) { |
382 if (codecType_ == kVideoCodecVP8) { | 386 if (codecType_ == kVideoCodecVP8) { |
383 // QP is obtained from VP8-bitstream for HW, so the QP corresponds to the | 387 // QP is obtained from VP8-bitstream for HW, so the QP corresponds to the |
384 // (internal) range: [0, 127]. And we cannot change QP_max in HW, so it is | 388 // (internal) range: [0, 127]. And we cannot change QP_max in HW, so it is |
385 // always = 127. Note that in SW, QP is that of the user-level range [0, | 389 // always = 127. Note that in SW, QP is that of the user-level range [0, |
386 // 63]. | 390 // 63]. |
387 const int kMaxQp = 127; | 391 const int kMaxQp = 127; |
388 // TODO(pbos): Investigate whether high-QP thresholds make sense for VP8. | 392 const int kBadQpThreshold = 95; |
389 // This effectively disables high QP as VP8 QP can't go above this | 393 quality_scaler_.Init( |
390 // threshold. | 394 kMaxQp / kLowQpThresholdDenominator, kBadQpThreshold, false); |
391 const int kDisabledBadQpThreshold = kMaxQp + 1; | |
392 quality_scaler_.Init(kMaxQp / kLowQpThresholdDenominator, | |
393 kDisabledBadQpThreshold, true); | |
394 } else if (codecType_ == kVideoCodecH264) { | 395 } else if (codecType_ == kVideoCodecH264) { |
395 // H264 QP is in the range [0, 51]. | 396 // H264 QP is in the range [0, 51]. |
396 const int kMaxQp = 51; | 397 const int kMaxQp = 51; |
397 const int kBadQpThreshold = 40; | 398 const int kBadQpThreshold = 40; |
398 quality_scaler_.Init(kMaxQp / kLowQpThresholdDenominator, kBadQpThreshold, | 399 quality_scaler_.Init( |
399 false); | 400 kMaxQp / kLowQpThresholdDenominator, kBadQpThreshold, false); |
400 } else { | 401 } else { |
401 // When adding codec support to additional hardware codecs, also configure | 402 // When adding codec support to additional hardware codecs, also configure |
402 // their QP thresholds for scaling. | 403 // their QP thresholds for scaling. |
403 RTC_NOTREACHED() << "Unsupported codec without configured QP thresholds."; | 404 RTC_NOTREACHED() << "Unsupported codec without configured QP thresholds."; |
404 } | 405 } |
405 quality_scaler_.SetMinResolution(kMinWidth, kMinHeight); | 406 quality_scaler_.SetMinResolution(kMinWidth, kMinHeight); |
406 quality_scaler_.ReportFramerate(codec_settings->maxFramerate); | 407 quality_scaler_.ReportFramerate(codec_settings->maxFramerate); |
407 } | 408 } |
408 return codec_thread_->Invoke<int32_t>( | 409 return codec_thread_->Invoke<int32_t>( |
409 Bind(&MediaCodecVideoEncoder::InitEncodeOnCodecThread, | 410 Bind(&MediaCodecVideoEncoder::InitEncodeOnCodecThread, |
(...skipping 27 matching lines...) Expand all Loading... |
437 Bind(&MediaCodecVideoEncoder::ReleaseOnCodecThread, this)); | 438 Bind(&MediaCodecVideoEncoder::ReleaseOnCodecThread, this)); |
438 } | 439 } |
439 | 440 |
440 int32_t MediaCodecVideoEncoder::SetChannelParameters(uint32_t /* packet_loss */, | 441 int32_t MediaCodecVideoEncoder::SetChannelParameters(uint32_t /* packet_loss */, |
441 int64_t /* rtt */) { | 442 int64_t /* rtt */) { |
442 return WEBRTC_VIDEO_CODEC_OK; | 443 return WEBRTC_VIDEO_CODEC_OK; |
443 } | 444 } |
444 | 445 |
445 int32_t MediaCodecVideoEncoder::SetRates(uint32_t new_bit_rate, | 446 int32_t MediaCodecVideoEncoder::SetRates(uint32_t new_bit_rate, |
446 uint32_t frame_rate) { | 447 uint32_t frame_rate) { |
447 if (scale_) | |
448 quality_scaler_.ReportFramerate(frame_rate); | |
449 | |
450 return codec_thread_->Invoke<int32_t>( | 448 return codec_thread_->Invoke<int32_t>( |
451 Bind(&MediaCodecVideoEncoder::SetRatesOnCodecThread, | 449 Bind(&MediaCodecVideoEncoder::SetRatesOnCodecThread, |
452 this, | 450 this, |
453 new_bit_rate, | 451 new_bit_rate, |
454 frame_rate)); | 452 frame_rate)); |
455 } | 453 } |
456 | 454 |
457 void MediaCodecVideoEncoder::OnMessage(rtc::Message* msg) { | 455 void MediaCodecVideoEncoder::OnMessage(rtc::Message* msg) { |
458 RTC_DCHECK(codec_thread_checker_.CalledOnValidThread()); | 456 RTC_DCHECK(codec_thread_checker_.CalledOnValidThread()); |
459 JNIEnv* jni = AttachCurrentThreadIfNeeded(); | 457 JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
505 fps = MAX_VIDEO_FPS; | 503 fps = MAX_VIDEO_FPS; |
506 } | 504 } |
507 | 505 |
508 width_ = width; | 506 width_ = width; |
509 height_ = height; | 507 height_ = height; |
510 last_set_bitrate_kbps_ = kbps; | 508 last_set_bitrate_kbps_ = kbps; |
511 last_set_fps_ = (fps < MAX_VIDEO_FPS) ? fps : MAX_VIDEO_FPS; | 509 last_set_fps_ = (fps < MAX_VIDEO_FPS) ? fps : MAX_VIDEO_FPS; |
512 yuv_size_ = width_ * height_ * 3 / 2; | 510 yuv_size_ = width_ * height_ * 3 / 2; |
513 frames_received_ = 0; | 511 frames_received_ = 0; |
514 frames_encoded_ = 0; | 512 frames_encoded_ = 0; |
515 frames_dropped_ = 0; | 513 frames_dropped_media_encoder_ = 0; |
| 514 consecutive_full_queue_frame_drops_ = 0; |
516 frames_in_queue_ = 0; | 515 frames_in_queue_ = 0; |
517 current_timestamp_us_ = 0; | 516 current_timestamp_us_ = 0; |
518 start_time_ms_ = GetCurrentTimeMs(); | 517 start_time_ms_ = GetCurrentTimeMs(); |
519 current_frames_ = 0; | 518 current_frames_ = 0; |
520 current_bytes_ = 0; | 519 current_bytes_ = 0; |
521 current_acc_qp_ = 0; | 520 current_acc_qp_ = 0; |
522 current_encoding_time_ms_ = 0; | 521 current_encoding_time_ms_ = 0; |
523 last_input_timestamp_ms_ = -1; | 522 last_input_timestamp_ms_ = -1; |
524 last_output_timestamp_ms_ = -1; | 523 last_output_timestamp_ms_ = -1; |
525 output_timestamp_ = 0; | 524 output_timestamp_ = 0; |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
627 if (frames_encoded_ < kMaxEncodedLogFrames) { | 626 if (frames_encoded_ < kMaxEncodedLogFrames) { |
628 ALOGD << "Encoder frame in # " << (frames_received_ - 1) << ". TS: " << | 627 ALOGD << "Encoder frame in # " << (frames_received_ - 1) << ". TS: " << |
629 (int)(current_timestamp_us_ / 1000) << ". Q: " << frames_in_queue_ << | 628 (int)(current_timestamp_us_ / 1000) << ". Q: " << frames_in_queue_ << |
630 ". Fps: " << last_set_fps_ << ". Kbps: " << last_set_bitrate_kbps_; | 629 ". Fps: " << last_set_fps_ << ". Kbps: " << last_set_bitrate_kbps_; |
631 } | 630 } |
632 | 631 |
633 if (drop_next_input_frame_) { | 632 if (drop_next_input_frame_) { |
634 ALOGW << "Encoder drop frame - failed callback."; | 633 ALOGW << "Encoder drop frame - failed callback."; |
635 drop_next_input_frame_ = false; | 634 drop_next_input_frame_ = false; |
636 current_timestamp_us_ += rtc::kNumMicrosecsPerSec / last_set_fps_; | 635 current_timestamp_us_ += rtc::kNumMicrosecsPerSec / last_set_fps_; |
| 636 frames_dropped_media_encoder_++; |
637 OnDroppedFrame(); | 637 OnDroppedFrame(); |
638 return WEBRTC_VIDEO_CODEC_OK; | 638 return WEBRTC_VIDEO_CODEC_OK; |
639 } | 639 } |
640 | 640 |
641 RTC_CHECK(frame_types->size() == 1) << "Unexpected stream count"; | 641 RTC_CHECK(frame_types->size() == 1) << "Unexpected stream count"; |
642 | 642 |
643 // Check if we accumulated too many frames in encoder input buffers | 643 // Check if we accumulated too many frames in encoder input buffers |
644 // or the encoder latency exceeds 70 ms and drop frame if so. | 644 // or the encoder latency exceeds 70 ms and drop frame if so. |
645 if (frames_in_queue_ > 0 && last_input_timestamp_ms_ >= 0) { | 645 if (frames_in_queue_ > 0 && last_input_timestamp_ms_ >= 0) { |
646 int encoder_latency_ms = last_input_timestamp_ms_ - | 646 int encoder_latency_ms = last_input_timestamp_ms_ - |
647 last_output_timestamp_ms_; | 647 last_output_timestamp_ms_; |
648 if (frames_in_queue_ > MAX_ENCODER_Q_SIZE || | 648 if (frames_in_queue_ > MAX_ENCODER_Q_SIZE || |
649 encoder_latency_ms > MAX_ENCODER_LATENCY_MS) { | 649 encoder_latency_ms > MAX_ENCODER_LATENCY_MS) { |
650 ALOGD << "Drop frame - encoder is behind by " << encoder_latency_ms << | 650 ALOGD << "Drop frame - encoder is behind by " << encoder_latency_ms << |
651 " ms. Q size: " << frames_in_queue_; | 651 " ms. Q size: " << frames_in_queue_ << ". Consecutive drops: " << |
| 652 consecutive_full_queue_frame_drops_; |
652 current_timestamp_us_ += rtc::kNumMicrosecsPerSec / last_set_fps_; | 653 current_timestamp_us_ += rtc::kNumMicrosecsPerSec / last_set_fps_; |
| 654 consecutive_full_queue_frame_drops_++; |
| 655 if (consecutive_full_queue_frame_drops_ >= |
| 656 ENCODER_STALL_FRAMEDROP_THRESHOLD) { |
| 657 ALOGE << "Encoder got stuck. Reset."; |
| 658 ResetCodecOnCodecThread(); |
| 659 return WEBRTC_VIDEO_CODEC_ERROR; |
| 660 } |
| 661 frames_dropped_media_encoder_++; |
653 OnDroppedFrame(); | 662 OnDroppedFrame(); |
654 return WEBRTC_VIDEO_CODEC_OK; | 663 return WEBRTC_VIDEO_CODEC_OK; |
655 } | 664 } |
656 } | 665 } |
| 666 consecutive_full_queue_frame_drops_ = 0; |
657 | 667 |
658 VideoFrame input_frame = frame; | 668 VideoFrame input_frame = frame; |
659 if (scale_) { | 669 if (scale_) { |
660 // Check framerate before spatial resolution change. | 670 // Check framerate before spatial resolution change. |
661 quality_scaler_.OnEncodeFrame(frame); | 671 quality_scaler_.OnEncodeFrame(frame); |
662 const webrtc::QualityScaler::Resolution scaled_resolution = | 672 const webrtc::QualityScaler::Resolution scaled_resolution = |
663 quality_scaler_.GetScaledResolution(); | 673 quality_scaler_.GetScaledResolution(); |
664 if (scaled_resolution.width != frame.width() || | 674 if (scaled_resolution.width != frame.width() || |
665 scaled_resolution.height != frame.height()) { | 675 scaled_resolution.height != frame.height()) { |
666 if (frame.native_handle() != nullptr) { | 676 if (frame.native_handle() != nullptr) { |
(...skipping 21 matching lines...) Expand all Loading... |
688 const bool key_frame = | 698 const bool key_frame = |
689 frame_types->front() != webrtc::kVideoFrameDelta || send_key_frame; | 699 frame_types->front() != webrtc::kVideoFrameDelta || send_key_frame; |
690 bool encode_status = true; | 700 bool encode_status = true; |
691 if (!input_frame.native_handle()) { | 701 if (!input_frame.native_handle()) { |
692 int j_input_buffer_index = jni->CallIntMethod(*j_media_codec_video_encoder_, | 702 int j_input_buffer_index = jni->CallIntMethod(*j_media_codec_video_encoder_, |
693 j_dequeue_input_buffer_method_); | 703 j_dequeue_input_buffer_method_); |
694 CHECK_EXCEPTION(jni); | 704 CHECK_EXCEPTION(jni); |
695 if (j_input_buffer_index == -1) { | 705 if (j_input_buffer_index == -1) { |
696 // Video codec falls behind - no input buffer available. | 706 // Video codec falls behind - no input buffer available. |
697 ALOGW << "Encoder drop frame - no input buffers available"; | 707 ALOGW << "Encoder drop frame - no input buffers available"; |
| 708 frame_rtc_times_ms_.erase(frame_rtc_times_ms_.begin()); |
698 current_timestamp_us_ += rtc::kNumMicrosecsPerSec / last_set_fps_; | 709 current_timestamp_us_ += rtc::kNumMicrosecsPerSec / last_set_fps_; |
699 frame_rtc_times_ms_.erase(frame_rtc_times_ms_.begin()); | 710 frames_dropped_media_encoder_++; |
| 711 OnDroppedFrame(); |
700 return WEBRTC_VIDEO_CODEC_OK; // TODO(fischman): see webrtc bug 2887. | 712 return WEBRTC_VIDEO_CODEC_OK; // TODO(fischman): see webrtc bug 2887. |
701 } | 713 } |
702 if (j_input_buffer_index == -2) { | 714 if (j_input_buffer_index == -2) { |
703 ResetCodecOnCodecThread(); | 715 ResetCodecOnCodecThread(); |
704 return WEBRTC_VIDEO_CODEC_ERROR; | 716 return WEBRTC_VIDEO_CODEC_ERROR; |
705 } | 717 } |
706 encode_status = EncodeByteBufferOnCodecThread(jni, key_frame, input_frame, | 718 encode_status = EncodeByteBufferOnCodecThread(jni, key_frame, input_frame, |
707 j_input_buffer_index); | 719 j_input_buffer_index); |
708 } else { | 720 } else { |
709 encode_status = EncodeTextureOnCodecThread(jni, key_frame, input_frame); | 721 encode_status = EncodeTextureOnCodecThread(jni, key_frame, input_frame); |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
820 } | 832 } |
821 | 833 |
822 int32_t MediaCodecVideoEncoder::ReleaseOnCodecThread() { | 834 int32_t MediaCodecVideoEncoder::ReleaseOnCodecThread() { |
823 RTC_DCHECK(codec_thread_checker_.CalledOnValidThread()); | 835 RTC_DCHECK(codec_thread_checker_.CalledOnValidThread()); |
824 if (!inited_) { | 836 if (!inited_) { |
825 return WEBRTC_VIDEO_CODEC_OK; | 837 return WEBRTC_VIDEO_CODEC_OK; |
826 } | 838 } |
827 JNIEnv* jni = AttachCurrentThreadIfNeeded(); | 839 JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
828 ALOGD << "EncoderReleaseOnCodecThread: Frames received: " << | 840 ALOGD << "EncoderReleaseOnCodecThread: Frames received: " << |
829 frames_received_ << ". Encoded: " << frames_encoded_ << | 841 frames_received_ << ". Encoded: " << frames_encoded_ << |
830 ". Dropped: " << frames_dropped_; | 842 ". Dropped: " << frames_dropped_media_encoder_; |
831 ScopedLocalRefFrame local_ref_frame(jni); | 843 ScopedLocalRefFrame local_ref_frame(jni); |
832 for (size_t i = 0; i < input_buffers_.size(); ++i) | 844 for (size_t i = 0; i < input_buffers_.size(); ++i) |
833 jni->DeleteGlobalRef(input_buffers_[i]); | 845 jni->DeleteGlobalRef(input_buffers_[i]); |
834 input_buffers_.clear(); | 846 input_buffers_.clear(); |
835 jni->CallVoidMethod(*j_media_codec_video_encoder_, j_release_method_); | 847 jni->CallVoidMethod(*j_media_codec_video_encoder_, j_release_method_); |
836 CHECK_EXCEPTION(jni); | 848 CHECK_EXCEPTION(jni); |
837 rtc::MessageQueueManager::Clear(this); | 849 rtc::MessageQueueManager::Clear(this); |
838 inited_ = false; | 850 inited_ = false; |
839 use_surface_ = false; | 851 use_surface_ = false; |
840 ALOGD << "EncoderReleaseOnCodecThread done."; | 852 ALOGD << "EncoderReleaseOnCodecThread done."; |
841 return WEBRTC_VIDEO_CODEC_OK; | 853 return WEBRTC_VIDEO_CODEC_OK; |
842 } | 854 } |
843 | 855 |
844 int32_t MediaCodecVideoEncoder::SetRatesOnCodecThread(uint32_t new_bit_rate, | 856 int32_t MediaCodecVideoEncoder::SetRatesOnCodecThread(uint32_t new_bit_rate, |
845 uint32_t frame_rate) { | 857 uint32_t frame_rate) { |
846 RTC_DCHECK(codec_thread_checker_.CalledOnValidThread()); | 858 RTC_DCHECK(codec_thread_checker_.CalledOnValidThread()); |
847 frame_rate = (frame_rate < MAX_ALLOWED_VIDEO_FPS) ? | 859 frame_rate = (frame_rate < MAX_ALLOWED_VIDEO_FPS) ? |
848 frame_rate : MAX_ALLOWED_VIDEO_FPS; | 860 frame_rate : MAX_ALLOWED_VIDEO_FPS; |
849 if (last_set_bitrate_kbps_ == new_bit_rate && | 861 if (last_set_bitrate_kbps_ == new_bit_rate && |
850 last_set_fps_ == frame_rate) { | 862 last_set_fps_ == frame_rate) { |
851 return WEBRTC_VIDEO_CODEC_OK; | 863 return WEBRTC_VIDEO_CODEC_OK; |
852 } | 864 } |
| 865 if (scale_) { |
| 866 quality_scaler_.ReportFramerate(frame_rate); |
| 867 } |
853 JNIEnv* jni = AttachCurrentThreadIfNeeded(); | 868 JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
854 ScopedLocalRefFrame local_ref_frame(jni); | 869 ScopedLocalRefFrame local_ref_frame(jni); |
855 if (new_bit_rate > 0) { | 870 if (new_bit_rate > 0) { |
856 last_set_bitrate_kbps_ = new_bit_rate; | 871 last_set_bitrate_kbps_ = new_bit_rate; |
857 } | 872 } |
858 if (frame_rate > 0) { | 873 if (frame_rate > 0) { |
859 last_set_fps_ = frame_rate; | 874 last_set_fps_ = frame_rate; |
860 } | 875 } |
861 bool ret = jni->CallBooleanMethod(*j_media_codec_video_encoder_, | 876 bool ret = jni->CallBooleanMethod(*j_media_codec_video_encoder_, |
862 j_set_rates_method_, | 877 j_set_rates_method_, |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1128 if (head[3] != 0x01) { // got 000000xx | 1143 if (head[3] != 0x01) { // got 000000xx |
1129 head++; // xx != 1, continue searching. | 1144 head++; // xx != 1, continue searching. |
1130 continue; | 1145 continue; |
1131 } | 1146 } |
1132 return (int32_t)(head - buffer); | 1147 return (int32_t)(head - buffer); |
1133 } | 1148 } |
1134 return -1; | 1149 return -1; |
1135 } | 1150 } |
1136 | 1151 |
1137 void MediaCodecVideoEncoder::OnDroppedFrame() { | 1152 void MediaCodecVideoEncoder::OnDroppedFrame() { |
1138 frames_dropped_++; | |
1139 // Report dropped frame to quality_scaler_. | 1153 // Report dropped frame to quality_scaler_. |
1140 if (scale_) | 1154 if (scale_) |
1141 quality_scaler_.ReportDroppedFrame(); | 1155 quality_scaler_.ReportDroppedFrame(); |
1142 } | 1156 } |
1143 | 1157 |
1144 int MediaCodecVideoEncoder::GetTargetFramerate() { | 1158 int MediaCodecVideoEncoder::GetTargetFramerate() { |
1145 return scale_ ? quality_scaler_.GetTargetFramerate() : -1; | 1159 return scale_ ? quality_scaler_.GetTargetFramerate() : -1; |
1146 } | 1160 } |
1147 | 1161 |
1148 const char* MediaCodecVideoEncoder::ImplementationName() const { | 1162 const char* MediaCodecVideoEncoder::ImplementationName() const { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1241 } | 1255 } |
1242 | 1256 |
1243 void MediaCodecVideoEncoderFactory::DestroyVideoEncoder( | 1257 void MediaCodecVideoEncoderFactory::DestroyVideoEncoder( |
1244 webrtc::VideoEncoder* encoder) { | 1258 webrtc::VideoEncoder* encoder) { |
1245 ALOGD << "Destroy video encoder."; | 1259 ALOGD << "Destroy video encoder."; |
1246 delete encoder; | 1260 delete encoder; |
1247 } | 1261 } |
1248 | 1262 |
1249 } // namespace webrtc_jni | 1263 } // namespace webrtc_jni |
1250 | 1264 |
OLD | NEW |