diff options
Diffstat (limited to 'webrtc/modules/video_coding/main/source/timing.cc')
-rw-r--r-- | webrtc/modules/video_coding/main/source/timing.cc | 279 |
1 files changed, 0 insertions, 279 deletions
diff --git a/webrtc/modules/video_coding/main/source/timing.cc b/webrtc/modules/video_coding/main/source/timing.cc deleted file mode 100644 index 8d59135876..0000000000 --- a/webrtc/modules/video_coding/main/source/timing.cc +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/video_coding/main/source/timing.h" - -#include "webrtc/modules/video_coding/main/source/internal_defines.h" -#include "webrtc/modules/video_coding/main/source/jitter_buffer_common.h" -#include "webrtc/system_wrappers/include/clock.h" -#include "webrtc/system_wrappers/include/metrics.h" -#include "webrtc/system_wrappers/include/timestamp_extrapolator.h" - - -namespace webrtc { - -VCMTiming::VCMTiming(Clock* clock, - VCMTiming* master_timing) - : crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), - clock_(clock), - master_(false), - ts_extrapolator_(), - codec_timer_(), - render_delay_ms_(kDefaultRenderDelayMs), - min_playout_delay_ms_(0), - jitter_delay_ms_(0), - current_delay_ms_(0), - last_decode_ms_(0), - prev_frame_timestamp_(0), - num_decoded_frames_(0), - num_delayed_decoded_frames_(0), - first_decoded_frame_ms_(-1), - sum_missed_render_deadline_ms_(0) { - if (master_timing == NULL) { - master_ = true; - ts_extrapolator_ = new TimestampExtrapolator(clock_->TimeInMilliseconds()); - } else { - ts_extrapolator_ = master_timing->ts_extrapolator_; - } -} - -VCMTiming::~VCMTiming() { - UpdateHistograms(); - if (master_) { - delete ts_extrapolator_; - } - delete crit_sect_; -} - -void VCMTiming::UpdateHistograms() const { - CriticalSectionScoped cs(crit_sect_); - if (num_decoded_frames_ == 0) { - return; - } - int64_t elapsed_sec = - (clock_->TimeInMilliseconds() - first_decoded_frame_ms_) / 1000; - if (elapsed_sec < metrics::kMinRunTimeInSeconds) { - return; - } - RTC_HISTOGRAM_COUNTS_100("WebRTC.Video.DecodedFramesPerSecond", - static_cast<int>((num_decoded_frames_ / elapsed_sec) + 0.5f)); - RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.DelayedFramesToRenderer", - num_delayed_decoded_frames_ * 100 / num_decoded_frames_); - if (num_delayed_decoded_frames_ > 0) { - RTC_HISTOGRAM_COUNTS_1000( - "WebRTC.Video.DelayedFramesToRenderer_AvgDelayInMs", - sum_missed_render_deadline_ms_ / num_delayed_decoded_frames_); - } -} - -void VCMTiming::Reset() { - CriticalSectionScoped cs(crit_sect_); - ts_extrapolator_->Reset(clock_->TimeInMilliseconds()); - codec_timer_.Reset(); - render_delay_ms_ = kDefaultRenderDelayMs; - min_playout_delay_ms_ = 0; - jitter_delay_ms_ = 0; - current_delay_ms_ = 0; - prev_frame_timestamp_ = 0; -} - -void VCMTiming::ResetDecodeTime() { - CriticalSectionScoped lock(crit_sect_); - codec_timer_.Reset(); -} - -void VCMTiming::set_render_delay(uint32_t render_delay_ms) { - CriticalSectionScoped cs(crit_sect_); - render_delay_ms_ = render_delay_ms; -} - -void VCMTiming::set_min_playout_delay(uint32_t min_playout_delay_ms) { - CriticalSectionScoped cs(crit_sect_); - min_playout_delay_ms_ = min_playout_delay_ms; -} - -void VCMTiming::SetJitterDelay(uint32_t jitter_delay_ms) { - CriticalSectionScoped cs(crit_sect_); - if (jitter_delay_ms != jitter_delay_ms_) { - jitter_delay_ms_ = jitter_delay_ms; - // When in initial state, set current delay to minimum delay. - if (current_delay_ms_ == 0) { - current_delay_ms_ = jitter_delay_ms_; - } - } -} - -void VCMTiming::UpdateCurrentDelay(uint32_t frame_timestamp) { - CriticalSectionScoped cs(crit_sect_); - uint32_t target_delay_ms = TargetDelayInternal(); - - if (current_delay_ms_ == 0) { - // Not initialized, set current delay to target. - current_delay_ms_ = target_delay_ms; - } else if (target_delay_ms != current_delay_ms_) { - int64_t delay_diff_ms = static_cast<int64_t>(target_delay_ms) - - current_delay_ms_; - // Never change the delay with more than 100 ms every second. If we're - // changing the delay in too large steps we will get noticeable freezes. By - // limiting the change we can increase the delay in smaller steps, which - // will be experienced as the video is played in slow motion. When lowering - // the delay the video will be played at a faster pace. - int64_t max_change_ms = 0; - if (frame_timestamp < 0x0000ffff && prev_frame_timestamp_ > 0xffff0000) { - // wrap - max_change_ms = kDelayMaxChangeMsPerS * (frame_timestamp + - (static_cast<int64_t>(1) << 32) - prev_frame_timestamp_) / 90000; - } else { - max_change_ms = kDelayMaxChangeMsPerS * - (frame_timestamp - prev_frame_timestamp_) / 90000; - } - if (max_change_ms <= 0) { - // Any changes less than 1 ms are truncated and - // will be postponed. Negative change will be due - // to reordering and should be ignored. - return; - } - delay_diff_ms = std::max(delay_diff_ms, -max_change_ms); - delay_diff_ms = std::min(delay_diff_ms, max_change_ms); - - current_delay_ms_ = current_delay_ms_ + static_cast<int32_t>(delay_diff_ms); - } - prev_frame_timestamp_ = frame_timestamp; -} - -void VCMTiming::UpdateCurrentDelay(int64_t render_time_ms, - int64_t actual_decode_time_ms) { - CriticalSectionScoped cs(crit_sect_); - uint32_t target_delay_ms = TargetDelayInternal(); - int64_t delayed_ms = actual_decode_time_ms - - (render_time_ms - MaxDecodeTimeMs() - render_delay_ms_); - if (delayed_ms < 0) { - return; - } - if (current_delay_ms_ + delayed_ms <= target_delay_ms) { - current_delay_ms_ += static_cast<uint32_t>(delayed_ms); - } else { - current_delay_ms_ = target_delay_ms; - } -} - -int32_t VCMTiming::StopDecodeTimer(uint32_t time_stamp, - int64_t start_time_ms, - int64_t now_ms, - int64_t render_time_ms) { - CriticalSectionScoped cs(crit_sect_); - int32_t time_diff_ms = codec_timer_.StopTimer(start_time_ms, now_ms); - assert(time_diff_ms >= 0); - last_decode_ms_ = time_diff_ms; - - // Update stats. - ++num_decoded_frames_; - if (num_decoded_frames_ == 1) { - first_decoded_frame_ms_ = now_ms; - } - int time_until_rendering_ms = render_time_ms - render_delay_ms_ - now_ms; - if (time_until_rendering_ms < 0) { - sum_missed_render_deadline_ms_ += -time_until_rendering_ms; - ++num_delayed_decoded_frames_; - } - return 0; -} - -void VCMTiming::IncomingTimestamp(uint32_t time_stamp, int64_t now_ms) { - CriticalSectionScoped cs(crit_sect_); - ts_extrapolator_->Update(now_ms, time_stamp); -} - -int64_t VCMTiming::RenderTimeMs(uint32_t frame_timestamp, int64_t now_ms) - const { - CriticalSectionScoped cs(crit_sect_); - const int64_t render_time_ms = RenderTimeMsInternal(frame_timestamp, now_ms); - return render_time_ms; -} - -int64_t VCMTiming::RenderTimeMsInternal(uint32_t frame_timestamp, - int64_t now_ms) const { - int64_t estimated_complete_time_ms = - ts_extrapolator_->ExtrapolateLocalTime(frame_timestamp); - if (estimated_complete_time_ms == -1) { - estimated_complete_time_ms = now_ms; - } - - // Make sure that we have at least the playout delay. - uint32_t actual_delay = std::max(current_delay_ms_, min_playout_delay_ms_); - return estimated_complete_time_ms + actual_delay; -} - -// Must be called from inside a critical section. -int32_t VCMTiming::MaxDecodeTimeMs(FrameType frame_type /*= kVideoFrameDelta*/) - const { - const int32_t decode_time_ms = codec_timer_.RequiredDecodeTimeMs(frame_type); - assert(decode_time_ms >= 0); - return decode_time_ms; -} - -uint32_t VCMTiming::MaxWaitingTime(int64_t render_time_ms, int64_t now_ms) - const { - CriticalSectionScoped cs(crit_sect_); - - const int64_t max_wait_time_ms = render_time_ms - now_ms - - MaxDecodeTimeMs() - render_delay_ms_; - - if (max_wait_time_ms < 0) { - return 0; - } - return static_cast<uint32_t>(max_wait_time_ms); -} - -bool VCMTiming::EnoughTimeToDecode(uint32_t available_processing_time_ms) - const { - CriticalSectionScoped cs(crit_sect_); - int32_t max_decode_time_ms = MaxDecodeTimeMs(); - if (max_decode_time_ms < 0) { - // Haven't decoded any frames yet, try decoding one to get an estimate - // of the decode time. - return true; - } else if (max_decode_time_ms == 0) { - // Decode time is less than 1, set to 1 for now since - // we don't have any better precision. Count ticks later? - max_decode_time_ms = 1; - } - return static_cast<int32_t>(available_processing_time_ms) - - max_decode_time_ms > 0; -} - -uint32_t VCMTiming::TargetVideoDelay() const { - CriticalSectionScoped cs(crit_sect_); - return TargetDelayInternal(); -} - -uint32_t VCMTiming::TargetDelayInternal() const { - return std::max(min_playout_delay_ms_, - jitter_delay_ms_ + MaxDecodeTimeMs() + render_delay_ms_); -} - -void VCMTiming::GetTimings(int* decode_ms, - int* max_decode_ms, - int* current_delay_ms, - int* target_delay_ms, - int* jitter_buffer_ms, - int* min_playout_delay_ms, - int* render_delay_ms) const { - CriticalSectionScoped cs(crit_sect_); - *decode_ms = last_decode_ms_; - *max_decode_ms = MaxDecodeTimeMs(); - *current_delay_ms = current_delay_ms_; - *target_delay_ms = TargetDelayInternal(); - *jitter_buffer_ms = jitter_delay_ms_; - *min_playout_delay_ms = min_playout_delay_ms_; - *render_delay_ms = render_delay_ms_; -} - -} // namespace webrtc |