virtual ~frame_consumer() {}\r
\r
virtual bool send(const safe_ptr<read_frame>& frame) = 0;\r
- virtual void initialize(const video_format_desc& format_desc) = 0;\r
+ virtual void initialize(const video_format_desc& format_desc, int channel_index, int sub_index) = 0;\r
virtual std::wstring print() const = 0;\r
virtual bool has_synchronization_clock() const {return true;}\r
virtual size_t buffer_depth() const = 0;\r
{\r
core::video_format_desc format_desc;\r
virtual bool send(const safe_ptr<read_frame>&){return false;}\r
- virtual void initialize(const video_format_desc&){}\r
+ virtual void initialize(const video_format_desc&, int, int){}\r
virtual std::wstring print() const {return L"empty";}\r
virtual bool has_synchronization_clock() const {return false;}\r
virtual size_t buffer_depth() const {return 0;};\r
{ \r
typedef std::pair<safe_ptr<read_frame>, safe_ptr<read_frame>> fill_and_key;\r
\r
+ const int channel_index_;\r
safe_ptr<diagnostics::graph> graph_;\r
boost::timer consume_timer_;\r
\r
executor executor_;\r
\r
public:\r
- implementation(const safe_ptr<diagnostics::graph>& graph, const video_format_desc& format_desc) \r
- : graph_(graph)\r
+ implementation(const safe_ptr<diagnostics::graph>& graph, const video_format_desc& format_desc, int channel_index) \r
+ : channel_index_(channel_index)\r
+ , graph_(graph)\r
, format_desc_(format_desc)\r
, executor_(L"output")\r
{\r
consumers_.erase(index);\r
});\r
\r
- consumer->initialize(format_desc_);\r
+ consumer->initialize(format_desc_, channel_index_, index);\r
\r
executor_.invoke([&]\r
{\r
{ \r
try\r
{\r
- it->second->initialize(format_desc_);\r
+ it->second->initialize(format_desc_, channel_index_, it->first);\r
++it;\r
}\r
catch(...)\r
CASPAR_LOG_CURRENT_EXCEPTION();\r
try\r
{\r
- consumer->initialize(format_desc_);\r
+ consumer->initialize(format_desc_, channel_index_, it->first);\r
if(consumer->send(frame))\r
++it;\r
else\r
}\r
};\r
\r
-output::output(const safe_ptr<diagnostics::graph>& graph, const video_format_desc& format_desc) : impl_(new implementation(graph, format_desc)){}\r
+output::output(const safe_ptr<diagnostics::graph>& graph, const video_format_desc& format_desc, int channel_index) : impl_(new implementation(graph, format_desc, channel_index)){}\r
void output::add(int index, safe_ptr<frame_consumer>&& consumer){impl_->add(index, std::move(consumer));}\r
void output::remove(int index){impl_->remove(index);}\r
void output::send(const std::pair<safe_ptr<read_frame>, ticket>& frame) {impl_->send(frame); }\r
class output : public target<std::pair<safe_ptr<read_frame>, ticket>>, boost::noncopyable\r
{\r
public:\r
- explicit output(const safe_ptr<diagnostics::graph>& graph, const video_format_desc& format_desc);\r
+ explicit output(const safe_ptr<diagnostics::graph>& graph, const video_format_desc& format_desc, int channel_index);\r
\r
void add(int index, safe_ptr<frame_consumer>&& consumer);\r
void remove(int index);\r
: index_(index)\r
, format_desc_(format_desc)\r
, ogl_(ogl)\r
- , output_(new caspar::core::output(graph_, format_desc))\r
+ , output_(new caspar::core::output(graph_, format_desc, index))\r
, mixer_(new caspar::core::mixer(graph_, output_, format_desc, ogl))\r
, stage_(new caspar::core::stage(graph_, mixer_, format_desc)) \r
{\r
\r
std::wstring print() const\r
{\r
- return L"video_channel[" + boost::lexical_cast<std::wstring>(index_+1) + L"|" + format_desc_.name + L"]";\r
+ return L"video_channel[" + boost::lexical_cast<std::wstring>(index_) + L"|" + format_desc_.name + L"]";\r
}\r
};\r
\r
safe_ptr<CBlueVelvet4> blue_;\r
const unsigned int device_index_;\r
const core::video_format_desc format_desc_;\r
+ const int channel_index_;\r
+ const int sub_index_;\r
\r
const std::wstring model_name_;\r
\r
\r
executor executor_;\r
public:\r
- bluefish_consumer(const core::video_format_desc& format_desc, unsigned int device_index, bool embedded_audio, bool key_only) \r
+ bluefish_consumer(const core::video_format_desc& format_desc, unsigned int device_index, bool embedded_audio, bool key_only, int channel_index, int sub_index) \r
: blue_(create_blue(device_index))\r
, device_index_(device_index)\r
, format_desc_(format_desc) \r
+ , channel_index_(channel_index)\r
+ , sub_index_(sub_index)\r
, model_name_(get_card_desc(*blue_))\r
, vid_fmt_(get_video_mode(*blue_, format_desc))\r
, embedded_audio_(embedded_audio)\r
\r
std::wstring print() const\r
{\r
- return model_name_ + L" [" + boost::lexical_cast<std::wstring>(device_index_) + L"|" + format_desc_.name + L"]";\r
+ return model_name_ + L" [" + boost::lexical_cast<std::wstring>(channel_index_) + L"-" + boost::lexical_cast<std::wstring>(sub_index_) + L"|device " + \r
+ boost::lexical_cast<std::wstring>(device_index_) + L"|" + format_desc_.name + L"]";\r
}\r
};\r
\r
{\r
}\r
\r
- virtual void initialize(const core::video_format_desc& format_desc)\r
+ virtual void initialize(const core::video_format_desc& format_desc, int channel_index, int sub_index)\r
{\r
- consumer_.reset(new bluefish_consumer(format_desc, device_index_, embedded_audio_, key_only_));\r
+ consumer_.reset(new bluefish_consumer(format_desc, device_index_, embedded_audio_, key_only_, channel_index, sub_index));\r
}\r
\r
virtual bool send(const safe_ptr<core::read_frame>& frame)\r
\r
virtual std::wstring print() const\r
{\r
- return consumer_ ? consumer_->print() : L"bluefish_consumer";\r
+ return consumer_->print();\r
}\r
\r
size_t buffer_depth() const\r
struct decklink_consumer : public IDeckLinkVideoOutputCallback, public IDeckLinkAudioOutputCallback, boost::noncopyable\r
{ \r
const configuration config_;\r
+ const int channel_index_;\r
+ const int sub_index_;\r
\r
CComPtr<IDeckLink> decklink_;\r
CComQIPtr<IDeckLinkOutput> output_;\r
boost::timer tick_timer_;\r
\r
public:\r
- decklink_consumer(const configuration& config, const core::video_format_desc& format_desc) \r
+ decklink_consumer(const configuration& config, const core::video_format_desc& format_desc, int channel_index, int sub_index) \r
: config_(config)\r
+ , channel_index_(channel_index)\r
+ , sub_index_(sub_index)\r
, decklink_(get_device(config.device_index))\r
, output_(decklink_)\r
, configuration_(decklink_)\r
\r
std::wstring print() const\r
{\r
- return model_name_ + L" [" + boost::lexical_cast<std::wstring>(config_.device_index) + L"|" + format_desc_.name + L"]";\r
+ return model_name_ + L" [" + boost::lexical_cast<std::wstring>(channel_index_) + L"-" + boost::lexical_cast<std::wstring>(sub_index_) + L"|device " +\r
+ boost::lexical_cast<std::wstring>(config_.device_index) + L"|" + format_desc_.name + L"]";\r
}\r
};\r
\r
CASPAR_LOG(info) << str << L" Successfully Uninitialized."; \r
}\r
\r
- virtual void initialize(const core::video_format_desc& format_desc)\r
+ virtual void initialize(const core::video_format_desc& format_desc, int channel_index, int sub_index)\r
{\r
- context_.reset([&]{return new decklink_consumer(config_, format_desc);}); \r
+ context_.reset([&]{return new decklink_consumer(config_, format_desc, channel_index, sub_index);}); \r
\r
CASPAR_LOG(info) << print() << L" Successfully Initialized."; \r
}\r
\r
virtual std::wstring print() const\r
{\r
- return context_ ? context_->print() : L"decklink_consumer";\r
+ return context_->print();\r
} \r
\r
virtual size_t buffer_depth() const\r
\r
\r
/* File created by MIDL compiler version 7.00.0555 */\r
-/* at Wed Nov 23 21:43:40 2011\r
+/* at Fri Nov 25 19:30:08 2011\r
*/\r
/* Compiler settings for interop\DeckLinkAPI.idl:\r
Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 7.00.0555 \r
\r
\r
/* File created by MIDL compiler version 7.00.0555 */\r
-/* at Wed Nov 23 21:43:40 2011\r
+/* at Fri Nov 25 19:30:08 2011\r
*/\r
/* Compiler settings for interop\DeckLinkAPI.idl:\r
Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 7.00.0555 \r
core::video_format_desc format_desc_;\r
public:\r
\r
- virtual void initialize(const core::video_format_desc& format_desc)\r
+ virtual void initialize(const core::video_format_desc& format_desc, int, int)\r
{\r
format_desc_ = format_desc;\r
}\r
{\r
safe_ptr<diagnostics::graph> graph_;\r
boost::timer perf_timer_;\r
+ int channel_index_;\r
+ int sub_index_;\r
\r
tbb::concurrent_bounded_queue<std::shared_ptr<std::vector<int16_t, tbb::cache_aligned_allocator<int16_t>>>> input_;\r
boost::circular_buffer<std::vector<int16_t, tbb::cache_aligned_allocator<int16_t>>> container_;\r
public:\r
oal_consumer() \r
: container_(16)\r
+ , channel_index_(-1)\r
+ , sub_index_(-1)\r
{\r
graph_->add_guide("tick-time", 0.5);\r
graph_->set_color("tick-time", diagnostics::color(0.0f, 0.6f, 0.9f)); \r
CASPAR_LOG(info) << print() << L" Shutting down."; \r
}\r
\r
- virtual void initialize(const core::video_format_desc& format_desc)\r
+ virtual void initialize(const core::video_format_desc& format_desc, int channel_index, int sub_index)\r
{\r
- format_desc_ = format_desc; \r
+ format_desc_ = format_desc; \r
+ channel_index_ = channel_index;\r
+ sub_index_ = sub_index;\r
if(Status() != Playing)\r
{\r
sf::SoundStream::Initialize(2, 48000);\r
\r
virtual std::wstring print() const\r
{\r
- return L"oal[" + format_desc_.name + L"]";\r
+ return L"oal[" + boost::lexical_cast<std::wstring>(channel_index_) + L"-" + boost::lexical_cast<std::wstring>(sub_index_) + L"|" + format_desc_.name + L"]";\r
}\r
\r
virtual size_t buffer_depth() const\r
\r
struct configuration\r
{\r
- size_t screen_index;\r
- stretch stretch;\r
- bool windowed;\r
- bool auto_deinterlace;\r
- bool key_only;\r
+ std::wstring name;\r
+ size_t screen_index;\r
+ stretch stretch;\r
+ bool windowed;\r
+ bool auto_deinterlace;\r
+ bool key_only;\r
\r
configuration()\r
- : screen_index(0)\r
+ : name(L"ogl")\r
+ , screen_index(0)\r
, stretch(fill)\r
, windowed(true)\r
, auto_deinterlace(true)\r
{ \r
const configuration config_;\r
core::video_format_desc format_desc_;\r
- \r
+ int channel_index_;\r
+ int sub_index_;\r
+\r
GLuint texture_;\r
std::vector<GLuint> pbos_;\r
\r
\r
ffmpeg::filter filter_;\r
public:\r
- ogl_consumer(const configuration& config, const core::video_format_desc& format_desc) \r
+ ogl_consumer(const configuration& config, const core::video_format_desc& format_desc, int channel_index, int sub_index) \r
: config_(config)\r
, format_desc_(format_desc)\r
+ , channel_index_(channel_index)\r
+ , sub_index_(sub_index)\r
, texture_(0)\r
, pbos_(2, 0) \r
, screen_width_(format_desc.width)\r
\r
std::wstring print() const\r
{ \r
- return L"ogl[" + boost::lexical_cast<std::wstring>(config_.screen_index) + L"|" + format_desc_.name + L"]";\r
+ return config_.name + L"[" + boost::lexical_cast<std::wstring>(channel_index_) + L"-" + boost::lexical_cast<std::wstring>(sub_index_) + L"|" + format_desc_.name + L"]";\r
}\r
\r
void calculate_aspect()\r
ogl_consumer_proxy(const configuration& config)\r
: config_(config){}\r
\r
- virtual void initialize(const core::video_format_desc& format_desc)\r
+ virtual void initialize(const core::video_format_desc& format_desc, int channel_index, int sub_index)\r
{\r
consumer_.reset();\r
- consumer_.reset(new ogl_consumer(config_, format_desc));\r
+ consumer_.reset(new ogl_consumer(config_, format_desc, channel_index, sub_index));\r
}\r
\r
virtual bool send(const safe_ptr<core::read_frame>& frame)\r
safe_ptr<core::frame_consumer> create_consumer(const boost::property_tree::ptree& ptree) \r
{\r
configuration config;\r
+ config.name = widen(ptree.get("name", narrow(config.name)));\r
config.screen_index = ptree.get("device", config.screen_index+1)-1;\r
config.windowed = ptree.get("windowed", config.windowed);\r
config.key_only = ptree.get("key-only", config.key_only);\r
<channel>\r
<video-mode>PAL</video-mode>\r
<consumers>\r
- <screen></screen>\r
+ <screen>\r
+ <name>My Screen</name>\r
+ </screen>\r
</consumers>\r
</channel>\r
</channels>\r
if(format_desc.format == video_format::invalid)\r
BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Invalid video-mode."));\r
\r
- channels_.push_back(make_safe<video_channel>(channels_.size(), format_desc, ogl_));\r
+ channels_.push_back(make_safe<video_channel>(channels_.size()+1, format_desc, ogl_));\r
\r
int index = 0;\r
BOOST_FOREACH(auto& xml_consumer, xml_channel.second.get_child("consumers"))\r