1 | use std::ops::{Deref, DerefMut}; |
2 | use std::ptr; |
3 | |
4 | use super::{Audio, Check, Conceal, Opened, Subtitle, Video}; |
5 | use codec::{traits, Context}; |
6 | use ffi::*; |
7 | use {Dictionary, Discard, Error, Rational}; |
8 | |
9 | pub struct Decoder(pub Context); |
10 | |
11 | impl Decoder { |
12 | pub fn open(mut self) -> Result<Opened, Error> { |
13 | unsafe { |
14 | match avcodec_open2(self.as_mut_ptr(), ptr::null(), ptr::null_mut()) { |
15 | 0 => Ok(Opened(self)), |
16 | e => Err(Error::from(e)), |
17 | } |
18 | } |
19 | } |
20 | |
21 | pub fn open_as<D: traits::Decoder>(mut self, codec: D) -> Result<Opened, Error> { |
22 | unsafe { |
23 | if let Some(codec) = codec.decoder() { |
24 | match avcodec_open2(self.as_mut_ptr(), codec.as_ptr(), ptr::null_mut()) { |
25 | 0 => Ok(Opened(self)), |
26 | e => Err(Error::from(e)), |
27 | } |
28 | } else { |
29 | Err(Error::DecoderNotFound) |
30 | } |
31 | } |
32 | } |
33 | |
34 | pub fn open_as_with<D: traits::Decoder>( |
35 | mut self, |
36 | codec: D, |
37 | options: Dictionary, |
38 | ) -> Result<Opened, Error> { |
39 | unsafe { |
40 | if let Some(codec) = codec.decoder() { |
41 | let mut opts = options.disown(); |
42 | let res = avcodec_open2(self.as_mut_ptr(), codec.as_ptr(), &mut opts); |
43 | |
44 | Dictionary::own(opts); |
45 | |
46 | match res { |
47 | 0 => Ok(Opened(self)), |
48 | e => Err(Error::from(e)), |
49 | } |
50 | } else { |
51 | Err(Error::DecoderNotFound) |
52 | } |
53 | } |
54 | } |
55 | |
56 | pub fn video(self) -> Result<Video, Error> { |
57 | if let Some(codec) = self.codec() { |
58 | self.open_as(codec).and_then(|o| o.video()) |
59 | } else if let Some(codec) = super::find(self.id()) { |
60 | self.open_as(codec).and_then(|o| o.video()) |
61 | } else { |
62 | Err(Error::DecoderNotFound) |
63 | } |
64 | } |
65 | |
66 | pub fn audio(self) -> Result<Audio, Error> { |
67 | if let Some(codec) = self.codec() { |
68 | self.open_as(codec).and_then(|o| o.audio()) |
69 | } else if let Some(codec) = super::find(self.id()) { |
70 | self.open_as(codec).and_then(|o| o.audio()) |
71 | } else { |
72 | Err(Error::DecoderNotFound) |
73 | } |
74 | } |
75 | |
76 | pub fn subtitle(self) -> Result<Subtitle, Error> { |
77 | if let Some(codec) = super::find(self.id()) { |
78 | self.open_as(codec).and_then(|o| o.subtitle()) |
79 | } else { |
80 | Err(Error::DecoderNotFound) |
81 | } |
82 | } |
83 | |
84 | pub fn conceal(&mut self, value: Conceal) { |
85 | unsafe { |
86 | (*self.as_mut_ptr()).error_concealment = value.bits(); |
87 | } |
88 | } |
89 | |
90 | pub fn check(&mut self, value: Check) { |
91 | unsafe { |
92 | (*self.as_mut_ptr()).err_recognition = value.bits(); |
93 | } |
94 | } |
95 | |
96 | pub fn skip_loop_filter(&mut self, value: Discard) { |
97 | unsafe { |
98 | (*self.as_mut_ptr()).skip_loop_filter = value.into(); |
99 | } |
100 | } |
101 | |
102 | pub fn skip_idct(&mut self, value: Discard) { |
103 | unsafe { |
104 | (*self.as_mut_ptr()).skip_idct = value.into(); |
105 | } |
106 | } |
107 | |
108 | pub fn skip_frame(&mut self, value: Discard) { |
109 | unsafe { |
110 | (*self.as_mut_ptr()).skip_frame = value.into(); |
111 | } |
112 | } |
113 | |
114 | pub fn packet_time_base(&self) -> Rational { |
115 | unsafe { Rational::from((*self.as_ptr()).pkt_timebase) } |
116 | } |
117 | |
118 | pub fn set_packet_time_base<R: Into<Rational>>(&mut self, value: R) { |
119 | unsafe { |
120 | (*self.as_mut_ptr()).pkt_timebase = value.into().into(); |
121 | } |
122 | } |
123 | } |
124 | |
125 | impl Deref for Decoder { |
126 | type Target = Context; |
127 | |
128 | fn deref(&self) -> &<Self as Deref>::Target { |
129 | &self.0 |
130 | } |
131 | } |
132 | |
133 | impl DerefMut for Decoder { |
134 | fn deref_mut(&mut self) -> &mut <Self as Deref>::Target { |
135 | &mut self.0 |
136 | } |
137 | } |
138 | |
139 | impl AsRef<Context> for Decoder { |
140 | fn as_ref(&self) -> &Context { |
141 | self |
142 | } |
143 | } |
144 | |
145 | impl AsMut<Context> for Decoder { |
146 | fn as_mut(&mut self) -> &mut Context { |
147 | &mut self.0 |
148 | } |
149 | } |
150 | |