Azure Kinect Sensor SDK  refs/heads/master
Documentation for https://github.com/Microsoft/Azure-Kinect-Sensor-SDK
playback.hpp
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 
18 namespace k4a
19 {
20 
27 {
28 public:
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 
47  ~data_block()
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 
117 private:
118  k4a_playback_data_block_t m_handle;
119 };
120 
128 class playback
129 {
130 public:
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 
511 private:
512  k4a_playback_t m_handle;
513 };
514 
515 } // namespace k4a
516 
517 #endif
The result was successful.
Definition: k4atypes.h:233
The result was successful.
Definition: types.h:130
playback(k4a_playback_t handle=nullptr) noexcept
Creates a k4a::playback from a k4a_playback_t Takes ownership of the handle, i.e. ...
Definition: playback.hpp:136
bool get_previous_data_block(const char *track, data_block *block)
Get the previous data block from the recording.
Definition: playback.hpp:452
k4a_result_t
Result code returned by Azure Kinect APIs.
Definition: k4atypes.h:217
Exception type thrown when a K4A API call fails.
Definition: k4a.hpp:33
playback & operator=(playback &&other) noexcept
Moves another k4a::playback into this k4a::playback; other is set to invalid.
Definition: playback.hpp:156
bool get_next_data_block(const char *track, data_block *block)
Get the next data block in the recording.
Definition: playback.hpp:428
std::chrono::microseconds get_device_timestamp_usec() const noexcept
Get the time stamp in micro seconds for the given data_block.
Definition: playback.hpp:94
Handle to an Azure Kinect capture.
Definition: k4atypes.h:122
k4a_buffer_result_t
Result code returned by Azure Kinect APIs.
Definition: k4atypes.h:231
data_block(k4a_playback_data_block_t handle=nullptr) noexcept
Creates a data_block from a k4a_playback_data_block_t Takes ownership of the handle, you should not call k4a_playback_data_block_release on the handle after giving it to the data_block; the data_block will take care of that.
Definition: playback.hpp:33
void seek_timestamp(std::chrono::microseconds offset, k4a_playback_seek_origin_t origin)
Seeks to a specific time point in the recording Throws error on failure.
Definition: playback.hpp:386
k4a_stream_result_t
Return codes returned by Azure Kinect playback API.
Definition: types.h:128
void reset() noexcept
Releases the underlying k4a_playback_data_block_t; the data_block is set to invalid.
Definition: playback.hpp:81
data_block(data_block &&other) noexcept
Moves another data_block into a new data_block.
Definition: playback.hpp:41
bool get_next_imu_sample(k4a_imu_sample_t *sample)
Get the next IMU sample in the recording.
Definition: playback.hpp:343
IMU sample.
Definition: k4atypes.h:1199
static playback open(const char *path)
Opens a K4A recording for playback.
Definition: playback.hpp:498
data_block & operator=(data_block &&other) noexcept
Moves another data_block into this data_block; other is set to invalid.
Definition: playback.hpp:54
calibration get_calibration() const
Get the camera calibration for the K4A device that made the recording, which is used for all transfor...
Definition: playback.hpp:225
std::vector< uint8_t > get_raw_calibration() const
Get the raw calibration blob for the K4A device that made the recording.
Definition: playback.hpp:200
k4a_record_configuration_t get_record_configuration() const
Gets the configuration of the recording.
Definition: playback.hpp:242
Definition: k4a.hpp:20
void close() noexcept
Closes a K4A recording.
Definition: playback.hpp:186
playback(playback &&other) noexcept
Moves another k4a::playback into a new k4a::playback.
Definition: playback.hpp:140
bool get_next_capture(capture *cap)
Get the next capture in the recording.
Definition: playback.hpp:261
std::chrono::microseconds get_recording_length() const noexcept
Get the last valid timestamp in the recording.
Definition: playback.hpp:400
Wrapper for k4a_capture_t.
Definition: k4a.hpp:414
k4a_buffer_result_t k4a_playback_get_attachment(k4a_playback_t playback_handle, const char *file_name, uint8_t *data, size_t *data_size)
Reads an attachment file from a recording.
Wrapper for k4a_playback_data_block_t.
Definition: playback.hpp:26
bool get_previous_imu_sample(k4a_imu_sample_t *sample)
Get the previous IMU sample in the recording.
Definition: playback.hpp:365
Handle to a block of data read from a k4a_playback_t custom track.
Definition: types.h:64
k4a_playback_seek_origin_t
Playback seeking positions.
Definition: types.h:143
bool get_attachment(const char *attachment, std::vector< uint8_t > *data)
Get the attachment block from the recording.
Definition: playback.hpp:476
Structure containing the device configuration used to record.
Definition: types.h:168
const uint8_t * get_buffer() const noexcept
Get the data_block buffer.
Definition: playback.hpp:112
The result was successful.
Definition: k4atypes.h:219
Handle to a k4a recording opened for playback.
Definition: types.h:49
void set_color_conversion(k4a_image_format_t format)
Set the image format that color captures will be converted to.
Definition: playback.hpp:412
bool is_valid() const noexcept
Returns true if the k4a::playback is valid, false otherwise.
Definition: playback.hpp:177
bool is_valid() const noexcept
Returns true if the data_block is valid, false otherwise.
Definition: playback.hpp:74
The input buffer was too small.
Definition: k4atypes.h:235
size_t get_buffer_size() const noexcept
Get the size of the data_block buffer.
Definition: playback.hpp:103
bool get_previous_capture(capture *cap)
Get the previous capture in the recording.
Definition: playback.hpp:285
Wrapper for k4a_playback_t.
Definition: playback.hpp:128
Wrapper for k4a_calibration_t.
Definition: k4a.hpp:645
bool get_tag(const char *name, std::string *out) const
Reads the value of a tag from the recording Returns false if the tag does not exist.
Definition: playback.hpp:308
The end of the data stream was reached.
Definition: types.h:132
k4a_image_format_t
Image format type.
Definition: k4atypes.h:332