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