]> git.sesse.net Git - nageru/blob - disk_space_estimator.cpp
Various Makefile tweaks (mostly related to cleaning moc files).
[nageru] / disk_space_estimator.cpp
1 #include "disk_space_estimator.h"
2
3 #include <stdio.h>
4 #include <sys/stat.h>
5 #include <sys/statfs.h>
6 #include <memory>
7
8 #include "timebase.h"
9
10 DiskSpaceEstimator::DiskSpaceEstimator(DiskSpaceEstimator::callback_t callback)
11         : callback(callback)
12 {
13 }
14
15 void DiskSpaceEstimator::report_write(const std::string &filename, uint64_t pts)
16 {
17         if (filename != last_filename) {
18                 last_filename = filename;
19                 measure_points.clear();
20         }
21
22         // Reject points that are out-of-order (happens with B-frames).
23         if (!measure_points.empty() && pts < measure_points.back().pts) {
24                 return;
25         }
26
27         // Remove too old points.
28         while (measure_points.size() > 1 && measure_points.front().pts + window_length < pts) {
29                 measure_points.pop_front();
30         }
31
32         struct stat st;
33         if (stat(filename.c_str(), &st) == -1) {
34                 perror(filename.c_str());
35                 return;
36         }
37
38         struct statfs fst;
39         if (statfs(filename.c_str(), &fst) == -1) {
40                 perror(filename.c_str());
41                 return;
42         }
43
44         if (!measure_points.empty()) {
45                 off_t free_bytes = off_t(fst.f_bavail) * fst.f_frsize;
46                 double bytes_per_second = double(st.st_size - measure_points.front().size) /
47                         (pts - measure_points.front().pts) * TIMEBASE;
48                 double seconds_left = free_bytes / bytes_per_second;
49                 callback(free_bytes, seconds_left);
50         }
51
52         measure_points.push_back({ pts, st.st_size });
53 }
54
55 DiskSpaceEstimator *global_disk_space_estimator = nullptr;  // Created in MainWindow::MainWindow().