gstreamer_analytics/
batchmeta.rs

1// Copyright (C) 2025 Sebastian Dröge <sebastian@centricular.com>
2//
3// This Source Code Form is subject to the terms of the Mozilla Public License, v2.0.
4// If a copy of the MPL was not distributed with this file, You can obtain one at
5// <https://mozilla.org/MPL/2.0/>.
6//
7// SPDX-License-Identifier: MPL-2.0
8
9use crate::ffi;
10use glib::translate::*;
11use gst::prelude::*;
12
13use std::{fmt, slice, sync::LazyLock};
14
15#[doc(alias = "GST_CAPS_FEATURE_META_GST_ANALYTICS_BATCH_META")]
16pub const CAPS_FEATURE_META_ANALYTICS_BATCH_META: &glib::GStr = unsafe {
17    glib::GStr::from_utf8_with_nul_unchecked(ffi::GST_CAPS_FEATURE_META_GST_ANALYTICS_BATCH_META)
18};
19pub static CAPS_FEATURES_META_ANALYTICS_BATCH_META: LazyLock<gst::CapsFeatures> =
20    LazyLock::new(|| gst::CapsFeatures::new([CAPS_FEATURE_META_ANALYTICS_BATCH_META]));
21
22#[repr(transparent)]
23#[doc(alias = "GstAnalyticsBatchMeta")]
24pub struct AnalyticsBatchMeta(ffi::GstAnalyticsBatchMeta);
25
26unsafe impl Send for AnalyticsBatchMeta {}
27unsafe impl Sync for AnalyticsBatchMeta {}
28
29impl AnalyticsBatchMeta {
30    #[doc(alias = "gst_buffer_add_analytics_batch_meta")]
31    pub fn add<'a>(
32        buffer: &'a mut gst::BufferRef,
33    ) -> gst::MetaRefMut<'a, Self, gst::meta::Standalone> {
34        skip_assert_initialized!();
35
36        unsafe {
37            let meta = ffi::gst_buffer_add_analytics_batch_meta(buffer.as_mut_ptr());
38
39            Self::from_mut_ptr(buffer, meta)
40        }
41    }
42
43    pub fn streams(&self) -> &[AnalyticsBatchStream] {
44        unsafe {
45            if self.0.streams.is_null() {
46                &[]
47            } else {
48                slice::from_raw_parts(self.0.streams as *const _, self.0.n_streams)
49            }
50        }
51    }
52
53    pub fn streams_mut(&mut self) -> &mut [AnalyticsBatchStream] {
54        unsafe {
55            if self.0.streams.is_null() {
56                &mut []
57            } else {
58                slice::from_raw_parts_mut(self.0.streams as *mut _, self.0.n_streams)
59            }
60        }
61    }
62}
63
64unsafe impl gst::MetaAPI for AnalyticsBatchMeta {
65    type GstType = ffi::GstAnalyticsBatchMeta;
66
67    #[doc(alias = "gst_analytics_batch_meta_api_get_type")]
68    #[inline]
69    fn meta_api() -> glib::Type {
70        unsafe { from_glib(ffi::gst_analytics_batch_meta_api_get_type()) }
71    }
72}
73
74impl fmt::Debug for AnalyticsBatchMeta {
75    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
76        f.debug_struct("AnalyticsBatchMeta")
77            .field("streams", &self.streams())
78            .finish()
79    }
80}
81
82#[repr(transparent)]
83#[doc(alias = "GstAnalyticsBatchStream")]
84pub struct AnalyticsBatchStream(ffi::GstAnalyticsBatchStream);
85
86impl AnalyticsBatchStream {
87    pub fn index(&self) -> u32 {
88        self.0.index
89    }
90
91    pub fn buffers(&self) -> &[AnalyticsBatchBuffer] {
92        unsafe {
93            if self.0.buffers.is_null() {
94                &[]
95            } else {
96                slice::from_raw_parts(self.0.buffers as *const _, self.0.n_buffers)
97            }
98        }
99    }
100
101    pub fn buffers_mut(&mut self) -> &mut [AnalyticsBatchBuffer] {
102        unsafe {
103            if self.0.buffers.is_null() {
104                &mut []
105            } else {
106                slice::from_raw_parts_mut(self.0.buffers as *mut _, self.0.n_buffers)
107            }
108        }
109    }
110}
111
112impl fmt::Debug for AnalyticsBatchStream {
113    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
114        f.debug_struct("AnalyticsBatchStream")
115            .field("index", &self.index())
116            .field("buffers", &self.buffers())
117            .finish()
118    }
119}
120
121#[repr(transparent)]
122#[doc(alias = "GstAnalyticsBatchBuffer")]
123pub struct AnalyticsBatchBuffer(ffi::GstAnalyticsBatchBuffer);
124
125impl AnalyticsBatchBuffer {
126    pub fn sticky_events(&self) -> &[gst::Event] {
127        unsafe {
128            if self.0.sticky_events.is_null() {
129                &[]
130            } else {
131                slice::from_raw_parts(self.0.sticky_events as *const _, self.0.n_sticky_events)
132            }
133        }
134    }
135
136    pub fn serialized_events(&self) -> &[gst::Event] {
137        unsafe {
138            if self.0.serialized_events.is_null() {
139                &[]
140            } else {
141                slice::from_raw_parts(
142                    self.0.serialized_events as *const _,
143                    self.0.n_serialized_events,
144                )
145            }
146        }
147    }
148
149    pub fn buffer(&self) -> Option<&gst::BufferRef> {
150        unsafe {
151            if self.0.buffer.is_null() {
152                None
153            } else {
154                Some(gst::BufferRef::from_ptr(self.0.buffer))
155            }
156        }
157    }
158
159    pub fn buffer_owned(&self) -> Option<gst::Buffer> {
160        unsafe {
161            if self.0.buffer.is_null() {
162                None
163            } else {
164                Some(gst::Buffer::from_glib_none(self.0.buffer))
165            }
166        }
167    }
168
169    pub fn buffer_mut(&mut self) -> Option<&mut gst::BufferRef> {
170        unsafe {
171            if self.0.serialized_events.is_null() {
172                None
173            } else {
174                self.0.buffer = gst::ffi::gst_mini_object_make_writable(
175                    self.0.buffer as *mut gst::ffi::GstMiniObject,
176                ) as *mut gst::ffi::GstBuffer;
177                Some(gst::BufferRef::from_mut_ptr(self.0.buffer))
178            }
179        }
180    }
181
182    pub fn buffer_list(&self) -> Option<&gst::BufferListRef> {
183        unsafe {
184            if self.0.buffer_list.is_null() {
185                None
186            } else {
187                Some(gst::BufferListRef::from_ptr(self.0.buffer_list))
188            }
189        }
190    }
191
192    pub fn buffer_list_owned(&self) -> Option<gst::BufferList> {
193        unsafe {
194            if self.0.buffer_list.is_null() {
195                None
196            } else {
197                Some(gst::BufferList::from_glib_none(self.0.buffer_list))
198            }
199        }
200    }
201
202    pub fn buffer_list_mut(&mut self) -> Option<&mut gst::BufferListRef> {
203        unsafe {
204            if self.0.serialized_events.is_null() {
205                None
206            } else {
207                self.0.buffer_list = gst::ffi::gst_mini_object_make_writable(
208                    self.0.buffer_list as *mut gst::ffi::GstMiniObject,
209                ) as *mut gst::ffi::GstBufferList;
210                Some(gst::BufferListRef::from_mut_ptr(self.0.buffer_list))
211            }
212        }
213    }
214
215    #[doc(alias = "gst_analytics_batch_buffer_get_caps")]
216    pub fn caps(&self) -> Option<gst::Caps> {
217        unsafe {
218            from_glib_none(ffi::gst_analytics_batch_buffer_get_caps(mut_override(
219                &self.0,
220            )))
221        }
222    }
223
224    #[doc(alias = "gst_analytics_batch_buffer_get_segment")]
225    pub fn segment(&self) -> Option<gst::Segment> {
226        unsafe {
227            from_glib_none(ffi::gst_analytics_batch_buffer_get_segment(mut_override(
228                &self.0,
229            )))
230        }
231    }
232
233    #[doc(alias = "gst_analytics_batch_buffer_get_stream_id")]
234    pub fn stream_id(&self) -> Option<&glib::GStr> {
235        unsafe {
236            let res = ffi::gst_analytics_batch_buffer_get_stream_id(mut_override(&self.0));
237
238            if res.is_null() {
239                None
240            } else {
241                Some(glib::GStr::from_ptr(res))
242            }
243        }
244    }
245}
246
247impl fmt::Debug for AnalyticsBatchBuffer {
248    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
249        f.debug_struct("AnalyticsBatchBuffer")
250            .field("sticky_events", &self.sticky_events())
251            .field("serialized_events", &self.serialized_events())
252            .field("buffer", &self.buffer())
253            .finish()
254    }
255}