streamtools: refactor output/scaler drivers to their own directories
[jpcrr.git] / streamtools / timecounter.cpp
blobf041d90eb3301b87a3b8fb3457481a0c6682ae98
1 #include "timecounter.hpp"
2 #include <stdexcept>
3 #include <sstream>
5 timecounter::timecounter(const std::string& spec)
7 uint64_t base = 1000000000;
8 bool decimal = false;
9 uint64_t readfpu = 0;
11 if(!spec.length())
12 throw std::runtime_error("Empty fps spec is not legal");
14 for(size_t i = 0; i < spec.length(); i++) {
15 if(readfpu > 1844674407370955160ULL)
16 throw std::runtime_error("Overflow reading number");
17 if(!decimal)
18 if(spec[i] >= '0' && spec[i] <= '9')
19 readfpu = 10 * readfpu + (spec[i] - '0');
20 else if(spec[i] == '.')
21 decimal = true;
22 else {
23 std::stringstream str;
24 str << "Expected number or '.', got '" << spec[i] << "'";
25 throw std::runtime_error(str.str());
27 else
28 if(spec[i] >= '0' && spec[i] <= '9') {
29 if(base == 10000000000000000000ULL) {
30 std::stringstream str;
31 str << "fps number has more than 10 decimal digits";
32 throw std::runtime_error(str.str());
34 base *= 10;
35 readfpu = 10 * readfpu + (spec[i] - '0');
36 } else {
37 std::stringstream str;
38 str << "Expected number, got '" << spec[i] << "'";
39 throw std::runtime_error(str.str());
43 if(!readfpu)
44 throw std::runtime_error("0 is not valid fps value");
46 step_w = base / readfpu;
47 step_n = base % readfpu;
48 step_d = readfpu;
49 current_w = 0;
50 current_n = 0;
53 timecounter::timecounter(uint32_t spec)
55 if(spec > 0) {
56 step_w = 1000000000 / spec;
57 step_n = 1000000000 % spec;
58 step_d = spec;
59 } else {
60 step_w = step_n = 0;
61 step_d = 1;
63 current_w = 0;
64 current_n = 0;
67 timecounter::timecounter(uint32_t n, uint32_t d)
69 step_w = (1000000000ULL * d) / n;
70 step_n = (1000000000ULL * d) % n;
71 step_d = n;
72 current_w = 0;
73 current_n = 0;
76 timecounter::operator uint64_t()
78 return current_w;
81 timecounter& timecounter::operator++()
83 current_w += step_w;
84 current_n += step_n;
85 while(current_n >= step_d) {
86 current_n -= step_d;
87 current_w++;
89 return *this;
92 timecounter timecounter::operator++(int)
94 timecounter scratch = *this;
95 ++*this;
96 return scratch;