1 | use super::Disposition; |
2 | use codec::{self, packet}; |
3 | use ffi::*; |
4 | use format::context::common::Context; |
5 | use libc::c_int; |
6 | use {DictionaryRef, Discard, Rational}; |
7 | |
8 | #[derive (Debug)] |
9 | pub struct Stream<'a> { |
10 | context: &'a Context, |
11 | index: usize, |
12 | } |
13 | |
14 | impl<'a> Stream<'a> { |
15 | pub unsafe fn wrap(context: &Context, index: usize) -> Stream { |
16 | Stream { context, index } |
17 | } |
18 | |
19 | pub unsafe fn as_ptr(&self) -> *const AVStream { |
20 | *(*self.context.as_ptr()).streams.add(self.index) |
21 | } |
22 | } |
23 | |
24 | impl<'a> Stream<'a> { |
25 | pub fn id(&self) -> i32 { |
26 | unsafe { (*self.as_ptr()).id } |
27 | } |
28 | |
29 | #[cfg (not(feature = "ffmpeg_5_0" ))] |
30 | pub fn codec(&self) -> codec::Context { |
31 | unsafe { codec::Context::wrap((*self.as_ptr()).codec, Some(self.context.destructor())) } |
32 | } |
33 | |
34 | pub fn parameters(&self) -> codec::Parameters { |
35 | unsafe { |
36 | codec::Parameters::wrap((*self.as_ptr()).codecpar, Some(self.context.destructor())) |
37 | } |
38 | } |
39 | |
40 | pub fn index(&self) -> usize { |
41 | unsafe { (*self.as_ptr()).index as usize } |
42 | } |
43 | |
44 | pub fn time_base(&self) -> Rational { |
45 | unsafe { Rational::from((*self.as_ptr()).time_base) } |
46 | } |
47 | |
48 | pub fn start_time(&self) -> i64 { |
49 | unsafe { (*self.as_ptr()).start_time } |
50 | } |
51 | |
52 | pub fn duration(&self) -> i64 { |
53 | unsafe { (*self.as_ptr()).duration } |
54 | } |
55 | |
56 | pub fn frames(&self) -> i64 { |
57 | unsafe { (*self.as_ptr()).nb_frames } |
58 | } |
59 | |
60 | pub fn disposition(&self) -> Disposition { |
61 | unsafe { Disposition::from_bits_truncate((*self.as_ptr()).disposition) } |
62 | } |
63 | |
64 | pub fn discard(&self) -> Discard { |
65 | unsafe { Discard::from((*self.as_ptr()).discard) } |
66 | } |
67 | |
68 | pub fn side_data(&self) -> SideDataIter { |
69 | SideDataIter::new(self) |
70 | } |
71 | |
72 | pub fn rate(&self) -> Rational { |
73 | unsafe { Rational::from((*self.as_ptr()).r_frame_rate) } |
74 | } |
75 | |
76 | pub fn avg_frame_rate(&self) -> Rational { |
77 | unsafe { Rational::from((*self.as_ptr()).avg_frame_rate) } |
78 | } |
79 | |
80 | pub fn metadata(&self) -> DictionaryRef { |
81 | unsafe { DictionaryRef::wrap((*self.as_ptr()).metadata) } |
82 | } |
83 | } |
84 | |
85 | impl<'a> PartialEq for Stream<'a> { |
86 | fn eq(&self, other: &Self) -> bool { |
87 | unsafe { self.as_ptr() == other.as_ptr() } |
88 | } |
89 | } |
90 | |
91 | impl<'a> Eq for Stream<'a> {} |
92 | |
93 | pub struct SideDataIter<'a> { |
94 | stream: &'a Stream<'a>, |
95 | current: c_int, |
96 | } |
97 | |
98 | impl<'a> SideDataIter<'a> { |
99 | pub fn new<'sd, 's: 'sd>(stream: &'s Stream) -> SideDataIter<'sd> { |
100 | SideDataIter { stream, current: 0 } |
101 | } |
102 | } |
103 | |
104 | impl<'a> Iterator for SideDataIter<'a> { |
105 | type Item = packet::SideData<'a>; |
106 | |
107 | fn next(&mut self) -> Option<<Self as Iterator>::Item> { |
108 | unsafe { |
109 | if self.current >= (*self.stream.as_ptr()).nb_side_data { |
110 | return None; |
111 | } |
112 | |
113 | self.current += 1; |
114 | |
115 | Some(packet::SideData::wrap( |
116 | (*self.stream.as_ptr()) |
117 | .side_data |
118 | .offset((self.current - 1) as isize), |
119 | )) |
120 | } |
121 | } |
122 | |
123 | fn size_hint(&self) -> (usize, Option<usize>) { |
124 | unsafe { |
125 | let length = (*self.stream.as_ptr()).nb_side_data as usize; |
126 | |
127 | ( |
128 | length - self.current as usize, |
129 | Some(length - self.current as usize), |
130 | ) |
131 | } |
132 | } |
133 | } |
134 | |
135 | impl<'a> ExactSizeIterator for SideDataIter<'a> {} |
136 | |