Orbbec SDK K4A Wrapper
Loading...
Searching...
No Matches
playback.hpp
Go to the documentation of this file.
1
7#ifndef K4A_PLAYBACK_HPP
8#define K4A_PLAYBACK_HPP
9
10#include <k4a/k4a.hpp>
11#include <k4arecord/playback.h>
12
13#include <algorithm>
14#include <chrono>
15#include <string>
16#include <vector>
17
18namespace k4a
19{
20
27{
28public:
33 data_block(k4a_playback_data_block_t handle = nullptr) noexcept : m_handle(handle) {}
34
35 // No Copies allowed
36 data_block(const data_block &) = delete;
37 data_block &operator=(const data_block &) = delete;
38
41 data_block(data_block &&other) noexcept
42 {
43 m_handle = other.m_handle;
44 other.m_handle = nullptr;
45 }
46
48 {
49 reset();
50 }
51
54 data_block &operator=(data_block &&other) noexcept
55 {
56 if (this != &other)
57 {
58 reset();
59 m_handle = other.m_handle;
60 other.m_handle = nullptr;
61 }
62 return *this;
63 }
64
67 explicit operator bool() const noexcept
68 {
69 return is_valid();
70 }
71
74 bool is_valid() const noexcept
75 {
76 return m_handle != nullptr;
77 }
78
81 void reset() noexcept
82 {
83 if (m_handle)
84 {
85 k4a_playback_data_block_release(m_handle);
86 m_handle = nullptr;
87 }
88 }
89
94 std::chrono::microseconds get_device_timestamp_usec() const noexcept
95 {
96 return std::chrono::microseconds(k4a_playback_data_block_get_device_timestamp_usec(m_handle));
97 }
98
103 size_t get_buffer_size() const noexcept
104 {
105 return k4a_playback_data_block_get_buffer_size(m_handle);
106 }
107
112 const uint8_t *get_buffer() const noexcept
113 {
114 return k4a_playback_data_block_get_buffer(m_handle);
115 }
116
117private:
119};
120
129{
130public:
136 playback(k4a_playback_t handle = nullptr) noexcept : m_handle(handle) {}
137
140 playback(playback &&other) noexcept : m_handle(other.m_handle)
141 {
142 other.m_handle = nullptr;
143 }
144
145 playback(const playback &) = delete;
146
147 ~playback()
148 {
149 close();
150 }
151
152 playback &operator=(const playback &) = delete;
153
156 playback &operator=(playback &&other) noexcept
157 {
158 if (this != &other)
159 {
160 close();
161 m_handle = other.m_handle;
162 other.m_handle = nullptr;
163 }
164
165 return *this;
166 }
167
170 explicit operator bool() const noexcept
171 {
172 return is_valid();
173 }
174
177 bool is_valid() const noexcept
178 {
179 return m_handle != nullptr;
180 }
181
186 void close() noexcept
187 {
188 if (m_handle != nullptr)
189 {
190 k4a_playback_close(m_handle);
191 m_handle = nullptr;
192 }
193 }
194
200 std::vector<uint8_t> get_raw_calibration() const
201 {
202 std::vector<uint8_t> calibration;
203 size_t buffer = 0;
204 k4a_buffer_result_t result = k4a_playback_get_raw_calibration(m_handle, nullptr, &buffer);
205
206 if (result == K4A_BUFFER_RESULT_TOO_SMALL && buffer > 1)
207 {
208 calibration.resize(buffer);
209 result = k4a_playback_get_raw_calibration(m_handle, &calibration[0], &buffer);
210 }
211
212 if (result != K4A_BUFFER_RESULT_SUCCEEDED)
213 {
214 throw error("Failed to read raw device calibration from recording!");
215 }
216
217 return calibration;
218 }
219
226 {
227 calibration calib;
228 k4a_result_t result = k4a_playback_get_calibration(m_handle, &calib);
229
230 if (K4A_RESULT_SUCCEEDED != result)
231 {
232 throw error("Failed to read device calibration from recording!");
233 }
234
235 return calib;
236 }
237
243 {
245 k4a_result_t result = k4a_playback_get_record_configuration(m_handle, &config);
246
247 if (K4A_RESULT_SUCCEEDED != result)
248 {
249 throw error("Failed to read record configuration!");
250 }
251
252 return config;
253 }
254
262 {
263 k4a_capture_t capture_handle;
264 k4a_stream_result_t result = k4a_playback_get_next_capture(m_handle, &capture_handle);
265
266 if (K4A_STREAM_RESULT_SUCCEEDED == result)
267 {
268 *cap = capture(capture_handle);
269 return true;
270 }
271 else if (K4A_STREAM_RESULT_EOF == result)
272 {
273 return false;
274 }
275
276 throw error("Failed to get next capture!");
277 }
278
286 {
287 k4a_capture_t capture_handle;
288 k4a_stream_result_t result = k4a_playback_get_previous_capture(m_handle, &capture_handle);
289
290 if (K4A_STREAM_RESULT_SUCCEEDED == result)
291 {
292 *cap = capture(capture_handle);
293 return true;
294 }
295 else if (K4A_STREAM_RESULT_EOF == result)
296 {
297 return false;
298 }
299
300 throw error("Failed to get previous capture!");
301 }
302
308 bool get_tag(const char *name, std::string *out) const
309 {
310 std::string tag;
311 size_t buffer = 0;
312 k4a_buffer_result_t result = k4a_playback_get_tag(m_handle, name, nullptr, &buffer);
313
314 if (result == K4A_BUFFER_RESULT_TOO_SMALL && buffer > 0)
315 {
316 tag.resize(buffer);
317 result = k4a_playback_get_tag(m_handle, name, &tag[0], &buffer);
318 if (result == K4A_BUFFER_RESULT_SUCCEEDED && tag[buffer - 1] == 0)
319 {
320 // std::string expects there to not be as null terminator at the end of its data but
321 // k4a_playback_get_tag adds a null terminator, so we drop the last character of the string after we
322 // get the result back.
323 tag.resize(buffer - 1);
324 }
325 }
326
327 if (result != K4A_BUFFER_RESULT_SUCCEEDED)
328 {
329 return false;
330 }
331
332 *out = std::move(tag);
333
334 return true;
335 }
336
344 {
345 k4a_stream_result_t result = k4a_playback_get_next_imu_sample(m_handle, sample);
346
347 if (K4A_STREAM_RESULT_SUCCEEDED == result)
348 {
349 return true;
350 }
351 else if (K4A_STREAM_RESULT_EOF == result)
352 {
353 return false;
354 }
355
356 throw error("Failed to get next IMU sample!");
357 }
358
366 {
367 k4a_stream_result_t result = k4a_playback_get_previous_imu_sample(m_handle, sample);
368
369 if (K4A_STREAM_RESULT_SUCCEEDED == result)
370 {
371 return true;
372 }
373 else if (K4A_STREAM_RESULT_EOF == result)
374 {
375 return false;
376 }
377
378 throw error("Failed to get previous IMU sample!");
379 }
380
386 void seek_timestamp(std::chrono::microseconds offset, k4a_playback_seek_origin_t origin)
387 {
388 k4a_result_t result = k4a_playback_seek_timestamp(m_handle, offset.count(), origin);
389
390 if (K4A_RESULT_SUCCEEDED != result)
391 {
392 throw error("Failed to seek recording!");
393 }
394 }
395
400 std::chrono::microseconds get_recording_length() const noexcept
401 {
402 return std::chrono::microseconds(k4a_playback_get_recording_length_usec(m_handle));
403 }
404
413 {
414 k4a_result_t result = k4a_playback_set_color_conversion(m_handle, format);
415
416 if (K4A_RESULT_SUCCEEDED != result)
417 {
418 throw error("Failed to set color conversion!");
419 }
420 }
421
428 bool get_next_data_block(const char *track, data_block *block)
429 {
430 k4a_playback_data_block_t block_handle;
431 k4a_stream_result_t result = k4a_playback_get_next_data_block(m_handle, track, &block_handle);
432
433 if (K4A_STREAM_RESULT_SUCCEEDED == result)
434 {
435 *block = data_block(block_handle);
436 return true;
437 }
438 else if (K4A_STREAM_RESULT_EOF == result)
439 {
440 return false;
441 }
442
443 throw error("Failed to get next data block!");
444 }
445
452 bool get_previous_data_block(const char *track, data_block *block)
453 {
454 k4a_playback_data_block_t block_handle;
455 k4a_stream_result_t result = k4a_playback_get_previous_data_block(m_handle, track, &block_handle);
456
457 if (K4A_STREAM_RESULT_SUCCEEDED == result)
458 {
459 *block = data_block(block_handle);
460 return true;
461 }
462 else if (K4A_STREAM_RESULT_EOF == result)
463 {
464 return false;
465 }
466
467 throw error("Failed to get previous data block!");
468 }
469
476 bool get_attachment(const char *attachment, std::vector<uint8_t> *data)
477 {
478 size_t data_size = 0;
479 k4a_buffer_result_t result = k4a_playback_get_attachment(m_handle, attachment, nullptr, &data_size);
480 if (result == K4A_BUFFER_RESULT_TOO_SMALL)
481 {
482 data->resize(data_size);
483 result = k4a_playback_get_attachment(m_handle, attachment, &(*data)[0], &data_size);
484 if (result != K4A_BUFFER_RESULT_SUCCEEDED)
485 {
486 throw error("Failed to read attachment!");
487 }
488 return true;
489 }
490 return false;
491 }
492
498 static playback open(const char *path)
499 {
500 k4a_playback_t handle = nullptr;
501 k4a_result_t result = k4a_playback_open(path, &handle);
502
503 if (K4A_RESULT_SUCCEEDED != result)
504 {
505 throw error("Failed to open recording!");
506 }
507
508 return playback(handle);
509 }
510
511private:
512 k4a_playback_t m_handle;
513};
514
515} // namespace k4a
516
517#endif
data_block(k4a_playback_data_block_t handle=nullptr) noexcept
Definition: playback.hpp:33
void reset() noexcept
Definition: playback.hpp:81
const uint8_t * get_buffer() const noexcept
Definition: playback.hpp:112
std::chrono::microseconds get_device_timestamp_usec() const noexcept
Definition: playback.hpp:94
size_t get_buffer_size() const noexcept
Definition: playback.hpp:103
data_block & operator=(data_block &&other) noexcept
Definition: playback.hpp:54
bool is_valid() const noexcept
Definition: playback.hpp:74
data_block(data_block &&other) noexcept
Definition: playback.hpp:41
std::vector< uint8_t > get_raw_calibration() const
Definition: playback.hpp:200
void seek_timestamp(std::chrono::microseconds offset, k4a_playback_seek_origin_t origin)
Definition: playback.hpp:386
playback(k4a_playback_t handle=nullptr) noexcept
Definition: playback.hpp:136
bool is_valid() const noexcept
Definition: playback.hpp:177
bool get_previous_data_block(const char *track, data_block *block)
Definition: playback.hpp:452
bool get_next_imu_sample(k4a_imu_sample_t *sample)
Definition: playback.hpp:343
bool get_next_data_block(const char *track, data_block *block)
Definition: playback.hpp:428
bool get_previous_capture(capture *cap)
Definition: playback.hpp:285
bool get_previous_imu_sample(k4a_imu_sample_t *sample)
Definition: playback.hpp:365
bool get_tag(const char *name, std::string *out) const
Definition: playback.hpp:308
static playback open(const char *path)
Definition: playback.hpp:498
std::chrono::microseconds get_recording_length() const noexcept
Definition: playback.hpp:400
calibration get_calibration() const
Definition: playback.hpp:225
void set_color_conversion(k4a_image_format_t format)
Definition: playback.hpp:412
void close() noexcept
Definition: playback.hpp:186
k4a_record_configuration_t get_record_configuration() const
Definition: playback.hpp:242
bool get_attachment(const char *attachment, std::vector< uint8_t > *data)
Definition: playback.hpp:476
playback & operator=(playback &&other) noexcept
Definition: playback.hpp:156
bool get_next_capture(capture *cap)
Definition: playback.hpp:261
playback(playback &&other) noexcept
Definition: playback.hpp:140
k4a_result_t
Definition: k4atypes.h:218
k4a_playback_seek_origin_t
Definition: types.h:144
k4a_buffer_result_t
Definition: k4atypes.h:232
k4a_stream_result_t
Definition: types.h:129
k4a_image_format_t
Definition: k4atypes.h:333
@ K4A_RESULT_SUCCEEDED
Definition: k4atypes.h:219
@ K4A_BUFFER_RESULT_TOO_SMALL
Definition: k4atypes.h:235
@ K4A_BUFFER_RESULT_SUCCEEDED
Definition: k4atypes.h:233
@ K4A_STREAM_RESULT_EOF
Definition: types.h:132
@ K4A_STREAM_RESULT_SUCCEEDED
Definition: types.h:130
K4ARECORD_EXPORT k4a_buffer_result_t k4a_playback_get_attachment(k4a_playback_t playback_handle, const char *file_name, uint8_t *data, size_t *data_size)