azure_kinect/
playback.rs

1use crate::imu::ImuSample;
2use crate::playback_data_block::PlaybackDataBlock;
3use crate::playback_track::PlaybackTrack;
4use crate::utility::*;
5use crate::*;
6use azure_kinect_sys::k4a::*;
7use azure_kinect_sys::k4arecord::{
8    k4a_playback_data_block_t, k4a_playback_seek_origin_t, k4a_playback_t,
9    k4a_record_configuration_t,
10};
11use std::ptr;
12
13pub struct RecordConfiguration {
14    pub(crate) value: k4a_record_configuration_t,
15}
16
17impl RecordConfiguration {
18    #[doc = " Image format used to record the color camera."]
19    pub fn color_format(&self) -> ImageFormat {
20        ImageFormat::from_primitive(self.value.color_format)
21    }
22    #[doc = " Image resolution used to record the color camera."]
23    pub fn color_resolution(&self) -> ColorResolution {
24        ColorResolution::from_primitive(self.value.color_resolution)
25    }
26    #[doc = " Mode used to record the depth camera."]
27    pub fn depth_mode(&self) -> DepthMode {
28        DepthMode::from_primitive(self.value.depth_mode)
29    }
30    #[doc = " Frame rate used to record the color and depth camera."]
31    pub fn camera_fps(&self) -> Fps {
32        Fps::from_primitive(self.value.camera_fps)
33    }
34    #[doc = " True if the recording contains Color camera frames."]
35    pub fn color_track_enabled(&self) -> bool {
36        self.value.color_track_enabled
37    }
38    #[doc = " True if the recording contains Depth camera frames."]
39    pub fn depth_track_enabled(&self) -> bool {
40        self.value.depth_track_enabled
41    }
42    #[doc = " True if the recording contains IR camera frames."]
43    pub fn ir_track_enabled(&self) -> bool {
44        self.value.ir_track_enabled
45    }
46    #[doc = " True if the recording contains IMU sample data."]
47    pub fn imu_track_enabled(&self) -> bool {
48        self.value.imu_track_enabled
49    }
50    #[doc = " The delay between color and depth images in the recording."]
51    #[doc = " A negative delay means depth images are first { self.value. } and a positive delay means color images are first."]
52    pub fn depth_delay_off_color_usec(&self) -> i32 {
53        self.value.depth_delay_off_color_usec
54    }
55    #[doc = " External synchronization mode"]
56    pub fn wired_sync_mode(&self) -> WiredSyncMode {
57        WiredSyncMode::from_primitive(self.value.wired_sync_mode)
58    }
59    #[doc = " The delay between this recording and the externally synced master camera."]
60    #[doc = " This value is 0 unless \\p wired_sync_mode is set to ::K4A_WIRED_SYNC_MODE_SUBORDINATE"]
61    pub fn subordinate_delay_off_master_usec(&self) -> u32 {
62        self.value.subordinate_delay_off_master_usec
63    }
64    #[doc = " The timestamp offset of the start of the recording. All recorded timestamps are offset by this value such that"]
65    #[doc = " the recording starts at timestamp 0. This value can be used to synchronize timestamps between 2 recording files."]
66    pub fn start_timestamp_offset_usec(&self) -> u32 {
67        self.value.start_timestamp_offset_usec
68    }
69}
70
71pub struct Playback<'a> {
72    pub(crate) factory: &'a FactoryRecord,
73    pub(crate) handle: k4a_playback_t,
74}
75
76impl<'a> Playback<'a> {
77    pub(crate) fn from_handle(
78        factory: &'a FactoryRecord,
79        handle: azure_kinect_sys::k4arecord::k4a_playback_t,
80    ) -> Playback<'a> {
81        Playback { factory, handle }
82    }
83
84    /// Get the raw calibration blob for the K4A device that made the recording.
85    pub fn get_raw_calibration(&self) -> Result<Vec<u8>, Error> {
86        get_k4a_binary_data(&|calibration, buffer| unsafe {
87            (self
88                .factory
89                .api_record
90                .funcs
91                .k4a_playback_get_raw_calibration)(self.handle, calibration, buffer)
92        })
93    }
94
95    /// Get the camera calibration for the K4A device that made the recording, which is used for all transformation
96    pub fn get_calibration(&self) -> Result<Calibration, Error> {
97        let mut calibaraion = k4a_calibration_t::default();
98        Error::from_k4a_result_t(unsafe {
99            (self.factory.api_record.funcs.k4a_playback_get_calibration)(
100                self.handle,
101                std::mem::transmute(&mut calibaraion),
102            )
103        })
104        .to_result_fn(|| Calibration::from_handle(&self.factory.core().api, calibaraion))
105    }
106
107    /// Gets the configuration of the recording
108    pub fn get_record_configuration(&self) -> Result<RecordConfiguration, Error> {
109        let mut configuration = k4a_record_configuration_t::default();
110        Error::from_k4a_result_t(unsafe {
111            (self
112                .factory
113                .api_record
114                .funcs
115                .k4a_playback_get_record_configuration)(self.handle, &mut configuration)
116        })
117        .to_result(RecordConfiguration {
118            value: configuration,
119        })
120    }
121
122    /// Get the next capture in the recording.
123    pub fn get_next_capture(&self) -> Result<Capture, Error> {
124        let mut handle: k4a_capture_t = ptr::null_mut();
125        Error::from_k4a_stream_result_t(unsafe {
126            (self.factory.api_record.funcs.k4a_playback_get_next_capture)(
127                self.handle,
128                std::mem::transmute(&mut handle),
129            )
130        })
131        .to_result_fn(|| Capture::from_handle(&self.factory.core().api, handle))
132    }
133
134    /// Get the previous capture in the recording.
135    pub fn get_previous_capture(&self) -> Result<Capture, Error> {
136        let mut handle: k4a_capture_t = ptr::null_mut();
137        Error::from_k4a_stream_result_t(unsafe {
138            (self
139                .factory
140                .api_record
141                .funcs
142                .k4a_playback_get_previous_capture)(
143                self.handle, std::mem::transmute(&mut handle)
144            )
145        })
146        .to_result_fn(|| Capture::from_handle(&self.factory.core().api, handle))
147    }
148
149    /// Reads the value of a tag from the recording
150    pub fn get_tag(&self, name: &str) -> Result<String, Error> {
151        let name = std::ffi::CString::new(name).unwrap_or_default();
152        get_k4a_string(&|tag, buffer| unsafe {
153            (self.factory.api_record.funcs.k4a_playback_get_tag)(
154                self.handle,
155                name.as_ptr(),
156                tag,
157                buffer,
158            )
159        })
160    }
161
162    /// Get the next IMU sample in the recording.
163    pub fn get_next_imu_sample(&self) -> Result<ImuSample, Error> {
164        let mut imu_sample = k4a_imu_sample_t::default();
165        Error::from_k4a_stream_result_t(unsafe {
166            (self
167                .factory
168                .api_record
169                .funcs
170                .k4a_playback_get_next_imu_sample)(
171                self.handle,
172                std::mem::transmute(&mut imu_sample),
173            )
174        })
175        .to_result(ImuSample::from_native(imu_sample))
176    }
177
178    /// Get the previous IMU sample in the recording.
179    pub fn get_previous_imu_sample(&self) -> Result<ImuSample, Error> {
180        let mut imu_sample = k4a_imu_sample_t::default();
181        Error::from_k4a_stream_result_t(unsafe {
182            (self
183                .factory
184                .api_record
185                .funcs
186                .k4a_playback_get_previous_imu_sample)(
187                self.handle,
188                std::mem::transmute(&mut imu_sample),
189            )
190        })
191        .to_result(ImuSample::from_native(imu_sample))
192    }
193
194    /// Seeks to a specific time point in the recording
195    pub fn seek_timestamp(
196        &self,
197        offset_usec: i64,
198        origin: k4a_playback_seek_origin_t,
199    ) -> Result<(), Error> {
200        Error::from_k4a_result_t(unsafe {
201            (self.factory.api_record.funcs.k4a_playback_seek_timestamp)(
202                self.handle,
203                offset_usec,
204                origin,
205            )
206        })
207        .to_result(())
208    }
209
210    /// Get the last valid timestamp in the recording
211    pub fn get_recording_length_usec(&self) -> u64 {
212        unsafe {
213            (self
214                .factory
215                .api_record
216                .funcs
217                .k4a_playback_get_recording_length_usec)(self.handle)
218        }
219    }
220
221    /// Set the image format that color captures will be converted to. By default the conversion format will be the
222    /// same as the image format stored in the recording file, and no conversion will occur.
223    pub fn set_color_conversion(&mut self, format: ImageFormat) -> Result<(), Error> {
224        Error::from_k4a_result_t(unsafe {
225            (self
226                .factory
227                .api_record
228                .funcs
229                .k4a_playback_set_color_conversion)(self.handle, format.into())
230        })
231        .to_result(())
232    }
233
234    /// Get the next data block in the recording.
235    pub fn get_next_data_block(&self, track: &str) -> Result<PlaybackDataBlock, Error> {
236        let mut block_handle: k4a_playback_data_block_t = ptr::null_mut();
237        let track = std::ffi::CString::new(track).unwrap_or_default();
238
239        Error::from_k4a_stream_result_t(unsafe {
240            (self
241                .factory
242                .api_record
243                .funcs
244                .k4a_playback_get_next_data_block)(
245                self.handle, track.as_ptr(), &mut block_handle
246            )
247        })
248        .to_result_fn(|| PlaybackDataBlock::from_handle(&self.factory.api_record, block_handle))
249    }
250
251    /// Get the previous data block from the recording.
252    pub fn get_previous_data_block(&self, track: &str) -> Result<PlaybackDataBlock, Error> {
253        let mut block_handle: k4a_playback_data_block_t = ptr::null_mut();
254        let track = std::ffi::CString::new(track).unwrap_or_default();
255
256        Error::from_k4a_stream_result_t(unsafe {
257            (self
258                .factory
259                .api_record
260                .funcs
261                .k4a_playback_get_previous_data_block)(
262                self.handle,
263                track.as_ptr(),
264                &mut block_handle,
265            )
266        })
267        .to_result_fn(|| PlaybackDataBlock::from_handle(&self.factory.api_record, block_handle))
268    }
269
270    /// Get the attachment block from the recording.
271    pub fn get_attachment(&self, attachment: &str) -> Result<Vec<u8>, Error> {
272        let attachment = std::ffi::CString::new(attachment).unwrap_or_default();
273        get_k4a_binary_data(&|data, data_size| unsafe {
274            (self.factory.api_record.funcs.k4a_playback_get_attachment)(
275                self.handle,
276                attachment.as_ptr(),
277                data,
278                data_size,
279            )
280        })
281    }
282
283    /// Get the number of tracks in a playback file.
284    pub fn get_track_count(&self) -> usize {
285        unsafe {
286            (self.factory.api_record.funcs.k4a_playback_get_track_count)(self.handle) as usize
287        }
288    }
289
290    /// Gets the track at a specific index.
291    pub fn get_track(&self, track_index: usize) -> Result<PlaybackTrack, Error> {
292        Ok(PlaybackTrack::new(
293            &self,
294            get_k4a_cstring(&|track_name, track_name_size| unsafe {
295                (self.factory.api_record.funcs.k4a_playback_get_track_name)(
296                    self.handle,
297                    track_index,
298                    track_name,
299                    track_name_size,
300                )
301            })?,
302        ))
303    }
304}
305
306impl Drop for Playback<'_> {
307    fn drop(&mut self) {
308        unsafe {
309            (self.factory.api_record.funcs.k4a_playback_close)(self.handle);
310        }
311        self.handle = ptr::null_mut();
312    }
313}