template <class T, class T2>
unique_ptr<T> dynamic_pointer_cast(const unique_ptr<T2>& p)
{
- aT2to temp = std::dynamic_pointer_cast<T>(std::unique_ptr<T2>(p));
+ auto temp = std::dynamic_pointer_cast<T>(std::unique_ptr<T2>(p));
if(!temp)
throw std::bad_cast();
return unique_ptr<T>(std::move(temp));
template <class T, class T2>
shared_ptr<T> dynamic_pointer_cast(const shared_ptr<T2>& p)
{
- aT2to temp = std::dynamic_pointer_cast<T>(std::shared_ptr<T2>(p));
+ auto temp = std::dynamic_pointer_cast<T>(std::shared_ptr<T2>(p));
if(!temp)
throw std::bad_cast();
return shared_ptr<T>(std::move(temp));
spl::shared_ptr<core::frame_factory> frame_factory_;
core::video_format_desc in_format_desc_;
core::video_format_desc out_format_desc_;
+ core::constraints constraints_;
tbb::concurrent_bounded_queue<core::draw_frame> frame_buffer_;
, filter_(filter)
, in_format_desc_(in_format_desc)
, out_format_desc_(out_format_desc)
+ , constraints_(in_format_desc.width, in_format_desc.height)
, muxer_(in_format_desc.fps, frame_factory, out_format_desc, filter)
, audio_cadence_(out_format_desc.audio_cadence)
, sync_buffer_(out_format_desc.audio_cadence.size())
}
}
+ core::constraints& pixel_constraints()
+ {
+ return constraints_;
+ }
+
virtual HRESULT STDMETHODCALLTYPE QueryInterface (REFIID, LPVOID*) {return E_NOINTERFACE;}
virtual ULONG STDMETHODCALLTYPE AddRef () {return 1;}
virtual ULONG STDMETHODCALLTYPE Release () {return 1;}
{
return producer_->get_frame();
}
+
+ core::constraints& pixel_constraints() override
+ {
+ return producer_->pixel_constraints();
+ }
uint32_t nb_frames() const override
{
std::unique_ptr<video_decoder> video_decoder_;
std::unique_ptr<audio_decoder> audio_decoder_;
frame_muxer muxer_;
+ core::constraints constraints_;
core::draw_frame last_frame_;
{
video_decoder_.reset(new video_decoder(input_));
video_decoder_->subscribe(event_subject_);
+ constraints_.width.set(video_decoder_->width());
+ constraints_.height.set(video_decoder_->height());
CASPAR_LOG(info) << print() << L" " << video_decoder_->print();
}
end_seek();
return core::draw_frame::still(last_frame_);
}
-
+
+ core::constraints& pixel_constraints() override
+ {
+ return constraints_;
+ }
+
uint32_t nb_frames() const override
{
if(input_.loop())
const core::video_format_desc format_desc_;
const int width_;
const int height_;
+ core::constraints constraints_;
const int buffer_size_;
tbb::atomic<int> fps_;
, format_desc_(format_desc)
, width_(width > 0 ? width : format_desc.width)
, height_(height > 0 ? height : format_desc.height)
+ , constraints_(width_, height_)
, buffer_size_(env::properties().get(L"configuration.flash.buffer-depth", format_desc.fps > 30.0 ? 4 : 2))
, executor_(L"flash_producer")
{
return last_frame_ = frame;
}
+
+ core::constraints& pixel_constraints() override
+ {
+ return constraints_;
+ }
boost::unique_future<std::wstring> call(const std::wstring& param) override
{
monitor::basic_subject event_subject_;
const std::wstring filename_;
core::draw_frame frame_;
+ core::constraints constraints_;
explicit image_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const std::wstring& filename)
: filename_(filename)
FreeImage_FlipVertical(bitmap.get());
core::pixel_format_desc desc = core::pixel_format::bgra;
- desc.planes.push_back(core::pixel_format_desc::plane(FreeImage_GetWidth(bitmap.get()), FreeImage_GetHeight(bitmap.get()), 4));
+ auto width = FreeImage_GetWidth(bitmap.get());
+ auto height = FreeImage_GetHeight(bitmap.get());
+ desc.planes.push_back(core::pixel_format_desc::plane(width, height, 4));
auto frame = frame_factory->create_frame(this, desc);
std::copy_n(FreeImage_GetBits(bitmap.get()), frame.image_data(0).size(), frame.image_data(0).begin());
frame_ = core::draw_frame(std::move(frame));
+ constraints_.width.set(width);
+ constraints_.height.set(height);
CASPAR_LOG(info) << print() << L" Initialized";
}
return frame_;
}
+
+ core::constraints& pixel_constraints() override
+ {
+ return constraints_;
+ }
std::wstring print() const override
{
core::video_format_desc format_desc_;
int width_;
int height_;
+ core::constraints constraints_;
double delta_;
double speed_;
width_ = FreeImage_GetWidth(bitmap.get());
height_ = FreeImage_GetHeight(bitmap.get());
+ constraints_.width.set(width_);
+ constraints_.height.set(height_);
bool vertical = width_ == format_desc_.width;
bool horizontal = height_ == format_desc_.height;
return result;
}
+
+ core::constraints& pixel_constraints() override
+ {
+ return constraints_;
+ }
std::wstring print() const override
{
class reroute_producer : public reactive::observer<std::map<int, core::draw_frame>>
, public core::frame_producer_base
{
+ core::constraints constraints_;
const spl::shared_ptr<diagnostics::graph> graph_;
tbb::concurrent_bounded_queue<std::map<int, core::draw_frame>> input_buffer_;
}
return boost::accumulate(frames | boost::adaptors::map_values, core::draw_frame::empty(), core::draw_frame::over);
- }
+ }
+
+ core::constraints& pixel_constraints() override
+ {
+ return constraints_;
+ }
std::wstring print() const override
{
#include <core/video_format.h>
#include <core/frame/frame.h>
#include <core/consumer/frame_consumer.h>
+#include <core/consumer/frame_consumer.h>
#include <boost/timer.hpp>
#include <boost/circular_buffer.hpp>
bool key_only;
aspect_ratio aspect;
bool vsync;
+ bool interactive;
configuration()
: name(L"ogl")
, key_only(false)
, aspect(aspect_invalid)
, vsync(true)
+ , interactive(true)
{
}
};
caspar::prec_timer wait_timer_;
tbb::concurrent_bounded_queue<core::const_frame> frame_buffer_;
+ core::interaction_sink* sink_;
boost::thread thread_;
tbb::atomic<bool> is_running_;
ffmpeg::filter filter_;
public:
- screen_consumer(const configuration& config, const core::video_format_desc& format_desc, int channel_index)
+ screen_consumer(const configuration& config, const core::video_format_desc& format_desc, int channel_index, core::interaction_sink* sink)
: config_(config)
, format_desc_(format_desc)
, channel_index_(channel_index)
, screen_height_(format_desc.height)
, square_width_(format_desc.square_width)
, square_height_(format_desc.square_height)
+ , sink_(sink)
, filter_(format_desc.field_mode == core::field_mode::progressive || !config.auto_deinterlace ? L"" : L"YADIF=1:-1", boost::assign::list_of(PIX_FMT_BGRA))
{
if(format_desc_.format == core::video_format::ntsc && config_.aspect == configuration::aspect_4_3)
square_width_ = (format_desc.height*4)/3;
}
- frame_buffer_.set_capacity(2);
+ frame_buffer_.set_capacity(1);
graph_->set_color("tick-time", diagnostics::color(0.0f, 0.6f, 0.9f));
graph_->set_color("frame-time", diagnostics::color(0.1f, 1.0f, 0.1f));
void init()
{
window_.Create(sf::VideoMode(screen_width_, screen_height_, 32), u8(L"Screen consumer " + channel_and_format()), config_.windowed ? sf::Style::Resize | sf::Style::Close : sf::Style::Fullscreen);
- window_.ShowMouseCursor(false);
+ window_.ShowMouseCursor(config_.interactive);
window_.SetPosition(screen_x_, screen_y_);
window_.SetSize(screen_width_, screen_height_);
window_.SetActive();
sf::Event e;
while(window_.GetEvent(e))
{
- if(e.Type == sf::Event::Resized)
+ if (e.Type == sf::Event::Resized)
calculate_aspect();
- else if(e.Type == sf::Event::Closed)
+ else if (e.Type == sf::Event::Closed)
is_running_ = false;
+ else if (config_.interactive && sink_)
+ {
+ switch (e.Type)
+ {
+ case sf::Event::MouseMoved:
+ {
+ auto& mouse_move = e.MouseMove;
+ sink_->on_interaction(spl::make_shared<core::mouse_move_event>(
+ 1,
+ static_cast<double>(mouse_move.X) / screen_width_,
+ static_cast<double>(mouse_move.Y) / screen_height_));
+ }
+ break;
+ case sf::Event::MouseButtonPressed:
+ case sf::Event::MouseButtonReleased:
+ {
+ auto& mouse_button = e.MouseButton;
+ sink_->on_interaction(spl::make_shared<core::mouse_button_event>(
+ 1,
+ static_cast<double>(mouse_button.X) / screen_width_,
+ static_cast<double>(mouse_button.Y) / screen_height_,
+ static_cast<int>(mouse_button.Button),
+ e.Type == sf::Event::MouseButtonPressed));
+ }
+ break;
+ }
+ }
}
auto frame = core::const_frame::empty();
{
const configuration config_;
std::unique_ptr<screen_consumer> consumer_;
+ core::interaction_sink* sink_;
public:
- screen_consumer_proxy(const configuration& config)
- : config_(config){}
+ screen_consumer_proxy(const configuration& config, core::interaction_sink* sink)
+ : config_(config)
+ , sink_(sink)
+ {
+ }
// frame_consumer
void initialize(const core::video_format_desc& format_desc, int channel_index) override
{
consumer_.reset();
- consumer_.reset(new screen_consumer(config_, format_desc, channel_index));
+ consumer_.reset(new screen_consumer(config_, format_desc, channel_index, sink_));
}
boost::unique_future<bool> send(core::const_frame frame) override
int buffer_depth() const override
{
- return 2;
+ return 1;
}
int index() const override
if(name_it != params.end() && ++name_it != params.end())
config.name = *name_it;
- return spl::make_shared<screen_consumer_proxy>(config);
+ return spl::make_shared<screen_consumer_proxy>(config, nullptr);
}
-spl::shared_ptr<core::frame_consumer> create_consumer(const boost::property_tree::wptree& ptree)
+spl::shared_ptr<core::frame_consumer> create_consumer(const boost::property_tree::wptree& ptree, core::interaction_sink* sink)
{
configuration config;
config.name = ptree.get(L"name", config.name);
else if(aspect_str == L"4:3")
config.aspect = configuration::aspect_4_3;
- return spl::make_shared<screen_consumer_proxy>(config);
+ return spl::make_shared<screen_consumer_proxy>(config, sink);
}
}}
\ No newline at end of file
#pragma once
#include <common/memory.h>
+#include <core/interaction/interaction_sink.h>
#include <vector>
#include <boost/property_tree/ptree.hpp>
spl::shared_ptr<core::frame_consumer> create_consumer(const std::vector<std::wstring>& params);
-spl::shared_ptr<core::frame_consumer> create_consumer(const boost::property_tree::wptree& ptree);
+spl::shared_ptr<core::frame_consumer> create_consumer(const boost::property_tree::wptree& ptree, core::interaction_sink* sink);
}}
\ No newline at end of file
#include <core/video_format.h>
#include <core/producer/stage.h>
#include <core/producer/frame_producer.h>
+#include <core/producer/scene/scene_producer.h>
#include <core/consumer/output.h>
#include <modules/bluefish/bluefish.h>
flash::init();
CASPAR_LOG(info) << L"Initialized flash module.";
+ register_producer_factory(&core::scene::create_dummy_scene_producer);
+
setup_channels(env::properties());
CASPAR_LOG(info) << L"Initialized channels.";
{
auto name = xml_consumer.first;
if(name == L"screen")
- channel->output().add(caspar::screen::create_consumer(xml_consumer.second));
+ channel->output().add(caspar::screen::create_consumer(xml_consumer.second, &channel->stage()));
else if(name == L"bluefish")
channel->output().add(bluefish::create_consumer(xml_consumer.second));
else if(name == L"decklink")