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: i32 = *self.ptr;
80 self.ptr = self.ptr.offset(count: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: Sample = (*self.ptr).into();
107 self.ptr = self.ptr.offset(count: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(init:ChannelLayout::MONO, |acc: ChannelLayout, cur: ChannelLayout| {
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 = ChannelLayout::from_bits_truncate(*self.ptr);
144 self.ptr = self.ptr.offset(count:1);
145
146 Some(layout)
147 }
148 }
149}
150