1 | use std::ops::{Deref, DerefMut}; |
2 | use std::ptr; |
3 | |
4 | use ffi::*; |
5 | use libc::c_int; |
6 | |
7 | use super::{audio, subtitle, video}; |
8 | use codec::Context; |
9 | use {media, packet, Error, Frame, Rational}; |
10 | |
11 | pub struct Encoder(pub Context); |
12 | |
13 | impl Encoder { |
14 | pub fn video(mut self) -> Result<video::Video, Error> { |
15 | match self.medium() { |
16 | media::Type::Unknown => { |
17 | unsafe { |
18 | (*self.as_mut_ptr()).codec_type = media::Type::Video.into(); |
19 | } |
20 | |
21 | Ok(video::Video(self)) |
22 | } |
23 | |
24 | media::Type::Video => Ok(video::Video(self)), |
25 | |
26 | _ => Err(Error::InvalidData), |
27 | } |
28 | } |
29 | |
30 | pub fn audio(mut self) -> Result<audio::Audio, Error> { |
31 | match self.medium() { |
32 | media::Type::Unknown => { |
33 | unsafe { |
34 | (*self.as_mut_ptr()).codec_type = media::Type::Audio.into(); |
35 | } |
36 | |
37 | Ok(audio::Audio(self)) |
38 | } |
39 | |
40 | media::Type::Audio => Ok(audio::Audio(self)), |
41 | |
42 | _ => Err(Error::InvalidData), |
43 | } |
44 | } |
45 | |
46 | pub fn subtitle(mut self) -> Result<subtitle::Subtitle, Error> { |
47 | match self.medium() { |
48 | media::Type::Unknown => { |
49 | unsafe { |
50 | (*self.as_mut_ptr()).codec_type = media::Type::Subtitle.into(); |
51 | } |
52 | |
53 | Ok(subtitle::Subtitle(self)) |
54 | } |
55 | |
56 | media::Type::Subtitle => Ok(subtitle::Subtitle(self)), |
57 | |
58 | _ => Err(Error::InvalidData), |
59 | } |
60 | } |
61 | |
62 | pub fn send_frame(&mut self, frame: &Frame) -> Result<(), Error> { |
63 | unsafe { |
64 | match avcodec_send_frame(self.as_mut_ptr(), frame.as_ptr()) { |
65 | e if e < 0 => Err(Error::from(e)), |
66 | _ => Ok(()), |
67 | } |
68 | } |
69 | } |
70 | |
71 | /// Sends a NULL packet to the encoder to signal end of stream and enter |
72 | /// draining mode. |
73 | pub fn send_eof(&mut self) -> Result<(), Error> { |
74 | unsafe { self.send_frame(&Frame::wrap(ptr::null_mut())) } |
75 | } |
76 | |
77 | pub fn receive_packet<P: packet::Mut>(&mut self, packet: &mut P) -> Result<(), Error> { |
78 | unsafe { |
79 | match avcodec_receive_packet(self.as_mut_ptr(), packet.as_mut_ptr()) { |
80 | e if e < 0 => Err(Error::from(e)), |
81 | _ => Ok(()), |
82 | } |
83 | } |
84 | } |
85 | |
86 | pub fn set_bit_rate(&mut self, value: usize) { |
87 | unsafe { |
88 | (*self.as_mut_ptr()).bit_rate = value as i64; |
89 | } |
90 | } |
91 | |
92 | pub fn set_max_bit_rate(&mut self, value: usize) { |
93 | unsafe { |
94 | (*self.as_mut_ptr()).rc_max_rate = value as i64; |
95 | } |
96 | } |
97 | |
98 | pub fn set_tolerance(&mut self, value: usize) { |
99 | unsafe { |
100 | (*self.as_mut_ptr()).bit_rate_tolerance = value as c_int; |
101 | } |
102 | } |
103 | |
104 | pub fn set_quality(&mut self, value: usize) { |
105 | unsafe { |
106 | (*self.as_mut_ptr()).global_quality = value as c_int; |
107 | } |
108 | } |
109 | |
110 | pub fn set_compression(&mut self, value: Option<usize>) { |
111 | unsafe { |
112 | if let Some(value) = value { |
113 | (*self.as_mut_ptr()).compression_level = value as c_int; |
114 | } else { |
115 | (*self.as_mut_ptr()).compression_level = -1; |
116 | } |
117 | } |
118 | } |
119 | |
120 | pub fn set_time_base<R: Into<Rational>>(&mut self, value: R) { |
121 | unsafe { |
122 | (*self.as_mut_ptr()).time_base = value.into().into(); |
123 | } |
124 | } |
125 | |
126 | pub fn set_frame_rate<R: Into<Rational>>(&mut self, value: Option<R>) { |
127 | unsafe { |
128 | if let Some(value) = value { |
129 | (*self.as_mut_ptr()).framerate = value.into().into(); |
130 | } else { |
131 | (*self.as_mut_ptr()).framerate.num = 0; |
132 | (*self.as_mut_ptr()).framerate.den = 1; |
133 | } |
134 | } |
135 | } |
136 | } |
137 | |
138 | impl Deref for Encoder { |
139 | type Target = Context; |
140 | |
141 | fn deref(&self) -> &<Self as Deref>::Target { |
142 | &self.0 |
143 | } |
144 | } |
145 | |
146 | impl DerefMut for Encoder { |
147 | fn deref_mut(&mut self) -> &mut <Self as Deref>::Target { |
148 | &mut self.0 |
149 | } |
150 | } |
151 | |
152 | impl AsRef<Context> for Encoder { |
153 | fn as_ref(&self) -> &Context { |
154 | self |
155 | } |
156 | } |
157 | |
158 | impl AsMut<Context> for Encoder { |
159 | fn as_mut(&mut self) -> &mut Context { |
160 | &mut *self |
161 | } |
162 | } |
163 | |