Skip to main content

gstreamer_video/
video_dsc.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::fmt;
4
5use crate::ffi;
6use glib::translate::IntoGlibPtr;
7
8#[doc(alias = "GstH274DigitallySignedContentInitialization")]
9#[repr(transparent)]
10pub struct H274DigitallySignedContentInitialization(
11    ffi::GstH274DigitallySignedContentInitialization,
12);
13
14impl H274DigitallySignedContentInitialization {
15    pub fn new(
16        hash_method_type: u8,
17        content_uuid: Option<[u8; 16]>,
18        key_source_uri: Option<&str>,
19    ) -> Self {
20        skip_assert_initialized!();
21        let key_source_uri_ptr = key_source_uri
22            .map(|s| glib::GString::from(s).into_glib_ptr())
23            .unwrap_or(std::ptr::null_mut());
24
25        let ffi = ffi::GstH274DigitallySignedContentInitialization {
26            id: 0,
27            hash_method_type,
28            key_retrieval_mode_idc: 0,
29            use_key_register_idx_flag: 0,
30            key_register_idx: 0,
31            content_uuid_present_flag: content_uuid.is_some() as u8,
32            content_uuid: content_uuid.unwrap_or([0u8; 16]),
33            num_verification_substreams: 1,
34            ref_substream_flag: std::ptr::null_mut(),
35            ref_substream_flag_len: 0,
36            vss_implicit_association_mode_flag: 0,
37            signed_content_start_flag: 1,
38            sei_signing_flag: 0,
39            key_source_uri: key_source_uri_ptr,
40        };
41
42        Self(ffi)
43    }
44
45    pub fn id(&self) -> u8 {
46        self.0.id
47    }
48
49    pub fn hash_method_type(&self) -> u8 {
50        self.0.hash_method_type
51    }
52
53    pub fn key_retrieval_mode_idc(&self) -> u32 {
54        self.0.key_retrieval_mode_idc
55    }
56
57    pub fn use_key_register_idx_flag(&self) -> bool {
58        self.0.use_key_register_idx_flag != 0
59    }
60
61    pub fn key_register_idx(&self) -> u32 {
62        self.0.key_register_idx
63    }
64
65    pub fn content_uuid_present_flag(&self) -> bool {
66        self.0.content_uuid_present_flag != 0
67    }
68
69    pub fn content_uuid(&self) -> &[u8; 16] {
70        &self.0.content_uuid
71    }
72
73    pub fn num_verification_substreams(&self) -> u32 {
74        self.0.num_verification_substreams
75    }
76
77    pub fn ref_substream_flag(&self) -> &[u8] {
78        if self.0.ref_substream_flag.is_null() {
79            &[]
80        } else {
81            unsafe {
82                std::slice::from_raw_parts(self.0.ref_substream_flag, self.0.ref_substream_flag_len)
83            }
84        }
85    }
86
87    pub fn vss_implicit_association_mode_flag(&self) -> bool {
88        self.0.vss_implicit_association_mode_flag != 0
89    }
90
91    pub fn signed_content_start_flag(&self) -> bool {
92        self.0.signed_content_start_flag != 0
93    }
94
95    pub fn sei_signing_flag(&self) -> bool {
96        self.0.sei_signing_flag != 0
97    }
98
99    pub fn key_source_uri(&self) -> Option<&str> {
100        if self.0.key_source_uri.is_null() {
101            None
102        } else {
103            unsafe { Some(glib::GStr::from_ptr(self.0.key_source_uri).as_str()) }
104        }
105    }
106
107    #[inline]
108    pub unsafe fn from_glib_ptr_borrow(
109        ptr: &ffi::GstH274DigitallySignedContentInitialization,
110    ) -> &Self {
111        unsafe { &*(ptr as *const ffi::GstH274DigitallySignedContentInitialization as *const Self) }
112    }
113
114    #[inline]
115    pub fn as_ptr(&self) -> *const ffi::GstH274DigitallySignedContentInitialization {
116        &self.0
117    }
118
119    // rustdoc-stripper-ignore-next
120    /// Set the `key_retrieval_mode_idc` field (H.274 §D.3.24).
121    ///
122    /// 0 = trust record (e.g. C2PA manifest), 1 = certificate (X.509 PEM).
123    pub fn set_key_retrieval_mode_idc(&mut self, mode_idc: u32) {
124        self.0.key_retrieval_mode_idc = mode_idc;
125    }
126}
127
128impl Clone for H274DigitallySignedContentInitialization {
129    fn clone(&self) -> Self {
130        unsafe {
131            let mut dst = std::mem::zeroed();
132            ffi::gst_h274_dsc_initialization_copy(&mut dst, &self.0);
133            Self(dst)
134        }
135    }
136}
137
138impl Drop for H274DigitallySignedContentInitialization {
139    fn drop(&mut self) {
140        unsafe {
141            ffi::gst_h274_dsc_initialization_clear(&mut self.0);
142        }
143    }
144}
145
146impl fmt::Debug for H274DigitallySignedContentInitialization {
147    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
148        f.debug_struct("H274DigitallySignedContentInitialization")
149            .field("id", &self.id())
150            .field("hash_method_type", &self.hash_method_type())
151            .field("key_retrieval_mode_idc", &self.key_retrieval_mode_idc())
152            .field(
153                "use_key_register_idx_flag",
154                &self.use_key_register_idx_flag(),
155            )
156            .field("key_register_idx", &self.key_register_idx())
157            .field(
158                "content_uuid_present_flag",
159                &self.content_uuid_present_flag(),
160            )
161            .field("content_uuid", &self.content_uuid())
162            .field(
163                "num_verification_substreams",
164                &self.num_verification_substreams(),
165            )
166            .field("ref_substream_flag", &self.ref_substream_flag())
167            .field(
168                "vss_implicit_association_mode_flag",
169                &self.vss_implicit_association_mode_flag(),
170            )
171            .field(
172                "signed_content_start_flag",
173                &self.signed_content_start_flag(),
174            )
175            .field("sei_signing_flag", &self.sei_signing_flag())
176            .field("key_source_uri", &self.key_source_uri())
177            .finish()
178    }
179}
180
181#[doc(alias = "GstH274DigitallySignedContentSelection")]
182#[repr(transparent)]
183pub struct H274DigitallySignedContentSelection(ffi::GstH274DigitallySignedContentSelection);
184
185impl H274DigitallySignedContentSelection {
186    pub fn new(verification_substream_id: u8) -> Self {
187        skip_assert_initialized!();
188        let ffi = ffi::GstH274DigitallySignedContentSelection {
189            id: 0,
190            verification_substream_id,
191        };
192
193        Self(ffi)
194    }
195
196    pub fn id(&self) -> u8 {
197        self.0.id
198    }
199
200    pub fn verification_substream_id(&self) -> u8 {
201        self.0.verification_substream_id
202    }
203
204    #[inline]
205    pub unsafe fn from_glib_ptr_borrow(ptr: &ffi::GstH274DigitallySignedContentSelection) -> &Self {
206        unsafe { &*(ptr as *const ffi::GstH274DigitallySignedContentSelection as *const Self) }
207    }
208
209    #[inline]
210    pub fn as_ptr(&self) -> *const ffi::GstH274DigitallySignedContentSelection {
211        &self.0
212    }
213}
214
215impl Clone for H274DigitallySignedContentSelection {
216    fn clone(&self) -> Self {
217        unsafe {
218            let mut dst = std::mem::zeroed();
219            ffi::gst_h274_dsc_selection_copy(&mut dst, &self.0);
220            Self(dst)
221        }
222    }
223}
224
225impl fmt::Debug for H274DigitallySignedContentSelection {
226    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
227        f.debug_struct("H274DigitallySignedContentSelection")
228            .field("id", &self.id())
229            .field(
230                "verification_substream_id",
231                &self.verification_substream_id(),
232            )
233            .finish()
234    }
235}
236
237#[doc(alias = "GstH274DigitallySignedContentVerification")]
238#[repr(transparent)]
239pub struct H274DigitallySignedContentVerification(ffi::GstH274DigitallySignedContentVerification);
240
241impl H274DigitallySignedContentVerification {
242    pub fn new(verification_substream_id: u8, signature: &[u8]) -> Self {
243        skip_assert_initialized!();
244        assert!(!signature.is_empty(), "DSC signature must not be empty");
245        let signature_length_in_octets_minus1 = (signature.len() - 1) as u32;
246
247        let slice: glib::Slice<u8> = signature.into();
248        let signature_ptr = slice.into_glib_ptr();
249
250        let ffi = ffi::GstH274DigitallySignedContentVerification {
251            id: 0,
252            verification_substream_id,
253            signature_length_in_octets_minus1,
254            signature: signature_ptr,
255            signed_content_end_flag: 1,
256        };
257
258        Self(ffi)
259    }
260
261    pub fn id(&self) -> u8 {
262        self.0.id
263    }
264
265    pub fn verification_substream_id(&self) -> u8 {
266        self.0.verification_substream_id
267    }
268
269    pub fn signature(&self) -> &[u8] {
270        if self.0.signature.is_null() {
271            &[]
272        } else {
273            let len = (self.0.signature_length_in_octets_minus1 + 1) as usize;
274            unsafe { std::slice::from_raw_parts(self.0.signature, len) }
275        }
276    }
277
278    pub fn signature_length_in_octets(&self) -> u32 {
279        self.0.signature_length_in_octets_minus1 + 1
280    }
281
282    pub fn signed_content_end_flag(&self) -> bool {
283        self.0.signed_content_end_flag != 0
284    }
285
286    #[inline]
287    pub unsafe fn from_glib_ptr_borrow(
288        ptr: &ffi::GstH274DigitallySignedContentVerification,
289    ) -> &Self {
290        unsafe { &*(ptr as *const ffi::GstH274DigitallySignedContentVerification as *const Self) }
291    }
292
293    #[inline]
294    pub fn as_ptr(&self) -> *const ffi::GstH274DigitallySignedContentVerification {
295        &self.0
296    }
297}
298
299impl Clone for H274DigitallySignedContentVerification {
300    fn clone(&self) -> Self {
301        unsafe {
302            let mut dst = std::mem::zeroed();
303            ffi::gst_h274_dsc_verification_copy(&mut dst, &self.0);
304            Self(dst)
305        }
306    }
307}
308
309impl Drop for H274DigitallySignedContentVerification {
310    fn drop(&mut self) {
311        unsafe {
312            ffi::gst_h274_dsc_verification_clear(&mut self.0);
313        }
314    }
315}
316
317impl fmt::Debug for H274DigitallySignedContentVerification {
318    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
319        f.debug_struct("H274DigitallySignedContentVerification")
320            .field("id", &self.id())
321            .field(
322                "verification_substream_id",
323                &self.verification_substream_id(),
324            )
325            .field("signature_length", &self.signature().len())
326            .field("signature", &self.signature())
327            .field("signed_content_end_flag", &self.signed_content_end_flag())
328            .finish()
329    }
330}