1use std::vec::Vec;
10
11use derive_more::IsVariant;
12use ffmpeg_next::{codec::Parameters, ffi::avcodec_parameters_copy};
13
14use crate::demuxer::{DemuxError, ParametersAlloc, ParametersCopy, ParametersMissing};
15
16#[derive(Clone, Debug, Default)]
18pub struct VideoPacketExtra {
19 stream_index: i32,
20 byte_pos: Option<i64>,
21 side_data: Vec<SideDataEntry>,
22}
23
24impl VideoPacketExtra {
25 #[cfg_attr(not(tarpaulin), inline(always))]
28 pub const fn new(stream_index: i32) -> Self {
29 Self {
30 stream_index,
31 byte_pos: None,
32 side_data: Vec::new(),
33 }
34 }
35
36 #[cfg_attr(not(tarpaulin), inline(always))]
38 pub const fn stream_index(&self) -> i32 {
39 self.stream_index
40 }
41
42 #[cfg_attr(not(tarpaulin), inline(always))]
45 pub const fn byte_pos(&self) -> Option<i64> {
46 self.byte_pos
47 }
48
49 #[cfg_attr(not(tarpaulin), inline(always))]
51 pub fn side_data(&self) -> &[SideDataEntry] {
52 self.side_data.as_slice()
53 }
54
55 #[cfg_attr(not(tarpaulin), inline(always))]
57 #[must_use]
58 pub const fn with_stream_index(mut self, value: i32) -> Self {
59 self.stream_index = value;
60 self
61 }
62 #[cfg_attr(not(tarpaulin), inline(always))]
64 #[must_use]
65 pub const fn with_byte_pos(mut self, value: Option<i64>) -> Self {
66 self.byte_pos = value;
67 self
68 }
69 #[cfg_attr(not(tarpaulin), inline(always))]
71 #[must_use]
72 pub fn with_side_data(mut self, value: Vec<SideDataEntry>) -> Self {
73 self.side_data = value;
74 self
75 }
76
77 #[cfg_attr(not(tarpaulin), inline(always))]
79 pub const fn set_stream_index(&mut self, value: i32) -> &mut Self {
80 self.stream_index = value;
81 self
82 }
83 #[cfg_attr(not(tarpaulin), inline(always))]
85 pub const fn set_byte_pos(&mut self, value: Option<i64>) -> &mut Self {
86 self.byte_pos = value;
87 self
88 }
89 #[cfg_attr(not(tarpaulin), inline(always))]
91 pub fn set_side_data(&mut self, value: Vec<SideDataEntry>) -> &mut Self {
92 self.side_data = value;
93 self
94 }
95}
96
97#[derive(Clone, Debug, Default)]
100pub struct VideoFrameExtra {
101 sample_aspect_ratio: Option<(u32, u32)>,
102 picture_type: PictureType,
103 key_frame: bool,
104 interlaced: bool,
105 top_field_first: bool,
106 best_effort_timestamp: Option<i64>,
107 mastering_display: Option<MasteringDisplay>,
108 content_light_level: Option<ContentLightLevel>,
109 smpte_timecode: Vec<u32>,
110 side_data: Vec<SideDataEntry>,
111}
112
113impl VideoFrameExtra {
114 #[cfg_attr(not(tarpaulin), inline(always))]
116 pub const fn new() -> Self {
117 Self {
118 sample_aspect_ratio: None,
119 picture_type: PictureType::Unspecified,
120 key_frame: false,
121 interlaced: false,
122 top_field_first: false,
123 best_effort_timestamp: None,
124 mastering_display: None,
125 content_light_level: None,
126 smpte_timecode: Vec::new(),
127 side_data: Vec::new(),
128 }
129 }
130
131 #[cfg_attr(not(tarpaulin), inline(always))]
134 pub const fn sample_aspect_ratio(&self) -> Option<(u32, u32)> {
135 self.sample_aspect_ratio
136 }
137 #[cfg_attr(not(tarpaulin), inline(always))]
139 pub const fn picture_type(&self) -> PictureType {
140 self.picture_type
141 }
142 #[cfg_attr(not(tarpaulin), inline(always))]
144 pub const fn key_frame(&self) -> bool {
145 self.key_frame
146 }
147 #[cfg_attr(not(tarpaulin), inline(always))]
149 pub const fn interlaced(&self) -> bool {
150 self.interlaced
151 }
152 #[cfg_attr(not(tarpaulin), inline(always))]
154 pub const fn top_field_first(&self) -> bool {
155 self.top_field_first
156 }
157 #[cfg_attr(not(tarpaulin), inline(always))]
159 pub const fn best_effort_timestamp(&self) -> Option<i64> {
160 self.best_effort_timestamp
161 }
162 #[cfg_attr(not(tarpaulin), inline(always))]
164 pub const fn mastering_display(&self) -> Option<MasteringDisplay> {
165 self.mastering_display
166 }
167 #[cfg_attr(not(tarpaulin), inline(always))]
169 pub const fn content_light_level(&self) -> Option<ContentLightLevel> {
170 self.content_light_level
171 }
172 #[cfg_attr(not(tarpaulin), inline(always))]
174 pub fn smpte_timecode(&self) -> &[u32] {
175 self.smpte_timecode.as_slice()
176 }
177 #[cfg_attr(not(tarpaulin), inline(always))]
179 pub fn side_data(&self) -> &[SideDataEntry] {
180 self.side_data.as_slice()
181 }
182
183 #[cfg_attr(not(tarpaulin), inline(always))]
185 pub const fn with_sample_aspect_ratio(mut self, value: Option<(u32, u32)>) -> Self {
186 self.sample_aspect_ratio = value;
187 self
188 }
189 #[cfg_attr(not(tarpaulin), inline(always))]
191 #[must_use]
192 pub const fn with_picture_type(mut self, value: PictureType) -> Self {
193 self.picture_type = value;
194 self
195 }
196 #[cfg_attr(not(tarpaulin), inline(always))]
198 #[must_use]
199 pub const fn with_key_frame(mut self, value: bool) -> Self {
200 self.key_frame = value;
201 self
202 }
203 #[cfg_attr(not(tarpaulin), inline(always))]
205 #[must_use]
206 pub const fn with_interlaced(mut self, value: bool) -> Self {
207 self.interlaced = value;
208 self
209 }
210 #[cfg_attr(not(tarpaulin), inline(always))]
212 #[must_use]
213 pub const fn with_top_field_first(mut self, value: bool) -> Self {
214 self.top_field_first = value;
215 self
216 }
217 #[cfg_attr(not(tarpaulin), inline(always))]
219 #[must_use]
220 pub const fn with_best_effort_timestamp(mut self, value: Option<i64>) -> Self {
221 self.best_effort_timestamp = value;
222 self
223 }
224 #[cfg_attr(not(tarpaulin), inline(always))]
226 #[must_use]
227 pub const fn with_mastering_display(mut self, value: Option<MasteringDisplay>) -> Self {
228 self.mastering_display = value;
229 self
230 }
231 #[cfg_attr(not(tarpaulin), inline(always))]
233 #[must_use]
234 pub const fn with_content_light_level(mut self, value: Option<ContentLightLevel>) -> Self {
235 self.content_light_level = value;
236 self
237 }
238 #[cfg_attr(not(tarpaulin), inline(always))]
240 #[must_use]
241 pub fn with_smpte_timecode(mut self, value: Vec<u32>) -> Self {
242 self.smpte_timecode = value;
243 self
244 }
245 #[cfg_attr(not(tarpaulin), inline(always))]
247 #[must_use]
248 pub fn with_side_data(mut self, value: Vec<SideDataEntry>) -> Self {
249 self.side_data = value;
250 self
251 }
252
253 #[cfg_attr(not(tarpaulin), inline(always))]
255 pub const fn set_sample_aspect_ratio(&mut self, value: Option<(u32, u32)>) -> &mut Self {
256 self.sample_aspect_ratio = value;
257 self
258 }
259 #[cfg_attr(not(tarpaulin), inline(always))]
261 pub const fn set_picture_type(&mut self, value: PictureType) -> &mut Self {
262 self.picture_type = value;
263 self
264 }
265 #[cfg_attr(not(tarpaulin), inline(always))]
267 pub const fn set_key_frame(&mut self, value: bool) -> &mut Self {
268 self.key_frame = value;
269 self
270 }
271 #[cfg_attr(not(tarpaulin), inline(always))]
273 pub const fn set_interlaced(&mut self, value: bool) -> &mut Self {
274 self.interlaced = value;
275 self
276 }
277 #[cfg_attr(not(tarpaulin), inline(always))]
279 pub const fn set_top_field_first(&mut self, value: bool) -> &mut Self {
280 self.top_field_first = value;
281 self
282 }
283 #[cfg_attr(not(tarpaulin), inline(always))]
285 pub const fn set_best_effort_timestamp(&mut self, value: Option<i64>) -> &mut Self {
286 self.best_effort_timestamp = value;
287 self
288 }
289 #[cfg_attr(not(tarpaulin), inline(always))]
291 pub const fn set_mastering_display(&mut self, value: Option<MasteringDisplay>) -> &mut Self {
292 self.mastering_display = value;
293 self
294 }
295 #[cfg_attr(not(tarpaulin), inline(always))]
297 pub const fn set_content_light_level(&mut self, value: Option<ContentLightLevel>) -> &mut Self {
298 self.content_light_level = value;
299 self
300 }
301 #[cfg_attr(not(tarpaulin), inline(always))]
303 pub fn set_smpte_timecode(&mut self, value: Vec<u32>) -> &mut Self {
304 self.smpte_timecode = value;
305 self
306 }
307 #[cfg_attr(not(tarpaulin), inline(always))]
309 pub fn set_side_data(&mut self, value: Vec<SideDataEntry>) -> &mut Self {
310 self.side_data = value;
311 self
312 }
313}
314
315#[derive(Clone, Debug, Default)]
317pub struct AudioPacketExtra {
318 stream_index: i32,
319 byte_pos: Option<i64>,
320 side_data: Vec<SideDataEntry>,
321}
322
323impl AudioPacketExtra {
324 #[cfg_attr(not(tarpaulin), inline(always))]
326 pub const fn new(stream_index: i32) -> Self {
327 Self {
328 stream_index,
329 byte_pos: None,
330 side_data: Vec::new(),
331 }
332 }
333
334 #[cfg_attr(not(tarpaulin), inline(always))]
336 pub const fn stream_index(&self) -> i32 {
337 self.stream_index
338 }
339 #[cfg_attr(not(tarpaulin), inline(always))]
341 pub const fn byte_pos(&self) -> Option<i64> {
342 self.byte_pos
343 }
344 #[cfg_attr(not(tarpaulin), inline(always))]
346 pub fn side_data(&self) -> &[SideDataEntry] {
347 self.side_data.as_slice()
348 }
349
350 #[cfg_attr(not(tarpaulin), inline(always))]
352 #[must_use]
353 pub const fn with_stream_index(mut self, value: i32) -> Self {
354 self.stream_index = value;
355 self
356 }
357 #[cfg_attr(not(tarpaulin), inline(always))]
359 #[must_use]
360 pub const fn with_byte_pos(mut self, value: Option<i64>) -> Self {
361 self.byte_pos = value;
362 self
363 }
364 #[cfg_attr(not(tarpaulin), inline(always))]
366 #[must_use]
367 pub fn with_side_data(mut self, value: Vec<SideDataEntry>) -> Self {
368 self.side_data = value;
369 self
370 }
371
372 #[cfg_attr(not(tarpaulin), inline(always))]
374 pub const fn set_stream_index(&mut self, value: i32) -> &mut Self {
375 self.stream_index = value;
376 self
377 }
378 #[cfg_attr(not(tarpaulin), inline(always))]
380 pub const fn set_byte_pos(&mut self, value: Option<i64>) -> &mut Self {
381 self.byte_pos = value;
382 self
383 }
384 #[cfg_attr(not(tarpaulin), inline(always))]
386 pub fn set_side_data(&mut self, value: Vec<SideDataEntry>) -> &mut Self {
387 self.side_data = value;
388 self
389 }
390}
391
392#[derive(Clone, Debug, Default)]
394pub struct AudioFrameExtra {
395 best_effort_timestamp: Option<i64>,
396 side_data: Vec<SideDataEntry>,
397}
398
399impl AudioFrameExtra {
400 #[cfg_attr(not(tarpaulin), inline(always))]
402 pub const fn new() -> Self {
403 Self {
404 best_effort_timestamp: None,
405 side_data: Vec::new(),
406 }
407 }
408
409 #[cfg_attr(not(tarpaulin), inline(always))]
411 pub const fn best_effort_timestamp(&self) -> Option<i64> {
412 self.best_effort_timestamp
413 }
414 #[cfg_attr(not(tarpaulin), inline(always))]
416 pub fn side_data(&self) -> &[SideDataEntry] {
417 self.side_data.as_slice()
418 }
419
420 #[cfg_attr(not(tarpaulin), inline(always))]
422 #[must_use]
423 pub const fn with_best_effort_timestamp(mut self, value: Option<i64>) -> Self {
424 self.best_effort_timestamp = value;
425 self
426 }
427 #[cfg_attr(not(tarpaulin), inline(always))]
429 #[must_use]
430 pub fn with_side_data(mut self, value: Vec<SideDataEntry>) -> Self {
431 self.side_data = value;
432 self
433 }
434
435 #[cfg_attr(not(tarpaulin), inline(always))]
437 pub const fn set_best_effort_timestamp(&mut self, value: Option<i64>) -> &mut Self {
438 self.best_effort_timestamp = value;
439 self
440 }
441 #[cfg_attr(not(tarpaulin), inline(always))]
443 pub fn set_side_data(&mut self, value: Vec<SideDataEntry>) -> &mut Self {
444 self.side_data = value;
445 self
446 }
447}
448
449#[derive(Clone, Debug, Default)]
451pub struct SubtitlePacketExtra {
452 stream_index: i32,
453 language: Option<[u8; 3]>,
454 forced: bool,
455 side_data: Vec<SideDataEntry>,
456}
457
458impl SubtitlePacketExtra {
459 #[cfg_attr(not(tarpaulin), inline(always))]
462 pub const fn new(stream_index: i32) -> Self {
463 Self {
464 stream_index,
465 language: None,
466 forced: false,
467 side_data: Vec::new(),
468 }
469 }
470
471 #[cfg_attr(not(tarpaulin), inline(always))]
473 pub const fn stream_index(&self) -> i32 {
474 self.stream_index
475 }
476 #[cfg_attr(not(tarpaulin), inline(always))]
478 pub const fn language(&self) -> Option<[u8; 3]> {
479 self.language
480 }
481 #[cfg_attr(not(tarpaulin), inline(always))]
483 pub const fn forced(&self) -> bool {
484 self.forced
485 }
486 #[cfg_attr(not(tarpaulin), inline(always))]
493 pub fn side_data(&self) -> &[SideDataEntry] {
494 self.side_data.as_slice()
495 }
496
497 #[cfg_attr(not(tarpaulin), inline(always))]
499 #[must_use]
500 pub const fn with_stream_index(mut self, value: i32) -> Self {
501 self.stream_index = value;
502 self
503 }
504 #[cfg_attr(not(tarpaulin), inline(always))]
506 #[must_use]
507 pub const fn with_language(mut self, value: Option<[u8; 3]>) -> Self {
508 self.language = value;
509 self
510 }
511 #[cfg_attr(not(tarpaulin), inline(always))]
513 #[must_use]
514 pub fn with_side_data(mut self, value: Vec<SideDataEntry>) -> Self {
515 self.side_data = value;
516 self
517 }
518 #[cfg_attr(not(tarpaulin), inline(always))]
520 pub fn set_side_data(&mut self, value: Vec<SideDataEntry>) -> &mut Self {
521 self.side_data = value;
522 self
523 }
524 #[cfg_attr(not(tarpaulin), inline(always))]
526 #[must_use]
527 pub const fn with_forced(mut self, value: bool) -> Self {
528 self.forced = value;
529 self
530 }
531
532 #[cfg_attr(not(tarpaulin), inline(always))]
534 pub const fn set_stream_index(&mut self, value: i32) -> &mut Self {
535 self.stream_index = value;
536 self
537 }
538 #[cfg_attr(not(tarpaulin), inline(always))]
540 pub const fn set_language(&mut self, value: Option<[u8; 3]>) -> &mut Self {
541 self.language = value;
542 self
543 }
544 #[cfg_attr(not(tarpaulin), inline(always))]
546 pub const fn set_forced(&mut self, value: bool) -> &mut Self {
547 self.forced = value;
548 self
549 }
550}
551
552#[derive(Clone, Debug, Default)]
554pub struct SubtitleFrameExtra {
555 start_display_time: u32,
556 end_display_time: u32,
557}
558
559impl SubtitleFrameExtra {
560 #[cfg_attr(not(tarpaulin), inline(always))]
562 pub const fn new(start_display_time: u32, end_display_time: u32) -> Self {
563 Self {
564 start_display_time,
565 end_display_time,
566 }
567 }
568
569 #[cfg_attr(not(tarpaulin), inline(always))]
571 pub const fn start_display_time(&self) -> u32 {
572 self.start_display_time
573 }
574 #[cfg_attr(not(tarpaulin), inline(always))]
576 pub const fn end_display_time(&self) -> u32 {
577 self.end_display_time
578 }
579
580 #[cfg_attr(not(tarpaulin), inline(always))]
582 #[must_use]
583 pub const fn with_start_display_time(mut self, value: u32) -> Self {
584 self.start_display_time = value;
585 self
586 }
587 #[cfg_attr(not(tarpaulin), inline(always))]
589 #[must_use]
590 pub const fn with_end_display_time(mut self, value: u32) -> Self {
591 self.end_display_time = value;
592 self
593 }
594
595 #[cfg_attr(not(tarpaulin), inline(always))]
597 pub const fn set_start_display_time(&mut self, value: u32) -> &mut Self {
598 self.start_display_time = value;
599 self
600 }
601 #[cfg_attr(not(tarpaulin), inline(always))]
603 pub const fn set_end_display_time(&mut self, value: u32) -> &mut Self {
604 self.end_display_time = value;
605 self
606 }
607}
608
609#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Hash, IsVariant)]
611#[non_exhaustive]
612pub enum PictureType {
613 #[default]
615 Unspecified,
616 I,
618 P,
620 B,
622 S,
624 Si,
626 Sp,
628 Bi,
630}
631
632#[derive(Clone, Debug)]
637pub struct SideDataEntry {
638 kind: i32,
639 data: Vec<u8>,
640}
641
642impl SideDataEntry {
643 #[cfg_attr(not(tarpaulin), inline(always))]
645 pub const fn new(kind: i32, data: Vec<u8>) -> Self {
646 Self { kind, data }
647 }
648
649 #[cfg_attr(not(tarpaulin), inline(always))]
651 pub const fn kind(&self) -> i32 {
652 self.kind
653 }
654 #[cfg_attr(not(tarpaulin), inline(always))]
656 pub fn data(&self) -> &[u8] {
657 self.data.as_slice()
658 }
659
660 #[cfg_attr(not(tarpaulin), inline(always))]
662 #[must_use]
663 pub const fn with_kind(mut self, value: i32) -> Self {
664 self.kind = value;
665 self
666 }
667 #[cfg_attr(not(tarpaulin), inline(always))]
669 #[must_use]
670 pub fn with_data(mut self, value: Vec<u8>) -> Self {
671 self.data = value;
672 self
673 }
674
675 #[cfg_attr(not(tarpaulin), inline(always))]
677 pub const fn set_kind(&mut self, value: i32) -> &mut Self {
678 self.kind = value;
679 self
680 }
681 #[cfg_attr(not(tarpaulin), inline(always))]
683 pub fn set_data(&mut self, value: Vec<u8>) -> &mut Self {
684 self.data = value;
685 self
686 }
687}
688
689#[derive(Copy, Clone, Debug, PartialEq)]
691pub struct MasteringDisplay {
692 display_primaries: [(u32, u32); 3],
693 white_point: (u32, u32),
694 max_luminance: (u32, u32),
695 min_luminance: (u32, u32),
696}
697
698impl MasteringDisplay {
699 #[cfg_attr(not(tarpaulin), inline(always))]
701 pub const fn new(
702 display_primaries: [(u32, u32); 3],
703 white_point: (u32, u32),
704 max_luminance: (u32, u32),
705 min_luminance: (u32, u32),
706 ) -> Self {
707 Self {
708 display_primaries,
709 white_point,
710 max_luminance,
711 min_luminance,
712 }
713 }
714
715 #[cfg_attr(not(tarpaulin), inline(always))]
718 pub const fn display_primaries(&self) -> [(u32, u32); 3] {
719 self.display_primaries
720 }
721 #[cfg_attr(not(tarpaulin), inline(always))]
723 pub const fn white_point(&self) -> (u32, u32) {
724 self.white_point
725 }
726 #[cfg_attr(not(tarpaulin), inline(always))]
728 pub const fn max_luminance(&self) -> (u32, u32) {
729 self.max_luminance
730 }
731 #[cfg_attr(not(tarpaulin), inline(always))]
733 pub const fn min_luminance(&self) -> (u32, u32) {
734 self.min_luminance
735 }
736
737 #[cfg_attr(not(tarpaulin), inline(always))]
739 pub const fn with_display_primaries(mut self, value: [(u32, u32); 3]) -> Self {
740 self.display_primaries = value;
741 self
742 }
743 #[cfg_attr(not(tarpaulin), inline(always))]
745 pub const fn with_white_point(mut self, value: (u32, u32)) -> Self {
746 self.white_point = value;
747 self
748 }
749 #[cfg_attr(not(tarpaulin), inline(always))]
751 pub const fn with_max_luminance(mut self, value: (u32, u32)) -> Self {
752 self.max_luminance = value;
753 self
754 }
755 #[cfg_attr(not(tarpaulin), inline(always))]
757 pub const fn with_min_luminance(mut self, value: (u32, u32)) -> Self {
758 self.min_luminance = value;
759 self
760 }
761
762 #[cfg_attr(not(tarpaulin), inline(always))]
764 pub const fn set_display_primaries(&mut self, value: [(u32, u32); 3]) -> &mut Self {
765 self.display_primaries = value;
766 self
767 }
768 #[cfg_attr(not(tarpaulin), inline(always))]
770 pub const fn set_white_point(&mut self, value: (u32, u32)) -> &mut Self {
771 self.white_point = value;
772 self
773 }
774 #[cfg_attr(not(tarpaulin), inline(always))]
776 pub const fn set_max_luminance(&mut self, value: (u32, u32)) -> &mut Self {
777 self.max_luminance = value;
778 self
779 }
780 #[cfg_attr(not(tarpaulin), inline(always))]
782 pub const fn set_min_luminance(&mut self, value: (u32, u32)) -> &mut Self {
783 self.min_luminance = value;
784 self
785 }
786}
787
788#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Default)]
790pub struct ContentLightLevel {
791 max_cll: u32,
792 max_fall: u32,
793}
794
795impl ContentLightLevel {
796 #[cfg_attr(not(tarpaulin), inline(always))]
798 pub const fn new(max_cll: u32, max_fall: u32) -> Self {
799 Self { max_cll, max_fall }
800 }
801
802 #[cfg_attr(not(tarpaulin), inline(always))]
804 pub const fn max_cll(&self) -> u32 {
805 self.max_cll
806 }
807 #[cfg_attr(not(tarpaulin), inline(always))]
809 pub const fn max_fall(&self) -> u32 {
810 self.max_fall
811 }
812
813 #[cfg_attr(not(tarpaulin), inline(always))]
815 #[must_use]
816 pub const fn with_max_cll(mut self, value: u32) -> Self {
817 self.max_cll = value;
818 self
819 }
820 #[cfg_attr(not(tarpaulin), inline(always))]
822 #[must_use]
823 pub const fn with_max_fall(mut self, value: u32) -> Self {
824 self.max_fall = value;
825 self
826 }
827
828 #[cfg_attr(not(tarpaulin), inline(always))]
830 pub const fn set_max_cll(&mut self, value: u32) -> &mut Self {
831 self.max_cll = value;
832 self
833 }
834 #[cfg_attr(not(tarpaulin), inline(always))]
836 pub const fn set_max_fall(&mut self, value: u32) -> &mut Self {
837 self.max_fall = value;
838 self
839 }
840}
841
842#[derive(Clone, Debug, Default)]
854pub struct DataPacketExtra {
855 stream_index: i32,
856 byte_pos: Option<i64>,
857 side_data: Vec<SideDataEntry>,
858}
859
860impl DataPacketExtra {
861 #[cfg_attr(not(tarpaulin), inline(always))]
864 pub const fn new(stream_index: i32) -> Self {
865 Self {
866 stream_index,
867 byte_pos: None,
868 side_data: Vec::new(),
869 }
870 }
871
872 #[cfg_attr(not(tarpaulin), inline(always))]
874 pub const fn stream_index(&self) -> i32 {
875 self.stream_index
876 }
877 #[cfg_attr(not(tarpaulin), inline(always))]
880 pub const fn byte_pos(&self) -> Option<i64> {
881 self.byte_pos
882 }
883 #[cfg_attr(not(tarpaulin), inline(always))]
885 pub fn side_data(&self) -> &[SideDataEntry] {
886 self.side_data.as_slice()
887 }
888
889 #[cfg_attr(not(tarpaulin), inline(always))]
891 #[must_use]
892 pub const fn with_stream_index(mut self, value: i32) -> Self {
893 self.stream_index = value;
894 self
895 }
896 #[cfg_attr(not(tarpaulin), inline(always))]
898 #[must_use]
899 pub const fn with_byte_pos(mut self, value: Option<i64>) -> Self {
900 self.byte_pos = value;
901 self
902 }
903 #[cfg_attr(not(tarpaulin), inline(always))]
905 #[must_use]
906 pub fn with_side_data(mut self, value: Vec<SideDataEntry>) -> Self {
907 self.side_data = value;
908 self
909 }
910
911 #[cfg_attr(not(tarpaulin), inline(always))]
913 pub const fn set_stream_index(&mut self, value: i32) -> &mut Self {
914 self.stream_index = value;
915 self
916 }
917 #[cfg_attr(not(tarpaulin), inline(always))]
919 pub const fn set_byte_pos(&mut self, value: Option<i64>) -> &mut Self {
920 self.byte_pos = value;
921 self
922 }
923 #[cfg_attr(not(tarpaulin), inline(always))]
925 pub fn set_side_data(&mut self, value: Vec<SideDataEntry>) -> &mut Self {
926 self.side_data = value;
927 self
928 }
929}
930
931#[derive(Clone, Debug, Default)]
941pub struct AttachmentPacketExtra {
942 stream_index: i32,
943 synthesized: bool,
944}
945
946impl AttachmentPacketExtra {
947 #[cfg_attr(not(tarpaulin), inline(always))]
950 pub const fn new(stream_index: i32) -> Self {
951 Self {
952 stream_index,
953 synthesized: false,
954 }
955 }
956
957 #[cfg_attr(not(tarpaulin), inline(always))]
959 pub const fn stream_index(&self) -> i32 {
960 self.stream_index
961 }
962 #[cfg_attr(not(tarpaulin), inline(always))]
965 pub const fn synthesized(&self) -> bool {
966 self.synthesized
967 }
968
969 #[cfg_attr(not(tarpaulin), inline(always))]
971 #[must_use]
972 pub const fn with_stream_index(mut self, value: i32) -> Self {
973 self.stream_index = value;
974 self
975 }
976 #[cfg_attr(not(tarpaulin), inline(always))]
978 #[must_use]
979 pub const fn with_synthesized(mut self, value: bool) -> Self {
980 self.synthesized = value;
981 self
982 }
983
984 #[cfg_attr(not(tarpaulin), inline(always))]
986 pub const fn set_stream_index(&mut self, value: i32) -> &mut Self {
987 self.stream_index = value;
988 self
989 }
990 #[cfg_attr(not(tarpaulin), inline(always))]
992 pub const fn set_synthesized(&mut self, value: bool) -> &mut Self {
993 self.synthesized = value;
994 self
995 }
996}
997
998pub(crate) fn clone_parameters(
1012 source: &Parameters,
1013 stream_index: usize,
1014) -> Result<Parameters, DemuxError> {
1015 if unsafe { source.as_ptr() }.is_null() {
1023 return Err(DemuxError::ParametersMissing(ParametersMissing::new(
1024 stream_index,
1025 )));
1026 }
1027 let mut out = Parameters::new();
1028 if unsafe { out.as_ptr() }.is_null() {
1031 return Err(DemuxError::ParametersAlloc(ParametersAlloc::new(
1032 stream_index,
1033 )));
1034 }
1035 let rc = unsafe { avcodec_parameters_copy(out.as_mut_ptr(), source.as_ptr()) };
1039 if rc < 0 {
1040 return Err(DemuxError::ParametersCopy(ParametersCopy::new(
1041 stream_index,
1042 ffmpeg_next::Error::from(rc),
1043 )));
1044 }
1045 Ok(out)
1046}
1047
1048pub struct TrackExtra {
1086 stream_index: i32,
1087 disposition: i32,
1088 start_time: Option<i64>,
1089 frame_count: Option<i64>,
1090 parameters: Parameters,
1091}
1092
1093impl TrackExtra {
1094 pub fn new(stream_index: i32, parameters: Parameters) -> Result<Self, DemuxError> {
1108 if unsafe { parameters.as_ptr() }.is_null() {
1110 return Err(DemuxError::ParametersMissing(ParametersMissing::new(
1111 stream_index.max(0) as usize,
1112 )));
1113 }
1114 Ok(Self {
1115 stream_index,
1116 disposition: 0,
1117 start_time: None,
1118 frame_count: None,
1119 parameters,
1120 })
1121 }
1122
1123 pub fn try_clone(&self) -> Result<Self, DemuxError> {
1128 Ok(Self {
1131 stream_index: self.stream_index,
1132 disposition: self.disposition,
1133 start_time: self.start_time,
1134 frame_count: self.frame_count,
1135 parameters: self.clone_parameters()?,
1136 })
1137 }
1138
1139 pub fn clone_parameters(&self) -> Result<Parameters, DemuxError> {
1147 clone_parameters(&self.parameters, self.stream_index.max(0) as usize)
1148 }
1149
1150 #[cfg_attr(not(tarpaulin), inline(always))]
1152 pub const fn stream_index(&self) -> i32 {
1153 self.stream_index
1154 }
1155 #[cfg_attr(not(tarpaulin), inline(always))]
1157 pub const fn disposition(&self) -> i32 {
1158 self.disposition
1159 }
1160 #[cfg_attr(not(tarpaulin), inline(always))]
1163 pub const fn start_time(&self) -> Option<i64> {
1164 self.start_time
1165 }
1166 #[cfg_attr(not(tarpaulin), inline(always))]
1168 pub const fn frame_count(&self) -> Option<i64> {
1169 self.frame_count
1170 }
1171 #[cfg_attr(not(tarpaulin), inline(always))]
1174 pub const fn parameters(&self) -> &Parameters {
1175 &self.parameters
1176 }
1177
1178 #[cfg_attr(not(tarpaulin), inline(always))]
1180 #[must_use]
1181 pub const fn with_disposition(mut self, value: i32) -> Self {
1182 self.disposition = value;
1183 self
1184 }
1185 #[cfg_attr(not(tarpaulin), inline(always))]
1187 #[must_use]
1188 pub const fn with_start_time(mut self, value: Option<i64>) -> Self {
1189 self.start_time = value;
1190 self
1191 }
1192 #[cfg_attr(not(tarpaulin), inline(always))]
1194 #[must_use]
1195 pub const fn with_frame_count(mut self, value: Option<i64>) -> Self {
1196 self.frame_count = value;
1197 self
1198 }
1199
1200 #[cfg_attr(not(tarpaulin), inline(always))]
1202 pub const fn set_disposition(&mut self, value: i32) -> &mut Self {
1203 self.disposition = value;
1204 self
1205 }
1206 #[cfg_attr(not(tarpaulin), inline(always))]
1208 pub const fn set_start_time(&mut self, value: Option<i64>) -> &mut Self {
1209 self.start_time = value;
1210 self
1211 }
1212 #[cfg_attr(not(tarpaulin), inline(always))]
1214 pub const fn set_frame_count(&mut self, value: Option<i64>) -> &mut Self {
1215 self.frame_count = value;
1216 self
1217 }
1218}
1219
1220impl std::fmt::Debug for TrackExtra {
1221 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1226 f.debug_struct("TrackExtra")
1227 .field("stream_index", &self.stream_index)
1228 .field("disposition", &format_args!("{:#x}", self.disposition))
1229 .field("start_time", &self.start_time)
1230 .field("frame_count", &self.frame_count)
1231 .field(
1232 "parameters",
1233 &format_args!("{:?}", self.parameters.medium()),
1234 )
1235 .finish()
1236 }
1237}
1238
1239#[cfg(test)]
1240mod tests {
1241 use super::*;
1242
1243 #[test]
1244 fn defaults_construct() {
1245 let v = VideoPacketExtra::default();
1246 assert_eq!(v.stream_index(), 0);
1247 assert!(v.side_data().is_empty());
1248
1249 let f = VideoFrameExtra::default();
1250 assert_eq!(f.picture_type(), PictureType::Unspecified);
1251 assert!(!f.key_frame());
1252 assert!(f.mastering_display().is_none());
1253
1254 let s = SubtitleFrameExtra::default();
1255 assert_eq!(s.start_display_time(), 0);
1256 assert_eq!(s.end_display_time(), 0);
1257 }
1258
1259 #[test]
1260 fn picture_type_default_is_unspecified() {
1261 assert_eq!(PictureType::default(), PictureType::Unspecified);
1262 }
1263
1264 #[test]
1265 fn side_data_entry_carries_bytes() {
1266 let entry = SideDataEntry::new(12345, vec![1, 2, 3, 4]);
1267 assert_eq!(entry.kind(), 12345);
1268 assert_eq!(entry.data(), &[1, 2, 3, 4]);
1269 }
1270
1271 #[test]
1272 fn content_light_level_default_is_zero() {
1273 let cll = ContentLightLevel::default();
1274 assert_eq!(cll.max_cll(), 0);
1275 assert_eq!(cll.max_fall(), 0);
1276 }
1277
1278 #[test]
1279 fn builders_chain() {
1280 let v = VideoPacketExtra::new(7)
1281 .with_byte_pos(Some(1234))
1282 .with_side_data(vec![SideDataEntry::new(1, vec![0xAB])]);
1283 assert_eq!(v.stream_index(), 7);
1284 assert_eq!(v.byte_pos(), Some(1234));
1285 assert_eq!(v.side_data().len(), 1);
1286 }
1287
1288 #[test]
1289 fn setters_chain() {
1290 let mut v = VideoPacketExtra::default();
1291 v.set_stream_index(3).set_byte_pos(Some(99));
1292 assert_eq!(v.stream_index(), 3);
1293 assert_eq!(v.byte_pos(), Some(99));
1294 }
1295}