1use core::{mem::MaybeUninit, ptr};
2use x264::*;
3use {Data, Encoding, Error, Image, Picture, Result, Setup};
4
5pub struct Encoder {
7 raw: *mut x264_t,
8 params: x264_param_t,
9}
10
11impl Encoder {
12 pub fn builder() -> Setup {
16 Setup::default()
17 }
18
19 #[doc(hidden)]
20 pub unsafe fn from_raw(raw: *mut x264_t) -> Self {
21 let mut params = MaybeUninit::uninit();
22 x264_encoder_parameters(raw, params.as_mut_ptr());
23 Self {
24 raw,
25 params: params.assume_init(),
26 }
27 }
28
29 pub fn encode(&mut self, pts: i64, image: Image) -> Result<(Data, Picture)> {
36 assert_eq!(image.width(), self.width());
37 assert_eq!(image.height(), self.height());
38 assert_eq!(image.encoding(), self.encoding());
39 unsafe { self.encode_unchecked(pts, image) }
40 }
41
42 pub unsafe fn encode_unchecked(&mut self, pts: i64, image: Image) -> Result<(Data, Picture)> {
49 let image = image.raw();
50
51 let mut picture = MaybeUninit::uninit();
52 x264_picture_init(picture.as_mut_ptr());
53 let mut picture = picture.assume_init();
54 picture.i_pts = pts;
55 picture.img = image;
56
57 let mut len = 0;
58 let mut stuff = MaybeUninit::uninit();
59 let mut raw = MaybeUninit::uninit();
60
61 let err = x264_encoder_encode(self.raw, stuff.as_mut_ptr(), &mut len, &mut picture, raw.as_mut_ptr());
62
63 if err < 0 {
64 Err(Error)
65 } else {
66 let stuff = stuff.assume_init();
67 let raw = raw.assume_init();
68 let data = Data::from_raw_parts(stuff, len as usize);
69 let picture = Picture::from_raw(raw);
70 Ok((data, picture))
71 }
72 }
73
74 pub fn headers(&mut self) -> Result<Data> {
76 let mut len = 0;
77 let mut stuff = MaybeUninit::uninit();
78
79 let err = unsafe { x264_encoder_headers(self.raw, stuff.as_mut_ptr(), &mut len) };
80
81 if err < 0 {
82 Err(Error)
83 } else {
84 let stuff = unsafe { stuff.assume_init() };
85 Ok(unsafe { Data::from_raw_parts(stuff, len as usize) })
86 }
87 }
88
89 pub fn flush(self) -> Flush {
104 Flush { encoder: self }
105 }
106
107 pub fn width(&self) -> i32 {
109 self.params.i_width
110 }
111 pub fn height(&self) -> i32 {
113 self.params.i_height
114 }
115 pub fn encoding(&self) -> Encoding {
117 unsafe { Encoding::from_raw(self.params.i_csp) }
118 }
119}
120
121impl Drop for Encoder {
122 fn drop(&mut self) {
123 unsafe {
124 x264_encoder_close(self.raw);
125 }
126 }
127}
128
129pub struct Flush {
131 encoder: Encoder,
132}
133
134impl Flush {
138 pub fn next(&mut self) -> Option<Result<(Data, Picture)>> {
142 let enc = self.encoder.raw;
143
144 if unsafe { x264_encoder_delayed_frames(enc) } == 0 {
145 return None;
146 }
147
148 let mut len = 0;
149 let mut stuff = MaybeUninit::uninit();
150 let mut raw = MaybeUninit::uninit();
151
152 let err =
153 unsafe { x264_encoder_encode(enc, stuff.as_mut_ptr(), &mut len, ptr::null_mut(), raw.as_mut_ptr()) };
154
155 Some(if err < 0 {
156 Err(Error)
157 } else {
158 Ok(unsafe {
159 (
160 Data::from_raw_parts(stuff.assume_init(), len as usize),
161 Picture::from_raw(raw.assume_init()),
162 )
163 })
164 })
165 }
166}