use frame buffers with codec-specific type of data
[nihav.git] / src / demuxers / mod.rs
CommitLineData
66116504 1#[cfg(feature="demuxer_gdv")]
5869fd63 2pub mod gdv;
66116504 3#[cfg(feature="demuxer_avi")]
ca41f125 4pub mod avi;
5869fd63 5
5869fd63
KS
6use std::rc::Rc;
7use frame::*;
5869fd63
KS
8use io::byteio::*;
9
b1be9318 10#[derive(Debug,Clone,Copy,PartialEq)]
5869fd63
KS
11#[allow(dead_code)]
12pub enum DemuxerError {
13 EOF,
14 NoSuchInput,
15 InvalidData,
16 IOError,
17 NotImplemented,
18 MemoryError,
19}
20
21type DemuxerResult<T> = Result<T, DemuxerError>;
22
20ef4353 23pub trait Demux<'a> {
5869fd63 24 fn open(&mut self) -> DemuxerResult<()>;
66116504
KS
25 fn get_num_streams(&self) -> usize;
26 fn get_stream(&self, idx: usize) -> Option<Rc<NAStream>>;
5869fd63
KS
27 fn get_frame(&mut self) -> DemuxerResult<NAPacket>;
28 fn seek(&mut self, time: u64) -> DemuxerResult<()>;
29}
30
8869d452
KS
31pub 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>;
5869fd63
KS
33 fn fill_packet(&mut self, pkt: &mut NAPacket) -> DemuxerResult<()>;
34}
35
8869d452
KS
36impl<'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> {
5869fd63
KS
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); }
5869fd63
KS
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); }
5869fd63
KS
51 Ok(())
52 }
53}
54
999ca6c9 55struct Demuxer {
20ef4353
KS
56 streams: Vec<Rc<NAStream>>,
57}
58
59impl 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 }
999ca6c9 75 #[allow(dead_code)]
20ef4353
KS
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 }
66116504 84 pub fn get_num_streams(&self) -> usize { self.streams.len() }
5869fd63
KS
85}
86
87impl From<ByteIOError> for DemuxerError {
88 fn from(_: ByteIOError) -> Self { DemuxerError::IOError }
89}
90
3f7c7cfd 91///The structure used to create demuxers.
eb71d98f 92pub trait DemuxerCreator {
3f7c7cfd 93 /// Create new demuxer instance that will use `ByteReader` source as an input.
eb71d98f 94 fn new_demuxer<'a>(&self, br: &'a mut ByteReader<'a>) -> Box<Demux<'a> + 'a>;
3f7c7cfd 95 /// Get the name of current demuxer creator.
eb71d98f
KS
96 fn get_name(&self) -> &'static str;
97}
98
99const DEMUXERS: &[&'static DemuxerCreator] = &[
100#[cfg(feature="demuxer_avi")]
101 &avi::AVIDemuxerCreator {},
102#[cfg(feature="demuxer_gdv")]
103 &gdv::GDVDemuxerCreator {},
104];
105
106pub fn find_demuxer(name: &str) -> Option<&DemuxerCreator> {
3f7c7cfd
KS
107 for &dmx in DEMUXERS {
108 if dmx.get_name() == name {
109 return Some(dmx);
eb71d98f
KS
110 }
111 }
112 None
113}