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