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