tbb::concurrent_unordered_map<int, tbb::concurrent_bounded_queue<std::shared_ptr<SwsContext>>> sws_devices_;\r
tbb::concurrent_bounded_queue<spl::shared_ptr<buffer>> temp_buffers_;\r
public: \r
- boost::unique_future<core::const_array> operator()(std::vector<item> items, const core::video_format_desc& format_desc)\r
+ boost::unique_future<array<const std::uint8_t>> operator()(std::vector<item> items, const core::video_format_desc& format_desc)\r
{ \r
convert(items, format_desc.width, format_desc.height); \r
\r
\r
return async(launch::deferred, [=]\r
{\r
- return core::const_array(result->data(), format_desc.size, true, result);\r
+ return array<const std::uint8_t>(result->data(), format_desc.size, true, result);\r
}); \r
}\r
\r
{ \r
}\r
\r
- boost::unique_future<core::const_array> render(const core::video_format_desc& format_desc)\r
+ boost::unique_future<array<const std::uint8_t>> render(const core::video_format_desc& format_desc)\r
{\r
return renderer_(std::move(items_), format_desc);\r
}\r
\r
virtual core::mutable_frame create_frame(const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode)\r
{\r
- std::vector<core::mutable_array> buffers;\r
+ std::vector<array<std::uint8_t>> buffers;\r
BOOST_FOREACH(auto& plane, desc.planes)\r
{\r
auto buf = spl::make_shared<buffer>(plane.size);\r
- buffers.push_back(core::mutable_array(buf->data(), plane.size, true, buf));\r
+ buffers.push_back(array<std::uint8_t>(buf->data(), plane.size, true, buf));\r
}\r
return core::mutable_frame(std::move(buffers), core::audio_buffer(), tag, desc, frame_rate, field_mode);\r
}\r
void image_mixer::push(const core::frame_transform& transform){impl_->push(transform);}\r
void image_mixer::visit(const core::const_frame& frame){impl_->visit(frame);}\r
void image_mixer::pop(){impl_->pop();}\r
-boost::unique_future<core::const_array> image_mixer::operator()(const core::video_format_desc& format_desc){return impl_->render(format_desc);}\r
+boost::unique_future<array<const std::uint8_t>> image_mixer::operator()(const core::video_format_desc& format_desc){return impl_->render(format_desc);}\r
void image_mixer::begin_layer(core::blend_mode blend_mode){impl_->begin_layer(blend_mode);}\r
void image_mixer::end_layer(){impl_->end_layer();}\r
core::mutable_frame image_mixer::create_frame(const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) {return impl_->create_frame(tag, desc, frame_rate, field_mode);}\r
virtual void visit(const core::const_frame& frame);\r
virtual void pop();\r
\r
- virtual boost::unique_future<core::const_array> operator()(const core::video_format_desc& format_desc) override;\r
+ virtual boost::unique_future<array<const std::uint8_t>> operator()(const core::video_format_desc& format_desc) override;\r
\r
virtual core::mutable_frame create_frame(const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) override;\r
\r
{\r
}\r
\r
- boost::unique_future<core::const_array> operator()(std::vector<layer> layers, const core::video_format_desc& format_desc)\r
+ boost::unique_future<array<const std::uint8_t>> operator()(std::vector<layer> layers, const core::video_format_desc& format_desc)\r
{ \r
if(layers.empty())\r
{ // Bypass GPU with empty frame.\r
auto buffer = spl::make_shared<const std::vector<uint8_t, tbb::cache_aligned_allocator<uint8_t>>>(format_desc.size, 0);\r
return async(launch::deferred, [=]\r
{\r
- return core::const_array(buffer->data(), format_desc.size, true, buffer);\r
+ return array<const std::uint8_t>(buffer->data(), format_desc.size, true, buffer);\r
});\r
} \r
\r
- return flatten(ogl_->begin_invoke([=]() mutable -> boost::shared_future<core::const_array>\r
+ return flatten(ogl_->begin_invoke([=]() mutable -> boost::shared_future<array<const std::uint8_t>>\r
{\r
auto draw_buffer = create_mixer_buffer(format_desc.width, format_desc.height, 4);\r
\r
{ \r
}\r
\r
- boost::unique_future<core::const_array> render(const core::video_format_desc& format_desc)\r
+ boost::unique_future<array<const std::uint8_t>> render(const core::video_format_desc& format_desc)\r
{\r
return renderer_(std::move(layers_), format_desc);\r
}\r
\r
virtual core::mutable_frame create_frame(const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode)\r
{\r
- std::vector<core::mutable_array> buffers;\r
+ std::vector<array<std::uint8_t>> buffers;\r
BOOST_FOREACH(auto& plane, desc.planes) \r
buffers.push_back(ogl_->create_array(plane.size)); \r
\r
void image_mixer::push(const core::frame_transform& transform){impl_->push(transform);}\r
void image_mixer::visit(const core::const_frame& frame){impl_->visit(frame);}\r
void image_mixer::pop(){impl_->pop();}\r
-boost::unique_future<core::const_array> image_mixer::operator()(const core::video_format_desc& format_desc){return impl_->render(format_desc);}\r
+boost::unique_future<array<const std::uint8_t>> image_mixer::operator()(const core::video_format_desc& format_desc){return impl_->render(format_desc);}\r
void image_mixer::begin_layer(core::blend_mode blend_mode){impl_->begin_layer(blend_mode);}\r
void image_mixer::end_layer(){impl_->end_layer();}\r
core::mutable_frame image_mixer::create_frame(const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) {return impl_->create_frame(tag, desc, frame_rate, field_mode);}\r
\r
// Methods\r
\r
- virtual boost::unique_future<core::const_array> operator()(const core::video_format_desc& format_desc) override; \r
+ virtual boost::unique_future<array<const std::uint8_t>> operator()(const core::video_format_desc& format_desc) override; \r
virtual core::mutable_frame create_frame(const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) override;\r
\r
// core::image_mixer\r
};\r
\r
buffer::buffer(std::size_t size, usage usage) : impl_(new impl(size, usage)){}\r
+buffer::buffer(buffer&& other) : impl_(std::move(other.impl_)){}\r
buffer::~buffer(){}\r
+buffer& buffer::operator=(buffer&& other){impl_ = std::move(other.impl_); return *this;}\r
uint8_t* buffer::data(){return impl_->data_;}\r
void buffer::map(){impl_->map();}\r
void buffer::unmap(){impl_->unmap();}\r
void buffer::bind() const{impl_->bind();}\r
void buffer::unbind() const{impl_->unbind();}\r
std::size_t buffer::size() const { return impl_->size_; }\r
+int buffer::id() const {return impl_->pbo_;}\r
\r
}}}
\ No newline at end of file
// Constructors\r
\r
buffer(std::size_t size, usage usage);\r
+ buffer(buffer&& other);\r
~buffer();\r
\r
// Methods\r
+\r
+ buffer& operator=(buffer&& other);\r
\r
void map();\r
void unmap();\r
\r
uint8_t* data();\r
std::size_t size() const; \r
+\r
+ int id() const;\r
+\r
private:\r
struct impl;\r
spl::unique_ptr<impl> impl_;\r
#include <common/gl/gl_check.h>\r
#include <common/os/windows/windows.h>\r
\r
-\r
#include <boost/foreach.hpp>\r
\r
#include <gl/glew.h>\r
{ \r
static_assert(std::is_same<decltype(boost::declval<device>().impl_), spl::shared_ptr<impl>>::value, "impl_ must be shared_ptr");\r
\r
- tbb::concurrent_hash_map<buffer*, std::shared_ptr<texture>> texture_mapping_;\r
+ tbb::concurrent_hash_map<buffer*, std::shared_ptr<texture>> texture_cache_;\r
\r
std::unique_ptr<sf::Context> device_;\r
std::unique_ptr<sf::Context> host_alloc_device_;\r
\r
- std::array<tbb::concurrent_unordered_map<int, tbb::concurrent_bounded_queue<std::shared_ptr<texture>>>, 4> device_pools_;\r
- std::array<tbb::concurrent_unordered_map<int, tbb::concurrent_bounded_queue<std::shared_ptr<buffer>>>, 2> host_pools_;\r
+ std::array<tbb::concurrent_unordered_map<std::size_t, tbb::concurrent_bounded_queue<std::shared_ptr<texture>>>, 4> device_pools_;\r
+ std::array<tbb::concurrent_unordered_map<std::size_t, tbb::concurrent_bounded_queue<std::shared_ptr<buffer>>>, 2> host_pools_;\r
\r
GLuint fbo_;\r
\r
});\r
}\r
\r
- spl::shared_ptr<buffer> create_buffer(int size, buffer::usage usage)\r
+ spl::shared_ptr<buffer> create_buffer(std::size_t size, buffer::usage usage)\r
{\r
CASPAR_VERIFY(size > 0);\r
\r
else\r
buf->unmap();\r
\r
- self->texture_mapping_.erase(buf.get());\r
+ self->texture_cache_.erase(buf.get());\r
\r
pool->push(buf);\r
};\r
});\r
}\r
\r
- core::mutable_array create_array(int size)\r
+ array<std::uint8_t> create_array(std::size_t size)\r
{ \r
auto buf = create_buffer(size, buffer::usage::write_only);\r
- return core::mutable_array(buf->data(), buf->size(), false, buf);\r
+ return array<std::uint8_t>(buf->data(), buf->size(), false, buf);\r
}\r
\r
- boost::unique_future<spl::shared_ptr<texture>> copy_async(const core::const_array& source, int width, int height, int stride)\r
+ boost::unique_future<spl::shared_ptr<texture>> copy_async(const array<const std::uint8_t>& source, int width, int height, int stride)\r
{\r
auto buf = source.storage<spl::shared_ptr<buffer>>();\r
\r
return render_executor_.begin_invoke([=]() -> spl::shared_ptr<texture>\r
{\r
tbb::concurrent_hash_map<buffer*, std::shared_ptr<texture>>::const_accessor a;\r
- if(texture_mapping_.find(a, buf.get()))\r
+ if(texture_cache_.find(a, buf.get()))\r
return spl::make_shared_ptr(a->second);\r
\r
auto texture = create_texture(width, height, stride);\r
texture->copy_from(*buf); \r
\r
- texture_mapping_.insert(std::make_pair(buf.get(), texture));\r
+ texture_cache_.insert(std::make_pair(buf.get(), texture));\r
\r
return texture;\r
\r
}, task_priority::high_priority);\r
}\r
+ \r
+ boost::unique_future<spl::shared_ptr<texture>> copy_async(const array<std::uint8_t>& source, int width, int height, int stride)\r
+ {\r
+ auto buf = source.storage<spl::shared_ptr<buffer>>();\r
+ \r
+ return render_executor_.begin_invoke([=]() -> spl::shared_ptr<texture>\r
+ {\r
+ auto texture = create_texture(width, height, stride);\r
+ texture->copy_from(*buf); \r
+ return texture;\r
+ }, task_priority::high_priority);\r
+ }\r
\r
- boost::unique_future<core::const_array> copy_async(const spl::shared_ptr<texture>& source)\r
+ boost::unique_future<array<const std::uint8_t>> copy_async(const spl::shared_ptr<texture>& source)\r
{\r
- return flatten(render_executor_.begin_invoke([=]() -> boost::shared_future<core::const_array>\r
+ return flatten(render_executor_.begin_invoke([=]() -> boost::shared_future<array<const std::uint8_t>>\r
{\r
auto buffer = create_buffer(source->size(), buffer::usage::read_only); \r
source->copy_to(*buffer); \r
\r
- return make_shared(async(launch::deferred, [=]() mutable -> core::const_array\r
+ auto self = shared_from_this();\r
+ return make_shared(async(launch::deferred, [self, buffer]() mutable -> array<const std::uint8_t>\r
{\r
const auto& buf = buffer.get();\r
if(!buf->data())\r
- alloc_executor_.invoke(std::bind(&buffer::map, std::ref(buf))); // Defer blocking "map" call until data is needed.\r
+ self->alloc_executor_.invoke(std::bind(&buffer::map, std::ref(buf))); // Defer blocking "map" call until data is needed.\r
\r
- return core::const_array(buf->data(), buf->size(), true, buffer);\r
+ return array<const std::uint8_t>(buf->data(), buf->size(), true, buffer);\r
}));\r
}, task_priority::high_priority));\r
}\r
\r
device::device() \r
: executor_(L"OpenGL Rendering Context.")\r
- , impl_(new impl(executor_))\r
-{\r
-}\r
-device::~device(){} \r
+ , impl_(new impl(executor_)){}\r
+device::~device(){}\r
spl::shared_ptr<texture> device::create_texture(int width, int height, int stride){return impl_->create_texture(width, height, stride);}\r
-core::mutable_array device::create_array(int size){return impl_->create_array(size);}\r
-boost::unique_future<spl::shared_ptr<texture>> device::copy_async(const core::const_array& source, int width, int height, int stride){return impl_->copy_async(source, width, height, stride);}\r
-boost::unique_future<core::const_array> device::copy_async(const spl::shared_ptr<texture>& source){return impl_->copy_async(source);}\r
-std::wstring device::version(){return impl_->version();}\r
+array<std::uint8_t> device::create_array(int size){return impl_->create_array(size);}\r
+boost::unique_future<spl::shared_ptr<texture>> device::copy_async(const array<const std::uint8_t>& source, int width, int height, int stride){return impl_->copy_async(source, width, height, stride);}\r
+boost::unique_future<spl::shared_ptr<texture>> device::copy_async(const array<std::uint8_t>& source, int width, int height, int stride){return impl_->copy_async(source, width, height, stride);}\r
+boost::unique_future<array<const std::uint8_t>> device::copy_async(const spl::shared_ptr<texture>& source){return impl_->copy_async(source);}\r
+std::wstring device::version() const{return impl_->version();}\r
\r
\r
}}}\r
~device();\r
\r
// Methods\r
- \r
+ \r
spl::shared_ptr<texture> create_texture(int width, int height, int stride);\r
- core::mutable_array create_array(int size);\r
+ array<std::uint8_t> create_array(int size);\r
\r
- boost::unique_future<spl::shared_ptr<texture>> copy_async(const core::const_array& source, int width, int height, int stride);\r
- boost::unique_future<core::const_array> copy_async(const spl::shared_ptr<texture>& source);\r
+ boost::unique_future<spl::shared_ptr<texture>> copy_async(const array<const std::uint8_t>& source, int width, int height, int stride);\r
+ boost::unique_future<spl::shared_ptr<texture>> copy_async(const array<std::uint8_t>& source, int width, int height, int stride);\r
+ boost::unique_future<array<const std::uint8_t>> copy_async(const spl::shared_ptr<texture>& source);\r
\r
template<typename Func>\r
auto begin_invoke(Func&& func, task_priority priority = task_priority::normal_priority) -> boost::unique_future<decltype(func())> // noexcept\r
\r
// Properties\r
\r
- std::wstring version();\r
+ std::wstring version() const;\r
\r
private:\r
struct impl;\r
\r
struct texture::impl : boost::noncopyable\r
{\r
- GLuint id_;\r
+ GLuint id_;\r
\r
const int width_;\r
const int height_;\r
};\r
\r
texture::texture(int width, int height, int stride) : impl_(new impl(width, height, stride)){}\r
+texture::texture(texture&& other) : impl_(std::move(other.impl_)){}\r
texture::~texture(){}\r
+texture& texture::operator=(texture&& other){impl_ = std::move(other.impl_); return *this;}\r
void texture::bind(int index){impl_->bind(index);}\r
void texture::unbind(){impl_->unbind();}\r
void texture::attach(){impl_->attach();}\r
void texture::copy_to(buffer& dest){impl_->copy_to(dest);}\r
int texture::width() const { return impl_->width_; }\r
int texture::height() const { return impl_->height_; }\r
-int texture::size() const { return impl_->width_*impl_->height_*impl_->stride_; }\r
int texture::stride() const { return impl_->stride_; }\r
+std::size_t texture::size() const { return static_cast<std::size_t>(impl_->width_*impl_->height_*impl_->stride_); }\r
int texture::id() const{ return impl_->id_;}\r
\r
}}}
\ No newline at end of file
#pragma once\r
\r
#include <common/spl/memory.h>\r
-#include <common/forward.h>\r
\r
-FORWARD1(boost, template<typename> class unique_future);\r
+#include <cstddef>\r
\r
namespace caspar { namespace accelerator { namespace ogl {\r
\r
// Constructors\r
\r
texture(int width, int height, int stride);\r
+ texture(texture&& other);\r
~texture();\r
-\r
+ \r
// Methods\r
+\r
+ texture& operator=(texture&& other);\r
\r
void copy_from(buffer& source);\r
void copy_to(buffer& dest);\r
\r
int width() const;\r
int height() const;\r
- int size() const;\r
int stride() const; \r
+ std::size_t size() const;\r
+\r
int id() const;\r
+\r
private:\r
struct impl;\r
spl::unique_ptr<impl> impl_;\r
#include "../assert.h"\r
\r
namespace caspar { namespace core {\r
- \r
-mutable_array::mutable_array(mutable_array&& other)\r
- : ptr_(other.ptr_)\r
- , size_(other.size_)\r
- , cacheable_(other.cacheable_)\r
- , storage_(std::move(other.storage_))\r
-{\r
- CASPAR_ASSERT(storage_);\r
-}\r
- \r
-mutable_array& mutable_array::operator=(mutable_array&& other)\r
-{\r
- ptr_ = other.ptr_;\r
- size_ = other.size_;\r
- cacheable_ = other.cacheable_;\r
- storage_ = std::move(other.storage_);\r
-\r
- CASPAR_ASSERT(storage_);\r
-\r
- return *this;\r
-}\r
- \r
-std::uint8_t* mutable_array::begin() {return ptr_;} \r
-std::uint8_t* mutable_array::data() {return ptr_;}\r
-std::uint8_t* mutable_array::end() {return ptr_ + size_;} \r
-const std::uint8_t* mutable_array::begin() const {return ptr_;} \r
-const std::uint8_t* mutable_array::data() const {return ptr_;}\r
-const std::uint8_t* mutable_array::end() const {return ptr_ + size_;}\r
-std::size_t mutable_array::size() const {return size_;}\r
-bool mutable_array::empty() const {return size() == 0;}\r
-bool mutable_array::cacheable() const {return cacheable_;}\r
-\r
-const_array::const_array(const const_array& other)\r
- : ptr_(other.ptr_)\r
- , size_(other.size_)\r
- , cacheable_(other.cacheable_)\r
- , storage_(other.storage_)\r
-{\r
- CASPAR_ASSERT(storage_);\r
-}\r
-\r
-const_array::const_array(mutable_array&& other)\r
- : ptr_(other.ptr_)\r
- , size_(other.size_)\r
- , cacheable_(other.cacheable_)\r
- , storage_(std::move(other.storage_))\r
-{\r
- CASPAR_ASSERT(storage_);\r
-}\r
-\r
-const_array& const_array::operator=(const const_array& other)\r
-{\r
- const_array(other).swap(*this);\r
- return *this;\r
-}\r
-\r
-void const_array::swap(const_array& other)\r
-{\r
- ptr_ = other.ptr_;\r
- size_ = other.size_;\r
- storage_ = other.storage_;\r
- cacheable_ = other.cacheable_;\r
-}\r
- \r
-const std::uint8_t* const_array::begin() const {return ptr_;} \r
-const std::uint8_t* const_array::data() const {return ptr_;}\r
-const std::uint8_t* const_array::end() const {return ptr_ + size_;}\r
-std::size_t const_array::size() const {return size_;}\r
-bool const_array::empty() const {return size() == 0;}\r
-bool const_array::cacheable() const {return cacheable_;}\r
\r
}}
\ No newline at end of file
\r
FORWARD1(boost, template<typename> class shared_future);\r
\r
-namespace caspar { namespace core {\r
+namespace caspar {\r
\r
-class mutable_array\r
+template<typename T>\r
+class array sealed\r
{\r
- mutable_array(const mutable_array&);\r
- mutable_array& operator=(const mutable_array&);\r
+ array(const array<std::uint8_t>&);\r
+ array& operator=(const array<std::uint8_t>&);\r
\r
- friend class const_array;\r
+ template<typename> friend class array;\r
public:\r
\r
// Static Members\r
// Constructors\r
\r
template<typename T>\r
- explicit mutable_array(std::uint8_t* ptr, std::size_t size, bool cacheable, T&& storage)\r
+ explicit array(std::uint8_t* ptr, std::size_t size, bool cacheable, T&& storage)\r
: ptr_(ptr)\r
, size_(size)\r
, cacheable_(cacheable)\r
{\r
}\r
\r
- mutable_array(mutable_array&& other);\r
+ array(array&& other)\r
+ : ptr_(other.ptr_)\r
+ , size_(other.size_)\r
+ , cacheable_(other.cacheable_)\r
+ , storage_(std::move(other.storage_))\r
+ {\r
+ CASPAR_ASSERT(storage_);\r
+ }\r
\r
// Methods\r
+ \r
+ array& operator=(array&& other)\r
+ {\r
+ ptr_ = other.ptr_;\r
+ size_ = other.size_;\r
+ cacheable_ = other.cacheable_;\r
+ storage_ = std::move(other.storage_);\r
\r
- mutable_array& operator=(mutable_array&& other);\r
+ CASPAR_ASSERT(storage_);\r
\r
- // Properties\r
- \r
- std::uint8_t* begin();\r
- std::uint8_t* data();\r
- std::uint8_t* end();\r
- const std::uint8_t* begin() const;\r
- const std::uint8_t* data() const;\r
- const std::uint8_t* end() const;\r
- std::size_t size() const;\r
- bool empty() const;\r
- bool cacheable() const;\r
+ return *this;\r
+ }\r
+\r
+ // Properties \r
+ \r
+ T* begin() const {return ptr_;} \r
+ T* data() const {return ptr_;}\r
+ T* end() const {return reinterpret_cast<T*>(reinterpret_cast<char*>(ptr_) + size_);}\r
+ std::size_t size() const {return size_;}\r
+ bool empty() const {return size() == 0;}\r
+ bool cacheable() const {return cacheable_;}\r
\r
template<typename T>\r
T storage() const\r
return boost::any_cast<T>(*storage_);\r
}\r
private:\r
- std::uint8_t* ptr_;\r
- std::size_t size_;\r
- bool cacheable_;\r
+ T* ptr_;\r
+ std::size_t size_;\r
+ bool cacheable_;\r
std::unique_ptr<boost::any> storage_;\r
};\r
\r
-class const_array\r
+template<typename T>\r
+class array<const T> sealed\r
{\r
public:\r
\r
// Constructors\r
\r
template<typename T>\r
- explicit const_array(const std::uint8_t* ptr, std::size_t size, bool cacheable, T&& storage)\r
+ explicit array(const std::uint8_t* ptr, std::size_t size, bool cacheable, T&& storage)\r
: ptr_(ptr)\r
, size_(size)\r
, cacheable_(cacheable)\r
{\r
}\r
\r
- const_array(const const_array& other); \r
- const_array(mutable_array&& other);\r
+ array(const array& other)\r
+ : ptr_(other.ptr_)\r
+ , size_(other.size_)\r
+ , cacheable_(other.cacheable_)\r
+ , storage_(other.storage_)\r
+ {\r
+ CASPAR_ASSERT(storage_);\r
+ }\r
+\r
+ array(array<T>&& other)\r
+ : ptr_(other.ptr_)\r
+ , size_(other.size_)\r
+ , cacheable_(other.cacheable_)\r
+ , storage_(std::move(other.storage_))\r
+ {\r
+ CASPAR_ASSERT(storage_);\r
+ }\r
\r
// Methods\r
\r
- const_array& operator=(const const_array& other);\r
- void swap(const_array& other);\r
+ array& operator=(array other)\r
+ {\r
+ other.swap(*this);\r
+ return *this;\r
+ }\r
\r
- // Properties\r
- \r
- const std::uint8_t* begin() const;\r
- const std::uint8_t* data() const;\r
- const std::uint8_t* end() const;\r
- std::size_t size() const;\r
- bool empty() const;\r
- bool cacheable() const;\r
+ void swap(array& other)\r
+ {\r
+ ptr_ = other.ptr_;\r
+ size_ = other.size_;\r
+ storage_ = other.storage_;\r
+ cacheable_ = other.cacheable_;\r
+ }\r
\r
+ // Properties\r
+ \r
+ const T* begin() const {return ptr_;} \r
+ const T* data() const {return ptr_;}\r
+ const T* end() const {return reinterpret_cast<const T*>(reinterpret_cast<const char*>(ptr_) + size_);}\r
+ std::size_t size() const {return size_;}\r
+ bool empty() const {return size() == 0;}\r
+ bool cacheable() const {return cacheable_;}\r
+ \r
template<typename T>\r
T storage() const\r
{\r
}\r
\r
private:\r
- const std::uint8_t* ptr_;\r
- std::size_t size_;\r
- bool cacheable_;\r
+ const T* ptr_;\r
+ std::size_t size_;\r
+ bool cacheable_;\r
std::shared_ptr<boost::any> storage_;\r
};\r
\r
-}}
\ No newline at end of file
+}\r
+\r
+namespace std {\r
+ \r
+template<typename T>\r
+void swap(caspar::array<const T>& lhs, caspar::array<const T>& rhs)\r
+{\r
+ lhs.swap(rhs);\r
+}\r
+\r
+}\r
+\r
\r
struct mutable_frame::impl : boost::noncopyable\r
{ \r
- std::vector<mutable_array> buffers_;\r
+ std::vector<array<std::uint8_t>> buffers_;\r
core::audio_buffer audio_data_;\r
const core::pixel_format_desc desc_;\r
const void* tag_;\r
double frame_rate_;\r
core::field_mode field_mode_;\r
\r
- impl(std::vector<mutable_array> buffers, audio_buffer audio_buffer, const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) \r
+ impl(std::vector<array<std::uint8_t>> buffers, audio_buffer audio_buffer, const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) \r
: buffers_(std::move(buffers))\r
, audio_data_(std::move(audio_buffer))\r
, desc_(desc)\r
}\r
};\r
\r
-mutable_frame::mutable_frame(std::vector<mutable_array> image_buffers, audio_buffer audio_buffer, const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) \r
+mutable_frame::mutable_frame(std::vector<array<std::uint8_t>> image_buffers, audio_buffer audio_buffer, const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) \r
: impl_(new impl(std::move(image_buffers), std::move(audio_buffer), tag, desc, frame_rate, field_mode)){}\r
mutable_frame::~mutable_frame(){}\r
mutable_frame::mutable_frame(mutable_frame&& other) : impl_(std::move(other.impl_)){}\r
}\r
void mutable_frame::swap(mutable_frame& other){impl_.swap(other.impl_);}\r
const core::pixel_format_desc& mutable_frame::pixel_format_desc() const{return impl_->desc_;}\r
-const mutable_array& mutable_frame::image_data(std::size_t index) const{return impl_->buffers_.at(index);}\r
+const array<std::uint8_t>& mutable_frame::image_data(std::size_t index) const{return impl_->buffers_.at(index);}\r
const core::audio_buffer& mutable_frame::audio_data() const{return impl_->audio_data_;}\r
-mutable_array& mutable_frame::image_data(std::size_t index){return impl_->buffers_.at(index);}\r
+array<std::uint8_t>& mutable_frame::image_data(std::size_t index){return impl_->buffers_.at(index);}\r
core::audio_buffer& mutable_frame::audio_data(){return impl_->audio_data_;}\r
double mutable_frame::frame_rate() const{return impl_->frame_rate_;}\r
core::field_mode mutable_frame::field_mode() const{return impl_->field_mode_;}\r
\r
struct const_frame::impl : boost::noncopyable\r
{ \r
- mutable std::vector<boost::shared_future<const_array>> future_buffers_;\r
+ mutable std::vector<boost::shared_future<array<const std::uint8_t>>> future_buffers_;\r
int id_;\r
core::audio_buffer audio_data_;\r
const core::pixel_format_desc desc_;\r
{\r
}\r
\r
- impl(boost::shared_future<const_array> image, audio_buffer audio_buffer, const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) \r
+ impl(boost::shared_future<array<const std::uint8_t>> image, audio_buffer audio_buffer, const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) \r
: audio_data_(std::move(audio_buffer))\r
, desc_(desc)\r
, tag_(tag)\r
{\r
for(std::size_t n = 0; n < desc_.planes.size(); ++n)\r
{\r
- boost::promise<const_array> p;\r
+ boost::promise<array<const std::uint8_t>> p;\r
p.set_value(std::move(other.image_data(n)));\r
future_buffers_.push_back(p.get_future());\r
}\r
}\r
\r
- const_array image_data(int index) const\r
+ array<const std::uint8_t> image_data(int index) const\r
{\r
- return tag_ != empty().tag() ? future_buffers_.at(index).get() : const_array(nullptr, 0, true, 0);\r
+ return tag_ != empty().tag() ? future_buffers_.at(index).get() : array<const std::uint8_t>(nullptr, 0, true, 0);\r
}\r
\r
std::size_t width() const\r
};\r
\r
const_frame::const_frame(const void* tag) : impl_(new impl(tag)){}\r
-const_frame::const_frame(boost::shared_future<const_array> image, audio_buffer audio_buffer, const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) \r
+const_frame::const_frame(boost::shared_future<array<const std::uint8_t>> image, audio_buffer audio_buffer, const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) \r
: impl_(new impl(std::move(image), std::move(audio_buffer), tag, desc, frame_rate, field_mode)){}\r
const_frame::const_frame(mutable_frame&& other) : impl_(new impl(std::move(other))){}\r
const_frame::~const_frame(){}\r
bool const_frame::operator==(const const_frame& other){return *impl_ == *other.impl_;}\r
bool const_frame::operator!=(const const_frame& other){return !(*this == other);}\r
const core::pixel_format_desc& const_frame::pixel_format_desc()const{return impl_->desc_;}\r
-const_array const_frame::image_data(int index)const{return impl_->image_data(index);}\r
+array<const std::uint8_t> const_frame::image_data(int index)const{return impl_->image_data(index);}\r
const core::audio_buffer& const_frame::audio_data()const{return impl_->audio_data_;}\r
double const_frame::frame_rate()const{return impl_->frame_rate_;}\r
core::field_mode const_frame::field_mode()const{return impl_->field_mode_;}\r
\r
#include <common/spl/memory.h>\r
#include <common/forward.h>\r
+#include <common/memory/array.h>\r
\r
#include <boost/range.hpp>\r
#include <boost/any.hpp>\r
FORWARD1(boost, template<typename> class shared_future);\r
\r
namespace caspar { namespace core {\r
-\r
-class const_array;\r
-class mutable_array;\r
-\r
+ \r
typedef std::vector<int32_t, tbb::cache_aligned_allocator<int32_t>> audio_buffer;\r
\r
class mutable_frame sealed\r
\r
// Constructors\r
\r
- explicit mutable_frame(std::vector<mutable_array> image_buffers, \r
+ explicit mutable_frame(std::vector<array<std::uint8_t>> image_buffers, \r
audio_buffer audio_buffer, \r
const void* tag, \r
const struct pixel_format_desc& desc, \r
\r
const struct pixel_format_desc& pixel_format_desc() const;\r
\r
- const mutable_array& image_data(std::size_t index = 0) const;\r
+ const array<std::uint8_t>& image_data(std::size_t index = 0) const;\r
const core::audio_buffer& audio_data() const;\r
\r
- mutable_array& image_data(std::size_t index = 0);\r
+ array<std::uint8_t>& image_data(std::size_t index = 0);\r
core::audio_buffer& audio_data();\r
\r
double frame_rate() const;\r
// Constructors\r
\r
explicit const_frame(const void* tag = nullptr);\r
- explicit const_frame(boost::shared_future<const_array> image, \r
+ explicit const_frame(boost::shared_future<array<const std::uint8_t>> image, \r
audio_buffer audio_buffer, \r
const void* tag, \r
const struct pixel_format_desc& desc, \r
\r
const struct pixel_format_desc& pixel_format_desc() const;\r
\r
- const_array image_data(int index = 0) const;\r
+ array<const std::uint8_t> image_data(int index = 0) const;\r
const core::audio_buffer& audio_data() const;\r
\r
double frame_rate() const;\r
virtual void begin_layer(blend_mode blend_mode) = 0;\r
virtual void end_layer() = 0;\r
\r
- virtual boost::unique_future<const_array> operator()(const struct video_format_desc& format_desc) = 0;\r
+ virtual boost::unique_future<array<const std::uint8_t>> operator()(const struct video_format_desc& format_desc) = 0;\r
\r
virtual class mutable_frame create_frame(const void* tag, const struct pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) = 0;\r
\r
<template-path>D:\casparcg\_templates\</template-path>\r
</paths>\r
<log-level>trace</log-level>\r
- <accelerator>gpu</accelerator>\r
+ <accelerator>auto</accelerator>\r
<flash>\r
<buffer-depth>4</buffer-depth>\r
</flash>\r