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 21 VCMCodecTimer::VCMCodecTimer() 22 : 23 _filteredMax(0), 24 _ignoredSampleCount(0), 25 _shortMax(0), 26 _history() 27 { 28 Reset(); 29 } 30 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 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 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 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 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 131 int32_t VCMCodecTimer::RequiredDecodeTimeMs(FrameType /*frameType*/) const 132 { 133 return _filteredMax; 134 } 135 136 } 137