1 | use std::ops::{Deref, DerefMut}; |
2 | use std::ptr; |
3 | |
4 | use super::{Audio, Decoder, Subtitle, Video}; |
5 | use codec::{Context, Profile}; |
6 | use ffi::*; |
7 | use {media, packet, Error, Frame, Rational}; |
8 | |
9 | pub struct Opened(pub Decoder); |
10 | |
11 | impl Opened { |
12 | pub fn video(self) -> Result<Video, Error> { |
13 | if self.medium() == media::Type::Video { |
14 | Ok(Video(self)) |
15 | } else { |
16 | Err(Error::InvalidData) |
17 | } |
18 | } |
19 | |
20 | pub fn audio(self) -> Result<Audio, Error> { |
21 | if self.medium() == media::Type::Audio { |
22 | Ok(Audio(self)) |
23 | } else { |
24 | Err(Error::InvalidData) |
25 | } |
26 | } |
27 | |
28 | pub fn subtitle(self) -> Result<Subtitle, Error> { |
29 | if self.medium() == media::Type::Subtitle { |
30 | Ok(Subtitle(self)) |
31 | } else { |
32 | Err(Error::InvalidData) |
33 | } |
34 | } |
35 | |
36 | pub fn send_packet<P: packet::Ref>(&mut self, packet: &P) -> Result<(), Error> { |
37 | unsafe { |
38 | match avcodec_send_packet(self.as_mut_ptr(), packet.as_ptr()) { |
39 | e if e < 0 => Err(Error::from(e)), |
40 | _ => Ok(()), |
41 | } |
42 | } |
43 | } |
44 | |
45 | /// Sends a NULL packet to the decoder to signal end of stream and enter |
46 | /// draining mode. |
47 | pub fn send_eof(&mut self) -> Result<(), Error> { |
48 | unsafe { |
49 | match avcodec_send_packet(self.as_mut_ptr(), ptr::null()) { |
50 | e if e < 0 => Err(Error::from(e)), |
51 | _ => Ok(()), |
52 | } |
53 | } |
54 | } |
55 | |
56 | pub fn receive_frame(&mut self, frame: &mut Frame) -> Result<(), Error> { |
57 | unsafe { |
58 | match avcodec_receive_frame(self.as_mut_ptr(), frame.as_mut_ptr()) { |
59 | e if e < 0 => Err(Error::from(e)), |
60 | _ => Ok(()), |
61 | } |
62 | } |
63 | } |
64 | |
65 | pub fn bit_rate(&self) -> usize { |
66 | unsafe { (*self.as_ptr()).bit_rate as usize } |
67 | } |
68 | |
69 | pub fn delay(&self) -> usize { |
70 | unsafe { (*self.as_ptr()).delay as usize } |
71 | } |
72 | |
73 | pub fn profile(&self) -> Profile { |
74 | unsafe { Profile::from((self.id(), (*self.as_ptr()).profile)) } |
75 | } |
76 | |
77 | pub fn frame_rate(&self) -> Option<Rational> { |
78 | unsafe { |
79 | let value = (*self.as_ptr()).framerate; |
80 | |
81 | if value == (AVRational { num: 0, den: 1 }) { |
82 | None |
83 | } else { |
84 | Some(Rational::from(value)) |
85 | } |
86 | } |
87 | } |
88 | |
89 | pub fn flush(&mut self) { |
90 | unsafe { |
91 | avcodec_flush_buffers(self.as_mut_ptr()); |
92 | } |
93 | } |
94 | } |
95 | |
96 | impl Drop for Opened { |
97 | fn drop(&mut self) { |
98 | unsafe { |
99 | avcodec_close(self.as_mut_ptr()); |
100 | } |
101 | } |
102 | } |
103 | |
104 | impl Deref for Opened { |
105 | type Target = Decoder; |
106 | |
107 | fn deref(&self) -> &<Self as Deref>::Target { |
108 | &self.0 |
109 | } |
110 | } |
111 | |
112 | impl DerefMut for Opened { |
113 | fn deref_mut(&mut self) -> &mut <Self as Deref>::Target { |
114 | &mut self.0 |
115 | } |
116 | } |
117 | |
118 | impl AsRef<Context> for Opened { |
119 | fn as_ref(&self) -> &Context { |
120 | self |
121 | } |
122 | } |
123 | |
124 | impl AsMut<Context> for Opened { |
125 | fn as_mut(&mut self) -> &mut Context { |
126 | &mut self.0 |
127 | } |
128 | } |
129 | |