summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/api/video/video_timing.cc
blob: d16911fb5825b6a1a2e9d72d404f4bf3edadc7b9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/*
 *  Copyright (c) 2017 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 "api/video/video_timing.h"

#include <algorithm>

#include "api/array_view.h"
#include "api/units/time_delta.h"
#include "rtc_base/logging.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "rtc_base/strings/string_builder.h"

namespace webrtc {

uint16_t VideoSendTiming::GetDeltaCappedMs(int64_t base_ms, int64_t time_ms) {
  if (time_ms < base_ms) {
    RTC_DLOG(LS_ERROR) << "Delta " << (time_ms - base_ms)
                       << "ms expected to be positive";
  }
  return rtc::saturated_cast<uint16_t>(time_ms - base_ms);
}

uint16_t VideoSendTiming::GetDeltaCappedMs(TimeDelta delta) {
  if (delta < TimeDelta::Zero()) {
    RTC_DLOG(LS_ERROR) << "Delta " << delta.ms()
                       << "ms expected to be positive";
  }
  return rtc::saturated_cast<uint16_t>(delta.ms());
}

TimingFrameInfo::TimingFrameInfo()
    : rtp_timestamp(0),
      capture_time_ms(-1),
      encode_start_ms(-1),
      encode_finish_ms(-1),
      packetization_finish_ms(-1),
      pacer_exit_ms(-1),
      network_timestamp_ms(-1),
      network2_timestamp_ms(-1),
      receive_start_ms(-1),
      receive_finish_ms(-1),
      decode_start_ms(-1),
      decode_finish_ms(-1),
      render_time_ms(-1),
      flags(VideoSendTiming::kNotTriggered) {}

int64_t TimingFrameInfo::EndToEndDelay() const {
  return capture_time_ms >= 0 ? decode_finish_ms - capture_time_ms : -1;
}

bool TimingFrameInfo::IsLongerThan(const TimingFrameInfo& other) const {
  int64_t other_delay = other.EndToEndDelay();
  return other_delay == -1 || EndToEndDelay() > other_delay;
}

bool TimingFrameInfo::operator<(const TimingFrameInfo& other) const {
  return other.IsLongerThan(*this);
}

bool TimingFrameInfo::operator<=(const TimingFrameInfo& other) const {
  return !IsLongerThan(other);
}

bool TimingFrameInfo::IsOutlier() const {
  return !IsInvalid() && (flags & VideoSendTiming::kTriggeredBySize);
}

bool TimingFrameInfo::IsTimerTriggered() const {
  return !IsInvalid() && (flags & VideoSendTiming::kTriggeredByTimer);
}

bool TimingFrameInfo::IsInvalid() const {
  return flags == VideoSendTiming::kInvalid;
}

std::string TimingFrameInfo::ToString() const {
  if (IsInvalid()) {
    return "";
  }

  char buf[1024];
  rtc::SimpleStringBuilder sb(buf);

  sb << rtp_timestamp << ',' << capture_time_ms << ',' << encode_start_ms << ','
     << encode_finish_ms << ',' << packetization_finish_ms << ','
     << pacer_exit_ms << ',' << network_timestamp_ms << ','
     << network2_timestamp_ms << ',' << receive_start_ms << ','
     << receive_finish_ms << ',' << decode_start_ms << ',' << decode_finish_ms
     << ',' << render_time_ms << ',' << IsOutlier() << ','
     << IsTimerTriggered();

  return sb.str();
}

VideoPlayoutDelay::VideoPlayoutDelay(TimeDelta min, TimeDelta max)
    : min_(std::clamp(min, TimeDelta::Zero(), kMax)),
      max_(std::clamp(max, min_, kMax)) {
  if (!(TimeDelta::Zero() <= min && min <= max && max <= kMax)) {
    RTC_LOG(LS_ERROR) << "Invalid video playout delay: [" << min << "," << max
                      << "]. Clamped to [" << this->min() << "," << this->max()
                      << "]";
  }
}

bool VideoPlayoutDelay::Set(TimeDelta min, TimeDelta max) {
  if (TimeDelta::Zero() <= min && min <= max && max <= kMax) {
    min_ = min;
    max_ = max;
    return true;
  }
  return false;
}

}  // namespace webrtc