• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3  *
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
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "webrtc/modules/video_coding/main/source/codec_timer.h"
12 
13 #include <assert.h>
14 
15 namespace webrtc
16 {
17 
18 // The first kIgnoredSampleCount samples will be ignored.
19 static const int32_t kIgnoredSampleCount = 5;
20 
VCMCodecTimer()21 VCMCodecTimer::VCMCodecTimer()
22 :
23 _filteredMax(0),
24 _ignoredSampleCount(0),
25 _shortMax(0),
26 _history()
27 {
28     Reset();
29 }
30 
StopTimer(int64_t startTimeMs,int64_t nowMs)31 int32_t VCMCodecTimer::StopTimer(int64_t startTimeMs, int64_t nowMs)
32 {
33     const int32_t timeDiff = static_cast<int32_t>(nowMs - startTimeMs);
34     MaxFilter(timeDiff, nowMs);
35     return timeDiff;
36 }
37 
Reset()38 void VCMCodecTimer::Reset()
39 {
40     _filteredMax = 0;
41     _ignoredSampleCount = 0;
42     _shortMax = 0;
43     for (int i=0; i < MAX_HISTORY_SIZE; i++)
44     {
45         _history[i].shortMax = 0;
46         _history[i].timeMs = -1;
47     }
48 }
49 
50 // Update the max-value filter
MaxFilter(int32_t decodeTime,int64_t nowMs)51 void VCMCodecTimer::MaxFilter(int32_t decodeTime, int64_t nowMs)
52 {
53     if (_ignoredSampleCount >= kIgnoredSampleCount)
54     {
55         UpdateMaxHistory(decodeTime, nowMs);
56         ProcessHistory(nowMs);
57     }
58     else
59     {
60         _ignoredSampleCount++;
61     }
62 }
63 
64 void
UpdateMaxHistory(int32_t decodeTime,int64_t now)65 VCMCodecTimer::UpdateMaxHistory(int32_t decodeTime, int64_t now)
66 {
67     if (_history[0].timeMs >= 0 &&
68         now - _history[0].timeMs < SHORT_FILTER_MS)
69     {
70         if (decodeTime > _shortMax)
71         {
72             _shortMax = decodeTime;
73         }
74     }
75     else
76     {
77         // Only add a new value to the history once a second
78         if(_history[0].timeMs == -1)
79         {
80             // First, no shift
81             _shortMax = decodeTime;
82         }
83         else
84         {
85             // Shift
86             for(int i = (MAX_HISTORY_SIZE - 2); i >= 0 ; i--)
87             {
88                 _history[i+1].shortMax = _history[i].shortMax;
89                 _history[i+1].timeMs = _history[i].timeMs;
90             }
91         }
92         if (_shortMax == 0)
93         {
94             _shortMax = decodeTime;
95         }
96 
97         _history[0].shortMax = _shortMax;
98         _history[0].timeMs = now;
99         _shortMax = 0;
100     }
101 }
102 
103 void
ProcessHistory(int64_t nowMs)104 VCMCodecTimer::ProcessHistory(int64_t nowMs)
105 {
106     _filteredMax = _shortMax;
107     if (_history[0].timeMs == -1)
108     {
109         return;
110     }
111     for (int i=0; i < MAX_HISTORY_SIZE; i++)
112     {
113         if (_history[i].timeMs == -1)
114         {
115             break;
116         }
117         if (nowMs - _history[i].timeMs > MAX_HISTORY_SIZE * SHORT_FILTER_MS)
118         {
119             // This sample (and all samples after this) is too old
120             break;
121         }
122         if (_history[i].shortMax > _filteredMax)
123         {
124             // This sample is the largest one this far into the history
125             _filteredMax = _history[i].shortMax;
126         }
127     }
128 }
129 
130 // Get the maximum observed time within a time window
RequiredDecodeTimeMs(FrameType) const131 int32_t VCMCodecTimer::RequiredDecodeTimeMs(FrameType /*frameType*/) const
132 {
133     return _filteredMax;
134 }
135 
136 }
137