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) = super::find(self.id()) { |
58 | self.open_as(codec).and_then(|o| o.video()) |
59 | } else { |
60 | Err(Error::DecoderNotFound) |
61 | } |
62 | } |
63 | |
64 | pub fn audio(self) -> Result<Audio, Error> { |
65 | if let Some(codec) = super::find(self.id()) { |
66 | self.open_as(codec).and_then(|o| o.audio()) |
67 | } else { |
68 | Err(Error::DecoderNotFound) |
69 | } |
70 | } |
71 | |
72 | pub fn subtitle(self) -> Result<Subtitle, Error> { |
73 | if let Some(codec) = super::find(self.id()) { |
74 | self.open_as(codec).and_then(|o| o.subtitle()) |
75 | } else { |
76 | Err(Error::DecoderNotFound) |
77 | } |
78 | } |
79 | |
80 | pub fn conceal(&mut self, value: Conceal) { |
81 | unsafe { |
82 | (*self.as_mut_ptr()).error_concealment = value.bits(); |
83 | } |
84 | } |
85 | |
86 | pub fn check(&mut self, value: Check) { |
87 | unsafe { |
88 | (*self.as_mut_ptr()).err_recognition = value.bits(); |
89 | } |
90 | } |
91 | |
92 | pub fn skip_loop_filter(&mut self, value: Discard) { |
93 | unsafe { |
94 | (*self.as_mut_ptr()).skip_loop_filter = value.into(); |
95 | } |
96 | } |
97 | |
98 | pub fn skip_idct(&mut self, value: Discard) { |
99 | unsafe { |
100 | (*self.as_mut_ptr()).skip_idct = value.into(); |
101 | } |
102 | } |
103 | |
104 | pub fn skip_frame(&mut self, value: Discard) { |
105 | unsafe { |
106 | (*self.as_mut_ptr()).skip_frame = value.into(); |
107 | } |
108 | } |
109 | |
110 | pub fn time_base(&self) -> Rational { |
111 | unsafe { Rational::from((*self.as_ptr()).time_base) } |
112 | } |
113 | } |
114 | |
115 | impl Deref for Decoder { |
116 | type Target = Context; |
117 | |
118 | fn deref(&self) -> &<Self as Deref>::Target { |
119 | &self.0 |
120 | } |
121 | } |
122 | |
123 | impl DerefMut for Decoder { |
124 | fn deref_mut(&mut self) -> &mut <Self as Deref>::Target { |
125 | &mut self.0 |
126 | } |
127 | } |
128 | |
129 | impl AsRef<Context> for Decoder { |
130 | fn as_ref(&self) -> &Context { |
131 | self |
132 | } |
133 | } |
134 | |
135 | impl AsMut<Context> for Decoder { |
136 | fn as_mut(&mut self) -> &mut Context { |
137 | &mut self.0 |
138 | } |
139 | } |
140 | |