]> git.sesse.net Git - nageru/blob - shared/disk_space_estimator.h
163b7efd555dd81ac2df84a5fc8591f63b393673
[nageru] / shared / disk_space_estimator.h
1 #ifndef _DISK_SPACE_ESTIMATOR_H
2 #define _DISK_SPACE_ESTIMATOR_H
3
4 // A class responsible for measuring how much disk there is left when we
5 // store our video to disk, and how much recording time that equates to.
6 // It gets callbacks from the Mux writing the stream to disk (which also
7 // knows which filesystem the file is going to), makes its calculations,
8 // and calls back to the MainWindow, which shows it to the user.
9 //
10 // The bitrate is measured over a simple 30-second sliding window.
11
12 #include <atomic>
13 #include <deque>
14 #include <functional>
15 #include <stdint.h>
16 #include <string>
17 #include <sys/types.h>
18
19 #include "shared/timebase.h"
20
21 class DiskSpaceEstimator {
22 public:
23         typedef std::function<void(off_t free_bytes, double estimated_seconds_left)> callback_t;
24         DiskSpaceEstimator(callback_t callback);
25
26         // Report that a video frame with the given pts and size has just been
27         // written (possibly appended) to the given file.
28         //
29         // <pts> is taken to be in TIMEBASE units (see shared/timebase.h).
30         void report_write(const std::string &filename, off_t bytes, uint64_t pts);
31
32         // Report that a video frame with the given pts has just been written
33         // to the given file, so the estimator should stat the file and see
34         // by how much it grew since last time. Called by the Mux object
35         // responsible for writing to the stream on disk.
36         //
37         // If the filename changed since last time, the estimation is reset.
38         // <pts> is taken to be in TIMEBASE units (see shared/timebase.h).
39         //
40         // You should probably not mix this and report_write() on the same
41         // object. Really, report_write() matches Futatabi's controlled writes
42         // to a custom format, and report_append() matches Nageru's use of Mux
43         // (where we don't see the bytes flowing past).
44         void report_append(const std::string &filename, uint64_t pts);
45
46 private:
47         static constexpr int64_t window_length = 30 * TIMEBASE;
48
49         void report_write_internal(const std::string &filename, off_t file_size, uint64_t pts);
50
51         callback_t callback;
52
53         struct MeasurePoint {
54                 uint64_t pts;
55                 off_t size;
56         };
57         std::deque<MeasurePoint> measure_points;
58         uint64_t last_pts_reported = 0;
59
60         off_t total_size = 0;  // For report_write().
61         std::string last_filename;  // For report_append().
62
63         // Metrics.
64         std::atomic<int64_t> metric_disk_free_bytes{-1};
65 };
66
67 extern DiskSpaceEstimator *global_disk_space_estimator;
68
69 #endif  // !defined(_DISK_SPACE_ESTIMATOR_H)