1use glib::{prelude::*, translate::*};
4
5#[cfg(feature = "v1_20")]
6use crate::ElementProperties;
7use crate::{
8 ffi, EncodingAudioProfile, EncodingContainerProfile, EncodingProfile, EncodingVideoProfile,
9};
10
11mod sealed {
12 pub trait Sealed {}
13 impl<T: super::IsA<super::EncodingProfile>> Sealed for T {}
14}
15
16pub trait EncodingProfileExtManual: sealed::Sealed + IsA<EncodingProfile> + 'static {
17 #[cfg(feature = "v1_20")]
22 #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
23 #[doc(alias = "gst_encoding_profile_get_element_properties")]
24 #[doc(alias = "get_element_properties")]
25 fn element_properties(&self) -> Option<ElementProperties> {
26 unsafe {
27 from_glib_full::<_, Option<_>>(ffi::gst_encoding_profile_get_element_properties(
28 self.as_ref().to_glib_none().0,
29 ))
30 .map(ElementProperties)
31 }
32 }
33}
34
35impl<O: IsA<EncodingProfile>> EncodingProfileExtManual for O {}
36
37trait EncodingProfileBuilderCommon {
38 fn set_allow_dynamic_output(&self, allow_dynamic_output: bool);
39
40 fn set_description(&self, description: Option<&str>);
41
42 fn set_enabled(&self, enabled: bool);
43
44 fn set_format(&self, format: &gst::Caps);
45
46 fn set_name(&self, name: Option<&str>);
47
48 fn set_presence(&self, presence: u32);
49
50 fn set_preset(&self, preset: Option<&str>);
51
52 fn set_preset_name(&self, preset_name: Option<&str>);
53
54 #[cfg(feature = "v1_18")]
55 fn set_single_segment(&self, single_segment: bool);
56
57 #[cfg(feature = "v1_20")]
58 fn set_element_properties(&self, element_properties: ElementProperties);
59}
60
61impl<O: IsA<EncodingProfile>> EncodingProfileBuilderCommon for O {
62 fn set_allow_dynamic_output(&self, allow_dynamic_output: bool) {
64 unsafe {
65 ffi::gst_encoding_profile_set_allow_dynamic_output(
66 self.as_ref().to_glib_none().0,
67 allow_dynamic_output.into_glib(),
68 );
69 }
70 }
71
72 fn set_description(&self, description: Option<&str>) {
74 let description = description.to_glib_none();
75 unsafe {
76 ffi::gst_encoding_profile_set_description(
77 self.as_ref().to_glib_none().0,
78 description.0,
79 );
80 }
81 }
82
83 fn set_enabled(&self, enabled: bool) {
85 unsafe {
86 ffi::gst_encoding_profile_set_enabled(
87 self.as_ref().to_glib_none().0,
88 enabled.into_glib(),
89 );
90 }
91 }
92
93 fn set_format(&self, format: &gst::Caps) {
95 unsafe {
96 ffi::gst_encoding_profile_set_format(
97 self.as_ref().to_glib_none().0,
98 format.to_glib_none().0,
99 );
100 }
101 }
102
103 fn set_name(&self, name: Option<&str>) {
105 let name = name.to_glib_none();
106 unsafe {
107 ffi::gst_encoding_profile_set_name(self.as_ref().to_glib_none().0, name.0);
108 }
109 }
110
111 fn set_presence(&self, presence: u32) {
113 unsafe {
114 ffi::gst_encoding_profile_set_presence(self.as_ref().to_glib_none().0, presence);
115 }
116 }
117
118 fn set_preset(&self, preset: Option<&str>) {
120 let preset = preset.to_glib_none();
121 unsafe {
122 ffi::gst_encoding_profile_set_preset(self.as_ref().to_glib_none().0, preset.0);
123 }
124 }
125
126 fn set_preset_name(&self, preset_name: Option<&str>) {
128 let preset_name = preset_name.to_glib_none();
129 unsafe {
130 ffi::gst_encoding_profile_set_preset_name(
131 self.as_ref().to_glib_none().0,
132 preset_name.0,
133 );
134 }
135 }
136
137 #[cfg(feature = "v1_18")]
139 fn set_single_segment(&self, single_segment: bool) {
140 unsafe {
141 ffi::gst_encoding_profile_set_single_segment(
142 self.as_ref().to_glib_none().0,
143 single_segment.into_glib(),
144 );
145 }
146 }
147
148 #[cfg(feature = "v1_20")]
150 fn set_element_properties(&self, element_properties: ElementProperties) {
151 unsafe {
152 ffi::gst_encoding_profile_set_element_properties(
153 self.as_ref().to_glib_none().0,
154 element_properties.into_inner().into_glib_ptr(),
155 );
156 }
157 }
158}
159
160pub trait EncodingProfileHasRestrictionGetter {
161 #[doc(alias = "get_restriction")]
162 #[doc(alias = "gst_encoding_profile_get_restriction")]
163 fn restriction(&self) -> Option<gst::Caps>;
164}
165
166macro_rules! declare_encoding_profile_has_restriction(
167 ($name:ident) => {
168 impl EncodingProfileHasRestrictionGetter for $name {
169 fn restriction(&self) -> Option<gst::Caps> {
171 let profile: &EncodingProfile = glib::object::Cast::upcast_ref(self);
172
173 unsafe {
174 from_glib_full(ffi::gst_encoding_profile_get_restriction(
175 profile.to_glib_none().0,
176 ))
177 }
178 }
179 }
180 }
181);
182
183impl EncodingAudioProfile {
184 fn new(
186 format: &gst::Caps,
187 preset: Option<&str>,
188 restriction: Option<&gst::Caps>,
189 presence: u32,
190 ) -> EncodingAudioProfile {
191 skip_assert_initialized!();
192 let preset = preset.to_glib_none();
193 let restriction = restriction.to_glib_none();
194 unsafe {
195 from_glib_full(ffi::gst_encoding_audio_profile_new(
196 format.to_glib_none().0,
197 preset.0,
198 restriction.0,
199 presence,
200 ))
201 }
202 }
203
204 #[doc(alias = "gst_encoding_audio_profile_new")]
205 pub fn builder(format: &gst::Caps) -> EncodingAudioProfileBuilder {
206 assert_initialized_main_thread!();
207 EncodingAudioProfileBuilder::new(format)
208 }
209}
210
211declare_encoding_profile_has_restriction!(EncodingAudioProfile);
212
213impl EncodingVideoProfile {
214 fn new(
216 format: &gst::Caps,
217 preset: Option<&str>,
218 restriction: Option<&gst::Caps>,
219 presence: u32,
220 ) -> EncodingVideoProfile {
221 skip_assert_initialized!();
222 let preset = preset.to_glib_none();
223 let restriction = restriction.to_glib_none();
224 unsafe {
225 from_glib_full(ffi::gst_encoding_video_profile_new(
226 format.to_glib_none().0,
227 preset.0,
228 restriction.0,
229 presence,
230 ))
231 }
232 }
233
234 #[doc(alias = "gst_encoding_video_profile_new")]
235 pub fn builder(format: &gst::Caps) -> EncodingVideoProfileBuilder {
236 assert_initialized_main_thread!();
237 EncodingVideoProfileBuilder::new(format)
238 }
239
240 fn set_pass(&self, pass: u32) {
242 unsafe {
243 ffi::gst_encoding_video_profile_set_pass(self.to_glib_none().0, pass);
244 }
245 }
246
247 fn set_variableframerate(&self, variableframerate: bool) {
249 unsafe {
250 ffi::gst_encoding_video_profile_set_variableframerate(
251 self.to_glib_none().0,
252 variableframerate.into_glib(),
253 );
254 }
255 }
256}
257
258declare_encoding_profile_has_restriction!(EncodingVideoProfile);
259
260impl EncodingContainerProfile {
261 fn new(
263 name: Option<&str>,
264 description: Option<&str>,
265 format: &gst::Caps,
266 preset: Option<&str>,
267 ) -> EncodingContainerProfile {
268 skip_assert_initialized!();
269 let name = name.to_glib_none();
270 let description = description.to_glib_none();
271 let preset = preset.to_glib_none();
272 unsafe {
273 from_glib_full(ffi::gst_encoding_container_profile_new(
274 name.0,
275 description.0,
276 format.to_glib_none().0,
277 preset.0,
278 ))
279 }
280 }
281
282 #[doc(alias = "gst_encoding_container_profile_new")]
283 pub fn builder(format: &gst::Caps) -> EncodingContainerProfileBuilder {
284 assert_initialized_main_thread!();
285 EncodingContainerProfileBuilder::new(format)
286 }
287
288 fn add_profile(&self, profile: impl IsA<EncodingProfile>) {
290 unsafe {
291 let res = ffi::gst_encoding_container_profile_add_profile(
292 self.to_glib_none().0,
293 profile.upcast().into_glib_ptr(),
294 );
295 debug_assert_ne!(res, glib::ffi::GFALSE);
297 }
298 }
299}
300
301#[derive(Debug)]
302struct EncodingProfileBuilderCommonData<'a> {
303 format: &'a gst::Caps,
304 name: Option<&'a str>,
305 description: Option<&'a str>,
306 preset: Option<&'a str>,
307 preset_name: Option<&'a str>,
308 presence: u32,
309 allow_dynamic_output: bool,
310 enabled: bool,
311 #[cfg(feature = "v1_18")]
312 single_segment: bool,
313 #[cfg(feature = "v1_20")]
314 element_properties: Option<ElementProperties>,
315}
316
317impl<'a> EncodingProfileBuilderCommonData<'a> {
318 fn new(format: &'a gst::Caps) -> EncodingProfileBuilderCommonData<'a> {
319 skip_assert_initialized!();
320 EncodingProfileBuilderCommonData {
321 name: None,
322 description: None,
323 format,
324 preset: None,
325 preset_name: None,
326 presence: 0,
327 allow_dynamic_output: true,
328 enabled: true,
329 #[cfg(feature = "v1_18")]
330 single_segment: false,
331 #[cfg(feature = "v1_20")]
332 element_properties: None,
333 }
334 }
335}
336
337pub trait EncodingProfileBuilder<'a>: Sized {
338 #[doc(alias = "gst_encoding_profile_set_name")]
339 #[must_use]
340 fn name(self, name: &'a str) -> Self;
341 #[doc(alias = "gst_encoding_profile_set_description")]
342 #[must_use]
343 fn description(self, description: &'a str) -> Self;
344 #[doc(alias = "gst_encoding_profile_set_preset")]
345 #[must_use]
346 fn preset(self, preset: &'a str) -> Self;
347 #[doc(alias = "gst_encoding_profile_set_preset_name")]
348 #[must_use]
349 fn preset_name(self, preset_name: &'a str) -> Self;
350 #[doc(alias = "gst_encoding_profile_set_presence")]
351 #[must_use]
352 fn presence(self, presence: u32) -> Self;
353 #[doc(alias = "gst_encoding_profile_set_presence")]
354 #[must_use]
355 fn presence_if(self, presence: u32, predicate: bool) -> Self;
356 #[doc(alias = "gst_encoding_profile_set_presence")]
357 #[must_use]
358 fn presence_if_some(self, presence: Option<u32>) -> Self;
359 #[doc(alias = "gst_encoding_profile_set_allow_dynamic_output")]
360 #[must_use]
361 fn allow_dynamic_output(self, allow: bool) -> Self;
362 #[doc(alias = "gst_encoding_profile_set_allow_dynamic_output")]
363 #[must_use]
364 fn allow_dynamic_output_if_some(self, allow_dynamic_output: Option<bool>) -> Self;
365 #[doc(alias = "gst_encoding_profile_set_enabled")]
366 #[must_use]
367 fn enabled(self, enabled: bool) -> Self;
368 #[doc(alias = "gst_encoding_profile_set_enabled")]
369 #[must_use]
370 fn enabled_if_some(self, enabled: Option<bool>) -> Self;
371 #[cfg(feature = "v1_18")]
372 #[doc(alias = "gst_encoding_profile_set_single_segment")]
373 #[must_use]
374 fn single_segment(self, single_segment: bool) -> Self;
375 #[cfg(feature = "v1_18")]
376 #[doc(alias = "gst_encoding_profile_set_single_segment")]
377 #[must_use]
378 fn single_segment_if_some(self, single_segment: Option<bool>) -> Self;
379 #[cfg(feature = "v1_20")]
380 #[doc(alias = "gst_encoding_profile_set_element_properties")]
381 #[must_use]
382 fn element_properties(self, element_properties: ElementProperties) -> Self;
383 #[cfg(feature = "v1_20")]
384 #[doc(alias = "gst_encoding_profile_set_element_properties")]
385 #[must_use]
386 fn element_properties_if(self, element_properties: ElementProperties, predecate: bool) -> Self;
387 #[cfg(feature = "v1_20")]
388 #[doc(alias = "gst_encoding_profile_set_element_properties")]
389 #[must_use]
390 fn element_properties_if_some(self, element_properties: Option<ElementProperties>) -> Self;
391}
392
393macro_rules! declare_encoding_profile_builder_common(
394 ($name:ident) => {
395 impl<'a> EncodingProfileBuilder<'a> for $name<'a> {
396 fn name(mut self, name: &'a str) -> $name<'a> {
397 self.base.name = Some(name);
398 self
399 }
400
401 fn description(mut self, description: &'a str) -> $name<'a> {
402 self.base.description = Some(description);
403 self
404 }
405
406 fn preset(mut self, preset: &'a str) -> $name<'a> {
407 self.base.preset = Some(preset);
408 self
409 }
410
411 fn preset_name(mut self, preset_name: &'a str) -> $name<'a> {
412 self.base.preset_name = Some(preset_name);
413 self
414 }
415
416 fn presence(mut self, presence: u32) -> $name<'a> {
417 self.base.presence = presence;
418 self
419 }
420
421 fn presence_if(self, presence: u32, predicate: bool) -> $name<'a> {
422 if predicate {
423 self.presence(presence)
424 } else {
425 self
426 }
427 }
428
429 fn presence_if_some(self, presence: Option<u32>) -> $name<'a> {
430 if let Some(presence) = presence {
431 self.presence(presence)
432 } else {
433 self
434 }
435 }
436
437 fn allow_dynamic_output(mut self, allow: bool) -> $name<'a> {
438 self.base.allow_dynamic_output = allow;
439 self
440 }
441
442 fn allow_dynamic_output_if_some(self, allow_dynamic_output: Option<bool>) -> $name<'a> {
443 if let Some(allow_dynamic_output) = allow_dynamic_output {
444 self.allow_dynamic_output(allow_dynamic_output)
445 } else {
446 self
447 }
448 }
449
450 fn enabled(mut self, enabled: bool) -> $name<'a> {
451 self.base.enabled = enabled;
452 self
453 }
454
455 fn enabled_if_some(self, enabled: Option<bool>) -> $name<'a> {
456 if let Some(enabled) = enabled {
457 self.enabled(enabled)
458 } else {
459 self
460 }
461 }
462
463 #[cfg(feature = "v1_18")]
464 fn single_segment(mut self, single_segment: bool) -> $name<'a> {
465 self.base.single_segment = single_segment;
466 self
467 }
468
469 #[cfg(feature = "v1_18")]
470 fn single_segment_if_some(self, single_segment: Option<bool>) -> $name<'a> {
471 if let Some(single_segment) = single_segment {
472 self.single_segment(single_segment)
473 } else {
474 self
475 }
476 }
477
478 #[cfg(feature = "v1_20")]
479 fn element_properties(mut self, element_properties: ElementProperties) -> $name<'a> {
480 self.base.element_properties = Some(element_properties);
481 self
482 }
483
484 #[cfg(feature = "v1_20")]
485 fn element_properties_if(self, element_properties: ElementProperties, predicate: bool) -> $name<'a> {
486 if predicate {
487 self.element_properties(element_properties)
488 } else {
489 self
490 }
491 }
492
493 #[cfg(feature = "v1_20")]
494 fn element_properties_if_some(self, element_properties: Option<ElementProperties>) -> $name<'a> {
495 if let Some(element_properties) = element_properties {
496 self.element_properties(element_properties)
497 } else {
498 self
499 }
500 }
501 }
502 }
503);
504
505fn set_common_fields<T: EncodingProfileBuilderCommon>(
506 profile: &T,
507 base_data: EncodingProfileBuilderCommonData,
508) {
509 skip_assert_initialized!();
510 profile.set_format(base_data.format);
511 profile.set_name(base_data.name);
512 profile.set_description(base_data.description);
513 profile.set_preset(base_data.preset);
514 profile.set_preset_name(base_data.preset_name);
515 profile.set_allow_dynamic_output(base_data.allow_dynamic_output);
516 profile.set_enabled(base_data.enabled);
517 profile.set_presence(base_data.presence);
518 #[cfg(feature = "v1_18")]
519 {
520 profile.set_single_segment(base_data.single_segment);
521 }
522 #[cfg(feature = "v1_20")]
523 {
524 let mut base_data = base_data;
525 if let Some(element_properties) = base_data.element_properties.take() {
526 profile.set_element_properties(element_properties);
527 }
528 }
529}
530
531#[derive(Debug)]
532#[must_use = "The builder must be built to be used"]
533pub struct EncodingAudioProfileBuilder<'a> {
534 base: EncodingProfileBuilderCommonData<'a>,
535 restriction: Option<&'a gst::Caps>,
536}
537
538declare_encoding_profile_builder_common!(EncodingAudioProfileBuilder);
539
540impl<'a> EncodingAudioProfileBuilder<'a> {
541 fn new(format: &'a gst::Caps) -> Self {
542 skip_assert_initialized!();
543 EncodingAudioProfileBuilder {
544 base: EncodingProfileBuilderCommonData::new(format),
545 restriction: None,
546 }
547 }
548
549 #[doc(alias = "gst_encoding_profile_set_restriction")]
550 pub fn restriction(mut self, restriction: &'a gst::Caps) -> Self {
551 self.restriction = Some(restriction);
552 self
553 }
554
555 #[must_use = "Building the profile without using it has no effect"]
556 pub fn build(self) -> EncodingAudioProfile {
557 let profile = EncodingAudioProfile::new(
558 self.base.format,
559 self.base.preset,
560 self.restriction,
561 self.base.presence,
562 );
563
564 set_common_fields(&profile, self.base);
565
566 profile
567 }
568}
569
570#[derive(Debug)]
571#[must_use = "The builder must be built to be used"]
572pub struct EncodingVideoProfileBuilder<'a> {
573 base: EncodingProfileBuilderCommonData<'a>,
574 restriction: Option<&'a gst::Caps>,
575 pass: u32,
576 variable_framerate: bool,
577}
578
579declare_encoding_profile_builder_common!(EncodingVideoProfileBuilder);
580
581impl<'a> EncodingVideoProfileBuilder<'a> {
582 fn new(format: &'a gst::Caps) -> Self {
583 skip_assert_initialized!();
584 EncodingVideoProfileBuilder {
585 base: EncodingProfileBuilderCommonData::new(format),
586 restriction: None,
587 pass: 0,
588 variable_framerate: false,
589 }
590 }
591
592 #[doc(alias = "gst_encoding_video_profile_set_pass")]
593 pub fn pass(mut self, pass: u32) -> Self {
594 self.pass = pass;
595 self
596 }
597
598 #[doc(alias = "gst_encoding_video_profile_set_variableframerate")]
599 pub fn variable_framerate(mut self, variable_framerate: bool) -> Self {
600 self.variable_framerate = variable_framerate;
601 self
602 }
603
604 #[doc(alias = "gst_encoding_profile_set_restriction")]
605 pub fn restriction(mut self, restriction: &'a gst::Caps) -> Self {
606 self.restriction = Some(restriction);
607 self
608 }
609
610 #[must_use = "Building the profile without using it has no effect"]
611 pub fn build(self) -> EncodingVideoProfile {
612 let video_profile = EncodingVideoProfile::new(
613 self.base.format,
614 self.base.preset,
615 self.restriction,
616 self.base.presence,
617 );
618
619 video_profile.set_pass(self.pass);
620 video_profile.set_variableframerate(self.variable_framerate);
621
622 set_common_fields(&video_profile, self.base);
623
624 video_profile
625 }
626}
627
628#[derive(Debug)]
629#[must_use = "The builder must be built to be used"]
630pub struct EncodingContainerProfileBuilder<'a> {
631 base: EncodingProfileBuilderCommonData<'a>,
632 profiles: Vec<EncodingProfile>,
633}
634
635declare_encoding_profile_builder_common!(EncodingContainerProfileBuilder);
636
637impl<'a> EncodingContainerProfileBuilder<'a> {
638 fn new(format: &'a gst::Caps) -> Self {
639 skip_assert_initialized!();
640 EncodingContainerProfileBuilder {
641 base: EncodingProfileBuilderCommonData::new(format),
642 profiles: Vec::new(),
643 }
644 }
645
646 #[must_use = "Building the profile without using it has no effect"]
647 pub fn build(self) -> EncodingContainerProfile {
648 let container_profile = EncodingContainerProfile::new(
649 self.base.name,
650 self.base.description,
651 self.base.format,
652 self.base.preset,
653 );
654
655 for profile in self.profiles {
656 container_profile.add_profile(profile);
657 }
658
659 set_common_fields(&container_profile, self.base);
660
661 container_profile
662 }
663
664 #[doc(alias = "gst_encoding_container_profile_add_profile")]
665 pub fn add_profile(mut self, profile: impl IsA<EncodingProfile>) -> Self {
666 self.profiles.push(profile.upcast());
667 self
668 }
669}
670
671#[cfg(test)]
672mod tests {
673 use super::*;
674 use crate::{
675 auto::{EncodingContainerProfile, EncodingVideoProfile},
676 prelude::*,
677 };
678
679 const AUDIO_PROFILE_NAME: &str = "audio-profile";
680 const AUDIO_PROFILE_DESCRIPTION: &str = "audio-profile-description";
681 const PRESET: &str = "preset";
682 const PRESET_NAME: &str = "preset-name";
683 const PRESENCE: u32 = 5;
684 const ALLOW_DYNAMIC_OUTPUT: bool = false;
685 const ENABLED: bool = false;
686
687 const VIDEO_PROFILE_NAME: &str = "video-profile";
688 const VIDEO_PROFILE_DESCRIPTION: &str = "video-profile-description";
689
690 const CONTAINER_PROFILE_NAME: &str = "container-profile";
691 const CONTAINER_PROFILE_DESCRIPTION: &str = "container-profile-description";
692
693 const PASS: u32 = 8;
695 const VARIABLE_FRAMERATE: bool = true;
696
697 #[test]
698 fn test_encoding_audio_profile_builder() {
699 gst::init().unwrap();
700
701 let caps = gst::Caps::builder("audio/x-raw").build();
702
703 let restriction = gst_audio::AudioCapsBuilder::new()
704 .format(gst_audio::AudioFormat::S32le)
705 .build();
706
707 let audio_profile = EncodingAudioProfile::builder(&caps)
708 .name(AUDIO_PROFILE_NAME)
709 .description(AUDIO_PROFILE_DESCRIPTION)
710 .preset(PRESET)
711 .preset_name(PRESET_NAME)
712 .restriction(&restriction)
713 .presence(PRESENCE)
714 .allow_dynamic_output(ALLOW_DYNAMIC_OUTPUT)
715 .enabled(ENABLED)
716 .build();
717
718 assert_eq!(audio_profile.name().unwrap(), AUDIO_PROFILE_NAME);
719 assert_eq!(
720 audio_profile.description().unwrap(),
721 AUDIO_PROFILE_DESCRIPTION
722 );
723 assert_eq!(audio_profile.format(), caps);
724 assert_eq!(audio_profile.preset().unwrap(), PRESET);
725 assert_eq!(audio_profile.preset_name().unwrap(), PRESET_NAME);
726 assert_eq!(audio_profile.restriction().unwrap(), restriction);
727 assert_eq!(audio_profile.presence(), PRESENCE);
728 assert_eq!(audio_profile.allows_dynamic_output(), ALLOW_DYNAMIC_OUTPUT);
729 assert_eq!(audio_profile.is_enabled(), ENABLED);
730 }
731
732 #[test]
733 fn test_encoding_video_profile_builder() {
734 gst::init().unwrap();
735
736 let caps = gst::Caps::builder("video/x-raw").build();
737
738 let restriction = gst_video::VideoCapsBuilder::new()
739 .format(gst_video::VideoFormat::Rgba)
740 .build();
741
742 let video_profile = EncodingVideoProfile::builder(&caps)
743 .name(VIDEO_PROFILE_NAME)
744 .description(VIDEO_PROFILE_DESCRIPTION)
745 .preset(PRESET)
746 .preset_name(PRESET_NAME)
747 .restriction(&restriction)
748 .presence(PRESENCE)
749 .allow_dynamic_output(ALLOW_DYNAMIC_OUTPUT)
750 .enabled(ENABLED)
751 .pass(PASS)
752 .variable_framerate(VARIABLE_FRAMERATE)
753 .build();
754
755 assert_eq!(video_profile.name().unwrap(), VIDEO_PROFILE_NAME);
756 assert_eq!(
757 video_profile.description().unwrap(),
758 VIDEO_PROFILE_DESCRIPTION
759 );
760 assert_eq!(video_profile.format(), caps);
761 assert_eq!(video_profile.preset().unwrap(), PRESET);
762 assert_eq!(video_profile.preset_name().unwrap(), PRESET_NAME);
763 assert_eq!(video_profile.restriction().unwrap(), restriction);
764 assert_eq!(video_profile.presence(), PRESENCE);
765 assert_eq!(video_profile.allows_dynamic_output(), ALLOW_DYNAMIC_OUTPUT);
766 assert_eq!(video_profile.is_enabled(), ENABLED);
767
768 let video_profile: EncodingVideoProfile =
769 glib::object::Cast::downcast(video_profile).ok().unwrap();
770 assert_eq!(video_profile.is_variableframerate(), VARIABLE_FRAMERATE);
771 assert_eq!(video_profile.pass(), PASS);
772 }
773
774 #[test]
775 fn test_encoding_container_profile_builder() {
776 gst::init().unwrap();
777
778 let container_caps = gst::Caps::builder("container/x-caps").build();
779 let video_caps = gst::Caps::builder("video/x-raw").build();
780 let audio_caps = gst::Caps::builder("audio/x-raw").build();
781
782 let video_profile = EncodingVideoProfile::builder(&video_caps)
783 .name(VIDEO_PROFILE_NAME)
784 .description(VIDEO_PROFILE_DESCRIPTION)
785 .build();
786 let audio_profile = EncodingAudioProfile::builder(&audio_caps)
787 .name(AUDIO_PROFILE_NAME)
788 .description(AUDIO_PROFILE_DESCRIPTION)
789 .build();
790
791 let profile = EncodingContainerProfile::builder(&container_caps)
792 .name(CONTAINER_PROFILE_NAME)
793 .description(CONTAINER_PROFILE_DESCRIPTION)
794 .preset(PRESET)
795 .preset_name(PRESET_NAME)
796 .presence(PRESENCE)
797 .allow_dynamic_output(ALLOW_DYNAMIC_OUTPUT)
798 .enabled(ENABLED)
799 .add_profile(audio_profile.clone())
800 .add_profile(video_profile.clone())
801 .build();
802
803 assert_eq!(profile.name().unwrap(), CONTAINER_PROFILE_NAME);
804 assert_eq!(
805 profile.description().unwrap(),
806 CONTAINER_PROFILE_DESCRIPTION
807 );
808 assert_eq!(profile.format(), container_caps);
809 assert_eq!(profile.preset().unwrap(), PRESET);
810 assert_eq!(profile.preset_name().unwrap(), PRESET_NAME);
811 assert_eq!(profile.presence(), PRESENCE);
812 assert_eq!(profile.allows_dynamic_output(), ALLOW_DYNAMIC_OUTPUT);
813 assert_eq!(profile.is_enabled(), ENABLED);
814
815 let container_profile: EncodingContainerProfile =
816 glib::object::Cast::downcast(profile).ok().unwrap();
817
818 assert!(container_profile.contains_profile(&video_profile));
819 assert!(container_profile.contains_profile(&audio_profile));
820 }
821}