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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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}