diff --git a/Cargo.lock b/Cargo.lock index b3b1df7bf..d8241a77a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,26 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "atomig" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcecf20a3720c354e7648983ee8046436dea13caf0fe8f84a791c7fba456cf0f" +dependencies = [ + "atomig-macro", +] + +[[package]] +name = "atomig-macro" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a10c8c98ca4c65e4bdd6f1506beb768671f8dce3f5df4dd7d14632b6ecc6f43" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "bitflags" version = "2.4.0" @@ -85,6 +105,7 @@ dependencies = [ name = "rav1d" version = "0.2.0" dependencies = [ + "atomig", "bitflags", "cc", "cfg-if", @@ -131,7 +152,18 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn", + "syn 2.0.32", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index a821c3545..3e9dfce30 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,7 @@ path = "tests/seek_stress.rs" name = "seek_stress" [dependencies] +atomig = { version = "0.4.0", features = ["derive"] } bitflags = "2.4.0" cfg-if = "1.0.0" libc = "0.2" diff --git a/src/internal.rs b/src/internal.rs index 7c26e133f..d78307123 100644 --- a/src/internal.rs +++ b/src/internal.rs @@ -74,6 +74,7 @@ use crate::src::refmvs::refmvs_temporal_block; use crate::src::refmvs::refmvs_tile; use crate::src::refmvs::Rav1dRefmvsDSPContext; use crate::src::thread_data::thread_data; +use atomig::Atomic; use libc::pthread_cond_t; use libc::pthread_mutex_t; use libc::ptrdiff_t; @@ -253,7 +254,7 @@ pub struct Rav1dContext { pub(crate) inloop_filters: Rav1dInloopFilterType, pub(crate) decode_frame_type: Rav1dDecodeFrameType, pub(crate) drain: c_int, - pub(crate) frame_flags: PictureFlags, + pub(crate) frame_flags: Atomic, pub(crate) event_flags: Rav1dEventFlags, pub(crate) cached_error_props: Rav1dDataProps, pub(crate) cached_error: Rav1dResult, diff --git a/src/obu.rs b/src/obu.rs index 40c3c2fe8..584dd2bbb 100644 --- a/src/obu.rs +++ b/src/obu.rs @@ -2258,7 +2258,8 @@ unsafe fn parse_obus( match &c.seq_hdr { None => { c.frame_hdr = None; - c.frame_flags |= PictureFlags::NEW_SEQUENCE; + c.frame_flags + .fetch_or(PictureFlags::NEW_SEQUENCE, Ordering::Relaxed); } Some(c_seq_hdr) if !seq_hdr.eq_without_operating_parameter_info(&c_seq_hdr) => { // See 7.5, `operating_parameter_info` is allowed to change in @@ -2274,13 +2275,15 @@ unsafe fn parse_obus( rav1d_ref_dec(&mut c.refs[i as usize].refmvs); rav1d_cdf_thread_unref(&mut c.cdf[i as usize]); } - c.frame_flags |= PictureFlags::NEW_SEQUENCE; + c.frame_flags + .fetch_or(PictureFlags::NEW_SEQUENCE, Ordering::Relaxed); } Some(c_seq_hdr) if seq_hdr.operating_parameter_info != c_seq_hdr.operating_parameter_info => { // If operating_parameter_info changed, signal it - c.frame_flags |= PictureFlags::NEW_OP_PARAMS_INFO; + c.frame_flags + .fetch_or(PictureFlags::NEW_OP_PARAMS_INFO, Ordering::Relaxed); } _ => {} } @@ -2465,7 +2468,10 @@ unsafe fn parse_obus( } } } - RAV1D_OBU_TD => c.frame_flags |= PictureFlags::NEW_TEMPORAL_UNIT, + RAV1D_OBU_TD => { + c.frame_flags + .fetch_or(PictureFlags::NEW_TEMPORAL_UNIT, Ordering::Relaxed); + } RAV1D_OBU_PADDING => {} // Ignore OBUs we don't care about. _ => { // Print a warning, but don't fail for unknown types. diff --git a/src/picture.rs b/src/picture.rs index 595cf8043..7d52484a0 100644 --- a/src/picture.rs +++ b/src/picture.rs @@ -31,6 +31,8 @@ use crate::src::mem::Rav1dMemPoolBuffer; use crate::src::r#ref::rav1d_ref_dec; use crate::src::r#ref::rav1d_ref_inc; use crate::src::r#ref::rav1d_ref_wrap; +use atomig::Atom; +use atomig::AtomLogic; use bitflags::bitflags; use libc::free; use libc::malloc; @@ -42,12 +44,15 @@ use std::mem; use std::ptr; use std::slice; use std::sync::atomic::AtomicU32; +use std::sync::atomic::Ordering; use std::sync::Arc; use to_method::To as _; +#[derive(Clone, Copy, PartialEq, Eq, Hash, Default, Atom, AtomLogic)] +pub struct PictureFlags(u8); + bitflags! { - #[derive(Clone, Copy, PartialEq, Eq, Hash, Default)] - pub struct PictureFlags: u8 { + impl PictureFlags: u8 { const NEW_SEQUENCE = 1 << 0; const NEW_OP_PARAMS_INFO = 1 << 1; const NEW_TEMPORAL_UNIT = 1 << 2; @@ -254,8 +259,7 @@ pub(crate) unsafe fn rav1d_thread_picture_alloc( } else { PictureFlags::NEW_SEQUENCE | PictureFlags::NEW_OP_PARAMS_INFO }; - p.flags = c.frame_flags; - c.frame_flags &= flags_mask; + p.flags = c.frame_flags.fetch_and(flags_mask, Ordering::Relaxed); p.visible = frame_hdr.show_frame != 0; p.showable = frame_hdr.showable_frame != 0; p.progress = if have_frame_mt {