]> git.sesse.net Git - nageru/blobdiff - mixer.h
Write 1.4.0 changelog.
[nageru] / mixer.h
diff --git a/mixer.h b/mixer.h
index 1d6d0308ca5570ee926b2bab0fa4b44f8b58835a..f5aa4fbdd014758faa047f21bc4dfdf701467a81 100644 (file)
--- a/mixer.h
+++ b/mixer.h
@@ -3,52 +3,48 @@
 
 // The actual video mixer, running in its own separate background thread.
 
+#include <assert.h>
 #include <epoxy/gl.h>
+
 #undef Success
+
 #include <stdbool.h>
 #include <stdint.h>
-
-#include <movit/effect_chain.h>
-#include <movit/flat_input.h>
-#include <zita-resampler/resampler.h>
 #include <atomic>
+#include <chrono>
 #include <condition_variable>
 #include <cstddef>
 #include <functional>
+#include <map>
 #include <memory>
 #include <mutex>
+#include <queue>
 #include <string>
 #include <thread>
 #include <vector>
 
+#include "audio_mixer.h"
 #include "bmusb/bmusb.h"
-#include "alsa_output.h"
-#include "ebu_r128_proc.h"
-#include "video_encoder.h"
+#include "defs.h"
 #include "httpd.h"
+#include "input_state.h"
+#include "libusb.h"
 #include "pbo_frame_allocator.h"
 #include "ref_counted_frame.h"
 #include "ref_counted_gl_sync.h"
-#include "resampling_queue.h"
 #include "theme.h"
 #include "timebase.h"
-#include "stereocompressor.h"
-#include "filter.h"
-#include "input_state.h"
-#include "correlation_measurer.h"
+#include "video_encoder.h"
 
-class QuickSyncEncoder;
+class ALSAOutput;
 class QSurface;
+
 namespace movit {
 class Effect;
 class EffectChain;
 class FlatInput;
 class ResourcePool;
 }  // namespace movit
-
-namespace movit {
-class YCbCrInput;
-}
 class QSurfaceFormat;
 
 // For any card that's not the master (where we pick out the frames as they
@@ -165,15 +161,6 @@ public:
                output_channel[output].set_color_updated_callback(callback);
        }
 
-       typedef std::function<void(float level_lufs, float peak_db,
-                                  float global_level_lufs, float range_low_lufs, float range_high_lufs,
-                                  float gain_staging_db, float final_makeup_gain_db,
-                                  float correlation)> audio_level_callback_t;
-       void set_audio_level_callback(audio_level_callback_t callback)
-       {
-               audio_level_callback = callback;
-       }
-
        std::vector<std::string> get_transition_names()
        {
                return theme->get_transition_names(pts());
@@ -204,16 +191,6 @@ public:
                return theme->map_signal(channel);
        }
 
-       unsigned get_audio_source() const
-       {
-               return audio_source_channel;
-       }
-
-       void set_audio_source(unsigned channel)
-       {
-               audio_source_channel = channel;
-       }
-
        unsigned get_master_clock() const
        {
                return master_clock_channel;
@@ -239,100 +216,15 @@ public:
                theme->set_wb(channel, r, g, b);
        }
 
