| OLD | NEW | 
|    1 /* |    1 /* | 
|    2  *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. |    2  *  Copyright (c) 2016 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 "webrtc/modules/video_coding/frame_buffer2.h" |   11 #include "webrtc/modules/video_coding/frame_buffer2.h" | 
|   12  |   12  | 
|   13 #include <algorithm> |   13 #include <algorithm> | 
|   14 #include <cstring> |   14 #include <cstring> | 
|   15 #include <queue> |   15 #include <queue> | 
|   16  |   16  | 
|   17 #include "webrtc/base/checks.h" |   17 #include "webrtc/base/checks.h" | 
|   18 #include "webrtc/base/logging.h" |   18 #include "webrtc/base/logging.h" | 
|   19 #include "webrtc/modules/video_coding/include/video_coding_defines.h" |  | 
|   20 #include "webrtc/modules/video_coding/jitter_estimator.h" |   19 #include "webrtc/modules/video_coding/jitter_estimator.h" | 
|   21 #include "webrtc/modules/video_coding/timing.h" |   20 #include "webrtc/modules/video_coding/timing.h" | 
|   22 #include "webrtc/system_wrappers/include/clock.h" |   21 #include "webrtc/system_wrappers/include/clock.h" | 
|   23 #include "webrtc/system_wrappers/include/metrics.h" |   22 #include "webrtc/system_wrappers/include/metrics.h" | 
|   24  |   23  | 
|   25 namespace webrtc { |   24 namespace webrtc { | 
|   26 namespace video_coding { |   25 namespace video_coding { | 
|   27  |   26  | 
|   28 namespace { |   27 namespace { | 
|   29 // Max number of frames the buffer will hold. |   28 // Max number of frames the buffer will hold. | 
|   30 constexpr int kMaxFramesBuffered = 600; |   29 constexpr int kMaxFramesBuffered = 600; | 
|   31  |   30  | 
|   32 // Max number of decoded frame info that will be saved. |   31 // Max number of decoded frame info that will be saved. | 
|   33 constexpr int kMaxFramesHistory = 50; |   32 constexpr int kMaxFramesHistory = 50; | 
|   34 }  // namespace |   33 }  // namespace | 
|   35  |   34  | 
|   36 FrameBuffer::FrameBuffer(Clock* clock, |   35 FrameBuffer::FrameBuffer(Clock* clock, | 
|   37                          VCMJitterEstimator* jitter_estimator, |   36                          VCMJitterEstimator* jitter_estimator, | 
|   38                          VCMTiming* timing, |   37                          VCMTiming* timing) | 
|   39                          VCMReceiveStatisticsCallback* stats_callback) |  | 
|   40     : clock_(clock), |   38     : clock_(clock), | 
|   41       new_countinuous_frame_event_(false, false), |   39       new_countinuous_frame_event_(false, false), | 
|   42       jitter_estimator_(jitter_estimator), |   40       jitter_estimator_(jitter_estimator), | 
|   43       timing_(timing), |   41       timing_(timing), | 
|   44       inter_frame_delay_(clock_->TimeInMilliseconds()), |   42       inter_frame_delay_(clock_->TimeInMilliseconds()), | 
|   45       last_decoded_frame_it_(frames_.end()), |   43       last_decoded_frame_it_(frames_.end()), | 
|   46       last_continuous_frame_it_(frames_.end()), |   44       last_continuous_frame_it_(frames_.end()), | 
|   47       num_frames_history_(0), |   45       num_frames_history_(0), | 
|   48       num_frames_buffered_(0), |   46       num_frames_buffered_(0), | 
|   49       stopped_(false), |   47       stopped_(false), | 
|   50       protection_mode_(kProtectionNack), |   48       protection_mode_(kProtectionNack) {} | 
|   51       stats_callback_(stats_callback) {} |  | 
|   52  |   49  | 
|   53 FrameBuffer::~FrameBuffer() {} |   50 FrameBuffer::~FrameBuffer() { | 
 |   51   UpdateHistograms(); | 
 |   52 } | 
|   54  |   53  | 
|   55 FrameBuffer::ReturnReason FrameBuffer::NextFrame( |   54 FrameBuffer::ReturnReason FrameBuffer::NextFrame( | 
|   56     int64_t max_wait_time_ms, |   55     int64_t max_wait_time_ms, | 
|   57     std::unique_ptr<FrameObject>* frame_out) { |   56     std::unique_ptr<FrameObject>* frame_out) { | 
|   58   int64_t latest_return_time = clock_->TimeInMilliseconds() + max_wait_time_ms; |   57   int64_t latest_return_time = clock_->TimeInMilliseconds() + max_wait_time_ms; | 
|   59   int64_t wait_ms = max_wait_time_ms; |   58   int64_t wait_ms = max_wait_time_ms; | 
|   60   FrameMap::iterator next_frame_it; |   59   FrameMap::iterator next_frame_it; | 
|   61  |   60  | 
|   62   do { |   61   do { | 
|   63     int64_t now_ms = clock_->TimeInMilliseconds(); |   62     int64_t now_ms = clock_->TimeInMilliseconds(); | 
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  159 void FrameBuffer::Stop() { |  158 void FrameBuffer::Stop() { | 
|  160   rtc::CritScope lock(&crit_); |  159   rtc::CritScope lock(&crit_); | 
|  161   stopped_ = true; |  160   stopped_ = true; | 
|  162   new_countinuous_frame_event_.Set(); |  161   new_countinuous_frame_event_.Set(); | 
|  163 } |  162 } | 
|  164  |  163  | 
|  165 int FrameBuffer::InsertFrame(std::unique_ptr<FrameObject> frame) { |  164 int FrameBuffer::InsertFrame(std::unique_ptr<FrameObject> frame) { | 
|  166   rtc::CritScope lock(&crit_); |  165   rtc::CritScope lock(&crit_); | 
|  167   RTC_DCHECK(frame); |  166   RTC_DCHECK(frame); | 
|  168  |  167  | 
|  169   if (stats_callback_) |  168   ++num_total_frames_; | 
|  170     stats_callback_->OnCompleteFrame(frame->num_references == 0, frame->size()); |  169   if (frame->num_references == 0) | 
 |  170     ++num_key_frames_; | 
|  171  |  171  | 
|  172   FrameKey key(frame->picture_id, frame->spatial_layer); |  172   FrameKey key(frame->picture_id, frame->spatial_layer); | 
|  173   int last_continuous_picture_id = |  173   int last_continuous_picture_id = | 
|  174       last_continuous_frame_it_ == frames_.end() |  174       last_continuous_frame_it_ == frames_.end() | 
|  175           ? -1 |  175           ? -1 | 
|  176           : last_continuous_frame_it_->first.picture_id; |  176           : last_continuous_frame_it_->first.picture_id; | 
|  177  |  177  | 
|  178   if (num_frames_buffered_ >= kMaxFramesBuffered) { |  178   if (num_frames_buffered_ >= kMaxFramesBuffered) { | 
|  179     LOG(LS_WARNING) << "Frame with (picture_id:spatial_id) (" << key.picture_id |  179     LOG(LS_WARNING) << "Frame with (picture_id:spatial_id) (" << key.picture_id | 
|  180                     << ":" << static_cast<int>(key.spatial_layer) |  180                     << ":" << static_cast<int>(key.spatial_layer) | 
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  374                   ref_info->second.num_missing_decodable); |  374                   ref_info->second.num_missing_decodable); | 
|  375   } |  375   } | 
|  376  |  376  | 
|  377   RTC_DCHECK_LE(info->second.num_missing_continuous, |  377   RTC_DCHECK_LE(info->second.num_missing_continuous, | 
|  378                 info->second.num_missing_decodable); |  378                 info->second.num_missing_decodable); | 
|  379  |  379  | 
|  380   return true; |  380   return true; | 
|  381 } |  381 } | 
|  382  |  382  | 
|  383 void FrameBuffer::UpdateJitterDelay() { |  383 void FrameBuffer::UpdateJitterDelay() { | 
|  384   if (!stats_callback_) |  384   int unused; | 
|  385     return; |  385   int delay; | 
 |  386   timing_->GetTimings(&unused, &unused, &unused, &unused, &delay, &unused, | 
 |  387                       &unused); | 
|  386  |  388  | 
|  387   int decode_ms; |  389   accumulated_delay_ += delay; | 
|  388   int max_decode_ms; |  390   ++accumulated_delay_samples_; | 
|  389   int current_delay_ms; |  391 } | 
|  390   int target_delay_ms; |  392  | 
|  391   int jitter_buffer_ms; |  393 void FrameBuffer::UpdateHistograms() const { | 
|  392   int min_playout_delay_ms; |  394   rtc::CritScope lock(&crit_); | 
|  393   int render_delay_ms; |  395   if (num_total_frames_ > 0) { | 
|  394   if (timing_->GetTimings(&decode_ms, &max_decode_ms, ¤t_delay_ms, |  396     int key_frames_permille = (static_cast<float>(num_key_frames_) * 1000.0f / | 
|  395                           &target_delay_ms, &jitter_buffer_ms, |  397                                    static_cast<float>(num_total_frames_) + | 
|  396                           &min_playout_delay_ms, &render_delay_ms)) { |  398                                0.5f); | 
|  397     stats_callback_->OnFrameBufferTimingsUpdated( |  399     RTC_HISTOGRAM_COUNTS_1000("WebRTC.Video.KeyFramesReceivedInPermille", | 
|  398         decode_ms, max_decode_ms, current_delay_ms, target_delay_ms, |  400                               key_frames_permille); | 
|  399         jitter_buffer_ms, min_playout_delay_ms, render_delay_ms); |  401   } | 
 |  402  | 
 |  403   if (accumulated_delay_samples_ > 0) { | 
 |  404     RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.JitterBufferDelayInMs", | 
 |  405                                accumulated_delay_ / accumulated_delay_samples_); | 
|  400   } |  406   } | 
|  401 } |  407 } | 
|  402  |  408  | 
|  403 void FrameBuffer::ClearFramesAndHistory() { |  409 void FrameBuffer::ClearFramesAndHistory() { | 
|  404   frames_.clear(); |  410   frames_.clear(); | 
|  405   last_decoded_frame_it_ = frames_.end(); |  411   last_decoded_frame_it_ = frames_.end(); | 
|  406   last_continuous_frame_it_ = frames_.end(); |  412   last_continuous_frame_it_ = frames_.end(); | 
|  407   num_frames_history_ = 0; |  413   num_frames_history_ = 0; | 
|  408   num_frames_buffered_ = 0; |  414   num_frames_buffered_ = 0; | 
|  409 } |  415 } | 
|  410  |  416  | 
|  411 }  // namespace video_coding |  417 }  // namespace video_coding | 
|  412 }  // namespace webrtc |  418 }  // namespace webrtc | 
| OLD | NEW |