1use std::{
4 marker::PhantomData,
5 mem, ops,
6 ops::{Deref, DerefMut},
7 ptr,
8};
9
10use glib::{prelude::*, translate::*};
11
12use crate::{AllocationParams, Allocator, BufferPool, Structure, StructureRef, ffi};
13
14#[derive(Debug, Clone, PartialEq, Eq)]
15#[repr(transparent)]
16pub struct BufferPoolConfig(Structure);
17
18impl Deref for BufferPoolConfig {
19 type Target = BufferPoolConfigRef;
20
21 #[inline]
22 fn deref(&self) -> &BufferPoolConfigRef {
23 unsafe { &*(self.0.as_ptr() as *const StructureRef as *const BufferPoolConfigRef) }
24 }
25}
26
27impl DerefMut for BufferPoolConfig {
28 #[inline]
29 fn deref_mut(&mut self) -> &mut BufferPoolConfigRef {
30 unsafe { &mut *(self.0.as_ptr() as *mut StructureRef as *mut BufferPoolConfigRef) }
31 }
32}
33
34impl AsRef<BufferPoolConfigRef> for BufferPoolConfig {
35 #[inline]
36 fn as_ref(&self) -> &BufferPoolConfigRef {
37 self.deref()
38 }
39}
40
41impl AsMut<BufferPoolConfigRef> for BufferPoolConfig {
42 #[inline]
43 fn as_mut(&mut self) -> &mut BufferPoolConfigRef {
44 self.deref_mut()
45 }
46}
47
48#[derive(Debug)]
49#[repr(transparent)]
50pub struct BufferPoolConfigRef(StructureRef);
51
52impl BufferPoolConfigRef {
53 #[inline]
54 pub unsafe fn from_glib_borrow<'a>(ptr: *const ffi::GstStructure) -> &'a BufferPoolConfigRef {
55 unsafe {
56 debug_assert!(!ptr.is_null());
57
58 &*(ptr as *mut StructureRef as *mut BufferPoolConfigRef)
59 }
60 }
61
62 #[inline]
63 pub unsafe fn from_glib_borrow_mut<'a>(
64 ptr: *mut ffi::GstStructure,
65 ) -> &'a mut BufferPoolConfigRef {
66 unsafe {
67 debug_assert!(!ptr.is_null());
68
69 &mut *(ptr as *mut StructureRef as *mut BufferPoolConfigRef)
70 }
71 }
72
73 #[inline]
74 pub fn as_ptr(&self) -> *const ffi::GstStructure {
75 self as *const Self as *const ffi::GstStructure
76 }
77
78 #[inline]
79 pub fn as_mut_ptr(&self) -> *mut ffi::GstStructure {
80 self as *const Self as *mut ffi::GstStructure
81 }
82}
83
84impl ops::Deref for BufferPoolConfigRef {
85 type Target = crate::StructureRef;
86
87 #[inline]
88 fn deref(&self) -> &crate::StructureRef {
89 &self.0
90 }
91}
92
93impl ops::DerefMut for BufferPoolConfigRef {
94 #[inline]
95 fn deref_mut(&mut self) -> &mut crate::StructureRef {
96 &mut self.0
97 }
98}
99
100impl AsRef<crate::StructureRef> for BufferPoolConfigRef {
101 #[inline]
102 fn as_ref(&self) -> &crate::StructureRef {
103 &self.0
104 }
105}
106
107impl AsMut<crate::StructureRef> for BufferPoolConfigRef {
108 #[inline]
109 fn as_mut(&mut self) -> &mut crate::StructureRef {
110 &mut self.0
111 }
112}
113
114impl BufferPoolConfigRef {
115 #[doc(alias = "gst_buffer_pool_config_add_option")]
116 pub fn add_option(&mut self, option: &str) {
117 unsafe {
118 ffi::gst_buffer_pool_config_add_option(self.0.as_mut_ptr(), option.to_glib_none().0);
119 }
120 }
121
122 #[doc(alias = "gst_buffer_pool_config_has_option")]
123 pub fn has_option(&self, option: &str) -> bool {
124 unsafe {
125 from_glib(ffi::gst_buffer_pool_config_has_option(
126 self.0.as_mut_ptr(),
127 option.to_glib_none().0,
128 ))
129 }
130 }
131
132 #[doc(alias = "get_options")]
133 #[doc(alias = "gst_buffer_pool_config_n_options")]
134 #[doc(alias = "gst_buffer_pool_config_get_option")]
135 pub fn options(&self) -> OptionsIter<'_> {
136 OptionsIter::new(self)
137 }
138
139 #[doc(alias = "gst_buffer_pool_config_set_params")]
140 pub fn set_params(
141 &mut self,
142 caps: Option<&crate::Caps>,
143 size: u32,
144 min_buffers: u32,
145 max_buffers: u32,
146 ) {
147 unsafe {
148 ffi::gst_buffer_pool_config_set_params(
149 self.0.as_mut_ptr(),
150 caps.to_glib_none().0,
151 size,
152 min_buffers,
153 max_buffers,
154 );
155 }
156 }
157
158 #[doc(alias = "get_params")]
159 #[doc(alias = "gst_buffer_pool_config_get_params")]
160 pub fn params(&self) -> Option<(Option<crate::Caps>, u32, u32, u32)> {
161 unsafe {
162 let mut caps = ptr::null_mut();
163 let mut size = mem::MaybeUninit::uninit();
164 let mut min_buffers = mem::MaybeUninit::uninit();
165 let mut max_buffers = mem::MaybeUninit::uninit();
166
167 let ret: bool = from_glib(ffi::gst_buffer_pool_config_get_params(
168 self.0.as_mut_ptr(),
169 &mut caps,
170 size.as_mut_ptr(),
171 min_buffers.as_mut_ptr(),
172 max_buffers.as_mut_ptr(),
173 ));
174 if !ret {
175 return None;
176 }
177
178 Some((
179 from_glib_none(caps),
180 size.assume_init(),
181 min_buffers.assume_init(),
182 max_buffers.assume_init(),
183 ))
184 }
185 }
186
187 #[doc(alias = "gst_buffer_pool_config_validate_params")]
188 pub fn validate_params(
189 &self,
190 caps: Option<&crate::Caps>,
191 size: u32,
192 min_buffers: u32,
193 max_buffers: u32,
194 ) -> Result<(), glib::BoolError> {
195 unsafe {
196 glib::result_from_gboolean!(
197 ffi::gst_buffer_pool_config_validate_params(
198 self.0.as_mut_ptr(),
199 caps.to_glib_none().0,
200 size,
201 min_buffers,
202 max_buffers,
203 ),
204 "Parameters are not valid in this context"
205 )
206 }
207 }
208
209 #[doc(alias = "get_allocator")]
210 #[doc(alias = "gst_buffer_pool_config_get_allocator")]
211 pub fn allocator(&self) -> Option<(Option<Allocator>, AllocationParams)> {
212 unsafe {
213 let mut allocator = ptr::null_mut();
214 let mut params = mem::MaybeUninit::uninit();
215 let ret = from_glib(ffi::gst_buffer_pool_config_get_allocator(
216 self.0.as_mut_ptr(),
217 &mut allocator,
218 params.as_mut_ptr(),
219 ));
220 if ret {
221 Some((from_glib_none(allocator), params.assume_init().into()))
222 } else {
223 None
224 }
225 }
226 }
227
228 #[doc(alias = "gst_buffer_pool_config_set_allocator")]
229 pub fn set_allocator(
230 &self,
231 allocator: Option<&impl IsA<Allocator>>,
232 params: Option<&AllocationParams>,
233 ) {
234 assert!(allocator.is_some() || params.is_some());
235 unsafe {
236 ffi::gst_buffer_pool_config_set_allocator(
237 self.0.as_mut_ptr(),
238 allocator.to_glib_none().0 as *mut ffi::GstAllocator,
239 match params {
240 Some(val) => val.as_ptr(),
241 None => ptr::null(),
242 },
243 )
244 }
245 }
246}
247
248crate::utils::define_fixed_size_iter!(
249 OptionsIter,
250 &'a BufferPoolConfigRef,
251 &'a glib::GStr,
252 |collection: &BufferPoolConfigRef| unsafe {
253 ffi::gst_buffer_pool_config_n_options(collection.as_mut_ptr()) as usize
254 },
255 |collection: &BufferPoolConfigRef, idx: usize| unsafe {
256 glib::GStr::from_ptr(ffi::gst_buffer_pool_config_get_option(
257 collection.as_mut_ptr(),
258 idx as u32,
259 ))
260 }
261);
262
263#[derive(Debug, Copy, Clone)]
264#[doc(alias = "GstBufferPoolAcquireParams")]
265pub struct BufferPoolAcquireParams(ffi::GstBufferPoolAcquireParams);
266
267unsafe impl Send for BufferPoolAcquireParams {}
268unsafe impl Sync for BufferPoolAcquireParams {}
269
270impl BufferPoolAcquireParams {
271 pub fn with_flags(flags: crate::BufferPoolAcquireFlags) -> Self {
272 skip_assert_initialized!();
273 BufferPoolAcquireParams(ffi::GstBufferPoolAcquireParams {
274 format: ffi::GST_FORMAT_UNDEFINED,
275 start: -1,
276 stop: -1,
277 flags: flags.into_glib(),
278 _gst_reserved: [ptr::null_mut(); 4],
279 })
280 }
281
282 pub fn with_start_stop<T: crate::format::SpecificFormattedValue>(
283 start: T,
284 stop: T,
285 flags: crate::BufferPoolAcquireFlags,
286 ) -> Self {
287 skip_assert_initialized!();
288 unsafe {
289 BufferPoolAcquireParams(ffi::GstBufferPoolAcquireParams {
290 format: start.format().into_glib(),
291 start: start.into_raw_value(),
292 stop: stop.into_raw_value(),
293 flags: flags.into_glib(),
294 _gst_reserved: [ptr::null_mut(); 4],
295 })
296 }
297 }
298
299 pub fn flags(&self) -> crate::BufferPoolAcquireFlags {
300 unsafe { from_glib(self.0.flags) }
301 }
302
303 pub fn format(&self) -> crate::Format {
304 unsafe { from_glib(self.0.format) }
305 }
306
307 pub fn start(&self) -> crate::GenericFormattedValue {
308 unsafe { crate::GenericFormattedValue::new(from_glib(self.0.format), self.0.start) }
309 }
310
311 pub fn stop(&self) -> crate::GenericFormattedValue {
312 unsafe { crate::GenericFormattedValue::new(from_glib(self.0.format), self.0.stop) }
313 }
314
315 pub fn set_flags(&mut self, flags: crate::BufferPoolAcquireFlags) {
316 self.0.flags = flags.into_glib();
317 }
318
319 pub fn set_format(&mut self, format: crate::Format) {
320 self.0.format = format.into_glib();
321 }
322
323 pub fn set_start(&mut self, start: crate::GenericFormattedValue) {
324 assert_eq!(self.format(), start.format());
325 self.0.start = start.value();
326 }
327
328 pub fn set_stop(&mut self, stop: crate::GenericFormattedValue) {
329 assert_eq!(self.format(), stop.format());
330 self.0.stop = stop.value();
331 }
332}
333
334impl PartialEq for BufferPoolAcquireParams {
335 fn eq(&self, other: &Self) -> bool {
336 self.flags() == other.flags()
337 && self.format() == other.format()
338 && self.start() == other.start()
339 && self.stop() == other.stop()
340 }
341}
342
343impl Eq for BufferPoolAcquireParams {}
344
345impl Default for BufferPoolAcquireParams {
346 fn default() -> Self {
347 Self(ffi::GstBufferPoolAcquireParams {
348 format: ffi::GST_FORMAT_UNDEFINED,
349 start: -1,
350 stop: -1,
351 flags: ffi::GST_BUFFER_POOL_ACQUIRE_FLAG_NONE,
352 _gst_reserved: [ptr::null_mut(); 4],
353 })
354 }
355}
356
357#[doc(hidden)]
358impl<'a> ToGlibPtr<'a, *const ffi::GstBufferPoolAcquireParams> for BufferPoolAcquireParams {
359 type Storage = PhantomData<&'a Self>;
360
361 #[inline]
362 fn to_glib_none(
363 &'a self,
364 ) -> glib::translate::Stash<'a, *const ffi::GstBufferPoolAcquireParams, Self> {
365 glib::translate::Stash(&self.0, PhantomData)
366 }
367}
368
369#[doc(hidden)]
370impl<'a> ToGlibPtrMut<'a, *mut ffi::GstBufferPoolAcquireParams> for BufferPoolAcquireParams {
371 type Storage = PhantomData<&'a mut Self>;
372
373 #[inline]
374 fn to_glib_none_mut(
375 &'a mut self,
376 ) -> glib::translate::StashMut<'a, *mut ffi::GstBufferPoolAcquireParams, Self> {
377 glib::translate::StashMut(&mut self.0, PhantomData)
378 }
379}
380
381#[doc(hidden)]
382impl FromGlibPtrNone<*mut ffi::GstBufferPoolAcquireParams> for BufferPoolAcquireParams {
383 #[inline]
384 unsafe fn from_glib_none(ptr: *mut ffi::GstBufferPoolAcquireParams) -> Self {
385 unsafe { Self(*ptr) }
386 }
387}
388
389pub trait BufferPoolExtManual: IsA<BufferPool> + 'static {
390 #[doc(alias = "get_config")]
397 #[doc(alias = "gst_buffer_pool_get_config")]
398 fn config(&self) -> BufferPoolConfig {
399 unsafe {
400 let ptr = ffi::gst_buffer_pool_get_config(self.as_ref().to_glib_none().0);
401 BufferPoolConfig(from_glib_full(ptr))
402 }
403 }
404
405 #[doc(alias = "gst_buffer_pool_set_config")]
428 fn set_config(&self, config: BufferPoolConfig) -> Result<(), glib::error::BoolError> {
429 unsafe {
430 glib::result_from_gboolean!(
431 ffi::gst_buffer_pool_set_config(
432 self.as_ref().to_glib_none().0,
433 config.0.into_glib_ptr()
434 ),
435 "Failed to set config",
436 )
437 }
438 }
439
440 fn is_flushing(&self) -> bool {
441 unsafe {
442 let stash = self.as_ref().to_glib_none();
443 let ptr: *mut ffi::GstBufferPool = stash.0;
444
445 from_glib((*ptr).flushing)
446 }
447 }
448
449 #[doc(alias = "gst_buffer_pool_acquire_buffer")]
466 fn acquire_buffer(
467 &self,
468 params: Option<&BufferPoolAcquireParams>,
469 ) -> Result<crate::Buffer, crate::FlowError> {
470 let params_ptr = params.to_glib_none().0 as *mut _;
471
472 unsafe {
473 let mut buffer = ptr::null_mut();
474 crate::FlowSuccess::try_from_glib(ffi::gst_buffer_pool_acquire_buffer(
475 self.as_ref().to_glib_none().0,
476 &mut buffer,
477 params_ptr,
478 ))
479 .map(|_| from_glib_full(buffer))
480 }
481 }
482}
483
484impl<O: IsA<BufferPool>> BufferPoolExtManual for O {}
485
486#[cfg(test)]
487mod tests {
488 use super::*;
489 use crate::prelude::*;
490
491 #[test]
492 fn pool_with_params() {
493 crate::init().unwrap();
494
495 let pool = crate::BufferPool::new();
496 let mut config = pool.config();
497 config.set_params(Some(&crate::Caps::builder("foo/bar").build()), 1024, 0, 2);
498 pool.set_config(config).unwrap();
499
500 pool.set_active(true).unwrap();
501
502 let params =
503 crate::BufferPoolAcquireParams::with_flags(crate::BufferPoolAcquireFlags::DONTWAIT);
504
505 let _buf1 = pool.acquire_buffer(Some(¶ms)).unwrap();
506 let buf2 = pool.acquire_buffer(Some(¶ms)).unwrap();
507
508 assert!(pool.acquire_buffer(Some(¶ms)).is_err());
509
510 drop(buf2);
511 let _buf2 = pool.acquire_buffer(Some(¶ms)).unwrap();
512
513 pool.set_active(false).unwrap();
514 }
515
516 #[test]
517 fn pool_no_params() {
518 crate::init().unwrap();
519
520 let pool = crate::BufferPool::new();
521 let mut config = pool.config();
522 config.set_params(None, 1024, 0, 2);
523 pool.set_config(config).unwrap();
524
525 pool.set_active(true).unwrap();
526 let _buf1 = pool.acquire_buffer(None).unwrap();
527 pool.set_active(false).unwrap();
528 }
529}