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 15namespace webrtc 16{ 17 18// The first kIgnoredSampleCount samples will be ignored. 19static const int32_t kIgnoredSampleCount = 5; 20 21VCMCodecTimer::VCMCodecTimer() 22: 23_filteredMax(0), 24_ignoredSampleCount(0), 25_shortMax(0), 26_history() 27{ 28 Reset(); 29} 30 31int32_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 38void 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 51void 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 64void 65VCMCodecTimer::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 103void 104VCMCodecTimer::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 131int32_t VCMCodecTimer::RequiredDecodeTimeMs(FrameType /*frameType*/) const 132{ 133 return _filteredMax; 134} 135 136} 137