1 // Copyright (c) 2001-2016, Alliance for Open Media. All rights reserved
2 // Copyright (c) 2017-2020, The rav1e contributors. All rights reserved
3 //
4 // This source code is subject to the terms of the BSD 2 Clause License and
5 // the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 // was not distributed with this source code in the LICENSE file, you can
7 // obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 // Media Patent License 1.0 was not distributed with this source code in the
9 // PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10 
11 //! # C API for rav1e
12 //!
13 //! [rav1e](https://github.com/xiph/rav1e/) is an [AV1](https://aomediacodec.github.io/av1-spec/)
14 //! encoder written in [Rust](https://rust-lang.org)
15 //!
16 //! This is the C-compatible API
17 #![deny(missing_docs)]
18 
19 use std::slice;
20 use std::sync::Arc;
21 
22 use std::ffi::CStr;
23 use std::ffi::CString;
24 use std::os::raw::c_char;
25 use std::os::raw::c_int;
26 use std::os::raw::c_void;
27 
28 use libc::ptrdiff_t;
29 use libc::size_t;
30 
31 use num_derive::*;
32 use num_traits::cast::FromPrimitive;
33 
34 use crate::prelude as rav1e;
35 
36 type PixelRange = rav1e::PixelRange;
37 type ChromaSamplePosition = rav1e::ChromaSamplePosition;
38 type ChromaSampling = rav1e::ChromaSampling;
39 type MatrixCoefficients = rav1e::MatrixCoefficients;
40 type ColorPrimaries = rav1e::ColorPrimaries;
41 type TransferCharacteristics = rav1e::TransferCharacteristics;
42 type Rational = rav1e::Rational;
43 type FrameTypeOverride = rav1e::FrameTypeOverride;
44 type FrameOpaqueCb = Option<extern fn(*mut c_void)>;
45 
46 #[derive(Clone)]
47 enum FrameInternal {
48   U8(Arc<rav1e::Frame<u8>>),
49   U16(Arc<rav1e::Frame<u16>>),
50 }
51 
52 impl From<rav1e::Frame<u8>> for FrameInternal {
from(f: rav1e::Frame<u8>) -> FrameInternal53   fn from(f: rav1e::Frame<u8>) -> FrameInternal {
54     FrameInternal::U8(Arc::new(f))
55   }
56 }
57 
58 impl From<rav1e::Frame<u16>> for FrameInternal {
from(f: rav1e::Frame<u16>) -> FrameInternal59   fn from(f: rav1e::Frame<u16>) -> FrameInternal {
60     FrameInternal::U16(Arc::new(f))
61   }
62 }
63 
64 struct FrameOpaque {
65   opaque: *mut c_void,
66   cb: FrameOpaqueCb,
67 }
68 
69 unsafe impl Send for FrameOpaque {}
70 
71 impl Default for FrameOpaque {
default() -> Self72   fn default() -> Self {
73     FrameOpaque { opaque: std::ptr::null_mut(), cb: None }
74   }
75 }
76 
77 impl Drop for FrameOpaque {
drop(&mut self)78   fn drop(&mut self) {
79     let FrameOpaque { opaque, cb } = self;
80     if let Some(cb) = cb {
81       cb(*opaque);
82     }
83   }
84 }
85 
86 /// Raw video Frame
87 ///
88 /// It can be allocated through rav1e_frame_new(), populated using rav1e_frame_fill_plane()
89 /// and freed using rav1e_frame_unref().
90 pub struct Frame {
91   fi: FrameInternal,
92   frame_type: FrameTypeOverride,
93   opaque: Option<FrameOpaque>,
94 }
95 
96 /// Status that can be returned by encoder functions.
97 #[repr(C)]
98 #[derive(Copy, Clone, Debug, FromPrimitive, PartialEq)]
99 pub enum EncoderStatus {
100   /// Normal operation.
101   Success = 0,
102   /// The encoder needs more data to produce an output packet.
103   ///
104   /// May be emitted by `rav1e_receive_packet` when frame reordering is
105   /// enabled.
106   NeedMoreData,
107   /// There are enough frames in the queue.
108   ///
109   /// May be emitted by `rav1e_send_frame` when trying to send a frame after
110   /// the encoder has been flushed or the internal queue is full.
111   EnoughData,
112   /// The encoder has already produced the number of frames requested.
113   ///
114   /// May be emitted by `rav1e_receive_packet` after a flush request had been
115   /// processed or the frame limit had been reached.
116   LimitReached,
117   /// A Frame had been encoded but not emitted yet.
118   Encoded,
119   /// Generic fatal error.
120   Failure = -1,
121   /// A frame was encoded in the first pass of a 2-pass encode, but its stats
122   /// data was not retrieved with `rav1e_twopass_out`, or not enough stats data
123   /// was provided in the second pass of a 2-pass encode to encode the next
124   /// frame.
125   NotReady = -2,
126 }
127 
128 impl EncoderStatus {
to_c(&self) -> *const u8129   fn to_c(&self) -> *const u8 {
130     use self::EncoderStatus::*;
131     match self {
132       Success => "Normal operation\0".as_ptr(),
133       NeedMoreData => "The encoder needs more data to produce an output packet\0".as_ptr(),
134       EnoughData => "There are enough frames in the queue\0".as_ptr(),
135       LimitReached => "The encoder has already produced the number of frames requested\0".as_ptr(),
136       Encoded => "A Frame had been encoded but not emitted yet\0".as_ptr(),
137       Failure => "Generic fatal error\0".as_ptr(),
138       NotReady => "First-pass stats data not retrieved or not enough second-pass data provided\0".as_ptr(),
139     }
140   }
141 }
142 
143 impl From<Option<rav1e::EncoderStatus>> for EncoderStatus {
from(status: Option<rav1e::EncoderStatus>) -> Self144   fn from(status: Option<rav1e::EncoderStatus>) -> Self {
145     match status {
146       None => EncoderStatus::Success,
147       Some(s) => match s {
148         rav1e::EncoderStatus::NeedMoreData => EncoderStatus::NeedMoreData,
149         rav1e::EncoderStatus::EnoughData => EncoderStatus::EnoughData,
150         rav1e::EncoderStatus::LimitReached => EncoderStatus::LimitReached,
151         rav1e::EncoderStatus::Encoded => EncoderStatus::Encoded,
152         rav1e::EncoderStatus::Failure => EncoderStatus::Failure,
153         rav1e::EncoderStatus::NotReady => EncoderStatus::NotReady,
154       },
155     }
156   }
157 }
158 
159 /// Encoder configuration
160 ///
161 /// Instantiate it using rav1e_config_default() and fine-tune it using
162 /// rav1e_config_parse().
163 ///
164 /// Use rav1e_config_unref() to free its memory.
165 pub struct Config {
166   cfg: rav1e::Config,
167 }
168 
169 enum EncContext {
170   U8(rav1e::Context<u8>),
171   U16(rav1e::Context<u16>),
172 }
173 
174 impl EncContext {
new_frame(&self) -> FrameInternal175   fn new_frame(&self) -> FrameInternal {
176     match self {
177       EncContext::U8(ctx) => ctx.new_frame().into(),
178       EncContext::U16(ctx) => ctx.new_frame().into(),
179     }
180   }
send_frame( &mut self, frame: Option<FrameInternal>, frame_type: FrameTypeOverride, opaque: Option<Box<dyn std::any::Any + Send>>, ) -> Result<(), rav1e::EncoderStatus>181   fn send_frame(
182     &mut self, frame: Option<FrameInternal>, frame_type: FrameTypeOverride,
183     opaque: Option<Box<dyn std::any::Any + Send>>,
184   ) -> Result<(), rav1e::EncoderStatus> {
185     let info =
186       rav1e::FrameParameters { frame_type_override: frame_type, opaque };
187     if let Some(frame) = frame {
188       match (self, frame) {
189         (EncContext::U8(ctx), FrameInternal::U8(ref f)) => {
190           ctx.send_frame((f.clone(), info))
191         }
192         (EncContext::U16(ctx), FrameInternal::U16(ref f)) => {
193           ctx.send_frame((f.clone(), info))
194         }
195         _ => Err(rav1e::EncoderStatus::Failure),
196       }
197     } else {
198       match self {
199         EncContext::U8(ctx) => ctx.send_frame(None),
200         EncContext::U16(ctx) => ctx.send_frame(None),
201       }
202     }
203   }
204 
receive_packet(&mut self) -> Result<Packet, rav1e::EncoderStatus>205   fn receive_packet(&mut self) -> Result<Packet, rav1e::EncoderStatus> {
206     fn receive_packet<T: rav1e::Pixel>(
207       ctx: &mut rav1e::Context<T>,
208     ) -> Result<Packet, rav1e::EncoderStatus> {
209       ctx.receive_packet().map(|p| {
210         let mut p = std::mem::ManuallyDrop::new(p);
211         let opaque = p.opaque.take().map_or_else(
212           || std::ptr::null_mut(),
213           |o| {
214             let mut opaque = o.downcast::<FrameOpaque>().unwrap();
215             opaque.cb = None;
216             opaque.opaque
217           },
218         );
219         let p = std::mem::ManuallyDrop::into_inner(p);
220         let rav1e::Packet { data, input_frameno, frame_type, .. } = p;
221         let len = data.len();
222         let data = Box::into_raw(data.into_boxed_slice()) as *const u8;
223         Packet { data, len, input_frameno, frame_type, opaque }
224       })
225     }
226     match self {
227       EncContext::U8(ctx) => receive_packet(ctx),
228       EncContext::U16(ctx) => receive_packet(ctx),
229     }
230   }
231 
container_sequence_header(&self) -> Vec<u8>232   fn container_sequence_header(&self) -> Vec<u8> {
233     match self {
234       EncContext::U8(ctx) => ctx.container_sequence_header(),
235       EncContext::U16(ctx) => ctx.container_sequence_header(),
236     }
237   }
238 
twopass_bytes_needed(&mut self) -> usize239   fn twopass_bytes_needed(&mut self) -> usize {
240     match self {
241       EncContext::U8(ctx) => ctx.twopass_bytes_needed(),
242       EncContext::U16(ctx) => ctx.twopass_bytes_needed(),
243     }
244   }
245 
twopass_in(&mut self, buf: &[u8]) -> Result<usize, rav1e::EncoderStatus>246   fn twopass_in(&mut self, buf: &[u8]) -> Result<usize, rav1e::EncoderStatus> {
247     match self {
248       EncContext::U8(ctx) => ctx.twopass_in(buf),
249       EncContext::U16(ctx) => ctx.twopass_in(buf),
250     }
251   }
252 
twopass_out(&mut self) -> Option<&[u8]>253   fn twopass_out(&mut self) -> Option<&[u8]> {
254     match self {
255       EncContext::U8(ctx) => ctx.twopass_out(),
256       EncContext::U16(ctx) => ctx.twopass_out(),
257     }
258   }
259 
rc_summary_size(&self) -> usize260   fn rc_summary_size(&self) -> usize {
261     match self {
262       EncContext::U8(ctx) => ctx.rc_summary_size(),
263       EncContext::U16(ctx) => ctx.rc_summary_size(),
264     }
265   }
266 
rc_receive_pass_data(&mut self) -> Option<rav1e::RcData>267   fn rc_receive_pass_data(&mut self) -> Option<rav1e::RcData> {
268     match self {
269       EncContext::U8(ctx) => ctx.rc_receive_pass_data(),
270       EncContext::U16(ctx) => ctx.rc_receive_pass_data(),
271     }
272   }
273 
rc_second_pass_data_required(&self) -> usize274   fn rc_second_pass_data_required(&self) -> usize {
275     match self {
276       EncContext::U8(ctx) => ctx.rc_second_pass_data_required(),
277       EncContext::U16(ctx) => ctx.rc_second_pass_data_required(),
278     }
279   }
280 
rc_send_pass_data( &mut self, data: &[u8], ) -> Result<(), rav1e::EncoderStatus>281   fn rc_send_pass_data(
282     &mut self, data: &[u8],
283   ) -> Result<(), rav1e::EncoderStatus> {
284     match self {
285       EncContext::U8(ctx) => ctx.rc_send_pass_data(data),
286       EncContext::U16(ctx) => ctx.rc_send_pass_data(data),
287     }
288   }
289 }
290 
291 /// Encoder context
292 ///
293 /// Contains the encoding state, it is created by rav1e_context_new() using an
294 /// Encoder configuration.
295 ///
296 /// Use rav1e_context_unref() to free its memory.
297 pub struct Context {
298   ctx: EncContext,
299   last_err: Option<rav1e::EncoderStatus>,
300 }
301 
302 type FrameType = rav1e::FrameType;
303 
304 /// Encoded Packet
305 ///
306 /// The encoded packets are retrieved using rav1e_receive_packet().
307 ///
308 /// Use rav1e_packet_unref() to free its memory.
309 #[repr(C)]
310 pub struct Packet {
311   /// Encoded data buffer
312   pub data: *const u8,
313   /// Encoded data buffer size
314   pub len: size_t,
315   /// Frame sequence number
316   pub input_frameno: u64,
317   /// Frame type
318   pub frame_type: FrameType,
319   /// User provided opaque data
320   pub opaque: *mut c_void,
321 }
322 
323 /// Version information as presented in `[package]` `version`.
324 ///
325 /// e.g. `0.1.0``
326 ///
327 /// Can be parsed by [semver](https://crates.io/crates/semver).
328 /// This returns the version of the loaded library, regardless
329 /// of which version the library user was built against.
330 #[no_mangle]
rav1e_version_short() -> *const c_char331 pub unsafe extern fn rav1e_version_short() -> *const c_char {
332   concat!(env!("CARGO_PKG_VERSION"), "\0").as_ptr() as *const c_char
333 }
334 
335 /// Version information with the information
336 /// provided by `git describe --tags`.
337 ///
338 /// e.g. `0.1.0 (v0.1.0-1-g743d464)`
339 ///
340 /// This returns the version of the loaded library, regardless
341 /// of which version the library user was built against.
342 #[no_mangle]
rav1e_version_full() -> *const c_char343 pub unsafe extern fn rav1e_version_full() -> *const c_char {
344   concat!(
345     env!("CARGO_PKG_VERSION"),
346     " (",
347     env!("VERGEN_SEMVER_LIGHTWEIGHT"),
348     ")\0"
349   )
350   .as_ptr() as *const c_char
351 }
352 
353 /// Simple Data
354 ///
355 ///
356 ///
357 /// Use rav1e_data_unref() to free its memory.
358 #[repr(C)]
359 pub struct Data {
360   /// Pointer to the data buffer
361   pub data: *const u8,
362   /// Data buffer size
363   pub len: size_t,
364 }
365 
366 /// Free a RaData buffer
367 #[no_mangle]
rav1e_data_unref(data: *mut Data)368 pub unsafe extern fn rav1e_data_unref(data: *mut Data) {
369   if !data.is_null() {
370     let data = Box::from_raw(data);
371     let _ = Vec::from_raw_parts(
372       data.data as *mut u8,
373       data.len as usize,
374       data.len as usize,
375     );
376   }
377 }
378 
379 /// Create a RaConfig filled with default parameters.
380 #[no_mangle]
rav1e_config_default() -> *mut Config381 pub unsafe extern fn rav1e_config_default() -> *mut Config {
382   let cfg = rav1e::Config::default();
383 
384   let c = Box::new(Config { cfg });
385 
386   Box::into_raw(c)
387 }
388 
decode_slice<'a>( data: *mut *const u8, len: *mut size_t, ) -> (c_int, Option<&'a [u8]>)389 unsafe fn decode_slice<'a>(
390   data: *mut *const u8, len: *mut size_t,
391 ) -> (c_int, Option<&'a [u8]>) {
392   use std::convert::TryInto;
393 
394   if *len < 8 {
395     return (8, None);
396   }
397 
398   let buf = slice::from_raw_parts(*data, *len as usize);
399   let (len_bytes, rest) = buf.split_at(std::mem::size_of::<u64>());
400   let buf_len = u64::from_be_bytes(len_bytes.try_into().unwrap()) as usize;
401   let full_len = buf_len + 8;
402   if buf_len > rest.len() {
403     return (full_len as c_int, None);
404   }
405 
406   *len -= full_len;
407   *data = (*data).offset(full_len.try_into().unwrap());
408 
409   (0, Some(&rest[..buf_len]))
410 }
411 
412 /// Setup a second pass rate control using the provided summary
413 ///
414 /// Passing NULL data resets the rate control settings.
415 ///
416 /// If additional data is required, pointer and len stay unchanged, otherwise
417 /// they are updated.
418 ///
419 /// Return:
420 /// 0 on success
421 /// > 0 if the buffer has to be larger
422 /// < 0 on failure
423 #[no_mangle]
rav1e_config_set_rc_summary( cfg: *mut Config, data: *mut *const u8, len: *mut size_t, ) -> c_int424 pub unsafe extern fn rav1e_config_set_rc_summary(
425   cfg: *mut Config, data: *mut *const u8, len: *mut size_t,
426 ) -> c_int {
427   if data.is_null() {
428     (*cfg).cfg.rate_control.summary = None;
429 
430     return 0;
431   }
432 
433   let (needed, maybe_buf) = decode_slice(data, len);
434 
435   if maybe_buf.is_none() {
436     return needed;
437   }
438 
439   let summary = rav1e::RateControlSummary::from_slice(maybe_buf.unwrap()).ok();
440   if summary.is_none() {
441     -1
442   } else {
443     (*cfg).cfg.rate_control.summary = summary;
444 
445     0
446   }
447 }
448 
449 /// Request to emit pass data
450 ///
451 /// Set emit to 0 to not emit pass data, non-zero to emit pass data.
452 ///
453 #[no_mangle]
rav1e_config_set_emit_data( cfg: *mut Config, emit: c_int, )454 pub unsafe extern fn rav1e_config_set_emit_data(
455   cfg: *mut Config, emit: c_int,
456 ) {
457   (*cfg).cfg.rate_control.emit_pass_data = emit != 0;
458 }
459 
460 /// Set the display aspect ratio of the stream
461 ///
462 /// Needed for anamorphic video.
463 #[no_mangle]
rav1e_config_set_sample_aspect_ratio( cfg: *mut Config, sample_aspect_ratio: Rational, )464 pub unsafe extern fn rav1e_config_set_sample_aspect_ratio(
465   cfg: *mut Config, sample_aspect_ratio: Rational,
466 ) {
467   (*cfg).cfg.enc.sample_aspect_ratio = sample_aspect_ratio
468 }
469 
470 /// Set the time base of the stream
471 ///
472 /// Needed for rate control.
473 #[no_mangle]
rav1e_config_set_time_base( cfg: *mut Config, time_base: Rational, )474 pub unsafe extern fn rav1e_config_set_time_base(
475   cfg: *mut Config, time_base: Rational,
476 ) {
477   (*cfg).cfg.enc.time_base = time_base
478 }
479 
480 /// Set pixel format of the stream.
481 ///
482 /// Supported values for subsampling and chromapos are defined by the
483 /// enum types RaChromaSampling and RaChromaSamplePosition respectively.
484 /// Valid values for fullrange are 0 and 1.
485 ///
486 /// Returns a negative value on error or 0.
487 #[no_mangle]
rav1e_config_set_pixel_format( cfg: *mut Config, bit_depth: u8, subsampling: ChromaSampling, chroma_pos: ChromaSamplePosition, pixel_range: PixelRange, ) -> c_int488 pub unsafe extern fn rav1e_config_set_pixel_format(
489   cfg: *mut Config, bit_depth: u8, subsampling: ChromaSampling,
490   chroma_pos: ChromaSamplePosition, pixel_range: PixelRange,
491 ) -> c_int {
492   if bit_depth != 8 && bit_depth != 10 && bit_depth != 12 {
493     return -1;
494   }
495   (*cfg).cfg.enc.bit_depth = bit_depth as usize;
496 
497   let subsampling_val =
498     std::mem::transmute::<ChromaSampling, i32>(subsampling);
499   if ChromaSampling::from_i32(subsampling_val).is_none() {
500     return -1;
501   }
502   (*cfg).cfg.enc.chroma_sampling = subsampling;
503 
504   let chroma_pos_val =
505     std::mem::transmute::<ChromaSamplePosition, i32>(chroma_pos);
506   if ChromaSamplePosition::from_i32(chroma_pos_val).is_none() {
507     return -1;
508   }
509   (*cfg).cfg.enc.chroma_sample_position = chroma_pos;
510 
511   let pixel_range_val = std::mem::transmute::<PixelRange, i32>(pixel_range);
512   if PixelRange::from_i32(pixel_range_val).is_none() {
513     return -1;
514   }
515   (*cfg).cfg.enc.pixel_range = pixel_range;
516 
517   0
518 }
519 
520 /// Set color properties of the stream.
521 ///
522 /// Supported values are defined by the enum types
523 /// RaMatrixCoefficients, RaColorPrimaries, and RaTransferCharacteristics
524 /// respectively.
525 ///
526 /// Return a negative value on error or 0.
527 #[no_mangle]
rav1e_config_set_color_description( cfg: *mut Config, matrix: MatrixCoefficients, primaries: ColorPrimaries, transfer: TransferCharacteristics, ) -> c_int528 pub unsafe extern fn rav1e_config_set_color_description(
529   cfg: *mut Config, matrix: MatrixCoefficients, primaries: ColorPrimaries,
530   transfer: TransferCharacteristics,
531 ) -> c_int {
532   (*cfg).cfg.enc.color_description = Some(rav1e::ColorDescription {
533     matrix_coefficients: matrix,
534     color_primaries: primaries,
535     transfer_characteristics: transfer,
536   });
537 
538   if (*cfg).cfg.enc.color_description.is_some() {
539     0
540   } else {
541     -1
542   }
543 }
544 
545 /// Set the content light level information for HDR10 streams.
546 ///
547 /// Return a negative value on error or 0.
548 #[no_mangle]
rav1e_config_set_content_light( cfg: *mut Config, max_content_light_level: u16, max_frame_average_light_level: u16, ) -> c_int549 pub unsafe extern fn rav1e_config_set_content_light(
550   cfg: *mut Config, max_content_light_level: u16,
551   max_frame_average_light_level: u16,
552 ) -> c_int {
553   (*cfg).cfg.enc.content_light = Some(rav1e::ContentLight {
554     max_content_light_level,
555     max_frame_average_light_level,
556   });
557 
558   if (*cfg).cfg.enc.content_light.is_some() {
559     0
560   } else {
561     -1
562   }
563 }
564 
565 /// Set the mastering display information for HDR10 streams.
566 ///
567 /// primaries and white_point arguments are RaChromaticityPoint, containing 0.16 fixed point
568 /// values.
569 /// max_luminance is a 24.8 fixed point value.
570 /// min_luminance is a 18.14 fixed point value.
571 ///
572 /// Returns a negative value on error or 0.
573 /// cbindgen:ptrs-as-arrays=[[primaries;3]]
574 #[no_mangle]
rav1e_config_set_mastering_display( cfg: *mut Config, primaries: *const rav1e::ChromaticityPoint, white_point: rav1e::ChromaticityPoint, max_luminance: u32, min_luminance: u32, ) -> c_int575 pub unsafe extern fn rav1e_config_set_mastering_display(
576   cfg: *mut Config, primaries: *const rav1e::ChromaticityPoint,
577   white_point: rav1e::ChromaticityPoint, max_luminance: u32,
578   min_luminance: u32,
579 ) -> c_int {
580   let primaries = *(primaries as *const [rav1e::ChromaticityPoint; 3]);
581 
582   (*cfg).cfg.enc.mastering_display = Some(rav1e::MasteringDisplay {
583     primaries,
584     white_point,
585     max_luminance,
586     min_luminance,
587   });
588 
589   if (*cfg).cfg.enc.mastering_display.is_some() {
590     0
591   } else {
592     -1
593   }
594 }
595 
596 /// Free the RaConfig.
597 #[no_mangle]
rav1e_config_unref(cfg: *mut Config)598 pub unsafe extern fn rav1e_config_unref(cfg: *mut Config) {
599   if !cfg.is_null() {
600     let _ = Box::from_raw(cfg);
601   }
602 }
603 
tile_log2(blk_size: usize, target: usize) -> usize604 fn tile_log2(blk_size: usize, target: usize) -> usize {
605   let mut k = 0;
606   while (blk_size << k) < target {
607     k += 1;
608   }
609   k
610 }
611 
check_tile_log2(n: Result<usize, ()>) -> Result<usize, ()>612 fn check_tile_log2(n: Result<usize, ()>) -> Result<usize, ()> {
613   match n {
614     Ok(n) => {
615       if ((1 << tile_log2(1, n)) - n) == 0 || n == 0 {
616         Ok(n)
617       } else {
618         Err(())
619       }
620     }
621     Err(e) => Err(e),
622   }
623 }
624 
check_frame_size(n: Result<usize, ()>) -> Result<usize, ()>625 fn check_frame_size(n: Result<usize, ()>) -> Result<usize, ()> {
626   match n {
627     Ok(n) => {
628       if n >= 16 && n < u16::max_value().into() {
629         Ok(n)
630       } else {
631         Err(())
632       }
633     }
634     Err(e) => Err(e),
635   }
636 }
637 
option_match( cfg: *mut Config, key: *const c_char, value: *const c_char, ) -> Result<(), ()>638 unsafe fn option_match(
639   cfg: *mut Config, key: *const c_char, value: *const c_char,
640 ) -> Result<(), ()> {
641   let key = CStr::from_ptr(key).to_str().map_err(|_| ())?;
642   let value = CStr::from_ptr(value).to_str().map_err(|_| ())?;
643   let enc = &mut (*cfg).cfg.enc;
644 
645   match key {
646     "width" => enc.width = check_frame_size(value.parse().map_err(|_| ()))?,
647     "height" => enc.height = check_frame_size(value.parse().map_err(|_| ()))?,
648     "speed" => {
649       enc.speed_settings =
650         rav1e::SpeedSettings::from_preset(value.parse().map_err(|_| ())?)
651     }
652 
653     "threads" => (*cfg).cfg.threads = value.parse().map_err(|_| ())?,
654 
655     "tiles" => enc.tiles = value.parse().map_err(|_| ())?,
656     "tile_rows" => {
657       enc.tile_rows = check_tile_log2(value.parse().map_err(|_| ()))?
658     }
659     "tile_cols" => {
660       enc.tile_cols = check_tile_log2(value.parse().map_err(|_| ()))?
661     }
662 
663     "tune" => enc.tune = value.parse().map_err(|_| ())?,
664     "quantizer" => enc.quantizer = value.parse().map_err(|_| ())?,
665     "min_quantizer" => enc.min_quantizer = value.parse().map_err(|_| ())?,
666     "bitrate" => enc.bitrate = value.parse().map_err(|_| ())?,
667 
668     "key_frame_interval" => {
669       enc.set_key_frame_interval(
670         enc.min_key_frame_interval,
671         value.parse().map_err(|_| ())?,
672       );
673     }
674     "min_key_frame_interval" => {
675       enc.set_key_frame_interval(
676         value.parse().map_err(|_| ())?,
677         enc.max_key_frame_interval,
678       );
679     }
680     "switch_frame_interval" => {
681       enc.switch_frame_interval = value.parse().map_err(|_| ())?
682     }
683     "reservoir_frame_delay" => {
684       enc.reservoir_frame_delay = Some(value.parse().map_err(|_| ())?)
685     }
686     "rdo_lookahead_frames" => {
687       enc.rdo_lookahead_frames = value.parse().map_err(|_| ())?
688     }
689     "low_latency" => enc.low_latency = value.parse().map_err(|_| ())?,
690     "enable_timing_info" => {
691       enc.enable_timing_info = value.parse().map_err(|_| ())?
692     }
693     "still_picture" => enc.still_picture = value.parse().map_err(|_| ())?,
694 
695     _ => return Err(()),
696   }
697 
698   Ok(())
699 }
700 
701 /// Set a configuration parameter using its key and value as string.
702 ///
703 /// Available keys and values
704 /// - "width": width of the frame, default 640
705 /// - "height": height of the frame, default 480
706 /// - "speed": 0-10, default 6
707 /// - "threads": maximum number of threads to be used
708 /// - "tune": "psnr"-"psychovisual", default "psychovisual"
709 /// - "quantizer": 0-255, default 100
710 /// - "tiles": total number of tiles desired (0 denotes auto), default 0
711 /// - "tile_rows": number of tiles horizontally (must be a power of two, overridden by tiles if present), default 0
712 /// - "tile_cols": number of tiles vertically (must be a power of two, overridden by tiles if present), default 0
713 /// - "min_quantizer": minimum allowed base quantizer to use in bitrate mode, default 0
714 /// - "bitrate": target bitrate for the bitrate mode (required for two pass mode), default 0
715 /// - "key_frame_interval": maximum interval between two keyframes, default 240
716 /// - "min_key_frame_interval": minimum interval between two keyframes, default 12
717 /// - "switch_frame_interval": interval between switch frames, default 0
718 /// - "reservoir_frame_delay": number of temporal units over which to distribute the reservoir usage, default None
719 /// - "rdo_lookahead_frames": number of frames to read ahead for the RDO lookahead computation, default 40
720 /// - "low_latency": flag to enable low latency mode, default false
721 /// - "enable_timing_info": flag to enable signaling timing info in the bitstream, default false
722 /// - "still_picture": flag for still picture mode, default false
723 ///
724 /// Return a negative value on error or 0.
725 #[no_mangle]
rav1e_config_parse( cfg: *mut Config, key: *const c_char, value: *const c_char, ) -> c_int726 pub unsafe extern fn rav1e_config_parse(
727   cfg: *mut Config, key: *const c_char, value: *const c_char,
728 ) -> c_int {
729   if option_match(cfg, key, value) == Ok(()) {
730     0
731   } else {
732     -1
733   }
734 }
735 
736 /// Set a configuration parameter using its key and value as integer.
737 ///
738 /// Available keys and values are the same as rav1e_config_parse()
739 ///
740 /// Return a negative value on error or 0.
741 #[no_mangle]
rav1e_config_parse_int( cfg: *mut Config, key: *const c_char, value: c_int, ) -> c_int742 pub unsafe extern fn rav1e_config_parse_int(
743   cfg: *mut Config, key: *const c_char, value: c_int,
744 ) -> c_int {
745   let val = CString::new(value.to_string()).unwrap();
746   if option_match(cfg, key, val.as_ptr()) == Ok(()) {
747     0
748   } else {
749     -1
750   }
751 }
752 
753 /// Generate a new encoding context from a populated encoder configuration
754 ///
755 /// Multiple contexts can be generated through it.
756 /// Returns Null if context creation failed, e.g. by passing
757 /// an invalid Config.
758 #[no_mangle]
rav1e_context_new(cfg: *const Config) -> *mut Context759 pub unsafe extern fn rav1e_context_new(cfg: *const Config) -> *mut Context {
760   let cfg = &(*cfg).cfg;
761   let enc = &cfg.enc;
762 
763   let ctx = match enc.bit_depth {
764     8 => cfg.new_context().map(EncContext::U8),
765     _ => cfg.new_context().map(EncContext::U16),
766   };
767 
768   if let Ok(ctx) = ctx {
769     Box::into_raw(Box::new(Context { ctx, last_err: None }))
770   } else {
771     std::ptr::null_mut()
772   }
773 }
774 
775 /// Free the RaContext.
776 #[no_mangle]
rav1e_context_unref(ctx: *mut Context)777 pub unsafe extern fn rav1e_context_unref(ctx: *mut Context) {
778   if !ctx.is_null() {
779     let _ = Box::from_raw(ctx);
780   }
781 }
782 
783 /// Produce a new frame from the encoding context
784 ///
785 /// It must be populated using rav1e_frame_fill_plane().
786 ///
787 /// The frame is reference counted and must be released passing it to rav1e_frame_unref(),
788 /// see rav1e_send_frame().
789 #[no_mangle]
rav1e_frame_new(ctx: *const Context) -> *mut Frame790 pub unsafe extern fn rav1e_frame_new(ctx: *const Context) -> *mut Frame {
791   let fi = (*ctx).ctx.new_frame();
792   let frame_type = rav1e::FrameTypeOverride::No;
793   let f = Frame { fi, frame_type, opaque: None };
794   let frame = Box::new(f.into());
795 
796   Box::into_raw(frame)
797 }
798 
799 /// Free the RaFrame.
800 #[no_mangle]
rav1e_frame_unref(frame: *mut Frame)801 pub unsafe extern fn rav1e_frame_unref(frame: *mut Frame) {
802   if !frame.is_null() {
803     let _ = Box::from_raw(frame);
804   }
805 }
806 
807 /// Overrides the encoders frame type decision for a frame
808 ///
809 /// Must be called before rav1e_send_frame() if used.
810 #[no_mangle]
rav1e_frame_set_type( frame: *mut Frame, frame_type: FrameTypeOverride, ) -> c_int811 pub unsafe extern fn rav1e_frame_set_type(
812   frame: *mut Frame, frame_type: FrameTypeOverride,
813 ) -> c_int {
814   let frame_type_val =
815     std::mem::transmute::<FrameTypeOverride, i32>(frame_type);
816   if FrameTypeOverride::from_i32(frame_type_val).is_none() {
817     return -1;
818   }
819   (*frame).frame_type = frame_type;
820 
821   0
822 }
823 
824 /// Register an opaque data and a destructor to the frame
825 ///
826 /// It takes the ownership of its memory:
827 /// - it will relinquish the ownership to the context if
828 ///   rav1e_send_frame is called.
829 /// - it will call the destructor if rav1e_frame_unref is called
830 ///   otherwise.
831 #[no_mangle]
rav1e_frame_set_opaque( frame: *mut Frame, opaque: *mut c_void, cb: FrameOpaqueCb, )832 pub unsafe extern fn rav1e_frame_set_opaque(
833   frame: *mut Frame, opaque: *mut c_void, cb: FrameOpaqueCb,
834 ) {
835   if opaque.is_null() {
836     (*frame).opaque = None;
837   } else {
838     (*frame).opaque = Some(FrameOpaque { opaque, cb });
839   }
840 }
841 
842 /// Retrieve the first-pass data of a two-pass encode for the frame that was
843 /// just encoded. This should be called BEFORE every call to rav1e_receive_packet()
844 /// (including the very first one), even if no packet was produced by the
845 /// last call to rav1e_receive_packet, if any (i.e., RA_ENCODER_STATUS_ENCODED
846 /// was returned). It needs to be called once more after
847 /// RA_ENCODER_STATUS_LIMIT_REACHED is returned, to retrieve the header that
848 /// should be written to the front of the stats file (overwriting the
849 /// placeholder header that was emitted at the start of encoding).
850 ///
851 /// It is still safe to call this function when rav1e_receive_packet() returns any
852 /// other error. It will return NULL instead of returning a duplicate copy
853 /// of the previous frame's data.
854 ///
855 /// Must be freed with rav1e_data_unref().
856 #[no_mangle]
rav1e_twopass_out(ctx: *mut Context) -> *mut Data857 pub unsafe extern fn rav1e_twopass_out(ctx: *mut Context) -> *mut Data {
858   let buf = (*ctx).ctx.twopass_out();
859 
860   if buf.is_none() {
861     return std::ptr::null_mut();
862   }
863 
864   let v = buf.unwrap().to_vec();
865   Box::into_raw(Box::new(Data {
866     len: v.len(),
867     data: Box::into_raw(v.into_boxed_slice()) as *mut u8,
868   }))
869 }
870 
871 /// Rate Control Data
872 #[derive(Debug, PartialEq)]
873 #[repr(C)]
874 pub enum RcDataKind {
875   /// A Rate Control Summary Packet
876   ///
877   /// It is emitted once, after the encoder is flushed.
878   ///
879   /// It contains a summary of the rate control information for the
880   /// encoding process that just terminated.
881   Summary,
882   /// A Rate Control Frame-specific Packet
883   ///
884   /// It is emitted every time a frame is processed.
885   ///
886   /// The information contained is required to encode its matching
887   /// frame in a second pass encoding.
888   Frame,
889   /// There is no pass data available for now
890   ///
891   /// This is emitted if rav1e_rc_receive_pass_data is called more
892   /// often than it should.
893   Empty,
894 }
895 
896 /// Return the Rate Control Summary Packet size
897 ///
898 /// It is useful mainly to preserve space when saving
899 /// both Rate Control Summary and Frame Packets in a single file
900 #[no_mangle]
rav1e_rc_summary_size(ctx: *const Context) -> size_t901 pub unsafe extern fn rav1e_rc_summary_size(ctx: *const Context) -> size_t {
902   (*ctx).ctx.rc_summary_size() as size_t + 8
903 }
904 
905 /// Return the first pass data
906 ///
907 /// Call it after rav1e_receive_packet() returns a normal condition status:
908 /// EncoderStatus::Encoded,
909 /// EncoderStatus::Success,
910 /// EncoderStatus::LimitReached.
911 ///
912 /// use rav1e_data_unref() to free the data.
913 ///
914 /// It will return a `RcDataKind::Summary` once the encoder is flushed.
915 #[no_mangle]
rav1e_rc_receive_pass_data( ctx: *mut Context, data: *mut *mut Data, ) -> RcDataKind916 pub unsafe extern fn rav1e_rc_receive_pass_data(
917   ctx: *mut Context, data: *mut *mut Data,
918 ) -> RcDataKind {
919   use crate::api::RcData::*;
920   let (buf, kind) = match (*ctx).ctx.rc_receive_pass_data() {
921     Some(Summary(data)) => (data, RcDataKind::Summary),
922     Some(Frame(data)) => (data, RcDataKind::Frame),
923     None => return RcDataKind::Empty,
924   };
925 
926   let mut full_buf = Vec::with_capacity(buf.len() + 8);
927 
928   full_buf.extend_from_slice(&(buf.len() as u64).to_be_bytes());
929   full_buf.extend_from_slice(&buf);
930 
931   let full_buf = full_buf.into_boxed_slice();
932 
933   *data = Box::into_raw(Box::new(Data {
934     len: full_buf.len(),
935     data: Box::into_raw(full_buf) as *mut u8,
936   }));
937 
938   kind
939 }
940 
941 /// Number of pass data packets required to progress the encoding process.
942 ///
943 /// At least that number of packets must be passed before the encoder can
944 /// progress.
945 ///
946 /// Stop feeding-in pass data packets once the function returns 0.
947 ///
948 /// ``` c
949 /// while (rav1e_rc_second_pass_data_required(ctx) > 0) {
950 ///   int more = rav1e_rc_send_pass_data(ctx, &data, &len);
951 ///   if (more > 0) {
952 ///      refill(&data, &len);
953 ///   } else if (more < 0) {
954 ///     goto fail;
955 ///   }
956 /// }
957 /// ```
958 ///
959 #[no_mangle]
rav1e_rc_second_pass_data_required( ctx: *const Context, ) -> i32960 pub unsafe extern fn rav1e_rc_second_pass_data_required(
961   ctx: *const Context,
962 ) -> i32 {
963   (*ctx).ctx.rc_second_pass_data_required() as i32
964 }
965 
966 /// Feed the first pass Rate Control data to the encoder,
967 /// Frame-specific Packets only.
968 ///
969 /// Call it before receive_packet()
970 ///
971 /// If additional data is required, pointer and len stay unchanged, otherwise
972 /// they are updated.
973 ///
974 /// Returns:
975 /// - `0` on success,
976 /// - `> 0` the amount of bytes needed
977 /// - `< 0` on unrecoverable failure
978 #[no_mangle]
rav1e_rc_send_pass_data( ctx: *mut Context, data: *mut *const u8, len: *mut size_t, ) -> c_int979 pub unsafe extern fn rav1e_rc_send_pass_data(
980   ctx: *mut Context, data: *mut *const u8, len: *mut size_t,
981 ) -> c_int {
982   let (need, maybe_buf) = decode_slice(data, len);
983 
984   if maybe_buf.is_none() {
985     return need;
986   }
987 
988   let ret = (*ctx)
989     .ctx
990     .rc_send_pass_data(maybe_buf.unwrap())
991     .map(|_v| None)
992     .unwrap_or_else(|e| Some(e));
993 
994   (*ctx).last_err = ret;
995 
996   if ret.is_some() {
997     -1
998   } else {
999     0
1000   }
1001 }
1002 
1003 /// Ask how many bytes of the stats file are needed before the next frame
1004 /// of the second pass in a two-pass encode can be encoded. This is a lower
1005 /// bound (more might be required), but if 0 is returned, then encoding can
1006 /// proceed. This is just a hint to the application, and does not need to
1007 /// be called for encoding the second pass to work, so long as the
1008 /// application continues to provide more data to rav1e_twopass_in() in a loop
1009 /// until rav1e_twopass_in() returns 0.
1010 #[no_mangle]
rav1e_twopass_bytes_needed(ctx: *mut Context) -> size_t1011 pub unsafe extern fn rav1e_twopass_bytes_needed(ctx: *mut Context) -> size_t {
1012   (*ctx).ctx.twopass_bytes_needed() as size_t
1013 }
1014 
1015 /// Provide stats data produced in the first pass of a two-pass encode to the
1016 /// second pass. On success this returns the number of bytes of that data
1017 /// which were consumed. When encoding the second pass of a two-pass encode,
1018 /// this should be called repeatedly in a loop before every call to
1019 /// rav1e_receive_packet() (including the very first one) until no bytes are
1020 /// consumed, or until twopass_bytes_needed() returns 0. Returns -1 on failure.
1021 #[no_mangle]
rav1e_twopass_in( ctx: *mut Context, buf: *mut u8, buf_size: size_t, ) -> c_int1022 pub unsafe extern fn rav1e_twopass_in(
1023   ctx: *mut Context, buf: *mut u8, buf_size: size_t,
1024 ) -> c_int {
1025   let buf_slice = slice::from_raw_parts(buf, buf_size as usize);
1026   let r = (*ctx).ctx.twopass_in(buf_slice);
1027   match r {
1028     Ok(v) => v as c_int,
1029     Err(v) => {
1030       (*ctx).last_err = Some(v);
1031       -1
1032     }
1033   }
1034 }
1035 
1036 /// Send the frame for encoding
1037 ///
1038 /// The function increases the frame internal reference count and it can be passed multiple
1039 /// times to different rav1e_send_frame() with a caveat:
1040 ///
1041 /// The opaque data, if present, will be moved from the Frame to the context
1042 /// and returned by rav1e_receive_packet in the Packet opaque field or
1043 /// the destructor will be called on rav1e_context_unref if the frame is
1044 /// still pending in the encoder.
1045 ///
1046 /// Returns:
1047 /// - `0` on success,
1048 /// - `> 0` if the input queue is full
1049 /// - `< 0` on unrecoverable failure
1050 #[no_mangle]
rav1e_send_frame( ctx: *mut Context, frame: *mut Frame, ) -> EncoderStatus1051 pub unsafe extern fn rav1e_send_frame(
1052   ctx: *mut Context, frame: *mut Frame,
1053 ) -> EncoderStatus {
1054   let frame_internal =
1055     if frame.is_null() { None } else { Some((*frame).fi.clone()) };
1056   let frame_type = if frame.is_null() {
1057     rav1e::FrameTypeOverride::No
1058   } else {
1059     (*frame).frame_type
1060   };
1061 
1062   let maybe_opaque = if frame.is_null() {
1063     None
1064   } else {
1065     (*frame)
1066       .opaque
1067       .take()
1068       .map(|o| Box::new(o) as Box<dyn std::any::Any + Send>)
1069   };
1070 
1071   let ret = (*ctx)
1072     .ctx
1073     .send_frame(frame_internal, frame_type, maybe_opaque)
1074     .map(|_v| None)
1075     .unwrap_or_else(|e| Some(e));
1076 
1077   (*ctx).last_err = ret;
1078 
1079   ret.into()
1080 }
1081 
1082 /// Return the last encoder status
1083 #[no_mangle]
rav1e_last_status(ctx: *const Context) -> EncoderStatus1084 pub unsafe extern fn rav1e_last_status(ctx: *const Context) -> EncoderStatus {
1085   (*ctx).last_err.into()
1086 }
1087 
1088 /// Return a static string matching the EncoderStatus variant.
1089 ///
1090 #[no_mangle]
rav1e_status_to_str( status: EncoderStatus, ) -> *const c_char1091 pub unsafe extern fn rav1e_status_to_str(
1092   status: EncoderStatus,
1093 ) -> *const c_char {
1094   if EncoderStatus::from_i32(std::mem::transmute(status)).is_none() {
1095     return std::ptr::null();
1096   }
1097 
1098   status.to_c() as *const c_char
1099 }
1100 
1101 /// Receive encoded data
1102 ///
1103 /// Returns:
1104 /// - `0` on success
1105 /// - `> 0` if additional frame data is required
1106 /// - `< 0` on unrecoverable failure
1107 #[no_mangle]
rav1e_receive_packet( ctx: *mut Context, pkt: *mut *mut Packet, ) -> EncoderStatus1108 pub unsafe extern fn rav1e_receive_packet(
1109   ctx: *mut Context, pkt: *mut *mut Packet,
1110 ) -> EncoderStatus {
1111   let ret = (*ctx)
1112     .ctx
1113     .receive_packet()
1114     .map(|packet| {
1115       *pkt = Box::into_raw(Box::new(packet));
1116       None
1117     })
1118     .unwrap_or_else(|e| Some(e));
1119 
1120   (*ctx).last_err = ret;
1121 
1122   ret.into()
1123 }
1124 
1125 /// Free the RaPacket.
1126 #[no_mangle]
rav1e_packet_unref(pkt: *mut Packet)1127 pub unsafe extern fn rav1e_packet_unref(pkt: *mut Packet) {
1128   if !pkt.is_null() {
1129     let pkt = Box::from_raw(pkt);
1130     let _ = Vec::from_raw_parts(
1131       pkt.data as *mut u8,
1132       pkt.len as usize,
1133       pkt.len as usize,
1134     );
1135   }
1136 }
1137 
1138 /// Produce a sequence header matching the current encoding context
1139 ///
1140 /// Its format is compatible with the AV1 Matroska and ISOBMFF specification.
1141 ///
1142 /// Use rav1e_data_unref() to free it.
1143 #[no_mangle]
rav1e_container_sequence_header( ctx: *const Context, ) -> *mut Data1144 pub unsafe extern fn rav1e_container_sequence_header(
1145   ctx: *const Context,
1146 ) -> *mut Data {
1147   let buf = (*ctx).ctx.container_sequence_header();
1148 
1149   Box::into_raw(Box::new(Data {
1150     len: buf.len(),
1151     data: Box::into_raw(buf.into_boxed_slice()) as *mut u8,
1152   }))
1153 }
1154 
rav1e_frame_fill_plane_internal<T: rav1e::Pixel>( f: &mut Arc<rav1e::Frame<T>>, plane: c_int, data_slice: &[u8], stride: ptrdiff_t, bytewidth: c_int, )1155 fn rav1e_frame_fill_plane_internal<T: rav1e::Pixel>(
1156   f: &mut Arc<rav1e::Frame<T>>, plane: c_int, data_slice: &[u8],
1157   stride: ptrdiff_t, bytewidth: c_int,
1158 ) {
1159   let input = Arc::make_mut(f);
1160   input.planes[plane as usize].copy_from_raw_u8(
1161     data_slice,
1162     stride as usize,
1163     bytewidth as usize,
1164   );
1165 }
1166 
1167 /// Fill a frame plane
1168 ///
1169 /// Currently the frame contains 3 planes, the first is luminance followed by
1170 /// chrominance.
1171 ///
1172 /// The data is copied and this function has to be called for each plane.
1173 ///
1174 /// frame: A frame provided by rav1e_frame_new()
1175 /// plane: The index of the plane starting from 0
1176 /// data: The data to be copied
1177 /// data_len: Length of the buffer
1178 /// stride: Plane line in bytes, including padding
1179 /// bytewidth: Number of bytes per component, either 1 or 2
1180 #[no_mangle]
rav1e_frame_fill_plane( frame: *mut Frame, plane: c_int, data: *const u8, data_len: size_t, stride: ptrdiff_t, bytewidth: c_int, )1181 pub unsafe extern fn rav1e_frame_fill_plane(
1182   frame: *mut Frame, plane: c_int, data: *const u8, data_len: size_t,
1183   stride: ptrdiff_t, bytewidth: c_int,
1184 ) {
1185   let data_slice = slice::from_raw_parts(data, data_len as usize);
1186 
1187   match (*frame).fi {
1188     FrameInternal::U8(ref mut f) => {
1189       rav1e_frame_fill_plane_internal(f, plane, data_slice, stride, bytewidth)
1190     }
1191     FrameInternal::U16(ref mut f) => {
1192       rav1e_frame_fill_plane_internal(f, plane, data_slice, stride, bytewidth)
1193     }
1194   }
1195 }
1196 
1197 #[cfg(test)]
1198 mod test {
1199   use super::*;
1200 
1201   use std::ffi::CString;
1202 
1203   #[test]
forward_opaque()1204   fn forward_opaque() {
1205     unsafe {
1206       let rac = rav1e_config_default();
1207       let w = CString::new("width").unwrap();
1208       rav1e_config_parse_int(rac, w.as_ptr(), 64);
1209       let h = CString::new("height").unwrap();
1210       rav1e_config_parse_int(rac, h.as_ptr(), 64);
1211       let s = CString::new("speed").unwrap();
1212       rav1e_config_parse_int(rac, s.as_ptr(), 10);
1213 
1214       let rax = rav1e_context_new(rac);
1215 
1216       let f = rav1e_frame_new(rax);
1217 
1218       for i in 0..30 {
1219         let v = Box::new(i as u8);
1220         extern fn cb(o: *mut c_void) {
1221           let v = unsafe { Box::from_raw(o as *mut u8) };
1222           eprintln!("Would free {}", v);
1223         }
1224         rav1e_frame_set_opaque(f, Box::into_raw(v) as *mut c_void, Some(cb));
1225         rav1e_send_frame(rax, f);
1226       }
1227 
1228       rav1e_send_frame(rax, std::ptr::null_mut());
1229 
1230       for _ in 0..15 {
1231         let mut p: *mut Packet = std::ptr::null_mut();
1232         let ret = rav1e_receive_packet(rax, &mut p);
1233 
1234         if ret == EncoderStatus::Success {
1235           let v = Box::from_raw((*p).opaque as *mut u8);
1236           eprintln!("Opaque {}", v);
1237         }
1238 
1239         if ret == EncoderStatus::LimitReached {
1240           break;
1241         }
1242       }
1243 
1244       let v = Box::new(42u64);
1245       extern fn cb(o: *mut c_void) {
1246         let v = unsafe { Box::from_raw(o as *mut u64) };
1247         eprintln!("Would free {}", v);
1248       }
1249       rav1e_frame_set_opaque(f, Box::into_raw(v) as *mut c_void, Some(cb));
1250 
1251       // 42 would be freed after this
1252       rav1e_frame_unref(f);
1253       // 15 - reorder delay .. 29 would be freed after this
1254       rav1e_context_unref(rax);
1255       rav1e_config_unref(rac);
1256     }
1257   }
1258 
1259   #[test]
two_pass_encoding()1260   fn two_pass_encoding() {
1261     unsafe {
1262       let rac = rav1e_config_default();
1263       let w = CString::new("width").unwrap();
1264       rav1e_config_parse_int(rac, w.as_ptr(), 64);
1265       let h = CString::new("height").unwrap();
1266       rav1e_config_parse_int(rac, h.as_ptr(), 64);
1267       let s = CString::new("speed").unwrap();
1268       rav1e_config_parse_int(rac, s.as_ptr(), 10);
1269       let s = CString::new("bitrate").unwrap();
1270       rav1e_config_parse_int(rac, s.as_ptr(), 1000);
1271       rav1e_config_set_emit_data(rac, 1);
1272 
1273       let rax = rav1e_context_new(rac);
1274       let f = rav1e_frame_new(rax);
1275 
1276       for _ in 0..10 {
1277         rav1e_send_frame(rax, f);
1278       }
1279 
1280       rav1e_send_frame(rax, std::ptr::null_mut());
1281 
1282       let mut frame_data = std::collections::VecDeque::new();
1283       let mut summary: *mut Data = std::ptr::null_mut();
1284 
1285       loop {
1286         let mut p: *mut Packet = std::ptr::null_mut();
1287         let ret = rav1e_receive_packet(rax, &mut p);
1288         rav1e_packet_unref(p);
1289         if ret == EncoderStatus::LimitReached {
1290           let kind = rav1e_rc_receive_pass_data(rax, &mut summary);
1291           assert_eq!(kind, RcDataKind::Summary);
1292           eprintln!("Got rc summary {} bytes", (*summary).len);
1293           break;
1294         } else if ret == EncoderStatus::Encoded
1295           || ret == EncoderStatus::Success
1296         {
1297           let mut p: *mut Data = std::ptr::null_mut();
1298           let kind = rav1e_rc_receive_pass_data(rax, &mut p);
1299           assert_eq!(kind, RcDataKind::Frame);
1300           eprintln!("Got rc frame data {} bytes", (*p).len);
1301           frame_data.push_back(p);
1302         }
1303       }
1304 
1305       rav1e_config_set_emit_data(rac, 0);
1306       let mut data = (*summary).data;
1307       let mut len = (*summary).len;
1308       let ret = rav1e_config_set_rc_summary(rac, &mut data, &mut len);
1309       assert_eq!(ret, 0);
1310 
1311       rav1e_data_unref(summary);
1312 
1313       for _ in 0..10 {
1314         rav1e_send_frame(rax, f);
1315       }
1316 
1317       rav1e_send_frame(rax, std::ptr::null_mut());
1318 
1319       loop {
1320         let mut p: *mut Packet = std::ptr::null_mut();
1321         while rav1e_rc_second_pass_data_required(rax) > 0 {
1322           let d = frame_data.pop_front().unwrap();
1323           let mut data = (*d).data;
1324           let mut len = (*d).len;
1325           rav1e_rc_send_pass_data(rax, &mut data, &mut len);
1326           rav1e_data_unref(d);
1327         }
1328 
1329         let ret = rav1e_receive_packet(rax, &mut p);
1330         rav1e_packet_unref(p);
1331         if ret == EncoderStatus::LimitReached {
1332           break;
1333         }
1334       }
1335 
1336       rav1e_frame_unref(f);
1337       rav1e_context_unref(rax);
1338       rav1e_config_unref(rac);
1339     }
1340   }
1341 }
1342