Line data Source code
1 : /* 2 : * Copyright(c) 2019 Intel Corporation 3 : * SPDX - License - Identifier: BSD - 2 - Clause - Patent 4 : */ 5 : 6 : #include <stdint.h> 7 : 8 : #ifndef __USE_POSIX199309 9 : #define __USE_POSIX199309 10 : #endif 11 : #include <time.h> 12 : #include <stdio.h> 13 : 14 : #ifdef _WIN32 15 : #include <windows.h> 16 : #else 17 : #include <sys/time.h> 18 : #endif 19 : 20 : #include "EbTime.h" 21 : 22 : #if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC__) 23 : __attribute__((optimize("unroll-loops"))) 24 : #endif 25 : 26 4 : void StartTime(uint64_t *Startseconds, uint64_t *Startuseconds) { 27 : #ifdef _WIN32 28 : *Startseconds = (uint64_t)clock(); 29 : (void)(*Startuseconds); 30 : #else 31 : struct timeval start; 32 4 : gettimeofday(&start, NULL); 33 4 : *Startseconds = start.tv_sec; 34 4 : *Startuseconds = start.tv_usec; 35 : #endif 36 4 : } 37 : 38 120 : void FinishTime(uint64_t *Finishseconds, uint64_t *Finishuseconds) { 39 : #ifdef _WIN32 40 : *Finishseconds = (uint64_t)clock(); 41 : (void)(*Finishuseconds); 42 : #else 43 : struct timeval finish; 44 120 : gettimeofday(&finish, NULL); 45 120 : *Finishseconds = finish.tv_sec; 46 120 : *Finishuseconds = finish.tv_usec; 47 : #endif 48 120 : } 49 : 50 240 : void ComputeOverallElapsedTime(uint64_t Startseconds, uint64_t Startuseconds, uint64_t Finishseconds, uint64_t Finishuseconds, double *duration) 51 : { 52 : #ifdef _WIN32 53 : //double duration; 54 : *duration = (double)(Finishseconds - Startseconds) / CLOCKS_PER_SEC; 55 : (void)(Startuseconds); 56 : (void)(Finishuseconds); 57 : #else 58 : long mtime, seconds, useconds; 59 240 : seconds = Finishseconds - Startseconds; 60 240 : useconds = Finishuseconds - Startuseconds; 61 240 : mtime = ((seconds) * 1000 + useconds / 1000.0) + 0.5; 62 240 : *duration = (double)mtime / 1000; 63 : #endif 64 240 : } 65 : 66 0 : void ComputeOverallElapsedTimeMs(uint64_t Startseconds, uint64_t Startuseconds, uint64_t Finishseconds, uint64_t Finishuseconds, double *duration) 67 : { 68 : #ifdef _WIN32 69 : //double duration; 70 : *duration = (double)(Finishseconds - Startseconds); 71 : (void)(Startuseconds); 72 : (void)(Finishuseconds); 73 : #else 74 : long mtime, seconds, useconds; 75 0 : seconds = Finishseconds - Startseconds; 76 0 : useconds = Finishuseconds - Startuseconds; 77 0 : mtime = ((seconds) * 1000 + useconds / 1000.0) + 0.5; 78 0 : *duration = (double)mtime; 79 : #endif 80 0 : } 81 : 82 0 : static void SleepMs(uint64_t milliSeconds) 83 : { 84 0 : if(milliSeconds) { 85 : #ifdef _WIN32 86 : Sleep((DWORD) milliSeconds); 87 : #else 88 : struct timespec req,rem; 89 0 : req.tv_sec=(int32_t)(milliSeconds/1000); 90 0 : milliSeconds -= req.tv_sec * 1000; 91 0 : req.tv_nsec = milliSeconds * 1000000UL; 92 0 : nanosleep(&req,&rem); 93 : #endif 94 : } 95 0 : } 96 : 97 0 : void Injector(uint64_t processed_frame_count, 98 : uint32_t injector_frame_rate) 99 : { 100 : #ifdef _WIN32 101 : static LARGE_INTEGER startCount; // this is the start time 102 : static LARGE_INTEGER counterFreq; // performance counter frequency 103 : LARGE_INTEGER nowCount; // this is the current time 104 : #else 105 0 : uint64_t currentTimesSeconds = 0; 106 0 : uint64_t currentTimesuSeconds = 0; 107 : static uint64_t startTimesSeconds; 108 : static uint64_t startTimesuSeconds; 109 : #endif 110 : 111 0 : double injectorInterval = (double)(1<<16)/(double)injector_frame_rate; // 1.0 / injector frame rate (in this case, 1.0/encodRate) 112 : double elapsedTime; 113 : double predictedTime; 114 0 : int32_t bufferFrames = 1; // How far ahead of time should we let it get 115 : int32_t milliSecAhead; 116 : static int32_t firstTime = 0; 117 : 118 0 : if (firstTime == 0) 119 : { 120 0 : firstTime = 1; 121 : 122 : #ifdef _WIN32 123 : QueryPerformanceFrequency(&counterFreq); 124 : QueryPerformanceCounter(&startCount); 125 : #else 126 0 : StartTime((uint64_t*)&startTimesSeconds, (uint64_t*)&startTimesuSeconds); 127 : #endif 128 : } 129 : else 130 : { 131 : #ifdef _WIN32 132 : QueryPerformanceCounter(&nowCount); 133 : elapsedTime = (double)(nowCount.QuadPart - startCount.QuadPart) / (double)counterFreq.QuadPart; 134 : #else 135 0 : FinishTime((uint64_t*)¤tTimesSeconds, (uint64_t*)¤tTimesuSeconds); 136 0 : ComputeOverallElapsedTime(startTimesSeconds, startTimesuSeconds, currentTimesSeconds, currentTimesuSeconds, &elapsedTime); 137 : #endif 138 : 139 0 : predictedTime = (processed_frame_count - bufferFrames) * injectorInterval; 140 0 : milliSecAhead = (int32_t)(1000 * (predictedTime - elapsedTime )); 141 0 : if (milliSecAhead>0) { 142 : // timeBeginPeriod(1); 143 0 : SleepMs(milliSecAhead); 144 : // timeEndPeriod (1); 145 : } 146 : } 147 0 : }