ffmpeg_next_crossfix/software/resampling/
context.rs

1use std::ptr;
2
3use super::Delay;
4use ffi::*;
5use libc::c_int;
6use std::ffi::c_void;
7use util::format;
8use Dictionary;
9use {frame, ChannelLayout, Error};
10
11#[derive(Eq, PartialEq, Copy, Clone)]
12pub struct Definition {
13    pub format: format::Sample,
14    pub channel_layout: ChannelLayout,
15    pub rate: u32,
16}
17
18pub struct Context {
19    ptr: *mut SwrContext,
20
21    input: Definition,
22    output: Definition,
23}
24
25unsafe impl Send for Context {}
26
27impl 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
39impl 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        output.set_rate(self.output.rate);
146
147        unsafe {
148            if output.is_empty() {
149                output.alloc(
150                    self.output.format,
151                    input.samples(),
152                    self.output.channel_layout,
153                );
154            }
155
156            match swr_convert_frame(self.as_mut_ptr(), output.as_mut_ptr(), input.as_ptr()) {
157                0 => Ok(self.delay()),
158
159                e => Err(Error::from(e)),
160            }
161        }
162    }
163
164    /// Convert one of the remaining internal frames.
165    ///
166    /// When there are no more internal frames `Ok(None)` will be returned.
167    pub fn flush(&mut self, output: &mut frame::Audio) -> Result<Option<Delay>, Error> {
168        output.set_rate(self.output.rate);
169
170        unsafe {
171            match swr_convert_frame(self.as_mut_ptr(), output.as_mut_ptr(), ptr::null()) {
172                0 => Ok(self.delay()),
173
174                e => Err(Error::from(e)),
175            }
176        }
177    }
178}
179
180impl Drop for Context {
181    fn drop(&mut self) {
182        unsafe {
183            swr_free(&mut self.as_mut_ptr());
184        }
185    }
186}