simplify error handling
[nihav.git] / src / demuxers / mod.rs
1 #[cfg(feature="demuxer_gdv")]
2 pub mod gdv;
3 #[cfg(feature="demuxer_avi")]
4 pub mod avi;
5
6 use std::rc::Rc;
7 use frame::*;
8 use io::byteio::*;
9
10 #[derive(Debug,Clone,Copy,PartialEq)]
11 #[allow(dead_code)]
12 pub enum DemuxerError {
13 EOF,
14 NoSuchInput,
15 InvalidData,
16 IOError,
17 NotImplemented,
18 MemoryError,
19 }
20
21 type DemuxerResult<T> = Result<T, DemuxerError>;
22
23 pub trait Demux<'a> {
24 fn open(&mut self) -> DemuxerResult<()>;
25 fn get_num_streams(&self) -> usize;
26 fn get_stream(&self, idx: usize) -> Option<Rc<NAStream>>;
27 fn get_frame(&mut self) -> DemuxerResult<NAPacket>;
28 fn seek(&mut self, time: u64) -> DemuxerResult<()>;
29 }
30
31 pub trait NAPacketReader {
32 fn read_packet(&mut self, str: Rc<NAStream>, pts: Option<u64>, dts: Option<u64>, dur: Option<u64>, keyframe: bool, size: usize) -> DemuxerResult<NAPacket>;
33 fn fill_packet(&mut self, pkt: &mut NAPacket) -> DemuxerResult<()>;
34 }
35
36 impl<'a> NAPacketReader for ByteReader<'a> {
37 fn read_packet(&mut self, str: Rc<NAStream>, pts: Option<u64>, dts: Option<u64>, dur: Option<u64>, kf: bool, size: usize) -> DemuxerResult<NAPacket> {
38 let mut buf: Vec<u8> = Vec::with_capacity(size);
39 if buf.capacity() < size { return Err(DemuxerError::MemoryError); }
40 buf.resize(size, 0);
41 let res = self.read_buf(buf.as_mut_slice());
42 if let Err(_) = res { return Err(DemuxerError::IOError); }
43 let pkt = NAPacket::new(str, pts, dts, dur, kf, buf);
44 Ok(pkt)
45 }
46 fn fill_packet(&mut self, pkt: &mut NAPacket) -> DemuxerResult<()> {
47 let mut refbuf = pkt.get_buffer();
48 let mut buf = Rc::make_mut(&mut refbuf);
49 let res = self.read_buf(buf.as_mut_slice());
50 if let Err(_) = res { return Err(DemuxerError::IOError); }
51 Ok(())
52 }
53 }
54
55 struct Demuxer {
56 streams: Vec<Rc<NAStream>>,
57 }
58
59 impl Demuxer {
60 pub fn new() -> Self { Demuxer { streams: Vec::new() } }
61 pub fn add_stream(&mut self, stream: NAStream) -> Option<usize> {
62 let stream_num = self.streams.len();
63 let mut str = stream.clone();
64 str.set_num(stream_num);
65 self.streams.push(Rc::new(str));
66 Some(stream_num)
67 }
68 pub fn get_stream(&self, idx: usize) -> Option<Rc<NAStream>> {
69 if idx < self.streams.len() {
70 Some(self.streams[idx].clone())
71 } else {
72 None
73 }
74 }
75 #[allow(dead_code)]
76 pub fn get_stream_by_id(&self, id: u32) -> Option<Rc<NAStream>> {
77 for i in 0..self.streams.len() {
78 if self.streams[i].get_id() == id {
79 return Some(self.streams[i].clone());
80 }
81 }
82 None
83 }
84 pub fn get_num_streams(&self) -> usize { self.streams.len() }
85 }
86
87 impl From<ByteIOError> for DemuxerError {
88 fn from(_: ByteIOError) -> Self { DemuxerError::IOError }
89 }
90
91 ///The structure used to create demuxers.
92 pub trait DemuxerCreator {
93 /// Create new demuxer instance that will use `ByteReader` source as an input.
94 fn new_demuxer<'a>(&self, br: &'a mut ByteReader<'a>) -> Box<Demux<'a> + 'a>;
95 /// Get the name of current demuxer creator.
96 fn get_name(&self) -> &'static str;
97 }
98
99 const DEMUXERS: &[&'static DemuxerCreator] = &[
100 #[cfg(feature="demuxer_avi")]
101 &avi::AVIDemuxerCreator {},
102 #[cfg(feature="demuxer_gdv")]
103 &gdv::GDVDemuxerCreator {},
104 ];
105
106 pub fn find_demuxer(name: &str) -> Option<&DemuxerCreator> {
107 for &dmx in DEMUXERS {
108 if dmx.get_name() == name {
109 return Some(dmx);
110 }
111 }
112 None
113 }