Home | History | Annotate | Download | only in source
      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