1use crate::Capture;
2use crate::*;
3use azure_kinect_sys::k4a::*;
4use azure_kinect_sys::k4arecord::{
5 k4a_record_subtitle_settings_t, k4a_record_t, k4a_record_video_settings_t,
6};
7use std::ffi::CString;
8use std::ptr;
9
10pub struct RecordVideoSettings {
11 pub(crate) value: k4a_record_video_settings_t,
12}
13
14impl RecordVideoSettings {
15 pub fn new(width: u64, height: u64, frame_rate: u64) -> RecordVideoSettings {
16 RecordVideoSettings {
17 value: k4a_record_video_settings_t {
18 width,
19 height,
20 frame_rate,
21 },
22 }
23 }
24
25 #[doc = "< Frame width of the video"]
26 pub fn width(&self) -> u64 {
27 self.value.width
28 }
29 #[doc = "< Frame height of the video"]
30 pub fn height(&self) -> u64 {
31 self.value.height
32 }
33 #[doc = "< Frame rate (frames-per-second) of the video"]
34 pub fn frame_rate(&self) -> u64 {
35 self.value.frame_rate
36 }
37}
38
39pub struct RecordSubtitleSettings {
40 pub(crate) value: k4a_record_subtitle_settings_t,
41}
42
43impl RecordSubtitleSettings {
44 pub fn new(high_freq_data: bool) -> RecordSubtitleSettings {
45 RecordSubtitleSettings {
46 value: k4a_record_subtitle_settings_t { high_freq_data },
47 }
48 }
49
50 pub fn high_freq_data(&self) -> bool {
51 self.value.high_freq_data
52 }
53}
54
55pub struct Record<'a> {
56 pub(crate) api_record: &'a azure_kinect_sys::api::ApiRecord,
57 pub(crate) handle: k4a_record_t,
58}
59
60impl Record<'_> {
61 pub(crate) fn from_handle(
62 api_record: &azure_kinect_sys::api::ApiRecord,
63 handle: k4a_record_t,
64 ) -> Record {
65 Record { api_record, handle }
66 }
67
68 pub fn flush(&self) -> Result<(), Error> {
70 Error::from_k4a_result_t(unsafe { (self.api_record.funcs.k4a_record_flush)(self.handle) })
71 .to_result(())
72 }
73
74 pub fn add_tag(&self, name: &str, value: &str) -> Result<(), Error> {
76 let name = CString::new(name).unwrap_or_default();
77 let value = CString::new(value).unwrap_or_default();
78 Error::from_k4a_result_t(unsafe {
79 (self.api_record.funcs.k4a_record_add_tag)(self.handle, name.as_ptr(), value.as_ptr())
80 })
81 .to_result(())
82 }
83
84 pub fn add_imu_track(&self) -> Result<(), Error> {
86 Error::from_k4a_result_t(unsafe {
87 (self.api_record.funcs.k4a_record_add_imu_track)(self.handle)
88 })
89 .to_result(())
90 }
91
92 pub fn add_attachment(&self, attachment_name: &str, buffer: &[u8]) -> Result<(), Error> {
94 let attachment_name = CString::new(attachment_name).unwrap_or_default();
95 Error::from_k4a_result_t(unsafe {
96 (self.api_record.funcs.k4a_record_add_attachment)(
97 self.handle,
98 attachment_name.as_ptr(),
99 buffer.as_ptr(),
100 buffer.len(),
101 )
102 })
103 .to_result(())
104 }
105
106 pub fn add_custom_video_track(
108 &self,
109 track_name: &str,
110 codec_id: &str,
111 codec_context: &[u8],
112 track_settings: &RecordVideoSettings,
113 ) -> Result<(), Error> {
114 let track_name = CString::new(track_name).unwrap_or_default();
115 let codec_id = CString::new(codec_id).unwrap_or_default();
116 Error::from_k4a_result_t(unsafe {
117 (self.api_record.funcs.k4a_record_add_custom_video_track)(
118 self.handle,
119 track_name.as_ptr(),
120 codec_id.as_ptr(),
121 codec_context.as_ptr(),
122 codec_context.len(),
123 &track_settings.value,
124 )
125 })
126 .to_result(())
127 }
128
129 pub fn add_custom_subtitle_track(
131 &self,
132 track_name: &str,
133 codec_id: &str,
134 codec_context: &[u8],
135 track_settings: &RecordSubtitleSettings,
136 ) -> Result<(), Error> {
137 let track_name = CString::new(track_name).unwrap_or_default();
138 let codec_id = CString::new(codec_id).unwrap_or_default();
139 Error::from_k4a_result_t(unsafe {
140 (self.api_record.funcs.k4a_record_add_custom_subtitle_track)(
141 self.handle,
142 track_name.as_ptr(),
143 codec_id.as_ptr(),
144 codec_context.as_ptr(),
145 codec_context.len(),
146 &track_settings.value,
147 )
148 })
149 .to_result(())
150 }
151
152 pub fn write_header(&self) -> Result<(), Error> {
154 Error::from_k4a_result_t(unsafe {
155 (self.api_record.funcs.k4a_record_write_header)(self.handle)
156 })
157 .to_result(())
158 }
159
160 pub fn write_capture(&self, capture: &Capture) -> Result<(), Error> {
162 Error::from_k4a_result_t(unsafe {
163 (self.api_record.funcs.k4a_record_write_capture)(self.handle, capture.handle as _)
164 })
165 .to_result(())
166 }
167
168 pub fn write_imu_sample(&self, imu_sample: &ImuSample) -> Result<(), Error> {
170 Error::from_k4a_result_t(unsafe {
171 (self.api_record.funcs.k4a_record_write_imu_sample)(
172 self.handle,
173 std::mem::transmute::<k4a_imu_sample_t, _>(imu_sample.value),
174 )
175 })
176 .to_result(())
177 }
178
179 pub fn write_custom_track_data(
180 &self,
181 track_name: &str,
182 device_timestamp_usec: u64,
183 custom_data: &[u8],
184 ) -> Result<(), Error> {
185 let track_name = CString::new(track_name).unwrap_or_default();
186 Error::from_k4a_result_t(unsafe {
187 (self.api_record.funcs.k4a_record_write_custom_track_data)(
188 self.handle,
189 track_name.as_ptr(),
190 device_timestamp_usec,
191 custom_data.as_ptr() as *mut u8,
192 custom_data.len(),
193 )
194 })
195 .to_result(())
196 }
197}
198
199impl Drop for Record<'_> {
200 fn drop(&mut self) {
201 unsafe {
202 (self.api_record.funcs.k4a_record_close)(self.handle);
203 }
204 self.handle = ptr::null_mut();
205 }
206}