1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
use std::ffi::CString; use std::mem; use std::ops::{Deref, DerefMut}; use std::ptr; use super::common::Context; use super::destructor; use ffi::*; use util::range::Range; use {format, Codec, Error, Packet, Stream}; pub struct Input { ptr: *mut AVFormatContext, ctx: Context, } unsafe impl Send for Input {} impl Input { pub unsafe fn wrap(ptr: *mut AVFormatContext) -> Self { Input { ptr: ptr, ctx: Context::wrap(ptr, destructor::Mode::Input), } } pub unsafe fn as_ptr(&self) -> *const AVFormatContext { self.ptr as *const _ } pub unsafe fn as_mut_ptr(&mut self) -> *mut AVFormatContext { self.ptr } } impl Input { pub fn format(&self) -> format::Input { unsafe { format::Input::wrap((*self.as_ptr()).iformat) } } pub fn video_codec(&self) -> Option<Codec> { unsafe { let ptr = av_format_get_video_codec(self.as_ptr()); if ptr.is_null() { None } else { Some(Codec::wrap(ptr)) } } } pub fn audio_codec(&self) -> Option<Codec> { unsafe { let ptr = av_format_get_audio_codec(self.as_ptr()); if ptr.is_null() { None } else { Some(Codec::wrap(ptr)) } } } pub fn subtitle_codec(&self) -> Option<Codec> { unsafe { let ptr = av_format_get_subtitle_codec(self.as_ptr()); if ptr.is_null() { None } else { Some(Codec::wrap(ptr)) } } } pub fn data_codec(&self) -> Option<Codec> { unsafe { let ptr = av_format_get_data_codec(self.as_ptr()); if ptr.is_null() { None } else { Some(Codec::wrap(ptr)) } } } pub fn probe_score(&self) -> i32 { unsafe { av_format_get_probe_score(self.as_ptr()) } } pub fn packets(&mut self) -> PacketIter { PacketIter::new(self) } pub fn pause(&mut self) -> Result<(), Error> { unsafe { match av_read_pause(self.as_mut_ptr()) { 0 => Ok(()), e => Err(Error::from(e)), } } } pub fn play(&mut self) -> Result<(), Error> { unsafe { match av_read_play(self.as_mut_ptr()) { 0 => Ok(()), e => Err(Error::from(e)), } } } pub fn seek<R: Range<i64>>(&mut self, ts: i64, range: R) -> Result<(), Error> { unsafe { match avformat_seek_file( self.as_mut_ptr(), -1, range.start().cloned().unwrap_or(i64::min_value()), ts, range.end().cloned().unwrap_or(i64::max_value()), 0, ) { s if s >= 0 => Ok(()), e => Err(Error::from(e)), } } } } impl Deref for Input { type Target = Context; fn deref(&self) -> &Self::Target { &self.ctx } } impl DerefMut for Input { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.ctx } } pub struct PacketIter<'a> { context: &'a mut Input, } impl<'a> PacketIter<'a> { pub fn new(context: &mut Input) -> PacketIter { PacketIter { context: context } } } impl<'a> Iterator for PacketIter<'a> { type Item = (Stream<'a>, Packet); fn next(&mut self) -> Option<<Self as Iterator>::Item> { let mut packet = Packet::empty(); loop { match packet.read(self.context) { Ok(..) => unsafe { return Some(( Stream::wrap(mem::transmute_copy(&self.context), packet.stream()), packet, )); }, Err(Error::Eof) => return None, Err(..) => (), } } } } pub fn dump(ctx: &Input, index: i32, url: Option<&str>) { let url = url.map(|u| CString::new(u).unwrap()); unsafe { av_dump_format( ctx.as_ptr() as *mut _, index, url.map(|u| u.as_ptr()).unwrap_or(ptr::null()), 0, ); } }