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