ffmpeg/format/stream/
stream.rs

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