1use std::vec::Vec;
10
11use ffmpeg_next::{codec::Parameters, ffi::avcodec_parameters_copy};
12
13use crate::demuxer::DemuxError;
14
15#[derive(Clone, Debug, Default)]
17pub struct VideoPacketExtra {
18 stream_index: i32,
19 byte_pos: Option<i64>,
20 side_data: Vec<SideDataEntry>,
21}
22
23impl VideoPacketExtra {
24 #[cfg_attr(not(tarpaulin), inline(always))]
27 pub const fn new(stream_index: i32) -> Self {
28 Self {
29 stream_index,
30 byte_pos: None,
31 side_data: Vec::new(),
32 }
33 }
34
35 #[cfg_attr(not(tarpaulin), inline(always))]
37 pub const fn stream_index(&self) -> i32 {
38 self.stream_index
39 }
40
41 #[cfg_attr(not(tarpaulin), inline(always))]
44 pub const fn byte_pos(&self) -> Option<i64> {
45 self.byte_pos
46 }
47
48 #[cfg_attr(not(tarpaulin), inline(always))]
50 pub fn side_data(&self) -> &[SideDataEntry] {
51 self.side_data.as_slice()
52 }
53
54 #[cfg_attr(not(tarpaulin), inline(always))]
56 #[must_use]
57 pub const fn with_stream_index(mut self, value: i32) -> Self {
58 self.stream_index = value;
59 self
60 }
61 #[cfg_attr(not(tarpaulin), inline(always))]
63 #[must_use]
64 pub const fn with_byte_pos(mut self, value: Option<i64>) -> Self {
65 self.byte_pos = value;
66 self
67 }
68 #[cfg_attr(not(tarpaulin), inline(always))]
70 #[must_use]
71 pub fn with_side_data(mut self, value: Vec<SideDataEntry>) -> Self {
72 self.side_data = value;
73 self
74 }
75
76 #[cfg_attr(not(tarpaulin), inline(always))]
78 pub const fn set_stream_index(&mut self, value: i32) -> &mut Self {
79 self.stream_index = value;
80 self
81 }
82 #[cfg_attr(not(tarpaulin), inline(always))]
84 pub const fn set_byte_pos(&mut self, value: Option<i64>) -> &mut Self {
85 self.byte_pos = value;
86 self
87 }
88 #[cfg_attr(not(tarpaulin), inline(always))]
90 pub fn set_side_data(&mut self, value: Vec<SideDataEntry>) -> &mut Self {
91 self.side_data = value;
92 self
93 }
94}
95
96#[derive(Clone, Debug, Default)]
99pub struct VideoFrameExtra {
100 sample_aspect_ratio: Option<(u32, u32)>,
101 picture_type: PictureType,
102 key_frame: bool,
103 interlaced: bool,
104 top_field_first: bool,
105 best_effort_timestamp: Option<i64>,
106 mastering_display: Option<MasteringDisplay>,
107 content_light_level: Option<ContentLightLevel>,
108 smpte_timecode: Vec<u32>,
109 side_data: Vec<SideDataEntry>,
110}
111
112impl VideoFrameExtra {
113 #[cfg_attr(not(tarpaulin), inline(always))]
115 pub const fn new() -> Self {
116 Self {
117 sample_aspect_ratio: None,
118 picture_type: PictureType::Unspecified,
119 key_frame: false,
120 interlaced: false,
121 top_field_first: false,
122 best_effort_timestamp: None,
123 mastering_display: None,
124 content_light_level: None,
125 smpte_timecode: Vec::new(),
126 side_data: Vec::new(),
127 }
128 }
129
130 #[cfg_attr(not(tarpaulin), inline(always))]
133 pub const fn sample_aspect_ratio(&self) -> Option<(u32, u32)> {
134 self.sample_aspect_ratio
135 }
136 #[cfg_attr(not(tarpaulin), inline(always))]
138 pub const fn picture_type(&self) -> PictureType {
139 self.picture_type
140 }
141 #[cfg_attr(not(tarpaulin), inline(always))]
143 pub const fn key_frame(&self) -> bool {
144 self.key_frame
145 }
146 #[cfg_attr(not(tarpaulin), inline(always))]
148 pub const fn interlaced(&self) -> bool {
149 self.interlaced
150 }
151 #[cfg_attr(not(tarpaulin), inline(always))]
153 pub const fn top_field_first(&self) -> bool {
154 self.top_field_first
155 }
156 #[cfg_attr(not(tarpaulin), inline(always))]
158 pub const fn best_effort_timestamp(&self) -> Option<i64> {
159 self.best_effort_timestamp
160 }
161 #[cfg_attr(not(tarpaulin), inline(always))]
163 pub const fn mastering_display(&self) -> Option<MasteringDisplay> {
164 self.mastering_display
165 }
166 #[cfg_attr(not(tarpaulin), inline(always))]
168 pub const fn content_light_level(&self) -> Option<ContentLightLevel> {
169 self.content_light_level
170 }
171 #[cfg_attr(not(tarpaulin), inline(always))]
173 pub fn smpte_timecode(&self) -> &[u32] {
174 self.smpte_timecode.as_slice()
175 }
176 #[cfg_attr(not(tarpaulin), inline(always))]
178 pub fn side_data(&self) -> &[SideDataEntry] {
179 self.side_data.as_slice()
180 }
181
182 #[cfg_attr(not(tarpaulin), inline(always))]
184 pub const fn with_sample_aspect_ratio(mut self, value: Option<(u32, u32)>) -> Self {
185 self.sample_aspect_ratio = value;
186 self
187 }
188 #[cfg_attr(not(tarpaulin), inline(always))]
190 #[must_use]
191 pub const fn with_picture_type(mut self, value: PictureType) -> Self {
192 self.picture_type = value;
193 self
194 }
195 #[cfg_attr(not(tarpaulin), inline(always))]
197 #[must_use]
198 pub const fn with_key_frame(mut self, value: bool) -> Self {
199 self.key_frame = value;
200 self
201 }
202 #[cfg_attr(not(tarpaulin), inline(always))]
204 #[must_use]
205 pub const fn with_interlaced(mut self, value: bool) -> Self {
206 self.interlaced = value;
207 self
208 }
209 #[cfg_attr(not(tarpaulin), inline(always))]
211 #[must_use]
212 pub const fn with_top_field_first(mut self, value: bool) -> Self {
213 self.top_field_first = value;
214 self
215 }
216 #[cfg_attr(not(tarpaulin), inline(always))]
218 #[must_use]
219 pub const fn with_best_effort_timestamp(mut self, value: Option<i64>) -> Self {
220 self.best_effort_timestamp = value;
221 self
222 }
223 #[cfg_attr(not(tarpaulin), inline(always))]
225 #[must_use]
226 pub const fn with_mastering_display(mut self, value: Option<MasteringDisplay>) -> Self {
227 self.mastering_display = value;
228 self
229 }
230 #[cfg_attr(not(tarpaulin), inline(always))]
232 #[must_use]
233 pub const fn with_content_light_level(mut self, value: Option<ContentLightLevel>) -> Self {
234 self.content_light_level = value;
235 self
236 }
237 #[cfg_attr(not(tarpaulin), inline(always))]
239 #[must_use]
240 pub fn with_smpte_timecode(mut self, value: Vec<u32>) -> Self {
241 self.smpte_timecode = value;
242 self
243 }
244 #[cfg_attr(not(tarpaulin), inline(always))]
246 #[must_use]
247 pub fn with_side_data(mut self, value: Vec<SideDataEntry>) -> Self {
248 self.side_data = value;
249 self
250 }
251
252 #[cfg_attr(not(tarpaulin), inline(always))]
254 pub const fn set_sample_aspect_ratio(&mut self, value: Option<(u32, u32)>) -> &mut Self {
255 self.sample_aspect_ratio = value;
256 self
257 }
258 #[cfg_attr(not(tarpaulin), inline(always))]
260 pub const fn set_picture_type(&mut self, value: PictureType) -> &mut Self {
261 self.picture_type = value;
262 self
263 }
264 #[cfg_attr(not(tarpaulin), inline(always))]
266 pub const fn set_key_frame(&mut self, value: bool) -> &mut Self {
267 self.key_frame = value;
268 self
269 }
270 #[cfg_attr(not(tarpaulin), inline(always))]
272 pub const fn set_interlaced(&mut self, value: bool) -> &mut Self {
273 self.interlaced = value;
274 self
275 }
276 #[cfg_attr(not(tarpaulin), inline(always))]
278 pub const fn set_top_field_first(&mut self, value: bool) -> &mut Self {
279 self.top_field_first = value;
280 self
281 }
282 #[cfg_attr(not(tarpaulin), inline(always))]
284 pub const fn set_best_effort_timestamp(&mut self, value: Option<i64>) -> &mut Self {
285 self.best_effort_timestamp = value;
286 self
287 }
288 #[cfg_attr(not(tarpaulin), inline(always))]
290 pub const fn set_mastering_display(&mut self, value: Option<MasteringDisplay>) -> &mut Self {
291 self.mastering_display = value;
292 self
293 }
294 #[cfg_attr(not(tarpaulin), inline(always))]
296 pub const fn set_content_light_level(&mut self, value: Option<ContentLightLevel>) -> &mut Self {
297 self.content_light_level = value;
298 self
299 }
300 #[cfg_attr(not(tarpaulin), inline(always))]
302 pub fn set_smpte_timecode(&mut self, value: Vec<u32>) -> &mut Self {
303 self.smpte_timecode = value;
304 self
305 }
306 #[cfg_attr(not(tarpaulin), inline(always))]
308 pub fn set_side_data(&mut self, value: Vec<SideDataEntry>) -> &mut Self {
309 self.side_data = value;
310 self
311 }
312}
313
314#[derive(Clone, Debug, Default)]
316pub struct AudioPacketExtra {
317 stream_index: i32,
318 byte_pos: Option<i64>,
319 side_data: Vec<SideDataEntry>,
320}
321
322impl AudioPacketExtra {
323 #[cfg_attr(not(tarpaulin), inline(always))]
325 pub const fn new(stream_index: i32) -> Self {
326 Self {
327 stream_index,
328 byte_pos: None,
329 side_data: Vec::new(),
330 }
331 }
332
333 #[cfg_attr(not(tarpaulin), inline(always))]
335 pub const fn stream_index(&self) -> i32 {
336 self.stream_index
337 }
338 #[cfg_attr(not(tarpaulin), inline(always))]
340 pub const fn byte_pos(&self) -> Option<i64> {
341 self.byte_pos
342 }
343 #[cfg_attr(not(tarpaulin), inline(always))]
345 pub fn side_data(&self) -> &[SideDataEntry] {
346 self.side_data.as_slice()
347 }
348
349 #[cfg_attr(not(tarpaulin), inline(always))]
351 #[must_use]
352 pub const fn with_stream_index(mut self, value: i32) -> Self {
353 self.stream_index = value;
354 self
355 }
356 #[cfg_attr(not(tarpaulin), inline(always))]
358 #[must_use]
359 pub const fn with_byte_pos(mut self, value: Option<i64>) -> Self {
360 self.byte_pos = value;
361 self
362 }
363 #[cfg_attr(not(tarpaulin), inline(always))]
365 #[must_use]
366 pub fn with_side_data(mut self, value: Vec<SideDataEntry>) -> Self {
367 self.side_data = value;
368 self
369 }
370
371 #[cfg_attr(not(tarpaulin), inline(always))]
373 pub const fn set_stream_index(&mut self, value: i32) -> &mut Self {
374 self.stream_index = value;
375 self
376 }
377 #[cfg_attr(not(tarpaulin), inline(always))]
379 pub const fn set_byte_pos(&mut self, value: Option<i64>) -> &mut Self {
380 self.byte_pos = value;
381 self
382 }
383 #[cfg_attr(not(tarpaulin), inline(always))]
385 pub fn set_side_data(&mut self, value: Vec<SideDataEntry>) -> &mut Self {
386 self.side_data = value;
387 self
388 }
389}
390
391#[derive(Clone, Debug, Default)]
393pub struct AudioFrameExtra {
394 best_effort_timestamp: Option<i64>,
395 side_data: Vec<SideDataEntry>,
396}
397
398impl AudioFrameExtra {
399 #[cfg_attr(not(tarpaulin), inline(always))]
401 pub const fn new() -> Self {
402 Self {
403 best_effort_timestamp: None,
404 side_data: Vec::new(),
405 }
406 }
407
408 #[cfg_attr(not(tarpaulin), inline(always))]
410 pub const fn best_effort_timestamp(&self) -> Option<i64> {
411 self.best_effort_timestamp
412 }
413 #[cfg_attr(not(tarpaulin), inline(always))]
415 pub fn side_data(&self) -> &[SideDataEntry] {
416 self.side_data.as_slice()
417 }
418
419 #[cfg_attr(not(tarpaulin), inline(always))]
421 #[must_use]
422 pub const fn with_best_effort_timestamp(mut self, value: Option<i64>) -> Self {
423 self.best_effort_timestamp = value;
424 self
425 }
426 #[cfg_attr(not(tarpaulin), inline(always))]
428 #[must_use]
429 pub fn with_side_data(mut self, value: Vec<SideDataEntry>) -> Self {
430 self.side_data = value;
431 self
432 }
433
434 #[cfg_attr(not(tarpaulin), inline(always))]
436 pub const fn set_best_effort_timestamp(&mut self, value: Option<i64>) -> &mut Self {
437 self.best_effort_timestamp = value;
438 self
439 }
440 #[cfg_attr(not(tarpaulin), inline(always))]
442 pub fn set_side_data(&mut self, value: Vec<SideDataEntry>) -> &mut Self {
443 self.side_data = value;
444 self
445 }
446}
447
448#[derive(Clone, Debug, Default)]
450pub struct SubtitlePacketExtra {
451 stream_index: i32,
452 language: Option<[u8; 3]>,
453 forced: bool,
454 side_data: Vec<SideDataEntry>,
455}
456
457impl SubtitlePacketExtra {
458 #[cfg_attr(not(tarpaulin), inline(always))]
461 pub const fn new(stream_index: i32) -> Self {
462 Self {
463 stream_index,
464 language: None,
465 forced: false,
466 side_data: Vec::new(),
467 }
468 }
469
470 #[cfg_attr(not(tarpaulin), inline(always))]
472 pub const fn stream_index(&self) -> i32 {
473 self.stream_index
474 }
475 #[cfg_attr(not(tarpaulin), inline(always))]
477 pub const fn language(&self) -> Option<[u8; 3]> {
478 self.language
479 }
480 #[cfg_attr(not(tarpaulin), inline(always))]
482 pub const fn forced(&self) -> bool {
483 self.forced
484 }
485 #[cfg_attr(not(tarpaulin), inline(always))]
492 pub fn side_data(&self) -> &[SideDataEntry] {
493 self.side_data.as_slice()
494 }
495
496 #[cfg_attr(not(tarpaulin), inline(always))]
498 #[must_use]
499 pub const fn with_stream_index(mut self, value: i32) -> Self {
500 self.stream_index = value;
501 self
502 }
503 #[cfg_attr(not(tarpaulin), inline(always))]
505 #[must_use]
506 pub const fn with_language(mut self, value: Option<[u8; 3]>) -> Self {
507 self.language = value;
508 self
509 }
510 #[cfg_attr(not(tarpaulin), inline(always))]
512 #[must_use]
513 pub fn with_side_data(mut self, value: Vec<SideDataEntry>) -> Self {
514 self.side_data = value;
515 self
516 }
517 #[cfg_attr(not(tarpaulin), inline(always))]
519 pub fn set_side_data(&mut self, value: Vec<SideDataEntry>) -> &mut Self {
520 self.side_data = value;
521 self
522 }
523 #[cfg_attr(not(tarpaulin), inline(always))]
525 #[must_use]
526 pub const fn with_forced(mut self, value: bool) -> Self {
527 self.forced = value;
528 self
529 }
530
531 #[cfg_attr(not(tarpaulin), inline(always))]
533 pub const fn set_stream_index(&mut self, value: i32) -> &mut Self {
534 self.stream_index = value;
535 self
536 }
537 #[cfg_attr(not(tarpaulin), inline(always))]
539 pub const fn set_language(&mut self, value: Option<[u8; 3]>) -> &mut Self {
540 self.language = value;
541 self
542 }
543 #[cfg_attr(not(tarpaulin), inline(always))]
545 pub const fn set_forced(&mut self, value: bool) -> &mut Self {
546 self.forced = value;
547 self
548 }
549}
550
551#[derive(Clone, Debug, Default)]
553pub struct SubtitleFrameExtra {
554 start_display_time: u32,
555 end_display_time: u32,
556}
557
558impl SubtitleFrameExtra {
559 #[cfg_attr(not(tarpaulin), inline(always))]
561 pub const fn new(start_display_time: u32, end_display_time: u32) -> Self {
562 Self {
563 start_display_time,
564 end_display_time,
565 }
566 }
567
568 #[cfg_attr(not(tarpaulin), inline(always))]
570 pub const fn start_display_time(&self) -> u32 {
571 self.start_display_time
572 }
573 #[cfg_attr(not(tarpaulin), inline(always))]
575 pub const fn end_display_time(&self) -> u32 {
576 self.end_display_time
577 }
578
579 #[cfg_attr(not(tarpaulin), inline(always))]
581 #[must_use]
582 pub const fn with_start_display_time(mut self, value: u32) -> Self {
583 self.start_display_time = value;
584 self
585 }
586 #[cfg_attr(not(tarpaulin), inline(always))]
588 #[must_use]
589 pub const fn with_end_display_time(mut self, value: u32) -> Self {
590 self.end_display_time = value;
591 self
592 }
593
594 #[cfg_attr(not(tarpaulin), inline(always))]
596 pub const fn set_start_display_time(&mut self, value: u32) -> &mut Self {
597 self.start_display_time = value;
598 self
599 }
600 #[cfg_attr(not(tarpaulin), inline(always))]
602 pub const fn set_end_display_time(&mut self, value: u32) -> &mut Self {
603 self.end_display_time = value;
604 self
605 }
606}
607
608#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Hash)]
610#[non_exhaustive]
611pub enum PictureType {
612 #[default]
614 Unspecified,
615 I,
617 P,
619 B,
621 S,
623 Si,
625 Sp,
627 Bi,
629}
630
631#[derive(Clone, Debug)]
636pub struct SideDataEntry {
637 kind: i32,
638 data: Vec<u8>,
639}
640
641impl SideDataEntry {
642 #[cfg_attr(not(tarpaulin), inline(always))]
644 pub const fn new(kind: i32, data: Vec<u8>) -> Self {
645 Self { kind, data }
646 }
647
648 #[cfg_attr(not(tarpaulin), inline(always))]
650 pub const fn kind(&self) -> i32 {
651 self.kind
652 }
653 #[cfg_attr(not(tarpaulin), inline(always))]
655 pub fn data(&self) -> &[u8] {
656 self.data.as_slice()
657 }
658
659 #[cfg_attr(not(tarpaulin), inline(always))]
661 #[must_use]
662 pub const fn with_kind(mut self, value: i32) -> Self {
663 self.kind = value;
664 self
665 }
666 #[cfg_attr(not(tarpaulin), inline(always))]
668 #[must_use]
669 pub fn with_data(mut self, value: Vec<u8>) -> Self {
670 self.data = value;
671 self
672 }
673
674 #[cfg_attr(not(tarpaulin), inline(always))]
676 pub const fn set_kind(&mut self, value: i32) -> &mut Self {
677 self.kind = value;
678 self
679 }
680 #[cfg_attr(not(tarpaulin), inline(always))]
682 pub fn set_data(&mut self, value: Vec<u8>) -> &mut Self {
683 self.data = value;
684 self
685 }
686}
687
688#[derive(Copy, Clone, Debug, PartialEq)]
690pub struct MasteringDisplay {
691 display_primaries: [(u32, u32); 3],
692 white_point: (u32, u32),
693 max_luminance: (u32, u32),
694 min_luminance: (u32, u32),
695}
696
697impl MasteringDisplay {
698 #[cfg_attr(not(tarpaulin), inline(always))]
700 pub const fn new(
701 display_primaries: [(u32, u32); 3],
702 white_point: (u32, u32),
703 max_luminance: (u32, u32),
704 min_luminance: (u32, u32),
705 ) -> Self {
706 Self {
707 display_primaries,
708 white_point,
709 max_luminance,
710 min_luminance,
711 }
712 }
713
714 #[cfg_attr(not(tarpaulin), inline(always))]
717 pub const fn display_primaries(&self) -> [(u32, u32); 3] {
718 self.display_primaries
719 }
720 #[cfg_attr(not(tarpaulin), inline(always))]
722 pub const fn white_point(&self) -> (u32, u32) {
723 self.white_point
724 }
725 #[cfg_attr(not(tarpaulin), inline(always))]
727 pub const fn max_luminance(&self) -> (u32, u32) {
728 self.max_luminance
729 }
730 #[cfg_attr(not(tarpaulin), inline(always))]
732 pub const fn min_luminance(&self) -> (u32, u32) {
733 self.min_luminance
734 }
735
736 #[cfg_attr(not(tarpaulin), inline(always))]
738 pub const fn with_display_primaries(mut self, value: [(u32, u32); 3]) -> Self {
739 self.display_primaries = value;
740 self
741 }
742 #[cfg_attr(not(tarpaulin), inline(always))]
744 pub const fn with_white_point(mut self, value: (u32, u32)) -> Self {
745 self.white_point = value;
746 self
747 }
748 #[cfg_attr(not(tarpaulin), inline(always))]
750 pub const fn with_max_luminance(mut self, value: (u32, u32)) -> Self {
751 self.max_luminance = value;
752 self
753 }
754 #[cfg_attr(not(tarpaulin), inline(always))]
756 pub const fn with_min_luminance(mut self, value: (u32, u32)) -> Self {
757 self.min_luminance = value;
758 self
759 }
760
761 #[cfg_attr(not(tarpaulin), inline(always))]
763 pub const fn set_display_primaries(&mut self, value: [(u32, u32); 3]) -> &mut Self {
764 self.display_primaries = value;
765 self
766 }
767 #[cfg_attr(not(tarpaulin), inline(always))]
769 pub const fn set_white_point(&mut self, value: (u32, u32)) -> &mut Self {
770 self.white_point = value;
771 self
772 }
773 #[cfg_attr(not(tarpaulin), inline(always))]
775 pub const fn set_max_luminance(&mut self, value: (u32, u32)) -> &mut Self {
776 self.max_luminance = value;
777 self
778 }
779 #[cfg_attr(not(tarpaulin), inline(always))]
781 pub const fn set_min_luminance(&mut self, value: (u32, u32)) -> &mut Self {
782 self.min_luminance = value;
783 self
784 }
785}
786
787#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Default)]
789pub struct ContentLightLevel {
790 max_cll: u32,
791 max_fall: u32,
792}
793
794impl ContentLightLevel {
795 #[cfg_attr(not(tarpaulin), inline(always))]
797 pub const fn new(max_cll: u32, max_fall: u32) -> Self {
798 Self { max_cll, max_fall }
799 }
800
801 #[cfg_attr(not(tarpaulin), inline(always))]
803 pub const fn max_cll(&self) -> u32 {
804 self.max_cll
805 }
806 #[cfg_attr(not(tarpaulin), inline(always))]
808 pub const fn max_fall(&self) -> u32 {
809 self.max_fall
810 }
811
812 #[cfg_attr(not(tarpaulin), inline(always))]
814 #[must_use]
815 pub const fn with_max_cll(mut self, value: u32) -> Self {
816 self.max_cll = value;
817 self
818 }
819 #[cfg_attr(not(tarpaulin), inline(always))]
821 #[must_use]
822 pub const fn with_max_fall(mut self, value: u32) -> Self {
823 self.max_fall = value;
824 self
825 }
826
827 #[cfg_attr(not(tarpaulin), inline(always))]
829 pub const fn set_max_cll(&mut self, value: u32) -> &mut Self {
830 self.max_cll = value;
831 self
832 }
833 #[cfg_attr(not(tarpaulin), inline(always))]
835 pub const fn set_max_fall(&mut self, value: u32) -> &mut Self {
836 self.max_fall = value;
837 self
838 }
839}
840
841#[derive(Clone, Debug, Default)]
853pub struct DataPacketExtra {
854 stream_index: i32,
855 byte_pos: Option<i64>,
856 side_data: Vec<SideDataEntry>,
857}
858
859impl DataPacketExtra {
860 #[cfg_attr(not(tarpaulin), inline(always))]
863 pub const fn new(stream_index: i32) -> Self {
864 Self {
865 stream_index,
866 byte_pos: None,
867 side_data: Vec::new(),
868 }
869 }
870
871 #[cfg_attr(not(tarpaulin), inline(always))]
873 pub const fn stream_index(&self) -> i32 {
874 self.stream_index
875 }
876 #[cfg_attr(not(tarpaulin), inline(always))]
879 pub const fn byte_pos(&self) -> Option<i64> {
880 self.byte_pos
881 }
882 #[cfg_attr(not(tarpaulin), inline(always))]
884 pub fn side_data(&self) -> &[SideDataEntry] {
885 self.side_data.as_slice()
886 }
887
888 #[cfg_attr(not(tarpaulin), inline(always))]
890 #[must_use]
891 pub const fn with_stream_index(mut self, value: i32) -> Self {
892 self.stream_index = value;
893 self
894 }
895 #[cfg_attr(not(tarpaulin), inline(always))]
897 #[must_use]
898 pub const fn with_byte_pos(mut self, value: Option<i64>) -> Self {
899 self.byte_pos = value;
900 self
901 }
902 #[cfg_attr(not(tarpaulin), inline(always))]
904 #[must_use]
905 pub fn with_side_data(mut self, value: Vec<SideDataEntry>) -> Self {
906 self.side_data = value;
907 self
908 }
909
910 #[cfg_attr(not(tarpaulin), inline(always))]
912 pub const fn set_stream_index(&mut self, value: i32) -> &mut Self {
913 self.stream_index = value;
914 self
915 }
916 #[cfg_attr(not(tarpaulin), inline(always))]
918 pub const fn set_byte_pos(&mut self, value: Option<i64>) -> &mut Self {
919 self.byte_pos = value;
920 self
921 }
922 #[cfg_attr(not(tarpaulin), inline(always))]
924 pub fn set_side_data(&mut self, value: Vec<SideDataEntry>) -> &mut Self {
925 self.side_data = value;
926 self
927 }
928}
929
930#[derive(Clone, Debug, Default)]
940pub struct AttachmentPacketExtra {
941 stream_index: i32,
942 synthesized: bool,
943}
944
945impl AttachmentPacketExtra {
946 #[cfg_attr(not(tarpaulin), inline(always))]
949 pub const fn new(stream_index: i32) -> Self {
950 Self {
951 stream_index,
952 synthesized: false,
953 }
954 }
955
956 #[cfg_attr(not(tarpaulin), inline(always))]
958 pub const fn stream_index(&self) -> i32 {
959 self.stream_index
960 }
961 #[cfg_attr(not(tarpaulin), inline(always))]
964 pub const fn synthesized(&self) -> bool {
965 self.synthesized
966 }
967
968 #[cfg_attr(not(tarpaulin), inline(always))]
970 #[must_use]
971 pub const fn with_stream_index(mut self, value: i32) -> Self {
972 self.stream_index = value;
973 self
974 }
975 #[cfg_attr(not(tarpaulin), inline(always))]
977 #[must_use]
978 pub const fn with_synthesized(mut self, value: bool) -> Self {
979 self.synthesized = value;
980 self
981 }
982
983 #[cfg_attr(not(tarpaulin), inline(always))]
985 pub const fn set_stream_index(&mut self, value: i32) -> &mut Self {
986 self.stream_index = value;
987 self
988 }
989 #[cfg_attr(not(tarpaulin), inline(always))]
991 pub const fn set_synthesized(&mut self, value: bool) -> &mut Self {
992 self.synthesized = value;
993 self
994 }
995}
996
997pub(crate) fn clone_parameters(
1011 source: &Parameters,
1012 stream_index: usize,
1013) -> Result<Parameters, DemuxError> {
1014 if unsafe { source.as_ptr() }.is_null() {
1022 return Err(DemuxError::ParametersMissing { stream_index });
1023 }
1024 let mut out = Parameters::new();
1025 if unsafe { out.as_ptr() }.is_null() {
1028 return Err(DemuxError::ParametersAlloc { stream_index });
1029 }
1030 let rc = unsafe { avcodec_parameters_copy(out.as_mut_ptr(), source.as_ptr()) };
1034 if rc < 0 {
1035 return Err(DemuxError::ParametersCopy {
1036 stream_index,
1037 source: ffmpeg_next::Error::from(rc),
1038 });
1039 }
1040 Ok(out)
1041}
1042
1043pub struct TrackExtra {
1065 stream_index: i32,
1066 disposition: i32,
1067 start_time: Option<i64>,
1068 frame_count: Option<i64>,
1069 parameters: Parameters,
1070}
1071
1072impl TrackExtra {
1073 pub fn new(stream_index: i32, parameters: Parameters) -> Result<Self, DemuxError> {
1087 if unsafe { parameters.as_ptr() }.is_null() {
1089 return Err(DemuxError::ParametersMissing {
1090 stream_index: stream_index.max(0) as usize,
1091 });
1092 }
1093 Ok(Self {
1094 stream_index,
1095 disposition: 0,
1096 start_time: None,
1097 frame_count: None,
1098 parameters,
1099 })
1100 }
1101
1102 pub fn try_clone(&self) -> Result<Self, DemuxError> {
1107 Ok(Self {
1110 stream_index: self.stream_index,
1111 disposition: self.disposition,
1112 start_time: self.start_time,
1113 frame_count: self.frame_count,
1114 parameters: self.clone_parameters()?,
1115 })
1116 }
1117
1118 pub fn clone_parameters(&self) -> Result<Parameters, DemuxError> {
1126 clone_parameters(&self.parameters, self.stream_index.max(0) as usize)
1127 }
1128
1129 #[cfg_attr(not(tarpaulin), inline(always))]
1131 pub const fn stream_index(&self) -> i32 {
1132 self.stream_index
1133 }
1134 #[cfg_attr(not(tarpaulin), inline(always))]
1136 pub const fn disposition(&self) -> i32 {
1137 self.disposition
1138 }
1139 #[cfg_attr(not(tarpaulin), inline(always))]
1142 pub const fn start_time(&self) -> Option<i64> {
1143 self.start_time
1144 }
1145 #[cfg_attr(not(tarpaulin), inline(always))]
1147 pub const fn frame_count(&self) -> Option<i64> {
1148 self.frame_count
1149 }
1150 #[cfg_attr(not(tarpaulin), inline(always))]
1153 pub const fn parameters(&self) -> &Parameters {
1154 &self.parameters
1155 }
1156
1157 #[cfg_attr(not(tarpaulin), inline(always))]
1159 #[must_use]
1160 pub const fn with_disposition(mut self, value: i32) -> Self {
1161 self.disposition = value;
1162 self
1163 }
1164 #[cfg_attr(not(tarpaulin), inline(always))]
1166 #[must_use]
1167 pub const fn with_start_time(mut self, value: Option<i64>) -> Self {
1168 self.start_time = value;
1169 self
1170 }
1171 #[cfg_attr(not(tarpaulin), inline(always))]
1173 #[must_use]
1174 pub const fn with_frame_count(mut self, value: Option<i64>) -> Self {
1175 self.frame_count = value;
1176 self
1177 }
1178
1179 #[cfg_attr(not(tarpaulin), inline(always))]
1181 pub const fn set_disposition(&mut self, value: i32) -> &mut Self {
1182 self.disposition = value;
1183 self
1184 }
1185 #[cfg_attr(not(tarpaulin), inline(always))]
1187 pub const fn set_start_time(&mut self, value: Option<i64>) -> &mut Self {
1188 self.start_time = value;
1189 self
1190 }
1191 #[cfg_attr(not(tarpaulin), inline(always))]
1193 pub const fn set_frame_count(&mut self, value: Option<i64>) -> &mut Self {
1194 self.frame_count = value;
1195 self
1196 }
1197}
1198
1199impl std::fmt::Debug for TrackExtra {
1200 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1205 f.debug_struct("TrackExtra")
1206 .field("stream_index", &self.stream_index)
1207 .field("disposition", &format_args!("{:#x}", self.disposition))
1208 .field("start_time", &self.start_time)
1209 .field("frame_count", &self.frame_count)
1210 .field(
1211 "parameters",
1212 &format_args!("{:?}", self.parameters.medium()),
1213 )
1214 .finish()
1215 }
1216}
1217
1218#[cfg(test)]
1219mod tests {
1220 use super::*;
1221
1222 #[test]
1223 fn defaults_construct() {
1224 let v = VideoPacketExtra::default();
1225 assert_eq!(v.stream_index(), 0);
1226 assert!(v.side_data().is_empty());
1227
1228 let f = VideoFrameExtra::default();
1229 assert_eq!(f.picture_type(), PictureType::Unspecified);
1230 assert!(!f.key_frame());
1231 assert!(f.mastering_display().is_none());
1232
1233 let s = SubtitleFrameExtra::default();
1234 assert_eq!(s.start_display_time(), 0);
1235 assert_eq!(s.end_display_time(), 0);
1236 }
1237
1238 #[test]
1239 fn picture_type_default_is_unspecified() {
1240 assert_eq!(PictureType::default(), PictureType::Unspecified);
1241 }
1242
1243 #[test]
1244 fn side_data_entry_carries_bytes() {
1245 let entry = SideDataEntry::new(12345, vec![1, 2, 3, 4]);
1246 assert_eq!(entry.kind(), 12345);
1247 assert_eq!(entry.data(), &[1, 2, 3, 4]);
1248 }
1249
1250 #[test]
1251 fn content_light_level_default_is_zero() {
1252 let cll = ContentLightLevel::default();
1253 assert_eq!(cll.max_cll(), 0);
1254 assert_eq!(cll.max_fall(), 0);
1255 }
1256
1257 #[test]
1258 fn builders_chain() {
1259 let v = VideoPacketExtra::new(7)
1260 .with_byte_pos(Some(1234))
1261 .with_side_data(vec![SideDataEntry::new(1, vec![0xAB])]);
1262 assert_eq!(v.stream_index(), 7);
1263 assert_eq!(v.byte_pos(), Some(1234));
1264 assert_eq!(v.side_data().len(), 1);
1265 }
1266
1267 #[test]
1268 fn setters_chain() {
1269 let mut v = VideoPacketExtra::default();
1270 v.set_stream_index(3).set_byte_pos(Some(99));
1271 assert_eq!(v.stream_index(), 3);
1272 assert_eq!(v.byte_pos(), Some(99));
1273 }
1274}