ffmpeg_next_crossfix/codec/
audio.rs

1use std::ops::Deref;
2
3use super::codec::Codec;
4use ffi::*;
5use {format, ChannelLayout};
6
7#[derive(PartialEq, Eq, Copy, Clone)]
8pub struct Audio {
9    codec: Codec,
10}
11
12impl Audio {
13    pub unsafe fn new(codec: Codec) -> Audio {
14        Audio { codec }
15    }
16}
17
18impl Audio {
19    pub fn rates(&self) -> Option<RateIter> {
20        unsafe {
21            if (*self.as_ptr()).supported_samplerates.is_null() {
22                None
23            } else {
24                Some(RateIter::new((*self.codec.as_ptr()).supported_samplerates))
25            }
26        }
27    }
28
29    pub fn formats(&self) -> Option<FormatIter> {
30        unsafe {
31            if (*self.codec.as_ptr()).sample_fmts.is_null() {
32                None
33            } else {
34                Some(FormatIter::new((*self.codec.as_ptr()).sample_fmts))
35            }
36        }
37    }
38
39    pub fn channel_layouts(&self) -> Option<ChannelLayoutIter> {
40        unsafe {
41            if (*self.codec.as_ptr()).channel_layouts.is_null() {
42                None
43            } else {
44                Some(ChannelLayoutIter::new(
45                    (*self.codec.as_ptr()).channel_layouts,
46                ))
47            }
48        }
49    }
50}
51
52impl Deref for Audio {
53    type Target = Codec;
54
55    fn deref(&self) -> &Self::Target {
56        &self.codec
57    }
58}
59
60pub struct RateIter {
61    ptr: *const i32,
62}
63
64impl RateIter {
65    pub fn new(ptr: *const i32) -> Self {
66        RateIter { ptr }
67    }
68}
69
70impl Iterator for RateIter {
71    type Item = i32;
72
73    fn next(&mut self) -> Option<<Self as Iterator>::Item> {
74        unsafe {
75            if *self.ptr == 0 {
76                return None;
77            }
78
79            let rate = *self.ptr;
80            self.ptr = self.ptr.offset(1);
81
82            Some(rate)
83        }
84    }
85}
86
87pub struct FormatIter {
88    ptr: *const AVSampleFormat,
89}
90
91impl FormatIter {
92    pub fn new(ptr: *const AVSampleFormat) -> Self {
93        FormatIter { ptr }
94    }
95}
96
97impl Iterator for FormatIter {
98    type Item = format::Sample;
99
100    fn next(&mut self) -> Option<<Self as Iterator>::Item> {
101        unsafe {
102            if *self.ptr == AVSampleFormat::AV_SAMPLE_FMT_NONE {
103                return None;
104            }
105
106            let format = (*self.ptr).into();
107            self.ptr = self.ptr.offset(1);
108
109            Some(format)
110        }
111    }
112}
113
114pub struct ChannelLayoutIter {
115    ptr: *const u64,
116}
117
118impl ChannelLayoutIter {
119    pub fn new(ptr: *const u64) -> Self {
120        ChannelLayoutIter { ptr }
121    }
122
123    pub fn best(self, max: i32) -> ChannelLayout {
124        self.fold(ChannelLayout::MONO, |acc, cur| {
125            if cur.channels() > acc.channels() && cur.channels() <= max {
126                cur
127            } else {
128                acc
129            }
130        })
131    }
132}
133
134impl Iterator for ChannelLayoutIter {
135    type Item = ChannelLayout;
136
137    fn next(&mut self) -> Option<<Self as Iterator>::Item> {
138        unsafe {
139            if *self.ptr == 0 {
140                return None;
141            }
142
143            let layout = ChannelLayout::from_bits_truncate(*self.ptr);
144            self.ptr = self.ptr.offset(1);
145
146            Some(layout)
147        }
148    }
149}