Skip to main content

gstreamer_base/
base_parse_frame.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::{fmt, marker::PhantomData, ptr};
4
5use glib::translate::*;
6
7use crate::{BaseParse, BaseParseFrameFlags, ffi};
8
9/// Frame (context) data passed to each frame parsing virtual methods. In
10/// addition to providing the data to be checked for a valid frame or an already
11/// identified frame, it conveys additional metadata or control information
12/// from and to the subclass w.r.t. the particular frame in question (rather
13/// than global parameters). Some of these may apply to each parsing stage, others
14/// only to some a particular one. These parameters are effectively zeroed at start
15/// of each frame's processing, i.e. parsing virtual method invocation sequence.
16pub struct BaseParseFrame<'a>(
17    ptr::NonNull<ffi::GstBaseParseFrame>,
18    PhantomData<&'a BaseParse>,
19);
20
21unsafe impl Send for BaseParseFrame<'_> {}
22unsafe impl Sync for BaseParseFrame<'_> {}
23
24#[derive(Debug)]
25pub enum Overhead {
26    None,
27    Frame,
28    Bytes(u32),
29}
30
31#[doc(hidden)]
32impl IntoGlib for Overhead {
33    type GlibType = i32;
34
35    #[inline]
36    fn into_glib(self) -> i32 {
37        match self {
38            Self::None => 0,
39            Self::Frame => -1,
40            Self::Bytes(b) => i32::try_from(b).expect("overhead is higher than i32::MAX"),
41        }
42    }
43}
44
45impl FromGlib<i32> for Overhead {
46    #[inline]
47    unsafe fn from_glib(val: i32) -> Self {
48        skip_assert_initialized!();
49        match val {
50            0 => Self::None,
51            1 => Self::Frame,
52            b if b > 0 => Self::Bytes(val as u32),
53            _ => panic!("overheader is lower than -1"),
54        }
55    }
56}
57
58#[doc(hidden)]
59impl<'a> ::glib::translate::ToGlibPtr<'a, *mut ffi::GstBaseParseFrame> for BaseParseFrame<'a> {
60    type Storage = PhantomData<&'a Self>;
61
62    #[inline]
63    fn to_glib_none(&'a self) -> ::glib::translate::Stash<'a, *mut ffi::GstBaseParseFrame, Self> {
64        Stash(self.0.as_ptr(), PhantomData)
65    }
66
67    fn to_glib_full(&self) -> *mut ffi::GstBaseParseFrame {
68        unimplemented!()
69    }
70}
71
72impl fmt::Debug for BaseParseFrame<'_> {
73    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
74        let mut b = f.debug_struct("BaseParseFrame");
75
76        b.field("buffer", &self.buffer())
77            .field("output_buffer", &self.output_buffer())
78            .field("flags", &self.flags())
79            .field("offset", &self.offset())
80            .field("overhead", &self.overhead());
81
82        b.finish()
83    }
84}
85
86impl<'a> BaseParseFrame<'a> {
87    #[inline]
88    pub(crate) unsafe fn new(frame: *mut ffi::GstBaseParseFrame, _parse: &'a BaseParse) -> Self {
89        skip_assert_initialized!();
90
91        unsafe {
92            debug_assert!(!frame.is_null());
93            Self(ptr::NonNull::new_unchecked(frame), PhantomData)
94        }
95    }
96
97    #[doc(alias = "get_buffer")]
98    #[inline]
99    pub fn buffer(&self) -> Option<&gst::BufferRef> {
100        unsafe {
101            let ptr = (*self.to_glib_none().0).buffer;
102            if ptr.is_null() {
103                None
104            } else {
105                Some(gst::BufferRef::from_ptr(ptr))
106            }
107        }
108    }
109
110    #[doc(alias = "get_buffer_mut")]
111    pub fn buffer_mut(&mut self) -> Option<&mut gst::BufferRef> {
112        unsafe {
113            let ptr = (*self.to_glib_none().0).buffer;
114            if ptr.is_null() {
115                None
116            } else {
117                let writable: bool = from_glib(gst::ffi::gst_mini_object_is_writable(
118                    ptr as *const gst::ffi::GstMiniObject,
119                ));
120                assert!(writable);
121
122                Some(gst::BufferRef::from_mut_ptr(ptr))
123            }
124        }
125    }
126
127    #[doc(alias = "get_output_buffer")]
128    #[inline]
129    pub fn output_buffer(&self) -> Option<&gst::BufferRef> {
130        unsafe {
131            let ptr = (*self.to_glib_none().0).out_buffer;
132            if ptr.is_null() {
133                None
134            } else {
135                Some(gst::BufferRef::from_ptr(ptr))
136            }
137        }
138    }
139
140    #[doc(alias = "get_output_buffer_mut")]
141    pub fn output_buffer_mut(&mut self) -> Option<&mut gst::BufferRef> {
142        unsafe {
143            let ptr = (*self.to_glib_none().0).out_buffer;
144            if ptr.is_null() {
145                None
146            } else {
147                let writable: bool = from_glib(gst::ffi::gst_mini_object_is_writable(
148                    ptr as *const gst::ffi::GstMiniObject,
149                ));
150                assert!(writable);
151
152                Some(gst::BufferRef::from_mut_ptr(ptr))
153            }
154        }
155    }
156
157    pub fn set_output_buffer(&mut self, output_buffer: gst::Buffer) {
158        unsafe {
159            assert!(output_buffer.is_writable());
160            let prev = (*self.to_glib_none().0).out_buffer;
161
162            if !prev.is_null() {
163                gst::ffi::gst_mini_object_unref(prev as *mut gst::ffi::GstMiniObject);
164            }
165
166            (*self.to_glib_none().0).out_buffer = output_buffer.into_glib_ptr();
167        }
168    }
169
170    #[doc(alias = "get_flags")]
171    #[inline]
172    pub fn flags(&self) -> BaseParseFrameFlags {
173        let flags = unsafe { (*self.to_glib_none().0).flags };
174        BaseParseFrameFlags::from_bits_truncate(flags)
175    }
176
177    #[inline]
178    pub fn set_flags(&mut self, flags: BaseParseFrameFlags) {
179        unsafe { (*self.to_glib_none().0).flags |= flags.bits() }
180    }
181
182    #[inline]
183    pub fn unset_flags(&mut self, flags: BaseParseFrameFlags) {
184        unsafe { (*self.to_glib_none().0).flags &= !flags.bits() }
185    }
186
187    #[doc(alias = "get_offset")]
188    #[inline]
189    pub fn offset(&self) -> u64 {
190        unsafe { (*self.to_glib_none().0).offset }
191    }
192
193    #[doc(alias = "get_overhead")]
194    #[inline]
195    pub fn overhead(&self) -> Overhead {
196        unsafe { from_glib((*self.to_glib_none().0).overhead) }
197    }
198
199    #[inline]
200    pub fn set_overhead(&mut self, overhead: Overhead) {
201        unsafe {
202            (*self.to_glib_none().0).overhead = overhead.into_glib();
203        }
204    }
205}