You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
205 lines
7.9 KiB
205 lines
7.9 KiB
// License: Apache 2.0. See LICENSE file in root directory.
|
|
// Copyright(c) 2015 Intel Corporation. All Rights Reserved.
|
|
#pragma once
|
|
|
|
#include "callback-invocation.h"
|
|
#include "core/frame-holder.h"
|
|
|
|
#include <librealsense2/h/rs_sensor.h>
|
|
#include <rsutils/concurrency/concurrency.h>
|
|
#include <stdint.h>
|
|
#include <vector>
|
|
#include <mutex>
|
|
#include <memory>
|
|
#include <map>
|
|
|
|
|
|
namespace librealsense {
|
|
|
|
|
|
class synthetic_source_interface;
|
|
|
|
struct syncronization_environment
|
|
{
|
|
syncronization_environment( synthetic_source_interface * source,
|
|
single_consumer_frame_queue< frame_holder >& matches,
|
|
bool log )
|
|
: source( source )
|
|
, matches( matches )
|
|
, log( log )
|
|
{
|
|
}
|
|
synthetic_source_interface * source;
|
|
single_consumer_frame_queue< frame_holder > & matches;
|
|
bool log = true;
|
|
};
|
|
|
|
typedef int stream_id;
|
|
typedef std::function<void(frame_holder, const syncronization_environment&)> sync_callback;
|
|
|
|
class matcher_interface
|
|
{
|
|
public:
|
|
virtual void dispatch(frame_holder f, const syncronization_environment& env) = 0;
|
|
virtual void sync(frame_holder f, const syncronization_environment& env) = 0;
|
|
virtual void set_callback(sync_callback f) = 0;
|
|
virtual const std::vector<stream_id>& get_streams() const = 0;
|
|
virtual const std::vector<rs2_stream>& get_streams_types() const = 0;
|
|
virtual std::string get_name() const = 0;
|
|
virtual void stop() = 0;
|
|
};
|
|
|
|
class matcher: public matcher_interface
|
|
{
|
|
public:
|
|
matcher(std::vector<stream_id> streams_id = {});
|
|
virtual void sync(frame_holder f, const syncronization_environment& env) override;
|
|
virtual void set_callback(sync_callback f) override;
|
|
const std::vector<stream_id>& get_streams() const override;
|
|
const std::vector<rs2_stream>& get_streams_types() const override;
|
|
|
|
callback_invocation_holder begin_callback();
|
|
virtual ~matcher();
|
|
|
|
virtual std::string get_name() const override;
|
|
bool get_active() const;
|
|
void set_active(const bool active);
|
|
virtual void stop() override {}
|
|
|
|
protected:
|
|
std::vector<stream_id> _streams_id;
|
|
std::vector<rs2_stream> _streams_type;
|
|
sync_callback _callback;
|
|
callbacks_heap _callback_inflight;
|
|
std::string _name;
|
|
bool _active = true;
|
|
};
|
|
|
|
class identity_matcher : public matcher
|
|
{
|
|
public:
|
|
identity_matcher(stream_id stream, rs2_stream streams_type);
|
|
|
|
void dispatch(frame_holder f, const syncronization_environment& env) override;
|
|
|
|
};
|
|
|
|
class composite_matcher : public matcher
|
|
{
|
|
public:
|
|
composite_matcher(std::vector<std::shared_ptr<matcher>> const & matchers, std::string const & name);
|
|
|
|
|
|
virtual bool are_equivalent(frame_holder& a, frame_holder& b) = 0;
|
|
virtual bool is_smaller_than(frame_holder& a, frame_holder& b) = 0;
|
|
virtual bool skip_missing_stream( frame_interface const * waiting_to_be_released,
|
|
matcher * missing,
|
|
frame_header const & last_arrived,
|
|
const syncronization_environment & env )
|
|
= 0;
|
|
virtual void clean_inactive_streams(frame_holder& f) = 0;
|
|
virtual void update_last_arrived(frame_holder& f, matcher* m) = 0;
|
|
|
|
void dispatch(frame_holder f, const syncronization_environment& env) override;
|
|
void sync(frame_holder f, const syncronization_environment& env) override;
|
|
std::shared_ptr<matcher> find_matcher(const frame_holder& f);
|
|
virtual void stop() override;
|
|
|
|
static std::string frames_to_string( std::vector< frame_holder* > const& );
|
|
std::string matchers_to_string( std::vector< matcher* > const& );
|
|
|
|
protected:
|
|
virtual void update_next_expected( std::shared_ptr< matcher > const & matcher,
|
|
const frame_holder & f )
|
|
= 0;
|
|
|
|
struct matcher_queue
|
|
{
|
|
single_consumer_frame_queue< frame_holder > q;
|
|
|
|
matcher_queue();
|
|
};
|
|
|
|
std::map< matcher *, matcher_queue > _frames_queue;
|
|
std::map<stream_id, std::shared_ptr<matcher>> _matchers;
|
|
struct next_expected_t
|
|
{
|
|
double value; // timestamp/frame-number/etc.
|
|
double fps;
|
|
rs2_timestamp_domain domain;
|
|
};
|
|
std::map< matcher *, next_expected_t > _next_expected;
|
|
|
|
std::mutex _mutex;
|
|
};
|
|
|
|
// composite matcher that does not synchronize between any frames, and instead just passes them on to callback
|
|
class composite_identity_matcher : public composite_matcher
|
|
{
|
|
public:
|
|
composite_identity_matcher( std::vector< std::shared_ptr< matcher > > const & matchers );
|
|
|
|
void sync(frame_holder f, const syncronization_environment& env) override;
|
|
virtual bool are_equivalent(frame_holder& a, frame_holder& b) override { return false; }
|
|
virtual bool is_smaller_than(frame_holder& a, frame_holder& b) override { return false; }
|
|
virtual bool skip_missing_stream( frame_interface const * waiting_to_be_released,
|
|
matcher * missing,
|
|
frame_header const & last_arrived,
|
|
const syncronization_environment & env ) override
|
|
{
|
|
return false;
|
|
}
|
|
virtual void clean_inactive_streams(frame_holder& f) override {}
|
|
virtual void update_last_arrived(frame_holder& f, matcher* m) override {}
|
|
|
|
protected:
|
|
void update_next_expected( std::shared_ptr< matcher > const & matcher,
|
|
const frame_holder & f ) override
|
|
{
|
|
}
|
|
};
|
|
|
|
class frame_number_composite_matcher : public composite_matcher
|
|
{
|
|
public:
|
|
frame_number_composite_matcher(
|
|
std::vector< std::shared_ptr< matcher > > const & matchers );
|
|
virtual void update_last_arrived(frame_holder& f, matcher* m) override;
|
|
bool are_equivalent(frame_holder& a, frame_holder& b) override;
|
|
bool is_smaller_than(frame_holder& a, frame_holder& b) override;
|
|
bool skip_missing_stream( frame_interface const * waiting_to_be_released,
|
|
matcher * missing,
|
|
frame_header const & last_arrived,
|
|
const syncronization_environment & env ) override;
|
|
void clean_inactive_streams(frame_holder& f) override;
|
|
void update_next_expected( std::shared_ptr< matcher > const & matcher,
|
|
const frame_holder & f ) override;
|
|
|
|
private:
|
|
std::map<matcher*,unsigned long long> _last_arrived;
|
|
};
|
|
|
|
class timestamp_composite_matcher : public composite_matcher
|
|
{
|
|
public:
|
|
timestamp_composite_matcher( std::vector< std::shared_ptr< matcher > > const & matchers );
|
|
bool are_equivalent(frame_holder& a, frame_holder& b) override;
|
|
bool is_smaller_than(frame_holder& a, frame_holder& b) override;
|
|
virtual void update_last_arrived(frame_holder& f, matcher* m) override;
|
|
void clean_inactive_streams(frame_holder& f) override;
|
|
bool skip_missing_stream( frame_interface const * waiting_to_be_released,
|
|
matcher * missing,
|
|
frame_header const & last_arrived,
|
|
const syncronization_environment & env ) override;
|
|
void update_next_expected( std::shared_ptr< matcher > const & matcher,
|
|
const frame_holder & f ) override;
|
|
|
|
private:
|
|
double get_fps( frame_interface const * f );
|
|
bool are_equivalent( double a, double b, double fps );
|
|
std::map<matcher*, double> _last_arrived;
|
|
};
|
|
|
|
|
|
} // namespace librealsense
|