From 1f6cffb8e75978f2b3e54dda3c728f4eb1cb4f59 Mon Sep 17 00:00:00 2001 From: Helge Norberg Date: Wed, 25 Nov 2015 20:40:08 +0100 Subject: [PATCH] Improved performance in OSC message formatting especially noticeable in debug mode. --- protocol/osc/client.cpp | 37 +++++++++++++------ .../osc/oscpack/OscOutboundPacketStream.cpp | 6 +-- .../osc/oscpack/OscOutboundPacketStream.h | 6 ++- 3 files changed, 33 insertions(+), 16 deletions(-) diff --git a/protocol/osc/client.cpp b/protocol/osc/client.cpp index 1324bb673..be4c76c3a 100644 --- a/protocol/osc/client.cpp +++ b/protocol/osc/client.cpp @@ -85,19 +85,34 @@ struct param_visitor : public boost::static_visitor void operator()(const std::vector& value) {o << ::osc::Blob(value.data(), static_cast(value.size()));} }; -void write_osc_event(byte_vector& destination, const core::monitor::message& e) -{ - destination.resize(4096); +void write_osc_event(byte_vector& destination, const core::monitor::message& message, int retry_allocation_attempt = 0) +{ + static std::size_t max_size = 128; + + destination.resize(max_size); ::osc::OutboundPacketStream o(reinterpret_cast(destination.data()), static_cast(destination.size())); - o << ::osc::BeginMessage(e.path().c_str()); - - param_visitor param_visitor(o); - for (const auto& data : e.data()) - boost::apply_visitor(param_visitor, data); - - o << ::osc::EndMessage; - + + try + { + o << ::osc::BeginMessage(message.path().c_str()); + + param_visitor param_visitor(o); + for (const auto& data : message.data()) + boost::apply_visitor(param_visitor, data); + + o << ::osc::EndMessage; + } + catch (const ::osc::OutOfBufferMemoryException& e) + { + if (retry_allocation_attempt > message.data().size()) + throw; + + max_size = e.required; + CASPAR_LOG(trace) << L"[osc] Too small buffer for osc message. Increasing to " << max_size; + return write_osc_event(destination, message, retry_allocation_attempt + 1); + } + destination.resize(o.Size()); } diff --git a/protocol/osc/oscpack/OscOutboundPacketStream.cpp b/protocol/osc/oscpack/OscOutboundPacketStream.cpp index 6a005b99e..c39b4d879 100644 --- a/protocol/osc/oscpack/OscOutboundPacketStream.cpp +++ b/protocol/osc/oscpack/OscOutboundPacketStream.cpp @@ -223,7 +223,7 @@ void OutboundPacketStream::CheckForAvailableBundleSpace() unsigned long required = Size() + ((ElementSizeSlotRequired())?4:0) + 16; if( required > Capacity() ) - throw OutOfBufferMemoryException(); + throw OutOfBufferMemoryException(required); } @@ -234,7 +234,7 @@ void OutboundPacketStream::CheckForAvailableMessageSpace( const char *addressPat + RoundUp4(static_cast(strlen(addressPattern)) + 1) + 4; if( required > Capacity() ) - throw OutOfBufferMemoryException(); + throw OutOfBufferMemoryException(required); } @@ -245,7 +245,7 @@ void OutboundPacketStream::CheckForAvailableArgumentSpace( long argumentLength ) + RoundUp4( static_cast(end_ - typeTagsCurrent_) + 3 ); if( required > Capacity() ) - throw OutOfBufferMemoryException(); + throw OutOfBufferMemoryException(required); } diff --git a/protocol/osc/oscpack/OscOutboundPacketStream.h b/protocol/osc/oscpack/OscOutboundPacketStream.h index 5faefb901..242b6d87a 100644 --- a/protocol/osc/oscpack/OscOutboundPacketStream.h +++ b/protocol/osc/oscpack/OscOutboundPacketStream.h @@ -38,8 +38,10 @@ namespace osc{ class OutOfBufferMemoryException : public Exception{ public: - OutOfBufferMemoryException( const char *w="out of buffer memory" ) - : Exception( w ) {} + OutOfBufferMemoryException(std::size_t required_, const char *w="out of buffer memory" ) + : Exception( w ), required(required_) {} + + std::size_t required; }; class BundleNotInProgressException : public Exception{ -- 2.39.2