1use std::ptr::NonNull;
2use std::rc::Rc;
3
4use libde265_sys::*;
5
6use crate::{DeError, Image, Result};
7
8pub fn new_decoder() -> Result<(DecoderInput, DecoderOutput)> {
10 let decoder_context_ptr = unsafe { de265_new_decoder() };
11 if decoder_context_ptr.is_null() {
12 return Err(DeError::ErrorLibraryInitializationFailed);
13 }
14 let context = Rc::new(DecoderContext {
15 inner: decoder_context_ptr,
16 });
17 Ok((
18 DecoderInput {
19 context: context.clone(),
20 },
21 DecoderOutput { context },
22 ))
23}
24
25#[derive(Debug, Copy, Clone)]
26#[non_exhaustive]
27pub enum ParamI32 {
28 DumpSpsHeaders = de265_param::DE265_DECODER_PARAM_DUMP_SPS_HEADERS as _,
30 DumpVpsHeaders = de265_param::DE265_DECODER_PARAM_DUMP_VPS_HEADERS as _,
32 DumpPpsHeaders = de265_param::DE265_DECODER_PARAM_DUMP_PPS_HEADERS as _,
34 DumpSliceHeaders = de265_param::DE265_DECODER_PARAM_DUMP_SLICE_HEADERS as _,
36}
37
38#[derive(Debug, Copy, Clone)]
39#[non_exhaustive]
40pub enum ParamBool {
41 SeiCheckHash = de265_param::DE265_DECODER_PARAM_BOOL_SEI_CHECK_HASH as _,
43 SuppressFaultyPictures = de265_param::DE265_DECODER_PARAM_SUPPRESS_FAULTY_PICTURES as _,
45 DisableDeblocking = de265_param::DE265_DECODER_PARAM_DISABLE_DEBLOCKING as _,
47 DisableSAO = de265_param::DE265_DECODER_PARAM_DISABLE_SAO as _,
49}
50
51#[derive(Debug, Copy, Clone)]
53#[non_exhaustive]
54pub enum Acceleration {
55 Scalar = de265_acceleration::de265_acceleration_SCALAR as _,
57 MMS = de265_acceleration::de265_acceleration_MMX as _,
58 SSE = de265_acceleration::de265_acceleration_SSE as _,
59 SSE2 = de265_acceleration::de265_acceleration_SSE2 as _,
60 SSE4 = de265_acceleration::de265_acceleration_SSE4 as _,
61 AVX = de265_acceleration::de265_acceleration_AVX as _,
63 AVX2 = de265_acceleration::de265_acceleration_AVX2 as _,
65 ARM = de265_acceleration::de265_acceleration_ARM as _,
66 NEON = de265_acceleration::de265_acceleration_NEON as _,
67 Auto = de265_acceleration::de265_acceleration_AUTO as _,
68}
69
70pub(crate) struct DecoderContext {
71 pub(crate) inner: *mut de265_decoder_context,
72}
73
74impl Drop for DecoderContext {
75 fn drop(&mut self) {
76 if !self.inner.is_null() {
77 unsafe { de265_free_decoder(self.inner) };
78 }
79 }
80}
81
82pub enum DecodeResult {
83 Done,
85 CallAgain,
88}
89
90pub struct DecoderInput {
92 context: Rc<DecoderContext>,
93}
94
95impl DecoderInput {
96 #[inline(always)]
97 fn inner(&self) -> *mut de265_decoder_context {
98 self.context.inner
99 }
100
101 pub fn start_worker_threads(&mut self, num_threads: u32) -> Result<()> {
106 let result = unsafe {
107 de265_start_worker_threads(self.inner(), num_threads.min(i32::MAX as _) as _)
108 };
109 DeError::from_raw(result)
110 }
111
112 pub fn push_data(&mut self, data: &[u8], pts: i64, user_data: usize) -> Result<()> {
120 let result = unsafe {
121 de265_push_data(
122 self.inner(),
123 data.as_ptr() as _,
124 data.len() as _,
125 pts,
126 user_data as _,
127 )
128 };
129 DeError::from_raw(result)
130 }
131
132 pub fn push_end_of_nal(&mut self) {
135 unsafe { de265_push_end_of_NAL(self.inner()) };
136 }
137
138 pub fn push_end_of_frame(&mut self) {
143 unsafe { de265_push_end_of_frame(self.inner()) };
144 }
145
146 pub fn push_nal(&mut self, data: &[u8], pts: i64, user_data: usize) -> Result<()> {
151 let result = unsafe {
152 de265_push_NAL(
153 self.inner(),
154 data.as_ptr() as _,
155 data.len() as _,
156 pts,
157 user_data as _,
158 )
159 };
160 DeError::from_raw(result)
161 }
162
163 pub fn flush_data(&mut self) -> Result<()> {
168 let result = unsafe { de265_flush_data(self.inner()) };
169 DeError::from_raw(result)
170 }
171
172 pub fn number_of_input_bytes_pending(&self) -> usize {
176 let value = unsafe { de265_get_number_of_input_bytes_pending(self.inner()) };
177 value.max(0) as _
178 }
179
180 pub fn number_of_nal_units_pending(&self) -> usize {
184 let value = unsafe { de265_get_number_of_NAL_units_pending(self.inner()) };
185 value.max(0) as _
186 }
187
188 pub fn decode(&mut self) -> Result<DecodeResult> {
204 let mut more = 0;
205 let result = unsafe { de265_decode(self.inner(), &mut more) };
206 DeError::from_raw(result).map(|_| {
207 if more > 0 {
208 DecodeResult::CallAgain
209 } else {
210 DecodeResult::Done
211 }
212 })
213 }
214
215 #[deprecated(note = "you should use `push_data` or `push_nal` and `decode` methods instead.")]
226 pub fn decode_data(&mut self, data: &[u8]) -> Result<()> {
227 let result =
228 unsafe { de265_decode_data(self.inner(), data.as_ptr() as _, data.len() as _) };
229 DeError::from_raw(result)
230 }
231
232 pub fn reset(&mut self) {
234 unsafe { de265_reset(self.inner()) };
235 }
236
237 pub fn get_warning(&self) -> Result<()> {
238 let result = unsafe { de265_get_warning(self.inner()) };
239 DeError::from_raw(result)
240 }
241
242 pub fn highest_tid(&self) -> u32 {
246 unsafe { de265_get_highest_TID(self.inner()).max(0) as _ }
247 }
248
249 pub fn current_tid(&self) -> u32 {
251 unsafe { de265_get_current_TID(self.inner()).max(0) as _ }
252 }
253
254 pub fn set_limit_tid(&mut self, max_tid: u32) {
256 unsafe { de265_set_limit_TID(self.inner(), max_tid.min(i32::MAX as _) as _) };
257 }
258
259 pub fn set_framerate_ratio(&mut self, percent: u8) {
268 unsafe { de265_set_framerate_ratio(self.inner(), percent as _) };
269 }
270
271 pub fn change_framerate(&mut self, more_vs_less: i8) -> u32 {
279 unsafe {
280 de265_change_framerate(self.inner(), more_vs_less.clamp(-1, 1) as i32).max(0) as _
281 }
282 }
283
284 pub fn set_parameter_i32(&mut self, param: ParamI32, val: i32) {
286 unsafe {
287 de265_set_parameter_int(self.inner(), param as de265_param::Type, val);
288 }
289 }
290
291 pub fn set_parameter_bool(&mut self, param: ParamBool, val: bool) {
293 unsafe {
294 de265_set_parameter_bool(
295 self.inner(),
296 param as de265_param::Type,
297 if val { 1 } else { 0 },
298 );
299 }
300 }
301
302 pub fn set_acceleration(&mut self, val: Acceleration) {
304 unsafe {
305 de265_set_parameter_int(
306 self.inner(),
307 de265_param::DE265_DECODER_PARAM_ACCELERATION_CODE,
308 val as i32,
309 );
310 }
311 }
312
313 pub fn get_parameter_bool(&self, param: ParamBool) -> bool {
315 unsafe { de265_get_parameter_bool(self.inner(), param as de265_param::Type) != 0 }
316 }
317}
318
319pub struct DecoderOutput {
321 context: Rc<DecoderContext>,
322}
323
324impl DecoderOutput {
325 #[inline(always)]
326 pub(crate) fn inner(&self) -> *mut de265_decoder_context {
327 self.context.inner
328 }
329
330 pub fn next_picture(&mut self) -> Option<Image<'_>> {
332 let image_ptr = unsafe { de265_peek_next_picture(self.inner()) };
333 NonNull::new(image_ptr as _).map(|p| Image::new(self.context.as_ref(), p))
334 }
335}