From be1e405b1794c57cd563aa89e4463a9f734c9041 Mon Sep 17 00:00:00 2001 From: Eran Date: Tue, 14 Mar 2023 10:11:37 +0200 Subject: [PATCH 1/4] add rsutils::deferred --- .../rsutils/include/rsutils/deferred.h | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 third-party/rsutils/include/rsutils/deferred.h diff --git a/third-party/rsutils/include/rsutils/deferred.h b/third-party/rsutils/include/rsutils/deferred.h new file mode 100644 index 0000000000..e2eaeb494a --- /dev/null +++ b/third-party/rsutils/include/rsutils/deferred.h @@ -0,0 +1,55 @@ +// License: Apache 2.0. See LICENSE file in root directory. +// Copyright(c) 2023 Intel Corporation. All Rights Reserved. + +#pragma once + +#include + + +namespace rsutils { + + +// RAII for a function: calls it on destruction, allowing automatic calls when going out of scope very similar to a +// smart pointer that automatically deletes when going out of scope. +// +class deferred +{ +public: + typedef std::function< void() > fn; + +private: + fn _deferred; + + deferred( const deferred & ) = delete; + deferred & operator=( const deferred & ) = delete; + +public: + deferred( fn && f ) + : _deferred( f ) + { + } + + deferred( deferred && that ) = default; + + bool is_valid() const { return ! ! _deferred; } + operator bool() const { return is_valid(); } + + // Destructor forces deferred call to be executed + ~deferred() + { + if( is_valid() ) + execute(); + } + + // Prevent the deferred call from ever being invoked + void cancel() { _deferred = nullptr; } + + // Returns the deferred function so you can move it somewhere else + fn && detach() { return std::move( _deferred ); } + + // Cause the deferred call to be invoked NOW (throws if nothing there!) + void execute() { _deferred(); } +}; + + +} // namespace rsutils \ No newline at end of file From d0ce810c26900b046b37727cec940fa99d32e32e Mon Sep 17 00:00:00 2001 From: Eran Date: Tue, 14 Mar 2023 10:09:25 +0200 Subject: [PATCH 2/4] change archive to move additional_data --- src/archive.h | 2 +- src/frame-archive.h | 8 ++++---- src/media/ros/ros_reader.cpp | 14 ++++++++++---- src/proc/synthetic-stream.cpp | 15 +++++++++++---- src/sensor.cpp | 5 +++-- src/source.cpp | 10 +++++++--- src/source.h | 5 ++++- 7 files changed, 40 insertions(+), 19 deletions(-) diff --git a/src/archive.h b/src/archive.h index 2d09c1f82d..9170bfe9fd 100644 --- a/src/archive.h +++ b/src/archive.h @@ -17,7 +17,7 @@ namespace librealsense public: virtual callback_invocation_holder begin_callback() = 0; - virtual frame_interface* alloc_and_track(const size_t size, const frame_additional_data& additional_data, bool requires_memory) = 0; + virtual frame_interface* alloc_and_track(const size_t size, frame_additional_data && additional_data, bool requires_memory) = 0; virtual std::shared_ptr get_md_parsers() const = 0; diff --git a/src/frame-archive.h b/src/frame-archive.h index 5ca2052dc9..af758bfaee 100644 --- a/src/frame-archive.h +++ b/src/frame-archive.h @@ -26,7 +26,7 @@ namespace librealsense std::shared_ptr get_sensor() const override { return _sensor.lock(); } void set_sensor(std::shared_ptr s) override { _sensor = s; } - T alloc_frame(const size_t size, const frame_additional_data& additional_data, bool requires_memory) + T alloc_frame(const size_t size, frame_additional_data && additional_data, bool requires_memory) { T backbuffer; //const size_t size = modes[stream].get_image_size(stream); @@ -59,7 +59,7 @@ namespace librealsense { backbuffer.data.resize(size, 0); // TODO: Allow users to provide a custom allocator for frame buffers } - backbuffer.additional_data = additional_data; + backbuffer.additional_data = std::move( additional_data ); return backbuffer; } @@ -160,9 +160,9 @@ namespace librealsense ref->release(); } - frame_interface* alloc_and_track(const size_t size, const frame_additional_data& additional_data, bool requires_memory) override + frame_interface* alloc_and_track(const size_t size, frame_additional_data && additional_data, bool requires_memory) override { - auto frame = alloc_frame(size, additional_data, requires_memory); + auto frame = alloc_frame( size, std::move( additional_data ), requires_memory ); return track_frame(frame); } diff --git a/src/media/ros/ros_reader.cpp b/src/media/ros/ros_reader.cpp index 3532d5b2d1..453663e490 100644 --- a/src/media/ros/ros_reader.cpp +++ b/src/media/ros/ros_reader.cpp @@ -441,8 +441,11 @@ namespace librealsense get_frame_metadata(m_file, info_topic, stream_id, image_data, additional_data); } - frame_interface* frame = m_frame_source->alloc_frame((stream_id.stream_type == RS2_STREAM_DEPTH) ? RS2_EXTENSION_DEPTH_FRAME : RS2_EXTENSION_VIDEO_FRAME, - msg->data.size(), additional_data, true); + frame_interface * frame = m_frame_source->alloc_frame( + ( stream_id.stream_type == RS2_STREAM_DEPTH ) ? RS2_EXTENSION_DEPTH_FRAME : RS2_EXTENSION_VIDEO_FRAME, + msg->data.size(), + std::move( additional_data ), + true ); if (frame == nullptr) { LOG_WARNING("Failed to allocate new frame"); @@ -491,7 +494,10 @@ namespace librealsense get_frame_metadata(m_file, info_topic, stream_id, motion_data, additional_data); } - frame_interface* frame = m_frame_source->alloc_frame(RS2_EXTENSION_MOTION_FRAME, 3 * sizeof(float), additional_data, true); + frame_interface * frame = m_frame_source->alloc_frame( RS2_EXTENSION_MOTION_FRAME, + 3 * sizeof( float ), + std::move( additional_data ), + true ); if (frame == nullptr) { LOG_WARNING("Failed to allocate new frame"); @@ -637,7 +643,7 @@ namespace librealsense additional_data.timestamp = timestamp_ms.count(); - frame_interface* new_frame = m_frame_source->alloc_frame(frame_type, frame_size, additional_data, true); + frame_interface* new_frame = m_frame_source->alloc_frame(frame_type, frame_size, std::move( additional_data ), true); if (new_frame == nullptr) { LOG_WARNING("Failed to allocate new frame"); diff --git a/src/proc/synthetic-stream.cpp b/src/proc/synthetic-stream.cpp index 30038f2ade..0d84e721c6 100644 --- a/src/proc/synthetic-stream.cpp +++ b/src/proc/synthetic-stream.cpp @@ -341,7 +341,11 @@ namespace librealsense data.system_time = _actual_source.get_time(); data.is_blocking = original->is_blocking(); - auto res = _actual_source.alloc_frame(frame_type, vid_stream->get_width() * vid_stream->get_height() * sizeof(float) * 5, data, true); + auto res + = _actual_source.alloc_frame( frame_type, + vid_stream->get_width() * vid_stream->get_height() * sizeof( float ) * 5, + std::move( data ), + true ); if (!res) throw wrong_api_call_sequence_exception("Out of frame resources!"); res->set_sensor(original->get_sensor()); res->set_stream(stream); @@ -402,7 +406,7 @@ namespace librealsense auto of = dynamic_cast(original); frame_additional_data data = of->additional_data; - auto res = _actual_source.alloc_frame(frame_type, stride * height, data, true); + auto res = _actual_source.alloc_frame( frame_type, stride * height, std::move( data ), true ); if (!res) throw wrong_api_call_sequence_exception("Out of frame resources!"); vf = dynamic_cast(res); vf->metadata_parsers = of->metadata_parsers; @@ -425,7 +429,7 @@ namespace librealsense { auto of = dynamic_cast(original); frame_additional_data data = of->additional_data; - auto res = _actual_source.alloc_frame(frame_type, of->get_frame_data_size(), data, true); + auto res = _actual_source.alloc_frame( frame_type, of->get_frame_data_size(), std::move( data ), true ); if (!res) throw wrong_api_call_sequence_exception("Out of frame resources!"); auto mf = dynamic_cast(res); mf->metadata_parsers = of->metadata_parsers; @@ -471,7 +475,10 @@ namespace librealsense for (auto&& f : holders) req_size += get_embeded_frames_size(f.frame); - auto res = _actual_source.alloc_frame(RS2_EXTENSION_COMPOSITE_FRAME, req_size * sizeof(rs2_frame*), d, true); + auto res = _actual_source.alloc_frame( RS2_EXTENSION_COMPOSITE_FRAME, + req_size * sizeof( rs2_frame * ), + std::move( d ), + true ); if (!res) return nullptr; auto cf = static_cast(res); diff --git a/src/sensor.cpp b/src/sensor.cpp index be32c99961..60b7d51525 100644 --- a/src/sensor.cpp +++ b/src/sensor.cpp @@ -457,7 +457,7 @@ void log_callback_end( uint32_t fps, frame_holder fh = _source.alloc_frame( stream_to_frame_types( req_profile_base->get_stream_type() ), expected_size, - fr->additional_data, + std::move( fr->additional_data ), true ); auto diff = environment::get_instance().get_time_service()->get_time() - system_time; if( diff > 10 ) @@ -1013,7 +1013,8 @@ void log_callback_end( uint32_t fps, last_frame_number = frame_counter; last_timestamp = timestamp; - frame_holder frame = _source.alloc_frame(RS2_EXTENSION_MOTION_FRAME, data_size, fr->additional_data, true); + frame_holder frame + = _source.alloc_frame( RS2_EXTENSION_MOTION_FRAME, data_size, std::move( fr->additional_data ), true ); memcpy( (void *)frame->get_frame_data(), sensor_data.fo.pixels, sizeof( byte ) * sensor_data.fo.frame_size ); diff --git a/src/source.cpp b/src/source.cpp index 456835f407..e9e6d81aa9 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -88,11 +88,15 @@ namespace librealsense _metadata_parsers.reset(); } - frame_interface* frame_source::alloc_frame(rs2_extension type, size_t size, frame_additional_data additional_data, bool requires_memory) const + frame_interface * frame_source::alloc_frame( rs2_extension type, + size_t size, + frame_additional_data && additional_data, + bool requires_memory ) const { auto it = _archive.find(type); - if (it == _archive.end()) throw wrong_api_call_sequence_exception("Requested frame type is not supported!"); - return it->second->alloc_and_track(size, additional_data, requires_memory); + if( it == _archive.end() ) + throw wrong_api_call_sequence_exception( "Requested frame type is not supported!" ); + return it->second->alloc_and_track( size, std::move( additional_data ), requires_memory ); } void frame_source::set_sensor(const std::shared_ptr& s) diff --git a/src/source.h b/src/source.h index a8684d09ce..390c650903 100644 --- a/src/source.h +++ b/src/source.h @@ -25,7 +25,10 @@ namespace librealsense std::shared_ptr