for (int i = 1; i < theme->get_num_channels() + 2; ++i) {
DisplayFrame display_frame;
Theme::Chain chain = theme->get_chain(i, pts(), global_flags.width, global_flags.height, input_state); // FIXME: dimensions
- display_frame.chain = chain.chain;
- display_frame.setup_chain = chain.setup_chain;
+ display_frame.chain = move(chain.chain);
+ display_frame.setup_chain = move(chain.setup_chain);
display_frame.ready_fence = fence;
- display_frame.input_frames = chain.input_frames;
+ display_frame.input_frames = move(chain.input_frames);
display_frame.temp_textures = {};
output_channel[i].output_frame(display_frame);
}
if (has_ready_frame) {
parent->release_display_frame(&ready_frame);
}
- ready_frame = frame;
+ ready_frame = move(frame);
has_ready_frame = true;
// Call the callbacks under the mutex (they should be short),
}
if (has_ready_frame) {
assert(!has_current_frame);
- current_frame = ready_frame;
+ current_frame = move(ready_frame);
ready_frame.ready_fence.reset(); // Drop the refcount.
ready_frame.input_frames.clear(); // Drop the refcounts.
has_current_frame = true;
// TODO: Can we do better, e.g. by running setup_chain() and seeing what it references?
// Actually, setup_chain does maybe hold all the references we need now anyway?
+ chain.input_frames.reserve(num_cards * FRAME_HISTORY_LENGTH);
for (unsigned card_index = 0; card_index < num_cards; ++card_index) {
for (unsigned frame_num = 0; frame_num < FRAME_HISTORY_LENGTH; ++frame_num) {
chain.input_frames.push_back(input_state.buffered_frames[card_index][frame_num].frame);
#include <x264.h>
#include <atomic>
#include <cstdint>
+#include <functional>
#include <mutex>
#include "defs.h"
using namespace movit;
using namespace std;
using namespace std::chrono;
+using namespace std::placeholders;
namespace {
frames_being_encoded[qf.pts] = qf.received_ts;
}
- // See if we have a new bitrate to change to.
- unsigned new_rate = new_bitrate_kbit.exchange(0); // Read and clear.
- if (new_rate != 0) {
- bitrate_override_func = [new_rate](x264_param_t *param) {
- param->rc.i_bitrate = new_rate;
- update_vbv_settings(param);
- };
- }
-
- auto ycbcr_coefficients_override_func = [qf](x264_param_t *param) {
- if (qf.ycbcr_coefficients == YCBCR_REC_709) {
- param->vui.i_colmatrix = 1; // BT.709.
- } else {
- assert(qf.ycbcr_coefficients == YCBCR_REC_601);
- param->vui.i_colmatrix = 6; // BT.601/SMPTE 170M.
- }
- };
-
+ unsigned new_rate = new_bitrate_kbit.load(); // Can be 0 for no change.
if (speed_control) {
- speed_control->set_config_override_function([this, ycbcr_coefficients_override_func](x264_param_t *param) {
- if (bitrate_override_func) {
- bitrate_override_func(param);
- }
- ycbcr_coefficients_override_func(param);
- });
+ speed_control->set_config_override_function(bind(&speed_control_override_func, new_rate, qf.ycbcr_coefficients, _1));
} else {
x264_param_t param;
dyn.x264_encoder_parameters(x264, ¶m);
- if (bitrate_override_func) {
- bitrate_override_func(¶m);
- }
- ycbcr_coefficients_override_func(¶m);
+ speed_control_override_func(new_rate, qf.ycbcr_coefficients, ¶m);
dyn.x264_encoder_reconfig(x264, ¶m);
}
mux->add_packet(pkt, pic.i_pts, pic.i_dts);
}
}
+
+void X264Encoder::speed_control_override_func(unsigned bitrate_kbit, movit::YCbCrLumaCoefficients ycbcr_coefficients, x264_param_t *param)
+{
+ if (bitrate_kbit != 0) {
+ param->rc.i_bitrate = bitrate_kbit;
+ update_vbv_settings(param);
+ }
+
+ if (ycbcr_coefficients == YCBCR_REC_709) {
+ param->vui.i_colmatrix = 1; // BT.709.
+ } else {
+ assert(ycbcr_coefficients == YCBCR_REC_601);
+ param->vui.i_colmatrix = 6; // BT.601/SMPTE 170M.
+ }
+}
void init_x264();
void encode_frame(QueuedFrame qf);
+ // bitrate_kbit can be 0 for no change.
+ static void speed_control_override_func(unsigned bitrate_kbit, movit::YCbCrLumaCoefficients coefficients, x264_param_t *param);
+
// One big memory chunk of all 50 (or whatever) frames, allocated in
// the constructor. All data functions just use pointers into this
// pool.
x264_t *x264;
std::unique_ptr<X264SpeedControl> speed_control;
- std::function<void(x264_param_t *)> bitrate_override_func;
-
std::atomic<unsigned> new_bitrate_kbit{0}; // 0 for no change.
// Protects everything below it.