playa_ffmpeg/codec/encoder/
encoder.rs

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