1 | use std::ptr; |
2 | |
3 | use super::Delay; |
4 | use ffi::*; |
5 | use libc::c_int; |
6 | use std::ffi::c_void; |
7 | use util::format; |
8 | use Dictionary; |
9 | use {frame, ChannelLayout, Error}; |
10 | |
11 | #[derive (Eq, PartialEq, Copy, Clone)] |
12 | pub struct Definition { |
13 | pub format: format::Sample, |
14 | pub channel_layout: ChannelLayout, |
15 | pub rate: u32, |
16 | } |
17 | |
18 | pub struct Context { |
19 | ptr: *mut SwrContext, |
20 | |
21 | input: Definition, |
22 | output: Definition, |
23 | } |
24 | |
25 | unsafe impl Send for Context {} |
26 | |
27 | impl Context { |
28 | #[doc (hidden)] |
29 | pub unsafe fn as_ptr(&self) -> *const SwrContext { |
30 | self.ptr as *const _ |
31 | } |
32 | |
33 | #[doc (hidden)] |
34 | pub unsafe fn as_mut_ptr(&mut self) -> *mut SwrContext { |
35 | self.ptr |
36 | } |
37 | } |
38 | |
39 | impl Context { |
40 | /// Create a resampler with the given definitions. |
41 | pub fn get( |
42 | src_format: format::Sample, |
43 | src_channel_layout: ChannelLayout, |
44 | src_rate: u32, |
45 | dst_format: format::Sample, |
46 | dst_channel_layout: ChannelLayout, |
47 | dst_rate: u32, |
48 | ) -> Result<Self, Error> { |
49 | Self::get_with( |
50 | src_format, |
51 | src_channel_layout, |
52 | src_rate, |
53 | dst_format, |
54 | dst_channel_layout, |
55 | dst_rate, |
56 | Dictionary::new(), |
57 | ) |
58 | } |
59 | |
60 | /// Create a resampler with the given definitions and custom options dictionary. |
61 | pub fn get_with( |
62 | src_format: format::Sample, |
63 | src_channel_layout: ChannelLayout, |
64 | src_rate: u32, |
65 | dst_format: format::Sample, |
66 | dst_channel_layout: ChannelLayout, |
67 | dst_rate: u32, |
68 | options: Dictionary, |
69 | ) -> Result<Self, Error> { |
70 | unsafe { |
71 | let ptr = swr_alloc_set_opts( |
72 | ptr::null_mut(), |
73 | dst_channel_layout.bits() as i64, |
74 | dst_format.into(), |
75 | dst_rate as c_int, |
76 | src_channel_layout.bits() as i64, |
77 | src_format.into(), |
78 | src_rate as c_int, |
79 | 0, |
80 | ptr::null_mut(), |
81 | ); |
82 | |
83 | let mut opts = options.disown(); |
84 | let res = av_opt_set_dict(ptr as *mut c_void, &mut opts); |
85 | Dictionary::own(opts); |
86 | |
87 | if res != 0 { |
88 | return Err(Error::from(res)); |
89 | } |
90 | |
91 | if !ptr.is_null() { |
92 | match swr_init(ptr) { |
93 | e if e < 0 => Err(Error::from(e)), |
94 | |
95 | _ => Ok(Context { |
96 | ptr, |
97 | |
98 | input: Definition { |
99 | format: src_format, |
100 | channel_layout: src_channel_layout, |
101 | rate: src_rate, |
102 | }, |
103 | |
104 | output: Definition { |
105 | format: dst_format, |
106 | channel_layout: dst_channel_layout, |
107 | rate: dst_rate, |
108 | }, |
109 | }), |
110 | } |
111 | } else { |
112 | Err(Error::InvalidData) |
113 | } |
114 | } |
115 | } |
116 | |
117 | /// Get the input definition. |
118 | pub fn input(&self) -> &Definition { |
119 | &self.input |
120 | } |
121 | |
122 | /// Get the output definition. |
123 | pub fn output(&self) -> &Definition { |
124 | &self.output |
125 | } |
126 | |
127 | /// Get the remaining delay. |
128 | pub fn delay(&self) -> Option<Delay> { |
129 | unsafe { |
130 | match swr_get_delay(self.as_ptr() as *mut _, 1) { |
131 | 0 => None, |
132 | _ => Some(Delay::from(self)), |
133 | } |
134 | } |
135 | } |
136 | |
137 | /// Run the resampler from the given input to the given output. |
138 | /// |
139 | /// When there are internal frames to process it will return `Ok(Some(Delay { .. }))`. |
140 | pub fn run( |
141 | &mut self, |
142 | input: &frame::Audio, |
143 | output: &mut frame::Audio, |
144 | ) -> Result<Option<Delay>, Error> { |
145 | unsafe { |
146 | (*output.as_mut_ptr()).sample_rate = self.output.rate as i32; |
147 | } |
148 | |
149 | unsafe { |
150 | if output.is_empty() { |
151 | output.alloc( |
152 | self.output.format, |
153 | input.samples(), |
154 | self.output.channel_layout, |
155 | ); |
156 | } |
157 | |
158 | match swr_convert_frame(self.as_mut_ptr(), output.as_mut_ptr(), input.as_ptr()) { |
159 | 0 => Ok(self.delay()), |
160 | |
161 | e => Err(Error::from(e)), |
162 | } |
163 | } |
164 | } |
165 | |
166 | /// Convert one of the remaining internal frames. |
167 | /// |
168 | /// When there are no more internal frames `Ok(None)` will be returned. |
169 | pub fn flush(&mut self, output: &mut frame::Audio) -> Result<Option<Delay>, Error> { |
170 | unsafe { |
171 | (*output.as_mut_ptr()).sample_rate = self.output.rate as i32; |
172 | } |
173 | |
174 | unsafe { |
175 | match swr_convert_frame(self.as_mut_ptr(), output.as_mut_ptr(), ptr::null()) { |
176 | 0 => Ok(self.delay()), |
177 | |
178 | e => Err(Error::from(e)), |
179 | } |
180 | } |
181 | } |
182 | } |
183 | |
184 | impl Drop for Context { |
185 | fn drop(&mut self) { |
186 | unsafe { |
187 | swr_free(&mut self.as_mut_ptr()); |
188 | } |
189 | } |
190 | } |
191 | |