prev = it->second;\r
\r
next_audio_transforms_[tag] = next; // Store all active tags, inactive tags will be removed in end_pass.\r
- \r
- \r
+ \r
if(next.get_gain() < 0.001 && prev.get_gain() < 0.001)\r
return;\r
\r
static const int BASE = 1<<15;\r
\r
- auto next_gain = static_cast<int32_t>(next.get_gain()*BASE);\r
- auto prev_gain = static_cast<int32_t>(prev.get_gain()*BASE);\r
+ auto next_gain = static_cast<int>(next.get_gain()*BASE);\r
+ auto prev_gain = static_cast<int>(prev.get_gain()*BASE);\r
\r
int n_samples = audio_data_.size();\r
\r
{\r
int sample_gain = (prev_gain - (prev_gain * n)/n_samples) + (next_gain * n)/n_samples;\r
\r
- int sample = (static_cast<int32_t>(audio_data[n])*sample_gain)/BASE;\r
+ int sample = (static_cast<int>(audio_data[n])*sample_gain)/BASE;\r
\r
- audio_data_[n] = static_cast<int16_t>((static_cast<int32_t>(audio_data_[n]) + sample) & 0xFFFF);\r
+ audio_data_[n] = static_cast<int16_t>((static_cast<int>(audio_data_[n]) + sample) & 0xFFFF);\r
}\r
}\r
);\r
}\r
\r
\r
- std::vector<short> mix()\r
+ std::vector<int16_t> mix()\r
{\r
prev_audio_transforms_ = std::move(next_audio_transforms_); \r
return std::move(audio_data_);\r
void audio_mixer::begin(const core::basic_frame& frame){impl_->begin(frame);}\r
void audio_mixer::visit(core::write_frame& frame){impl_->visit(frame);}\r
void audio_mixer::end(){impl_->end();}\r
-std::vector<short> audio_mixer::mix(){return impl_->mix();}\r
+std::vector<int16_t> audio_mixer::mix(){return impl_->mix();}\r
\r
}}
\ No newline at end of file
virtual void visit(core::write_frame& frame);\r
virtual void end();\r
\r
- std::vector<short> mix();\r
+ std::vector<int16_t> mix();\r
\r
private:\r
struct implementation;\r
CASPAR_LOG(info) << print() << L" Successfully initialized."; \r
}\r
\r
- boost::unique_future<safe_ptr<const host_buffer>> mix_image(std::map<int, safe_ptr<core::basic_frame>> frames)\r
+ boost::unique_future<safe_ptr<host_buffer>> mix_image(std::map<int, safe_ptr<core::basic_frame>> frames)\r
{ \r
auto& root_image_transform = boost::fusion::at_key<core::image_transform>(root_transforms_);\r
auto& image_transforms = boost::fusion::at_key<core::image_transform>(transforms_);\r
return image_mixer_.render();\r
}\r
\r
- std::vector<short> mix_audio(const std::map<int, safe_ptr<core::basic_frame>>& frames)\r
+ std::vector<int16_t> mix_audio(const std::map<int, safe_ptr<core::basic_frame>>& frames)\r
{\r
auto& root_audio_transform = boost::fusion::at_key<core::audio_transform>(root_transforms_);\r
auto& audio_transforms = boost::fusion::at_key<core::audio_transform>(transforms_);\r
{\r
}\r
\r
- boost::unique_future<safe_ptr<const host_buffer>> render()\r
+ boost::unique_future<safe_ptr<host_buffer>> render()\r
{\r
auto read_buffer = read_buffer_;\r
-\r
- auto result = ogl_device::begin_invoke([=]() -> safe_ptr<const host_buffer>\r
- {\r
- read_buffer->map(); // Might block.\r
- return read_buffer;\r
- });\r
-\r
+ \r
auto render_queue = std::move(render_queue_);\r
\r
- ogl_device::begin_invoke([=]() mutable\r
+ return ogl_device::begin_invoke([=]() mutable -> safe_ptr<host_buffer>\r
{\r
local_key_ = false;\r
layer_key_ = false;\r
std::swap(local_key_buffer_, layer_key_buffer_);\r
}\r
\r
- // Start transfer from device to host.\r
+ std::swap(draw_buffer_, write_buffer_);\r
\r
- read_buffer_ = ogl_device::create_host_buffer(format_desc_.size, host_buffer::read_only);\r
- draw_buffer_->write(*read_buffer_);\r
+ // Start transfer from device to host. \r
+ auto result = ogl_device::create_host_buffer(format_desc_.size, host_buffer::read_only); \r
+ write_buffer_->write(*result);\r
\r
- std::swap(draw_buffer_, write_buffer_);\r
+ return result;\r
});\r
- \r
- return std::move(result);\r
}\r
\r
void draw(const render_item& item)\r
void image_mixer::begin(const core::basic_frame& frame){impl_->begin(frame);}\r
void image_mixer::visit(core::write_frame& frame){impl_->visit(frame);}\r
void image_mixer::end(){impl_->end();}\r
-boost::unique_future<safe_ptr<const host_buffer>> image_mixer::render(){return impl_->render();}\r
+boost::unique_future<safe_ptr<host_buffer>> image_mixer::render(){return impl_->render();}\r
safe_ptr<write_frame> image_mixer::create_frame(void* tag, const core::pixel_format_desc& desc){return impl_->create_frame(tag, desc);}\r
void image_mixer::begin_layer(){impl_->begin_layer();}\r
void image_mixer::end_layer(){impl_->end_layer();}\r
void begin_layer();\r
void end_layer();\r
\r
- boost::unique_future<safe_ptr<const host_buffer>> render();\r
+ boost::unique_future<safe_ptr<host_buffer>> render();\r
\r
safe_ptr<write_frame> create_frame(void* tag, const core::pixel_format_desc& format);\r
\r
#include "read_frame.h"\r
\r
#include "gpu/host_buffer.h" \r
+#include "gpu/ogl_device.h"\r
\r
namespace caspar { namespace core {\r
\r
struct read_frame::implementation : boost::noncopyable\r
{\r
- boost::unique_future<safe_ptr<const host_buffer>> image_data_;\r
+ boost::unique_future<safe_ptr<host_buffer>> image_data_;\r
std::vector<int16_t> audio_data_;\r
\r
public:\r
- implementation(boost::unique_future<safe_ptr<const host_buffer>>&& image_data, std::vector<int16_t>&& audio_data) \r
+ implementation(boost::unique_future<safe_ptr<host_buffer>>&& image_data, std::vector<int16_t>&& audio_data) \r
: image_data_(std::move(image_data))\r
, audio_data_(std::move(audio_data)){} \r
\r
{\r
try\r
{\r
+ if(!image_data_.get()->data())\r
+ {\r
+ ogl_device::invoke([&]\r
+ {\r
+ image_data_.get()->map();\r
+ }, high_priority);\r
+ }\r
+\r
if(!image_data_.get()->data())\r
return boost::iterator_range<const uint8_t*>();\r
auto ptr = static_cast<const uint8_t*>(image_data_.get()->data());\r
}\r
};\r
\r
-read_frame::read_frame(boost::unique_future<safe_ptr<const host_buffer>>&& image_data, std::vector<int16_t>&& audio_data) \r
+read_frame::read_frame(boost::unique_future<safe_ptr<host_buffer>>&& image_data, std::vector<int16_t>&& audio_data) \r
: impl_(new implementation(std::move(image_data), std::move(audio_data))){}\r
-read_frame::read_frame(safe_ptr<const host_buffer>&& image_data, std::vector<int16_t>&& audio_data) \r
+read_frame::read_frame(safe_ptr<host_buffer>&& image_data, std::vector<int16_t>&& audio_data) \r
{\r
- boost::promise<safe_ptr<const host_buffer>> p;\r
+ boost::promise<safe_ptr<host_buffer>> p;\r
p.set_value(std::move(image_data));\r
impl_.reset(new implementation(std::move(p.get_future()), std::move(audio_data)));\r
}\r
{\r
read_frame(){}\r
public:\r
- read_frame(boost::unique_future<safe_ptr<const host_buffer>>&& image_data, std::vector<int16_t>&& audio_data);\r
- read_frame(safe_ptr<const host_buffer>&& image_data, std::vector<int16_t>&& audio_data);\r
+ read_frame(boost::unique_future<safe_ptr<host_buffer>>&& image_data, std::vector<int16_t>&& audio_data);\r
+ read_frame(safe_ptr<host_buffer>&& image_data, std::vector<int16_t>&& audio_data);\r
\r
virtual const boost::iterator_range<const uint8_t*> image_data() const;\r
virtual const boost::iterator_range<const int16_t*> audio_data() const;\r
\r
bmp_.reset(CreateDIBSection(static_cast<HDC>(hdc_.get()), &info, DIB_RGB_COLORS, reinterpret_cast<void**>(&bmp_data_), 0, 0), DeleteObject);\r
SelectObject(static_cast<HDC>(hdc_.get()), bmp_.get()); \r
+\r
+ if(!bmp_data_)\r
+ BOOST_THROW_EXCEPTION(std::bad_alloc());\r
}\r
\r
operator HDC() {return static_cast<HDC>(hdc_.get());}\r