]> git.sesse.net Git - nageru/commitdiff
Unify disk_space_estimator.cpp from Nageru and Futatabi.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Mon, 3 Dec 2018 19:03:40 +0000 (20:03 +0100)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Mon, 3 Dec 2018 19:03:40 +0000 (20:03 +0100)
12 files changed:
futatabi/disk_space_estimator.cpp [deleted file]
futatabi/disk_space_estimator.h [deleted file]
futatabi/main.cpp
futatabi/mainwindow.cpp
futatabi/meson.build
nageru/mainwindow.cpp
nageru/meson.build
nageru/mixer.cpp
nageru/quicksync_encoder.cpp
shared/disk_space_estimator.cpp [moved from nageru/disk_space_estimator.cpp with 68% similarity]
shared/disk_space_estimator.h [moved from nageru/disk_space_estimator.h with 65% similarity]
shared/meson.build

diff --git a/futatabi/disk_space_estimator.cpp b/futatabi/disk_space_estimator.cpp
deleted file mode 100644 (file)
index 073e57e..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-#include "disk_space_estimator.h"
-
-#include "shared/timebase.h"
-
-#include <memory>
-#include <stdio.h>
-#include <sys/stat.h>
-#include <sys/statfs.h>
-
-DiskSpaceEstimator::DiskSpaceEstimator(DiskSpaceEstimator::callback_t callback)
-       : callback(callback)
-{
-}
-
-void DiskSpaceEstimator::report_write(const std::string &filename, size_t bytes, uint64_t pts)
-{
-       // Reject points that are out-of-order (happens with B-frames).
-       if (!measure_points.empty() && pts <= measure_points.back().pts) {
-               return;
-       }
-
-       // Remove too old points.
-       while (measure_points.size() > 1 && measure_points.front().pts + window_length < pts) {
-               measure_points.pop_front();
-       }
-
-       total_size += bytes;
-
-       struct statfs fst;
-       if (statfs(filename.c_str(), &fst) == -1) {
-               perror(filename.c_str());
-               return;
-       }
-
-       off_t free_bytes = off_t(fst.f_bavail) * fst.f_frsize;
-
-       if (!measure_points.empty()) {
-               double bytes_per_second = double(total_size - measure_points.front().size) /
-                       (pts - measure_points.front().pts) * TIMEBASE;
-               double seconds_left = free_bytes / bytes_per_second;
-
-               // Only report every second, since updating the UI can be expensive.
-               if (last_pts_reported == 0 || pts - last_pts_reported >= TIMEBASE) {
-                       callback(free_bytes, seconds_left);
-                       last_pts_reported = pts;
-               }
-       }
-
-       measure_points.push_back({ pts, total_size });
-}
-
-DiskSpaceEstimator *global_disk_space_estimator = nullptr;  // Created in MainWindow::MainWindow().
diff --git a/futatabi/disk_space_estimator.h b/futatabi/disk_space_estimator.h
deleted file mode 100644 (file)
index e4b2c51..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef _DISK_SPACE_ESTIMATOR_H
-#define _DISK_SPACE_ESTIMATOR_H
-
-// A class responsible for measuring how much disk there is left when we
-// store our video to disk, and how much recording time that equates to.
-// It gets callbacks from the Mux writing the stream to disk (which also
-// knows which filesystem the file is going to), makes its calculations,
-// and calls back to the MainWindow, which shows it to the user.
-//
-// The bitrate is measured over a simple 30-second sliding window.
-
-#include "shared/timebase.h"
-
-#include <deque>
-#include <functional>
-#include <stdint.h>
-#include <string>
-#include <sys/types.h>
-
-class DiskSpaceEstimator {
-public:
-       typedef std::function<void(off_t free_bytes, double estimated_seconds_left)> callback_t;
-       DiskSpaceEstimator(callback_t callback);
-
-       // Report that a video frame with the given pts and size has just been
-       // written (possibly appended) to the given file.
-       //
-       // <pts> is taken to be in TIMEBASE units (see shared/timebase.h).
-       void report_write(const std::string &filename, size_t bytes, uint64_t pts);
-
-private:
-       static constexpr int64_t window_length = 30 * TIMEBASE;
-
-       callback_t callback;
-
-       struct MeasurePoint {
-               uint64_t pts;
-               off_t size;
-       };
-       std::deque<MeasurePoint> measure_points;
-       uint64_t last_pts_reported = 0;
-       off_t total_size = 0;
-};
-
-extern DiskSpaceEstimator *global_disk_space_estimator;
-
-#endif  // !defined(_DISK_SPACE_ESTIMATOR_H)
index 46fb200eb149f47eba370d7a23697d992eda463d..f6d2ab12b6693a32d3fcfb6ab7f5556fc1dcbf7b 100644 (file)
@@ -22,7 +22,7 @@ extern "C" {
 #include "clip_list.h"
 #include "shared/context.h"
 #include "defs.h"
-#include "disk_space_estimator.h"
+#include "shared/disk_space_estimator.h"
 #include "shared/ffmpeg_raii.h"
 #include "flags.h"
 #include "frame_on_disk.h"
index 85a86a8a6f7bf5e2e6a621ddfbeacd97d2d646f9..2a05a24428a3774c76bfb04b67079e85e0c9f4d6 100644 (file)
@@ -1,7 +1,7 @@
 #include "mainwindow.h"
 
 #include "clip_list.h"
-#include "disk_space_estimator.h"
+#include "shared/disk_space_estimator.h"
 #include "flags.h"
 #include "frame_on_disk.h"
 #include "player.h"
index aa58291db76d66ec2e67a7d85ffda9e93a8b6dc9..55611e819effa9ea6e3f3ec5cedb75cf3ec9dec2 100644 (file)
@@ -34,7 +34,7 @@ srcs = ['flow.cpp', 'gpu_timers.cpp']
 
 # All the other files.
 srcs += ['main.cpp', 'player.cpp', 'video_stream.cpp', 'chroma_subsampler.cpp']
-srcs += ['vaapi_jpeg_decoder.cpp', 'db.cpp', 'disk_space_estimator.cpp', 'ycbcr_converter.cpp', 'flags.cpp']
+srcs += ['vaapi_jpeg_decoder.cpp', 'db.cpp', 'ycbcr_converter.cpp', 'flags.cpp']
 srcs += ['mainwindow.cpp', 'jpeg_frame_view.cpp', 'clip_list.cpp', 'frame_on_disk.cpp']
 srcs += moc_files
 srcs += proto_generated
index 05e41eb099bd1c1a0c42eb28ea8e6c980ce65c78..11e63913ea59734e9831ef5e625be3154020f704 100644 (file)
@@ -50,7 +50,7 @@
 #include "clickable_label.h"
 #include "context_menus.h"
 #include "correlation_meter.h"
-#include "disk_space_estimator.h"
+#include "shared/disk_space_estimator.h"
 #include "ellipsis_label.h"
 #include "flags.h"
 #include "glwidget.h"
index 737d889cbe30bc6ec6ef3f3bc827e6dda399d4f3..58a8feb1d4789216628e7483f1bcd0acb1676c41 100644 (file)
@@ -161,7 +161,7 @@ nageru_link_with += audio
 # Mixer objects.
 srcs += ['chroma_subsampler.cpp', 'v210_converter.cpp', 'mixer.cpp', 'pbo_frame_allocator.cpp',
        'theme.cpp', 'image_input.cpp', 'alsa_output.cpp',
-       'disk_space_estimator.cpp', 'timecode_renderer.cpp', 'tweaked_inputs.cpp']
+       'timecode_renderer.cpp', 'tweaked_inputs.cpp']
 
 # Streaming and encoding objects (largely the set that is shared between Nageru and Kaeru).
 stream_srcs = ['quicksync_encoder.cpp', 'x264_encoder.cpp', 'x264_dynamic.cpp', 'x264_speed_control.cpp', 'video_encoder.cpp',
index 3a5783ba0c46c3316808e843212d0328cc1cdb98..0d782e8d8758674e033b867353041bb7598118b1 100644 (file)
@@ -41,7 +41,7 @@
 #include "decklink_capture.h"
 #include "decklink_output.h"
 #include "defs.h"
-#include "disk_space_estimator.h"
+#include "shared/disk_space_estimator.h"
 #include "ffmpeg_capture.h"
 #include "flags.h"
 #include "input_mapping.h"
index ded20f65e5d9fc09b8ba94bf1561cca3fa1ed27d..9723118a7c3efaeab12ffdb5af3c1e9e84265093 100644 (file)
@@ -47,7 +47,7 @@ extern "C" {
 #include "audio_encoder.h"
 #include "shared/context.h"
 #include "defs.h"
-#include "disk_space_estimator.h"
+#include "shared/disk_space_estimator.h"
 #include "shared/ffmpeg_raii.h"
 #include "flags.h"
 #include "shared/mux.h"
@@ -1814,7 +1814,7 @@ void QuickSyncEncoderImpl::open_output_file(const std::string &filename)
                lock_guard<mutex> lock(file_audio_encoder_mutex);
                AVCodecParametersWithDeleter audio_codecpar = file_audio_encoder->get_codec_parameters();
                file_mux.reset(new Mux(avctx, frame_width, frame_height, Mux::CODEC_H264, video_extradata, audio_codecpar.get(), get_color_space(global_flags.ycbcr_rec709_coefficients), Mux::WITH_AUDIO, TIMEBASE,
-                       std::bind(&DiskSpaceEstimator::report_write, disk_space_estimator, filename, _1),
+                       std::bind(&DiskSpaceEstimator::report_append, disk_space_estimator, filename, _1),
                        Mux::WRITE_BACKGROUND,
                        { &current_file_mux_metrics, &total_mux_metrics }));
        }
similarity index 68%
rename from nageru/disk_space_estimator.cpp
rename to shared/disk_space_estimator.cpp
index 42fdfc24a04647d36b79dbc848d2f65000e4c3eb..da55ee1e46b5018a0f8e381752bf661e55c11cc1 100644 (file)
@@ -1,28 +1,47 @@
-#include "disk_space_estimator.h"
+#include "shared/disk_space_estimator.h"
 
+#include <memory>
 #include <stdio.h>
 #include <sys/stat.h>
 #include <sys/statfs.h>
-#include <memory>
 
 #include "shared/metrics.h"
 #include "shared/timebase.h"
 
+using namespace std;
+
 DiskSpaceEstimator::DiskSpaceEstimator(DiskSpaceEstimator::callback_t callback)
        : callback(callback)
 {
        global_metrics.add("disk_free_bytes", &metric_disk_free_bytes, Metrics::TYPE_GAUGE);
 }
 
-void DiskSpaceEstimator::report_write(const std::string &filename, uint64_t pts)
+void DiskSpaceEstimator::report_write(const string &filename, off_t bytes, uint64_t pts)
+{
+       total_size += bytes;
+       report_write_internal(filename, total_size, pts);
+}
+
+void DiskSpaceEstimator::report_append(const string &filename, uint64_t pts)
 {
        if (filename != last_filename) {
                last_filename = filename;
                measure_points.clear();
        }
 
+       struct stat st;
+       if (stat(filename.c_str(), &st) == -1) {
+               perror(filename.c_str());
+               return;
+       }
+
+       report_write_internal(filename, st.st_size, pts);
+}
+
+void DiskSpaceEstimator::report_write_internal(const string &filename, off_t file_size, uint64_t pts)
+{
        // Reject points that are out-of-order (happens with B-frames).
-       if (!measure_points.empty() && pts < measure_points.back().pts) {
+       if (!measure_points.empty() && pts <= measure_points.back().pts) {
                return;
        }
 
@@ -31,12 +50,6 @@ void DiskSpaceEstimator::report_write(const std::string &filename, uint64_t pts)
                measure_points.pop_front();
        }
 
-       struct stat st;
-       if (stat(filename.c_str(), &st) == -1) {
-               perror(filename.c_str());
-               return;
-       }
-
        struct statfs fst;
        if (statfs(filename.c_str(), &fst) == -1) {
                perror(filename.c_str());
@@ -47,7 +60,7 @@ void DiskSpaceEstimator::report_write(const std::string &filename, uint64_t pts)
        metric_disk_free_bytes = free_bytes;
 
        if (!measure_points.empty()) {
-               double bytes_per_second = double(st.st_size - measure_points.front().size) /
+               double bytes_per_second = double(file_size - measure_points.front().size) /
                        (pts - measure_points.front().pts) * TIMEBASE;
                double seconds_left = free_bytes / bytes_per_second;
 
@@ -58,7 +71,7 @@ void DiskSpaceEstimator::report_write(const std::string &filename, uint64_t pts)
                }
        }
 
-       measure_points.push_back({ pts, st.st_size });
+       measure_points.push_back({ pts, file_size });
 }
 
 DiskSpaceEstimator *global_disk_space_estimator = nullptr;  // Created in MainWindow::MainWindow().
similarity index 65%
rename from nageru/disk_space_estimator.h
rename to shared/disk_space_estimator.h
index ce81321638e2350adc9626d2d347fa8c3daa0b2e..163b7efd555dd81ac2df84a5fc8591f63b393673 100644 (file)
@@ -9,21 +9,26 @@
 //
 // The bitrate is measured over a simple 30-second sliding window.
 
-#include <stdint.h>
-#include <sys/types.h>
 #include <atomic>
 #include <deque>
 #include <functional>
+#include <stdint.h>
 #include <string>
+#include <sys/types.h>
 
 #include "shared/timebase.h"
 
-class DiskSpaceEstimator
-{
+class DiskSpaceEstimator {
 public:
        typedef std::function<void(off_t free_bytes, double estimated_seconds_left)> callback_t;
        DiskSpaceEstimator(callback_t callback);
 
+       // Report that a video frame with the given pts and size has just been
+       // written (possibly appended) to the given file.
+       //
+       // <pts> is taken to be in TIMEBASE units (see shared/timebase.h).
+       void report_write(const std::string &filename, off_t bytes, uint64_t pts);
+
        // Report that a video frame with the given pts has just been written
        // to the given file, so the estimator should stat the file and see
        // by how much it grew since last time. Called by the Mux object
@@ -31,13 +36,19 @@ public:
        //
        // If the filename changed since last time, the estimation is reset.
        // <pts> is taken to be in TIMEBASE units (see shared/timebase.h).
-       void report_write(const std::string &filename, uint64_t pts);
+       //
+       // You should probably not mix this and report_write() on the same
+       // object. Really, report_write() matches Futatabi's controlled writes
+       // to a custom format, and report_append() matches Nageru's use of Mux
+       // (where we don't see the bytes flowing past).
+       void report_append(const std::string &filename, uint64_t pts);
 
 private:
        static constexpr int64_t window_length = 30 * TIMEBASE;
 
+       void report_write_internal(const std::string &filename, off_t file_size, uint64_t pts);
+
        callback_t callback;
-       std::string last_filename;
 
        struct MeasurePoint {
                uint64_t pts;
@@ -46,6 +57,9 @@ private:
        std::deque<MeasurePoint> measure_points;
        uint64_t last_pts_reported = 0;
 
+       off_t total_size = 0;  // For report_write().
+       std::string last_filename;  // For report_append().
+
        // Metrics.
        std::atomic<int64_t> metric_disk_free_bytes{-1};
 };
index 1bb183b9a2e8107dc0753091421a269637b077c3..7ef0b3f83d021af6630df12f87178672cce2f0ff 100644 (file)
@@ -2,7 +2,7 @@ qt5 = import('qt5')
 qt5deps = dependency('qt5', modules: ['OpenGL'])
 libmicrohttpddep = dependency('libmicrohttpd')
 
-srcs = ['memcpy_interleaved.cpp', 'metacube2.cpp', 'ffmpeg_raii.cpp', 'mux.cpp', 'metrics.cpp', 'context.cpp', 'httpd.cpp']
+srcs = ['memcpy_interleaved.cpp', 'metacube2.cpp', 'ffmpeg_raii.cpp', 'mux.cpp', 'metrics.cpp', 'context.cpp', 'httpd.cpp', 'disk_space_estimator.cpp']
 shared = static_library('shared', srcs, include_directories: top_include, dependencies: [qt5deps, libmicrohttpddep])
 shareddep = declare_dependency(
    include_directories: top_include,