From: ronag Date: Thu, 10 Nov 2011 08:11:52 +0000 (+0000) Subject: git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches... X-Git-Tag: 2.0.0.2~1 X-Git-Url: https://git.sesse.net/?p=casparcg;a=commitdiff_plain;h=01d8a61541548cf535791be39d233799eefc4187 git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@1553 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d --- diff --git a/casparcg.sln b/casparcg.sln index bd760c768..dd18c288a 100644 --- a/casparcg.sln +++ b/casparcg.sln @@ -32,10 +32,6 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "image", "modules\image\image.vcxproj", "{3E11FF65-A9DA-4F80-87F2-A7C6379ED5E2}" EndProject Global - GlobalSection(SubversionScc) = preSolution - Svn-Managed = True - Manager = AnkhSVN - Subversion Support for Visual Studio - EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Develop|Win32 = Develop|Win32 @@ -144,4 +140,8 @@ Global {88F974F0-D09F-4788-8CF8-F563209E60C1} = {C54DA43E-4878-45DB-B76D-35970553672C} {3E11FF65-A9DA-4F80-87F2-A7C6379ED5E2} = {C54DA43E-4878-45DB-B76D-35970553672C} EndGlobalSection + GlobalSection(SubversionScc) = preSolution + Svn-Managed = True + Manager = AnkhSVN - Subversion Support for Visual Studio + EndGlobalSection EndGlobal diff --git a/common/memory/memcpy.h b/common/memory/memcpy.h index 57ab081e0..82040c02c 100644 --- a/common/memory/memcpy.h +++ b/common/memory/memcpy.h @@ -19,18 +19,26 @@ */ #pragma once +#include "../utility/assert.h" +#include "../memory/safe_ptr.h" + #include #include namespace caspar { -namespace internal { +namespace detail { -static void* fast_memcpy(void* dest, const void* source, size_t count) +static void* fast_memcpy_aligned_impl(void* dest, const void* source, size_t count) { - assert(dest != nullptr); - assert(source != nullptr); + CASPAR_ASSERT(dest != nullptr); + CASPAR_ASSERT(source != nullptr); + CASPAR_ASSERT(reinterpret_cast(dest) % 16 == 0); + CASPAR_ASSERT(reinterpret_cast(source) % 16 == 0); + + if(count == 0) + return dest; __asm { @@ -69,27 +77,112 @@ static void* fast_memcpy(void* dest, const void* source, size_t count) return dest; } +static void* fast_memcpy_unaligned_impl(void* dest, const void* source, size_t count) +{ + CASPAR_ASSERT(dest != nullptr); + CASPAR_ASSERT(source != nullptr); + + if(count == 0) + return dest; + + __asm + { + mov esi, source; + mov edi, dest; + mov ebx, count; + shr ebx, 7; + + cpy: + movdqu xmm0, [esi+00h]; + movdqu xmm1, [esi+10h]; + movdqu xmm2, [esi+20h]; + movdqu xmm3, [esi+30h]; + + movdqu [edi+00h], xmm0; + movdqu [edi+10h], xmm1; + movdqu [edi+20h], xmm2; + movdqu [edi+30h], xmm3; + + movdqu xmm4, [esi+40h]; + movdqu xmm5, [esi+50h]; + movdqu xmm6, [esi+60h]; + movdqu xmm7, [esi+70h]; + + movdqu [edi+40h], xmm4; + movdqu [edi+50h], xmm5; + movdqu [edi+60h], xmm6; + movdqu [edi+70h], xmm7; + + lea edi, [edi+80h]; + lea esi, [esi+80h]; + + dec ebx; + jnz cpy; + } + return dest; } -static void* fast_memcpy(void* dest, const void* source, size_t count) +static void* fast_memcpy_small_aligned(char* dest8, const char* source8, size_t count) { - if((reinterpret_cast(source) & 15) || (reinterpret_cast(dest) & 15)) - return memcpy(dest, source, count); + size_t rest = count & 127; + count &= ~127; + + fast_memcpy_aligned_impl(dest8, source8, count); + + return memcpy(dest8+count, source8+count, rest); +} - if(count < 2048) - return memcpy(dest, source, count); +static void* fast_memcpy_small_unaligned(char* dest8, const char* source8, size_t count) +{ + size_t rest = count & 127; + count &= ~127; + + fast_memcpy_unaligned_impl(dest8, source8, count); - size_t rest = count % 128; - count -= rest; + return memcpy(dest8+count, source8+count, rest); +} - tbb::affinity_partitioner ap; +static void* fast_memcpy_aligned(void* dest, const void* source, size_t count) +{ + auto dest8 = reinterpret_cast(dest); + auto source8 = reinterpret_cast(source); + + size_t rest = count & 2047; + count &= ~2047; + tbb::parallel_for(tbb::blocked_range(0, count/128), [&](const tbb::blocked_range& r) { - internal::fast_memcpy(reinterpret_cast(dest) + r.begin()*128, reinterpret_cast(source) + r.begin()*128, r.size()*128); - }, ap); + fast_memcpy_aligned_impl(reinterpret_cast(dest) + r.begin()*128, reinterpret_cast(source) + r.begin()*128, r.size()*128); + }); + + return fast_memcpy_small_aligned(dest8+count, source8+count, rest); +} - return memcpy(reinterpret_cast(dest)+count, reinterpret_cast(source)+count, rest); +static void* fast_memcpy_unaligned(void* dest, const void* source, size_t count) +{ + auto dest8 = reinterpret_cast(dest); + auto source8 = reinterpret_cast(source); + + size_t rest = count & 2047; + count &= ~2047; + + tbb::parallel_for(tbb::blocked_range(0, count/128), [&](const tbb::blocked_range& r) + { + fast_memcpy_unaligned_impl(reinterpret_cast(dest) + r.begin()*128, reinterpret_cast(source) + r.begin()*128, r.size()*128); + }); + + return fast_memcpy_small_unaligned(dest8+count, source8+count, rest); } +} -} \ No newline at end of file +template +T* fast_memcpy(T* dest, const void* source, size_t count) +{ + if((reinterpret_cast(source) & 15) || (reinterpret_cast(dest) & 15)) + return reinterpret_cast(detail::fast_memcpy_unaligned(dest, source, count)); + else + return reinterpret_cast(detail::fast_memcpy_aligned(dest, source, count)); +} + +} diff --git a/common/memory/safe_ptr.h b/common/memory/safe_ptr.h index 88c184af3..32016f37e 100644 --- a/common/memory/safe_ptr.h +++ b/common/memory/safe_ptr.h @@ -1,299 +1,423 @@ -/* -* copyright (c) 2010 Sveriges Television AB -* -* This file is part of CasparCG. -* -* CasparCG is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* CasparCG is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. - -* You should have received a copy of the GNU General Public License -* along with CasparCG. If not, see . -* -*/ #pragma once #include +#include #include -#include -namespace caspar { - +namespace caspar +{ + template class safe_ptr -{ - std::shared_ptr impl_; - template friend class safe_ptr; +{ + template friend class safe_ptr; public: - typedef T element_type; - - safe_ptr() : impl_(std::make_shared()){} - - safe_ptr(const safe_ptr& other) : impl_(other.impl_){} // noexcept - safe_ptr(safe_ptr&& other) : impl_(std::move(other.impl_)){} - - template - safe_ptr(const safe_ptr& other, typename std::enable_if::value, void*>::type = 0) : impl_(other.impl_){} // noexcept - - template - safe_ptr(const U& impl, typename std::enable_if::type, T*>::value, void>::type* = 0) - : impl_(std::make_shared(impl)) {} - - template - safe_ptr(const U& impl, D dtor, typename std::enable_if::type, T*>::value, void>::type* = 0) - : impl_(new U(impl), dtor) {} - - template - safe_ptr(U&& impl, typename std::enable_if::type, T*>::value, void>::type* = 0) - : impl_(std::make_shared(std::forward(impl))) {} - - template - safe_ptr(U&& impl, D dtor, typename std::enable_if::type, T*>::value, void>::type* = 0) - : impl_(new U(std::forward(impl)), dtor) {} - - template - explicit safe_ptr(const std::shared_ptr& impl, typename std::enable_if::value, void*>::type = 0) : impl_(impl) - { - if(!impl_) - throw std::invalid_argument("impl"); - } - - template - explicit safe_ptr(std::shared_ptr&& impl, typename std::enable_if::value, void*>::type = 0) : impl_(std::move(impl)) - { - if(!impl_) - throw std::invalid_argument("impl"); - } - - template - explicit safe_ptr(U* impl, typename std::enable_if::value, void*>::type = 0) : impl_(impl) - { - if(!impl_) - throw std::invalid_argument("impl"); - } - - template - explicit safe_ptr(U* impl, D dtor, typename std::enable_if::value, void*>::type = 0) : impl_(impl, dtor) - { - if(!impl_) - throw std::invalid_argument("impl"); - } - - template - typename std::enable_if::type, T*>::value, safe_ptr&>::type - operator=(const safe_ptr& other) - { - safe_ptr(other).swap(*this); - return *this; - } - - template - typename std::enable_if::type, T*>::value, safe_ptr&>::type - operator=(safe_ptr&& other) - { - safe_ptr(std::move(other)).swap(*this); - return *this; - } - - template - typename std::enable_if::type, T*>::value, safe_ptr&>::type - operator=(U&& impl) - { - safe_ptr temp(std::forward(impl)); - temp.swap(*this); - return *this; - } - - T& operator*() const // noexcept - { - return *impl_.get(); - } - - T* operator->() const // noexcept - { - return impl_.get(); - } - - T* get() const // noexcept - { - return impl_.get(); - } - - bool unique() const { return impl_.unique();} // noexcept - - long use_count() const { return impl_.use_count();} // noexcept - - void swap(safe_ptr& other) { impl_.swap(other.impl_); } // noexcept - - operator const std::shared_ptr&() const { return impl_;} // noexcept - - template - bool owner_before(const safe_ptr& ptr){ return impl_.owner_before(ptr.impl_); } // noexcept - - template - bool owner_before(const std::shared_ptr& ptr){ return impl_.owner_before(ptr); } // noexcept - - template - D* get_deleter(safe_ptr const& ptr) { return impl_.get_deleter(); } // noexcept + typedef T element_type; + + safe_ptr(); // will construct new T object using make_safe() + + safe_ptr(const safe_ptr& other) + : p_(other.p_) + { + } + + template + safe_ptr(const safe_ptr& other, typename std::enable_if::value, void*>::type = 0) + : p_(other.p_) + { + } + + safe_ptr(safe_ptr&& other) + : p_(other.p_) + { + } + + template + safe_ptr(safe_ptr&& other, typename std::enable_if::value, void*>::type = 0) + : p_(other.p_) + { + } + + template + safe_ptr(U&& v, typename std::enable_if::value, void>::type* = 0) + : p_(std::make_shared(std::forward(v))) + { + } + + template + safe_ptr(U&& v, D d, typename std::enable_if::value, void>::type* = 0) + : p_(new U(std::forward(v)), d) + { + } + + template + explicit safe_ptr(const std::shared_ptr& p, typename std::enable_if::value, void*>::type = 0) + : p_(p) + { + if(!p) + throw std::invalid_argument("p"); + } + + template + explicit safe_ptr(std::shared_ptr&& p, typename std::enable_if::value, void*>::type = 0) + : p_(std::move(p)) + { + if(!p_) + throw std::invalid_argument("p"); + } + + template + explicit safe_ptr(U* p, typename std::enable_if::value, void*>::type = 0) + : p_(p) + { + if(!p) + throw std::invalid_argument("p"); + } + + template + explicit safe_ptr(U* p, D d, typename std::enable_if::value, void*>::type = 0) + : p_(p, d) + { + if(!p) + throw std::invalid_argument("p"); + } + + template + typename std::enable_if::value, safe_ptr&>::type + operator=(const safe_ptr& other) + { + safe_ptr(other).swap(*this); + return *this; + } + + template + typename std::enable_if::value, safe_ptr&>::type + operator=(safe_ptr&& other) + { + safe_ptr(std::move(other)).swap(*this); + return *this; + } + + template + typename std::enable_if::value, safe_ptr&>::type + operator=(U&& v) + { + safe_ptr(std::forward(v)).swap(*this); + return *this; + } + + T& operator*() const + { + return *p_.get(); + } + + T* operator->() const + { + return p_.get(); + } + + T* get() const + { + return p_.get(); + } + + bool unique() const + { + return p_.unique(); + } + + long use_count() const + { + return p_.use_count(); + } + + void swap(safe_ptr& other) + { + p_.swap(other.p_); + } + + operator std::shared_ptr() const + { + return p_; + } + + operator std::weak_ptr() const + { + return std::weak_ptr(p_); + } + + template + bool owner_before(const safe_ptr& ptr) + { + return p_.owner_before(ptr.p_); + } + + template + bool owner_before(const std::shared_ptr& ptr) + { + return p_.owner_before(ptr); + } + + template + D* get_deleter(safe_ptr const& ptr) + { + return p_.get_deleter(); + } + +private: + std::shared_ptr p_; }; template -bool operator==(const std::shared_ptr& a, const safe_ptr& b) // noexcept +bool operator==(const safe_ptr& a, const safe_ptr& b) +{ + return a.get() == b.get(); +} + +template +bool operator==(const std::shared_ptr& a, const safe_ptr& b) +{ + return a.get() == b.get(); +} + +template +bool operator==(const safe_ptr& a, const std::shared_ptr& b) +{ + return a.get() == b.get(); +} + +template +bool operator!=(const safe_ptr& a, const safe_ptr& b) +{ + return a.get() != b.get(); +} + +template +bool operator!=(const std::shared_ptr& a, const safe_ptr& b) +{ + return a.get() != b.get(); +} + +template +bool operator!=(const safe_ptr& a, const std::shared_ptr& b) { - return a.get() == b.get(); + return a.get() != b.get(); } template -bool operator==(const safe_ptr& a, const std::shared_ptr& b) // noexcept +bool operator<(const safe_ptr& a, const safe_ptr& b) { - return a.get() == b.get(); + return a.get() < b.get(); } template -bool operator==(const safe_ptr& a, const safe_ptr& b) // noexcept +bool operator<(const std::shared_ptr& a, const safe_ptr& b) { - return a.get() == b.get(); + return a.get() < b.get(); } template -bool operator!=(const std::shared_ptr& a, const safe_ptr& b) // noexcept +bool operator<(const safe_ptr& a, const std::shared_ptr& b) { - return a.get() != b.get(); + return a.get() < b.get(); } template -bool operator!=(const safe_ptr& a, const std::shared_ptr& b) // noexcept +bool operator>(const safe_ptr& a, const safe_ptr& b) { - return a.get() != b.get(); + return a.get() > b.get(); } template -bool operator!=(const safe_ptr& a, const safe_ptr& b) // noexcept +bool operator>(const std::shared_ptr& a, const safe_ptr& b) { - return a.get() != b.get(); + return a.get() > b.get(); } template -bool operator<(const safe_ptr& a, const safe_ptr& b) // noexcept +bool operator>(const safe_ptr& a, const std::shared_ptr& b) { - return a.get() < b.get(); + return a.get() > b.get(); } template -bool operator>(const safe_ptr& a, const safe_ptr& b) // noexcept +bool operator>=(const safe_ptr& a, const safe_ptr& b) { - return a.get() > b.get(); + return a.get() >= b.get(); } template -bool operator>=(const safe_ptr& a, const safe_ptr& b) // noexcept +bool operator>=(const std::shared_ptr& a, const safe_ptr& b) { - return a.get() >= b.get(); + return a.get() >= b.get(); } template -bool operator<=(const safe_ptr& a, const safe_ptr& b) // noexcept +bool operator>=(const safe_ptr& a, const std::shared_ptr& b) { - return a.get() <= b.get(); + return a.get() >= b.get(); +} + +template +bool operator<=(const safe_ptr& a, const safe_ptr& b) +{ + return a.get() <= b.get(); +} + +template +bool operator<=(const std::shared_ptr& a, const safe_ptr& b) +{ + return a.get() <= b.get(); +} + +template +bool operator<=(const safe_ptr& a, const std::shared_ptr& b) +{ + return a.get() <= b.get(); } template -std::basic_ostream& operator<<(std::basic_ostream& out, const safe_ptr& p) +std::basic_ostream& operator<<(std::basic_ostream& out, const safe_ptr& p) { - return out << p.get(); + return out << p.get(); } template -void swap(safe_ptr& a, safe_ptr& b) // noexcept +void swap(safe_ptr& a, safe_ptr& b) { - a.swap(b); + a.swap(b); } template -T* get_pointer(safe_ptr const& p) // noexcept +T* get_pointer(safe_ptr const& p) { - return p.get(); + return p.get(); } template -safe_ptr static_pointer_cast(const safe_ptr& p) // noexcept +safe_ptr static_pointer_cast(const safe_ptr& p) { - return safe_ptr(std::static_pointer_cast(std::shared_ptr(p))); + return safe_ptr(std::static_pointer_cast(std::shared_ptr(p))); } template -safe_ptr const_pointer_cast(const safe_ptr& p) // noexcept +safe_ptr const_pointer_cast(const safe_ptr& p) { - return safe_ptr(std::const_pointer_cast(std::shared_ptr(p))); + return safe_ptr(std::const_pointer_cast(std::shared_ptr(p))); } template safe_ptr dynamic_pointer_cast(const safe_ptr& p) { - auto temp = std::dynamic_pointer_cast(std::shared_ptr(p)); - if(!temp) - throw std::bad_cast(); - return safe_ptr(temp); + auto temp = std::dynamic_pointer_cast(std::shared_ptr(p)); + if(!temp) + throw std::bad_cast(); + return safe_ptr(std::move(temp)); } +// +// enable_safe_this +// +// A safe_ptr version of enable_shared_from_this. +// So that an object may get safe_ptr objects to itself. +// + +template +class enable_safe_from_this : public std::enable_shared_from_this +{ +public: + safe_ptr safe_from_this() + { + return safe_ptr(this->shared_from_this()); + } + + safe_ptr safe_from_this() const + { + return safe_ptr(this->shared_from_this()); + } +protected: + enable_safe_from_this() + { + } + + enable_safe_from_this(const enable_safe_from_this&) + { + } + + enable_safe_from_this& operator=(const enable_safe_from_this&) + { + return *this; + } + + ~enable_safe_from_this () + { + } +}; + +// +// make_safe +// +// safe_ptr equivalents to make_shared +// + template -safe_ptr make_safe(const std::shared_ptr& ptr) +safe_ptr make_safe_ptr(const std::shared_ptr& ptr) { return safe_ptr(ptr); } template -safe_ptr make_safe(std::shared_ptr&& ptr) +safe_ptr make_safe_ptr(std::shared_ptr&& ptr) { - return safe_ptr(std::move(ptr)); + return safe_ptr(ptr); } template safe_ptr make_safe() { - return safe_ptr(); + return safe_ptr(std::make_shared()); } template safe_ptr make_safe(P0&& p0) { - return safe_ptr(std::make_shared(std::forward(p0))); + return safe_ptr(std::make_shared(std::forward(p0))); } template safe_ptr make_safe(P0&& p0, P1&& p1) { - return safe_ptr(std::make_shared(std::forward(p0), std::forward(p1))); + return safe_ptr(std::make_shared(std::forward(p0), std::forward(p1))); } template safe_ptr make_safe(P0&& p0, P1&& p1, P2&& p2) { - return safe_ptr(std::make_shared(std::forward(p0), std::forward(p1), std::forward(p2))); + return safe_ptr(std::make_shared(std::forward(p0), std::forward(p1), std::forward(p2))); } template safe_ptr make_safe(P0&& p0, P1&& p1, P2&& p2, P3&& p3) { - return safe_ptr(std::make_shared(std::forward(p0), std::forward(p1), std::forward(p2), std::forward(p3))); + return safe_ptr(std::make_shared(std::forward(p0), std::forward(p1), std::forward(p2), std::forward(p3))); } template safe_ptr make_safe(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4) { - return safe_ptr(std::make_shared(std::forward(p0), std::forward(p1), std::forward(p2), std::forward(p3), std::forward(p4))); + return safe_ptr(std::make_shared(std::forward(p0), std::forward(p1), std::forward(p2), std::forward(p3), std::forward(p4))); } template safe_ptr make_safe(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4, P5&& p5) { - return safe_ptr(std::make_shared(std::forward(p0), std::forward(p1), std::forward(p2), std::forward(p3), std::forward(p4), std::forward(p5))); + return safe_ptr(std::make_shared(std::forward(p0), std::forward(p1), std::forward(p2), std::forward(p3), std::forward(p4), std::forward(p5))); } -} \ No newline at end of file +template +safe_ptr::safe_ptr() + : p_(make_safe()) +{ +} + +} // namespace diff --git a/core/mixer/gpu/ogl_device.cpp b/core/mixer/gpu/ogl_device.cpp index 9f83317d9..b916d5a26 100644 --- a/core/mixer/gpu/ogl_device.cpp +++ b/core/mixer/gpu/ogl_device.cpp @@ -99,7 +99,7 @@ safe_ptr ogl_device::allocate_device_buffer(size_t width, size_t throw; } } - return make_safe(buffer); + return make_safe_ptr(buffer); } safe_ptr ogl_device::create_device_buffer(size_t width, size_t height, size_t stride) @@ -152,7 +152,7 @@ safe_ptr ogl_device::allocate_host_buffer(size_t size, host_buffer: } } - return make_safe(buffer); + return make_safe_ptr(buffer); } safe_ptr ogl_device::create_host_buffer(size_t size, host_buffer::usage_t usage) diff --git a/core/mixer/image/image_shader.cpp b/core/mixer/image/image_shader.cpp index f6a81cb83..e8662def2 100644 --- a/core/mixer/image/image_shader.cpp +++ b/core/mixer/image/image_shader.cpp @@ -259,7 +259,7 @@ safe_ptr get_image_shader(ogl_device& ogl, bool& blend_modes) if(g_shader) { blend_modes = g_blend_modes; - return make_safe(g_shader); + return make_safe_ptr(g_shader); } try @@ -286,7 +286,7 @@ safe_ptr get_image_shader(ogl_device& ogl, bool& blend_modes) } blend_modes = g_blend_modes; - return make_safe(g_shader); + return make_safe_ptr(g_shader); } -}} \ No newline at end of file +}} diff --git a/core/video_channel.cpp b/core/video_channel.cpp index 476a73eb3..682c98958 100644 --- a/core/video_channel.cpp +++ b/core/video_channel.cpp @@ -152,7 +152,7 @@ public: video_channel::video_channel(int index, const video_format_desc& format_desc, ogl_device& ogl) : impl_(new implementation(index, format_desc, ogl)){} video_channel::video_channel(video_channel&& other) : impl_(std::move(other.impl_)){} safe_ptr video_channel::stage() { return impl_->stage_;} -safe_ptr video_channel::mixer() { return make_safe(impl_->mixer_);} +safe_ptr video_channel::mixer() { return make_safe_ptr(impl_->mixer_);} safe_ptr video_channel::output() { return impl_->output_;} video_format_desc video_channel::get_video_format_desc() const{return impl_->context_.get_format_desc();} void video_channel::set_video_format_desc(const video_format_desc& format_desc){impl_->set_video_format_desc(format_desc);} diff --git a/modules/decklink/consumer/decklink_consumer.cpp b/modules/decklink/consumer/decklink_consumer.cpp index d4abdfa52..dcfbde7f3 100644 --- a/modules/decklink/consumer/decklink_consumer.cpp +++ b/modules/decklink/consumer/decklink_consumer.cpp @@ -319,7 +319,7 @@ public: std::shared_ptr frame; video_frame_buffer_.pop(frame); - schedule_next_video(make_safe(frame)); + schedule_next_video(make_safe_ptr(frame)); } catch(...) { @@ -352,7 +352,7 @@ public: { std::shared_ptr frame; audio_frame_buffer_.pop(frame); - schedule_next_audio(make_safe(frame)); + schedule_next_audio(make_safe_ptr(frame)); } } catch(...) diff --git a/modules/decklink/interop/DeckLinkAPI_h.h b/modules/decklink/interop/DeckLinkAPI_h.h index d499559cd..d88cbf46a 100644 --- a/modules/decklink/interop/DeckLinkAPI_h.h +++ b/modules/decklink/interop/DeckLinkAPI_h.h @@ -4,7 +4,7 @@ /* File created by MIDL compiler version 7.00.0555 */ -/* at Mon Oct 31 09:47:48 2011 +/* at Thu Nov 10 08:57:13 2011 */ /* Compiler settings for interop\DeckLinkAPI.idl: Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 7.00.0555 diff --git a/modules/decklink/interop/DeckLinkAPI_i.c b/modules/decklink/interop/DeckLinkAPI_i.c index 3d4f6ea71..9429f04e1 100644 --- a/modules/decklink/interop/DeckLinkAPI_i.c +++ b/modules/decklink/interop/DeckLinkAPI_i.c @@ -6,7 +6,7 @@ /* File created by MIDL compiler version 7.00.0555 */ -/* at Mon Oct 31 09:47:48 2011 +/* at Thu Nov 10 08:57:13 2011 */ /* Compiler settings for interop\DeckLinkAPI.idl: Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 7.00.0555 diff --git a/modules/decklink/util/util.h b/modules/decklink/util/util.h index 09bca5196..c733a319d 100644 --- a/modules/decklink/util/util.h +++ b/modules/decklink/util/util.h @@ -132,7 +132,7 @@ static CComPtr get_device(size_t device_index) { CComPtr pDecklinkIterator; if(FAILED(pDecklinkIterator.CoCreateInstance(CLSID_CDeckLinkIterator))) - BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("No Decklink drivers installed.")); + BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Decklink drivers not found.")); size_t n = 0; CComPtr decklink; diff --git a/modules/ffmpeg/ffmpeg_error.h b/modules/ffmpeg/ffmpeg_error.h index 017b13c75..71958c4c7 100644 --- a/modules/ffmpeg/ffmpeg_error.h +++ b/modules/ffmpeg/ffmpeg_error.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include @@ -16,6 +17,18 @@ extern "C" namespace caspar { namespace ffmpeg { struct ffmpeg_error : virtual caspar_exception{}; +struct averror_bsf_not_found : virtual ffmpeg_error{}; +struct averror_decoder_not_found : virtual ffmpeg_error{}; +struct averror_demuxer_not_found : virtual ffmpeg_error{}; +struct averror_encoder_not_found : virtual ffmpeg_error{}; +struct averror_eof : virtual ffmpeg_error{}; +struct averror_exit : virtual ffmpeg_error{}; +struct averror_filter_not_found : virtual ffmpeg_error{}; +struct averror_muxer_not_found : virtual ffmpeg_error{}; +struct averror_option_not_found : virtual ffmpeg_error{}; +struct averror_patchwelcome : virtual ffmpeg_error{}; +struct averror_protocol_not_found : virtual ffmpeg_error{}; +struct averror_stream_not_found : virtual ffmpeg_error{}; static std::string av_error_str(int errn) { @@ -26,34 +39,114 @@ static std::string av_error_str(int errn) return std::string(buf); } -#define THROW_ON_ERROR(ret, source, func) \ - if(ret < 0) \ - { \ - BOOST_THROW_EXCEPTION( \ - ffmpeg_error() << \ - msg_info(av_error_str(ret)) << \ - source_info(narrow(source)) << \ - boost::errinfo_api_function(func) << \ - boost::errinfo_errno(AVUNERROR(ret))); \ +static void throw_on_ffmpeg_error(int ret, const char* source, const char* func, const char* local_func, const char* file, int line) +{ + if(ret >= 0) + return; + + switch(ret) + { + case AVERROR_BSF_NOT_FOUND: + ::boost::exception_detail::throw_exception_(averror_bsf_not_found()<< + msg_info(av_error_str(ret)) << + source_info(narrow(source)) << + boost::errinfo_api_function(func) << + boost::errinfo_errno(AVUNERROR(ret)), local_func, file, line); + case AVERROR_DECODER_NOT_FOUND: + ::boost::exception_detail::throw_exception_(averror_decoder_not_found()<< + msg_info(av_error_str(ret)) << + source_info(narrow(source)) << + boost::errinfo_api_function(func) << + boost::errinfo_errno(AVUNERROR(ret)), local_func, file, line); + case AVERROR_DEMUXER_NOT_FOUND: + ::boost::exception_detail::throw_exception_(averror_demuxer_not_found()<< + msg_info(av_error_str(ret)) << + source_info(narrow(source)) << + boost::errinfo_api_function(func) << + boost::errinfo_errno(AVUNERROR(ret)), local_func, file, line); + case AVERROR_ENCODER_NOT_FOUND: + ::boost::exception_detail::throw_exception_(averror_encoder_not_found()<< + msg_info(av_error_str(ret)) << + source_info(narrow(source)) << + boost::errinfo_api_function(func) << + boost::errinfo_errno(AVUNERROR(ret)), local_func, file, line); + case AVERROR_EOF: + ::boost::exception_detail::throw_exception_(averror_eof()<< + msg_info(av_error_str(ret)) << + source_info(narrow(source)) << + boost::errinfo_api_function(func) << + boost::errinfo_errno(AVUNERROR(ret)), local_func, file, line); + case AVERROR_EXIT: + ::boost::exception_detail::throw_exception_(averror_exit()<< + msg_info(av_error_str(ret)) << + source_info(narrow(source)) << + boost::errinfo_api_function(func) << + boost::errinfo_errno(AVUNERROR(ret)), local_func, file, line); + case AVERROR_FILTER_NOT_FOUND: + ::boost::exception_detail::throw_exception_(averror_filter_not_found()<< + msg_info(av_error_str(ret)) << + source_info(narrow(source)) << + boost::errinfo_api_function(func) << + boost::errinfo_errno(AVUNERROR(ret)), local_func, file, line); + case AVERROR_MUXER_NOT_FOUND: + ::boost::exception_detail::throw_exception_(averror_muxer_not_found()<< + msg_info(av_error_str(ret)) << + source_info(narrow(source)) << + boost::errinfo_api_function(func) << + boost::errinfo_errno(AVUNERROR(ret)), local_func, file, line); + case AVERROR_OPTION_NOT_FOUND: + ::boost::exception_detail::throw_exception_(averror_option_not_found()<< + msg_info(av_error_str(ret)) << + source_info(narrow(source)) << + boost::errinfo_api_function(func) << + boost::errinfo_errno(AVUNERROR(ret)), local_func, file, line); + case AVERROR_PATCHWELCOME: + ::boost::exception_detail::throw_exception_(averror_patchwelcome()<< + msg_info(av_error_str(ret)) << + source_info(narrow(source)) << + boost::errinfo_api_function(func) << + boost::errinfo_errno(AVUNERROR(ret)), local_func, file, line); + case AVERROR_PROTOCOL_NOT_FOUND: + ::boost::exception_detail::throw_exception_(averror_protocol_not_found()<< + msg_info(av_error_str(ret)) << + source_info(narrow(source)) << + boost::errinfo_api_function(func) << + boost::errinfo_errno(AVUNERROR(ret)), local_func, file, line); + case AVERROR_STREAM_NOT_FOUND: + ::boost::exception_detail::throw_exception_(averror_stream_not_found()<< + msg_info(av_error_str(ret)) << + source_info(narrow(source)) << + boost::errinfo_api_function(func) << + boost::errinfo_errno(AVUNERROR(ret)), local_func, file, line); + default: + ::boost::exception_detail::throw_exception_(ffmpeg_error()<< + msg_info(av_error_str(ret)) << + source_info(narrow(source)) << + boost::errinfo_api_function(func) << + boost::errinfo_errno(AVUNERROR(ret)), local_func, file, line); } +} + +static void throw_on_ffmpeg_error(int ret, const std::wstring& source, const char* func, const char* local_func, const char* file, int line) +{ + throw_on_ffmpeg_error(ret, narrow(source).c_str(), func, local_func, file, line); +} + + +//#define THROW_ON_ERROR(ret, source, func) throw_on_ffmpeg_error(ret, source, __FUNC__, __FILE__, __LINE__) #define THROW_ON_ERROR_STR_(call) #call #define THROW_ON_ERROR_STR(call) THROW_ON_ERROR_STR_(call) +#define THROW_ON_ERROR(ret, func, source) \ + throw_on_ffmpeg_error(ret, source, func, __FUNCTION__, __FILE__, __LINE__); + #define THROW_ON_ERROR2(call, source) \ [&]() -> int \ { \ int ret = call; \ - if(ret < 0) \ - { \ - BOOST_THROW_EXCEPTION( \ - ffmpeg_error() << \ - msg_info(av_error_str(ret)) << \ - source_info(narrow(source)) << \ - boost::errinfo_api_function(THROW_ON_ERROR_STR(call)) << \ - boost::errinfo_errno(AVUNERROR(ret))); \ - } \ + throw_on_ffmpeg_error(ret, source, THROW_ON_ERROR_STR(call), __FUNCTION__, __FILE__, __LINE__); \ return ret; \ - }(); + }() }} \ No newline at end of file diff --git a/modules/ffmpeg/producer/input.cpp b/modules/ffmpeg/producer/input.cpp index ec661bcfa..47f6ebf74 100644 --- a/modules/ffmpeg/producer/input.cpp +++ b/modules/ffmpeg/producer/input.cpp @@ -227,7 +227,7 @@ private: } else { - THROW_ON_ERROR(ret, print(), "av_read_frame"); + THROW_ON_ERROR(ret, "av_read_frame", print()); if(read_packet->stream_index == default_stream_index_) { @@ -287,7 +287,7 @@ input::input(const safe_ptr& graph, const std::wstring& file : impl_(new implementation(graph, filename, loop, start, length)){} bool input::eof() const {return !impl_->is_running_;} bool input::try_pop(std::shared_ptr& packet){return impl_->try_pop(packet);} -safe_ptr input::context(){return make_safe(impl_->format_context_);} +safe_ptr input::context(){return make_safe_ptr(impl_->format_context_);} size_t input::nb_frames() const {return impl_->nb_frames();} size_t input::nb_loops() const {return impl_->nb_loops();} -}} \ No newline at end of file +}} diff --git a/shell/casparcg.config b/shell/casparcg.config index 1e09cf3bc..5a136818e 100644 --- a/shell/casparcg.config +++ b/shell/casparcg.config @@ -1,37 +1,25 @@ - L:\casparcg\_media\ - L:\casparcg\_log\ - L:\casparcg\_data\ - L:\casparcg\_templates\ + C:\Documents and Settings\rona01\Desktop\CasparCG 2.0 Beta 1\server\media\ + C:\Documents and Settings\rona01\Desktop\CasparCG 2.0 Beta 1\server\log\ + C:\Documents and Settings\rona01\Desktop\CasparCG 2.0 Beta 1\server\data\ + C:\Documents and Settings\rona01\Desktop\CasparCG 2.0 Beta 1\server\templates\ true - false + true true - PAL + 720p5000 - - 1 - true - - - - - PAL - - - 1 - - +