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