Something went wrong. Try again.
The open source OpenXR runtime
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151// Copyright 2026, Beyley Cardellio// SPDX-License-Identifier: BSL-1.0/*! * @file * @brief Header defining interfaces for time synchronization in Monado. * @author Beyley Cardellio <ep1cm1n10n123@gmail.com> * @ingroup xrt_iface */
#pragma once
#include "xrt/xrt_defines.h"
#ifdef __cplusplusextern "C" {#endif
enum t_timing_event_type{ //! Marks the beginning of an exposure. T_TIMING_EVENT_TYPE_CAMERA_EXPOSURE_START,};
/*! * Marks beginning of a camera exposure, pushed from the source to the sink. */struct t_timing_event_camera_exposure_start{ /*! * The sequence ID of this frame. These may have semantic meaning depending on the source, for example, on a * device with a SLAM/CONTROLLER/CONTROLLER cadence, `sequence_id % 3` will indicate which type of frame is * being exposed. * * This is intentionally left as a generic uint64_t, and not an enum to allow for matching source/sync types to * smuggle this data through while keeping the interface generic to any sink that wants to listen anyway, since * WMR controllers sync to each SLAM frame, and blink on their own for the next two frames. */ uint64_t sequence_id; //! The timestamp of the event, in local monotonic domain. See @ref os_monotonic_get_ns. int64_t timestamp_ns; //! Estimated frame period. May be 0 if unknown. uint64_t frame_period_ns; //! Estimated exposure time of the frame. May be 0 if unknown. uint64_t exposure_time_ns;};
struct t_timing_event{ enum t_timing_event_type type;
union { struct t_timing_event_camera_exposure_start camera_exposure_start; };};
/*! * @interface t_timing_event_sink * * A time sync sink is a component that receives timing events from a stable timing source, such as the exposure of * a camera frame. This allows the sink to attempt to synchronize its internal timing to the source. This is most * useful for devices such as the PS Sense controllers, or the WMR controllers, which need to synchronize their LED * flashes with a camera. * * Objects implementing t_timing_event_sink should likely also implement @ref xrt_frame_node and live within the * lifetime of an @ref xrt_frame_context. */struct t_timing_event_sink{ /*! * A function that the timing event sink will call to push a new timing event. * * @param sink The sink to push the timing event to. * @param event The timing event being pushed. */ void (*push_timing_event)(struct t_timing_event_sink *sink, const struct t_timing_event *event);};
/*! * Helper function for @ref t_timing_event_sink::push_timing_event. * * @copydoc t_timing_event_sink::push_timing_event * * @public @memberof t_timing_event_sink */XRT_NONNULL_ALL static inline voidt_timing_event_sink_push_timing_event(struct t_timing_event_sink *sink, const struct t_timing_event *event){ sink->push_timing_event(sink, event);}
/*! * @interface t_timing_event_source * * A time sync source is a component that generates timing events for an @ref t_timing_event_sink to consume. * * Objects implementing t_timing_event_source should likely also implement @ref xrt_frame_node and live within the * lifetime of an @ref xrt_frame_context. */struct t_timing_event_source{ /*! * Adds an event sink to this source * * @param source The source to add the sink to. * @param sink The sink to add to the source. * * @return 0 on success, or a negative value on failure (for example, the source is full). */ int (*add_sink)(struct t_timing_event_source *source, struct t_timing_event_sink *sink);
/*! * Removes an event sink from this source * * @param source The source to remove the sink from. * @param sink The sink to remove from the source. */ void (*remove_sink)(struct t_timing_event_source *source, struct t_timing_event_sink *sink);};
/*! * Helper function for @ref t_timing_event_source::add_sink. * * @copydoc t_timing_event_source::add_sink * * @public @memberof t_timing_event_source */XRT_NONNULL_ALL static inline intt_timing_event_source_add_sink(struct t_timing_event_source *source, struct t_timing_event_sink *sink){ return source->add_sink(source, sink);}
/*! * Helper function for @ref t_timing_event_source::remove_sink. * * @copydoc t_timing_event_source::remove_sink * * @public @memberof t_timing_event_source */XRT_NONNULL_ALL static inline voidt_timing_event_source_remove_sink(struct t_timing_event_source *source, struct t_timing_event_sink *sink){ source->remove_sink(source, sink);}
#ifdef __cplusplus}#endif