1 use std::ops::Deref; 2 3 use super::codec::Codec; 4 use ffi::*; 5 use {format, ChannelLayout}; 6 7 #[derive(PartialEq, Eq, Copy, Clone)] 8 pub struct Audio { 9 codec: Codec, 10 } 11 12 impl Audio { new(codec: Codec) -> Audio13 pub unsafe fn new(codec: Codec) -> Audio { 14 Audio { codec } 15 } 16 } 17 18 impl Audio { rates(&self) -> Option<RateIter>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 formats(&self) -> Option<FormatIter>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 channel_layouts(&self) -> Option<ChannelLayoutIter>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 52 impl Deref for Audio { 53 type Target = Codec; 54 deref(&self) -> &Self::Target55 fn deref(&self) -> &Self::Target { 56 &self.codec 57 } 58 } 59 60 pub struct RateIter { 61 ptr: *const i32, 62 } 63 64 impl RateIter { new(ptr: *const i32) -> Self65 pub fn new(ptr: *const i32) -> Self { 66 RateIter { ptr } 67 } 68 } 69 70 impl Iterator for RateIter { 71 type Item = i32; 72 next(&mut self) -> Option<<Self as Iterator>::Item>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 87 pub struct FormatIter { 88 ptr: *const AVSampleFormat, 89 } 90 91 impl FormatIter { new(ptr: *const AVSampleFormat) -> Self92 pub fn new(ptr: *const AVSampleFormat) -> Self { 93 FormatIter { ptr } 94 } 95 } 96 97 impl Iterator for FormatIter { 98 type Item = format::Sample; 99 next(&mut self) -> Option<<Self as Iterator>::Item>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 114 pub struct ChannelLayoutIter { 115 ptr: *const u64, 116 } 117 118 impl ChannelLayoutIter { new(ptr: *const u64) -> Self119 pub fn new(ptr: *const u64) -> Self { 120 ChannelLayoutIter { ptr } 121 } 122 best(self, max: i32) -> ChannelLayout123 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 134 impl Iterator for ChannelLayoutIter { 135 type Item = ChannelLayout; 136 next(&mut self) -> Option<<Self as Iterator>::Item>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 } 150