diff --git a/Cargo.toml b/Cargo.toml index c04c3c687d..8c9ee8615d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rav1e" -version = "0.4.0" +version = "0.5.0-alpha" authors = ["Thomas Daede "] edition = "2018" build = "build.rs" diff --git a/src/api/internal.rs b/src/api/internal.rs index 6d116db646..465f5e317b 100644 --- a/src/api/internal.rs +++ b/src/api/internal.rs @@ -10,7 +10,7 @@ use crate::activity::ActivityMask; use crate::api::lookahead::*; -use crate::api::{EncoderConfig, EncoderStatus, FrameType, Packet}; +use crate::api::{EncoderConfig, EncoderStatus, FrameType, Opaque, Packet}; use crate::color::ChromaSampling::Cs400; use crate::cpu_features::CpuFeatureLevel; use crate::dist::get_satd; @@ -256,7 +256,7 @@ pub(crate) struct ContextInner { /// The next `output_frameno` to be computed by lookahead. next_lookahead_output_frameno: u64, /// Optional opaque to be sent back to the user - opaque_q: BTreeMap>, + opaque_q: BTreeMap, } impl ContextInner { diff --git a/src/api/test.rs b/src/api/test.rs index 21d8fa3459..5cbeaa6ea1 100644 --- a/src/api/test.rs +++ b/src/api/test.rs @@ -1176,7 +1176,7 @@ fn send_frame_kf(ctx: &mut Context, keyframe: bool) { let frame_type_override = if keyframe { FrameTypeOverride::Key } else { FrameTypeOverride::No }; - let opaque = Some(Box::new(keyframe) as Box); + let opaque = Some(Opaque::new(keyframe)); let fp = FrameParameters { frame_type_override, opaque }; diff --git a/src/api/util.rs b/src/api/util.rs index 800d4d4a19..71b8611a9e 100644 --- a/src/api/util.rs +++ b/src/api/util.rs @@ -13,11 +13,35 @@ use crate::serialize::{Deserialize, Serialize}; use crate::stats::EncoderStats; use crate::util::Pixel; +use std::any::Any; use std::fmt; use std::sync::Arc; use thiserror::*; +/// Opaque type to be passed from Frame to Packet +#[derive(Debug)] +pub struct Opaque(Box); + +impl Opaque { + /// Wrap a type in the opaque struct + pub fn new(t: T) -> Self { + Opaque(Box::new(t) as Box) + } + + /// Attempt to downcast the opaque to a concrete type. + pub fn downcast(self) -> Result, Opaque> { + if self.0.is::() { + unsafe { + let raw: *mut (dyn Any + Send + Sync) = Box::into_raw(self.0); + Ok(Box::from_raw(raw as *mut T)) + } + } else { + Err(self) + } + } +} + // TODO: use the num crate? /// A rational number. #[derive(Clone, Copy, Debug)] @@ -181,7 +205,7 @@ pub struct Packet { pub enc_stats: EncoderStats, /// Optional user-provided opaque data #[cfg_attr(feature = "serialize", serde(skip))] - pub opaque: Option>, + pub opaque: Option, } impl PartialEq for Packet { diff --git a/src/capi.rs b/src/capi.rs index f4b4273c9d..d0aeda1f82 100644 --- a/src/capi.rs +++ b/src/capi.rs @@ -67,6 +67,7 @@ struct FrameOpaque { } unsafe impl Send for FrameOpaque {} +unsafe impl Sync for FrameOpaque {} impl Default for FrameOpaque { fn default() -> Self { @@ -180,7 +181,7 @@ impl EncContext { } fn send_frame( &mut self, frame: Option, frame_type: FrameTypeOverride, - opaque: Option>, + opaque: Option, ) -> Result<(), rav1e::EncoderStatus> { let info = rav1e::FrameParameters { frame_type_override: frame_type, opaque }; @@ -1062,10 +1063,7 @@ pub unsafe extern fn rav1e_send_frame( let maybe_opaque = if frame.is_null() { None } else { - (*frame) - .opaque - .take() - .map(|o| Box::new(o) as Box) + (*frame).opaque.take().map(|o| rav1e::Opaque::new(o)) }; let ret = (*ctx) diff --git a/src/frame/mod.rs b/src/frame/mod.rs index c245d6029d..af0f11d273 100644 --- a/src/frame/mod.rs +++ b/src/frame/mod.rs @@ -9,6 +9,7 @@ use num_derive::FromPrimitive; +use crate::api::Opaque; use crate::context::SB_SIZE; use crate::mc::SUBPEL_FILTER_SIZE; use crate::util::*; @@ -39,7 +40,7 @@ pub struct FrameParameters { /// Force emitted frame to be of the type selected pub frame_type_override: FrameTypeOverride, /// Output the provided data in the matching encoded Packet - pub opaque: Option>, + pub opaque: Option, } pub use v_frame::frame::Frame;