#include <assert.h>
#include <epoxy/egl.h>
+#include <movit/effect.h>
#include <movit/effect_chain.h>
#include <movit/effect_util.h>
#include <movit/flat_input.h>
ycbcr_format.cb_y_position = 0.5f;
ycbcr_format.cr_y_position = 0.5f;
+ // Initialize the neutral colors to sane values.
+ for (unsigned i = 0; i < MAX_VIDEO_CARDS; ++i) {
+ last_received_neutral_color[i] = RGBTriplet(1.0f, 1.0f, 1.0f);
+ }
+
// Display chain; shows the live output produced by the main chain (or rather, a copy of it).
display_chain.reset(new EffectChain(global_flags.width, global_flags.height, resource_pool.get()));
check_error();
new_frame.video_format = video_format;
new_frame.y_offset = y_offset;
new_frame.cbcr_offset = cbcr_offset;
+ if (card->type == CardType::FFMPEG_INPUT) {
+ FFmpegCapture *ffmpeg_capture = static_cast<FFmpegCapture *>(card->capture.get());
+ new_frame.neutral_color = ffmpeg_capture->get_last_neutral_color();
+ }
card->new_frames.push_back(move(new_frame));
card->jitter_history.frame_arrived(video_frame.received_timestamp, frame_length, dropped_frames);
card->may_have_dropped_last_frame = false;
new_frame->upload_func = nullptr;
}
+ // Only set the white balance if it actually changed. This means that the user
+ // is free to override the white balance in a video with no white balance information
+ // actually set (ie. r=g=b=1 all the time), or one where the white point is wrong,
+ // but frame-to-frame decisions will be heeded. We do this pretty much as late
+ // as possible (ie., after picking out the frame from the buffer), so that we are sure
+ // that the change takes effect on exactly the right frame.
+ if (fabs(new_frame->neutral_color.r - last_received_neutral_color[card_index].r) > 1e-3 ||
+ fabs(new_frame->neutral_color.g - last_received_neutral_color[card_index].g) > 1e-3 ||
+ fabs(new_frame->neutral_color.b - last_received_neutral_color[card_index].b) > 1e-3) {
+ theme->set_wb_for_signal(card_index, new_frame->neutral_color.r, new_frame->neutral_color.g, new_frame->neutral_color.b);
+ last_received_neutral_color[card_index] = new_frame->neutral_color;
+ }
+
if (new_frame->frame->data_copy != nullptr) {
int mjpeg_card_index = mjpeg_encoder->get_mjpeg_stream_for_card(card_index);
if (mjpeg_card_index != -1) {
- mjpeg_encoder->upload_frame(pts_int, mjpeg_card_index, new_frame->frame, new_frame->video_format, new_frame->y_offset, new_frame->cbcr_offset, move(raw_audio[card_index]));
+ RGBTriplet neutral_color = theme->get_white_balance_for_signal(card_index);
+ mjpeg_encoder->upload_frame(pts_int, mjpeg_card_index, new_frame->frame, new_frame->video_format, new_frame->y_offset, new_frame->cbcr_offset, move(raw_audio[card_index]), neutral_color);
}
}
+
}
int64_t frame_duration = output_frame_info.frame_duration;
// we dropped. (may_have_dropped_last_frame is set whenever we
// trim the queue completely away, and cleared when we actually
// get a new frame.)
- ((CEFCapture *)card->capture.get())->request_new_frame();
+ ((CEFCapture *)card->capture.get())->request_new_frame(/*ignore_if_locked=*/true);
}
#endif
} else {