]> git.sesse.net Git - casparcg/commitdiff
Improved performance in OSC message formatting especially noticeable in debug mode.
authorHelge Norberg <helge.norberg@svt.se>
Wed, 25 Nov 2015 19:40:08 +0000 (20:40 +0100)
committerHelge Norberg <helge.norberg@svt.se>
Wed, 25 Nov 2015 19:40:08 +0000 (20:40 +0100)
protocol/osc/client.cpp
protocol/osc/oscpack/OscOutboundPacketStream.cpp
protocol/osc/oscpack/OscOutboundPacketStream.h

index 1324bb6735082e74dfd99a7caaa141600ec0d62c..be4c76c3a60b9f2e27a8a35b101279ecea2090cb 100644 (file)
@@ -85,19 +85,34 @@ struct param_visitor : public boost::static_visitor<void>
        void operator()(const std::vector<int8_t>& value)       {o << ::osc::Blob(value.data(), static_cast<unsigned long>(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<char*>(destination.data()), static_cast<unsigned long>(destination.size()));
-       o << ::osc::BeginMessage(e.path().c_str());
-                               
-       param_visitor<decltype(o)> 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<decltype(o)> 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());
 }
 
index 6a005b99e39ff480a28bb569382d7732eb36527e..c39b4d879dfbb7428c7b80bb7537a80187e5f044 100644 (file)
@@ -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<unsigned long>(strlen(addressPattern)) + 1) + 4;
 
     if( required > Capacity() )
-        throw OutOfBufferMemoryException();
+        throw OutOfBufferMemoryException(required);
 }
 
 
@@ -245,7 +245,7 @@ void OutboundPacketStream::CheckForAvailableArgumentSpace( long argumentLength )
             + RoundUp4( static_cast<unsigned long>(end_ - typeTagsCurrent_) + 3 );
 
     if( required > Capacity() )
-        throw OutOfBufferMemoryException();
+        throw OutOfBufferMemoryException(required);
 }
 
 
index 5faefb901d353344f6740a83d4d4d3161a87fc00..242b6d87a191861fd73496c02e0b10bcf621afd1 100644 (file)
@@ -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{