-       void set_locut_cutoff(float cutoff_hz)
-       {
-               locut_cutoff_hz = cutoff_hz;
-       }
-
-       void set_locut_enabled(bool enabled)
-       {
-               locut_enabled = enabled;
-       }
-
-       bool get_locut_enabled() const
-       {
-               return locut_enabled;
-       }
-
-       float get_limiter_threshold_dbfs()
-       {
-               return limiter_threshold_dbfs;
-       }
-
-       float get_compressor_threshold_dbfs()
-       {
-               return compressor_threshold_dbfs;
-       }
-
-       void set_limiter_threshold_dbfs(float threshold_dbfs)
-       {
-               limiter_threshold_dbfs = threshold_dbfs;
-       }
-
-       void set_compressor_threshold_dbfs(float threshold_dbfs)
-       {
-               compressor_threshold_dbfs = threshold_dbfs;
-       }
-
-       void set_limiter_enabled(bool enabled)
-       {
-               limiter_enabled = enabled;
-       }
-
-       bool get_limiter_enabled() const
-       {
-               return limiter_enabled;
-       }
-
-       void set_compressor_enabled(bool enabled)
-       {
-               compressor_enabled = enabled;
-       }
-
-       bool get_compressor_enabled() const
-       {
-               return compressor_enabled;
-       }
-
-       void set_gain_staging_db(float gain_db)
-       {
-               std::unique_lock<std::mutex> lock(compressor_mutex);
-               level_compressor_enabled = false;
-               gain_staging_db = gain_db;
-       }
-
-       void set_gain_staging_auto(bool enabled)
-       {
-               std::unique_lock<std::mutex> lock(compressor_mutex);
-               level_compressor_enabled = enabled;
-       }
-
-       bool get_gain_staging_auto() const
-       {
-               std::unique_lock<std::mutex> lock(compressor_mutex);
-               return level_compressor_enabled;
-       }
-
-       void set_final_makeup_gain_db(float gain_db)
-       {
-               std::unique_lock<std::mutex> lock(compressor_mutex);
-               final_makeup_gain_auto = false;
-               final_makeup_gain = pow(10.0f, gain_db / 20.0f);
-       }
-
-       void set_final_makeup_gain_auto(bool enabled)
-       {
-               std::unique_lock<std::mutex> lock(compressor_mutex);
-               final_makeup_gain_auto = enabled;
-       }
+       // Note: You can also get this through the global variable global_audio_mixer.
+       AudioMixer *get_audio_mixer() { return &audio_mixer; }
+       const AudioMixer *get_audio_mixer() const { return &audio_mixer; }
 
        void schedule_cut()
        {
                should_cut = true;
        }
 
-       void reset_meters();
-
        unsigned get_num_cards() const { return num_cards; }
 
        std::string get_card_description(unsigned card_index) const {
@@ -340,7 +232,7 @@ public:
                return cards[card_index].capture->get_description();
        }
 
-       std::map<uint32_t, VideoMode> get_available_video_modes(unsigned card_index) const {
+       std::map<uint32_t, bmusb::VideoMode> get_available_video_modes(unsigned card_index) const {
                assert(card_index < num_cards);
                return cards[card_index].capture->get_available_video_modes();
        }
@@ -387,11 +279,15 @@ public:
                cards[card_index].capture->set_audio_input(input);
        }
 
+       void change_x264_bitrate(unsigned rate_kbit) {
+               video_encoder->change_x264_bitrate(rate_kbit);
+       }
+
 private:
-       void configure_card(unsigned card_index, CaptureInterface *capture, bool is_fake_capture);
+       void configure_card(unsigned card_index, bmusb::CaptureInterface *capture, bool is_fake_capture);
        void bm_frame(unsigned card_index, uint16_t timecode,
-               FrameAllocator::Frame video_frame, size_t video_offset, VideoFormat video_format,
-               FrameAllocator::Frame audio_frame, size_t audio_offset, AudioFormat audio_format);
+               bmusb::FrameAllocator::Frame video_frame, size_t video_offset, bmusb::VideoFormat video_format,
+               bmusb::FrameAllocator::Frame audio_frame, size_t audio_offset, bmusb::AudioFormat audio_format);
        void bm_hotplug_add(libusb_device *dev);
        void bm_hotplug_remove(unsigned card_index);
        void place_rectangle(movit::Effect *resample_effect, movit::Effect *padding_effect, float x0, float y0, float x1, float y1);
@@ -399,9 +295,7 @@ private:
        void handle_hotplugged_cards();
        void schedule_audio_resampling_tasks(unsigned dropped_frames, int num_samples_per_frame, int length_per_frame);
        void render_one_frame(int64_t duration);
-       void send_audio_level_callback();
        void audio_thread_func();
-       void process_audio_one_frame(int64_t frame_pts_int, int num_samples);
        void subsample_chroma(GLuint src_tex, GLuint dst_dst);
        void release_display_frame(DisplayFrame *frame);
        double pts() { return double(pts_int) / TIMEBASE; }
@@ -428,7 +322,7 @@ private:
        std::mutex bmusb_mutex;
        bool has_bmusb_thread = false;
        struct CaptureCard {
-               CaptureInterface *capture = nullptr;
+               bmusb::CaptureInterface *capture = nullptr;
                bool is_fake_capture;
                std::unique_ptr<PBOFrameAllocator> frame_allocator;
 
@@ -453,13 +347,11 @@ private:
                // frame rate is integer, will always stay zero.
                unsigned fractional_samples = 0;
 
-               std::mutex audio_mutex;
-               std::unique_ptr<ResamplingQueue> resampling_queue;  // Under audio_mutex.
                int last_timecode = -1;  // Unwrapped.
-               int64_t next_local_pts = 0;  // Beginning of next frame, in TIMEBASE units.
        };
-       CaptureCard cards[MAX_CARDS];  // protected by <bmusb_mutex>
-       void get_one_frame_from_each_card(unsigned master_card_index, CaptureCard::NewFrame new_frames[MAX_CARDS], bool has_new_frame[MAX_CARDS], int num_samples[MAX_CARDS]);
+       CaptureCard cards[MAX_VIDEO_CARDS];  // protected by <bmusb_mutex>
+       AudioMixer audio_mixer;  // Same as global_audio_mixer (see audio_mixer.h).
+       void get_one_frame_from_each_card(unsigned master_card_index, CaptureCard::NewFrame new_frames[MAX_VIDEO_CARDS], bool has_new_frame[MAX_VIDEO_CARDS], int num_samples[MAX_VIDEO_CARDS]);
 
        InputState input_state;
 
@@ -501,51 +393,22 @@ private:
        std::atomic<bool> should_quit{false};
        std::atomic<bool> should_cut{false};
 
-       audio_level_callback_t audio_level_callback = nullptr;
-       mutable std::mutex compressor_mutex;
-       Ebu_r128_proc r128;  // Under compressor_mutex.
-       CorrelationMeasurer correlation;  // Under compressor_mutex.
-
-       Resampler peak_resampler;
-       std::atomic<float> peak{0.0f};
-
-       StereoFilter locut;  // Default cutoff 120 Hz, 24 dB/oct.
-       std::atomic<float> locut_cutoff_hz;
-       std::atomic<bool> locut_enabled{true};
-
-       // First compressor; takes us up to about -12 dBFS.
-       StereoCompressor level_compressor;  // Under compressor_mutex. Used to set/override gain_staging_db if <level_compressor_enabled>.
-       float gain_staging_db = 0.0f;  // Under compressor_mutex.
-       bool level_compressor_enabled = true;  // Under compressor_mutex.
-
-       static constexpr float ref_level_dbfs = -14.0f;  // Chosen so that we end up around 0 LU in practice.
-       static constexpr float ref_level_lufs = -23.0f;  // 0 LU, more or less by definition.
-
-       StereoCompressor limiter;
-       std::atomic<float> limiter_threshold_dbfs{ref_level_dbfs + 4.0f};   // 4 dB.
-       std::atomic<bool> limiter_enabled{true};
-       StereoCompressor compressor;
-       std::atomic<float> compressor_threshold_dbfs{ref_level_dbfs - 12.0f};  // -12 dB.
-       std::atomic<bool> compressor_enabled{true};
-
-       double final_makeup_gain = 1.0;  // Under compressor_mutex. Read/write by the user. Note: Not in dB, we want the numeric precision so that we can change it slowly.
-       bool final_makeup_gain_auto = true;  // Under compressor_mutex.
-
        std::unique_ptr<ALSAOutput> alsa;
 
        struct AudioTask {
                int64_t pts_int;
                int num_samples;
+               bool adjust_rate;
        };
        std::mutex audio_mutex;
        std::condition_variable audio_task_queue_changed;
        std::queue<AudioTask> audio_task_queue;  // Under audio_mutex.
 
        // For mode scanning.
-       bool is_mode_scanning[MAX_CARDS]{ false };
-       std::vector<uint32_t> mode_scanlist[MAX_CARDS];
-       unsigned mode_scanlist_index[MAX_CARDS]{ 0 };
-       timespec last_mode_scan_change[MAX_CARDS];
+       bool is_mode_scanning[MAX_VIDEO_CARDS]{ false };
+       std::vector<uint32_t> mode_scanlist[MAX_VIDEO_CARDS];
+       unsigned mode_scanlist_index[MAX_VIDEO_CARDS]{ 0 };
+       std::chrono::steady_clock::time_point last_mode_scan_change[MAX_VIDEO_CARDS];
 };
 
 extern Mixer *global_mixer;