Skip to content

Commit

Permalink
struct Rav1dPictureData: Arcify (#992)
Browse files Browse the repository at this point in the history
* Fixes #866.
  • Loading branch information
kkysen authored Apr 24, 2024
2 parents dca64d2 + face592 commit 741073f
Show file tree
Hide file tree
Showing 9 changed files with 194 additions and 249 deletions.
60 changes: 27 additions & 33 deletions include/dav1d/picture.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::include::common::validate::validate_input;
use crate::include::dav1d::common::Dav1dDataProps;
use crate::include::dav1d::common::Rav1dDataProps;
use crate::include::dav1d::dav1d::Dav1dRef;
use crate::include::dav1d::headers::DRav1d;
use crate::include::dav1d::headers::Dav1dFrameHeader;
use crate::include::dav1d::headers::Dav1dITUTT35;
Expand All @@ -17,12 +16,10 @@ use crate::src::c_arc::RawArc;
use crate::src::error::Dav1dResult;
use crate::src::error::Rav1dError;
use crate::src::error::Rav1dError::EINVAL;
use crate::src::r#ref::Rav1dRef;
use libc::ptrdiff_t;
use libc::uintptr_t;
use std::ffi::c_int;
use std::ffi::c_void;
use std::ptr;
use std::ptr::NonNull;
use std::sync::Arc;

Expand Down Expand Up @@ -92,22 +89,24 @@ pub struct Dav1dPicture {
pub mastering_display_ref: Option<RawArc<Rav1dMasteringDisplay>>, // opaque, so we can change this
pub itut_t35_ref: Option<RawArc<DRav1d<Box<[Rav1dITUTT35]>, Box<[Dav1dITUTT35]>>>>, // opaque, so we can change this
pub reserved_ref: [uintptr_t; 4],
pub r#ref: Option<NonNull<Dav1dRef>>,
pub r#ref: Option<RawArc<Rav1dPictureData>>, // opaque, so we can change this
pub allocator_data: Option<NonNull<c_void>>,
}

#[derive(Clone)]
pub(crate) struct Rav1dPictureData {
pub data: [*mut c_void; 3],
pub allocator_data: Option<NonNull<c_void>>,
pub struct Rav1dPictureData {
pub(crate) data: [*mut c_void; 3],
pub(crate) allocator_data: Option<NonNull<c_void>>,
pub(crate) allocator: Rav1dPicAllocator,
}

impl Default for Rav1dPictureData {
fn default() -> Self {
Self {
data: [ptr::null_mut(); 3],
allocator_data: Default::default(),
}
impl Drop for Rav1dPictureData {
fn drop(&mut self) {
let Self {
data,
allocator_data,
ref allocator,
} = *self;
allocator.dealloc_picture_data(data, allocator_data);
}
}

Expand All @@ -121,22 +120,21 @@ impl Default for Rav1dPictureData {
pub(crate) struct Rav1dPicture {
pub seq_hdr: Option<Arc<DRav1d<Rav1dSequenceHeader, Dav1dSequenceHeader>>>,
pub frame_hdr: Option<Arc<DRav1d<Rav1dFrameHeader, Dav1dFrameHeader>>>,
pub data: Rav1dPictureData,
pub data: Option<Arc<Rav1dPictureData>>,
pub stride: [ptrdiff_t; 2],
pub p: Rav1dPictureParameters,
pub m: Rav1dDataProps,
pub content_light: Option<Arc<Rav1dContentLightLevel>>,
pub mastering_display: Option<Arc<Rav1dMasteringDisplay>>,
pub itut_t35: Arc<DRav1d<Box<[Rav1dITUTT35]>, Box<[Dav1dITUTT35]>>>,
pub r#ref: Option<NonNull<Rav1dRef>>,
}

impl From<Dav1dPicture> for Rav1dPicture {
fn from(value: Dav1dPicture) -> Self {
let Dav1dPicture {
seq_hdr: _,
frame_hdr: _,
data,
data: _,
stride,
p,
m,
Expand All @@ -151,8 +149,8 @@ impl From<Dav1dPicture> for Rav1dPicture {
mastering_display_ref,
itut_t35_ref,
reserved_ref: _,
r#ref,
allocator_data,
r#ref: data_ref,
allocator_data: _,
} = value;
Self {
// We don't `.update_rav1d()` [`Rav1dSequenceHeader`] because it's meant to be read-only.
Expand All @@ -161,10 +159,8 @@ impl From<Dav1dPicture> for Rav1dPicture {
// We don't `.update_rav1d()` [`Rav1dFrameHeader`] because it's meant to be read-only.
// Safety: `raw` came from [`RawArc::from_arc`].
frame_hdr: frame_hdr_ref.map(|raw| unsafe { raw.into_arc() }),
data: Rav1dPictureData {
data: data.map(|data| data.map_or_else(ptr::null_mut, NonNull::as_ptr)),
allocator_data,
},
// Safety: `raw` came from [`RawArc::from_arc`].
data: data_ref.map(|raw| unsafe { raw.into_arc() }),
stride,
p: p.into(),
m: m.into(),
Expand All @@ -177,7 +173,6 @@ impl From<Dav1dPicture> for Rav1dPicture {
itut_t35: itut_t35_ref
.map(|raw| unsafe { raw.into_arc() })
.unwrap_or_default(),
r#ref,
}
}
}
Expand All @@ -187,25 +182,23 @@ impl From<Rav1dPicture> for Dav1dPicture {
let Rav1dPicture {
seq_hdr,
frame_hdr,
data:
Rav1dPictureData {
data,
allocator_data,
},
data,
stride,
p,
m,
content_light,
mastering_display,
itut_t35,
r#ref,
} = value;
Self {
// [`DRav1d::from_rav1d`] is called right after [`parse_seq_hdr`].
seq_hdr: seq_hdr.as_ref().map(|arc| (&arc.as_ref().dav1d).into()),
// [`DRav1d::from_rav1d`] is called in [`parse_frame_hdr`].
frame_hdr: frame_hdr.as_ref().map(|arc| (&arc.as_ref().dav1d).into()),
data: data.map(NonNull::new),
data: data
.as_ref()
.map(|arc| arc.data.map(NonNull::new))
.unwrap_or_default(),
stride,
p: p.into(),
m: m.into(),
Expand All @@ -221,8 +214,9 @@ impl From<Rav1dPicture> for Dav1dPicture {
mastering_display_ref: mastering_display.map(RawArc::from_arc),
itut_t35_ref: Some(itut_t35).map(RawArc::from_arc),
reserved_ref: Default::default(),
r#ref,
allocator_data,
// Order flipped so that the borrow comes before the move.
allocator_data: data.as_ref().and_then(|arc| arc.allocator_data),
r#ref: data.map(RawArc::from_arc),
}
}
}
Expand Down
11 changes: 5 additions & 6 deletions src/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4564,7 +4564,7 @@ pub(crate) unsafe fn rav1d_decode_frame_exit(
f: &mut Rav1dFrameData,
retval: Rav1dResult,
) {
if !f.sr_cur.p.data.data[0].is_null() {
if f.sr_cur.p.data.is_some() {
f.task_thread.error = AtomicI32::new(0);
}
let cf = f.frame_thread.cf.get_mut();
Expand Down Expand Up @@ -4669,8 +4669,7 @@ pub unsafe fn rav1d_submit_frame(c: &mut Rav1dContext) -> Rav1dResult {
task_thread_lock = f.task_thread.cond.wait(task_thread_lock).unwrap();
}
let out_delayed = &mut c.frame_thread.out_delayed[next as usize];
if !out_delayed.p.data.data[0].is_null() || f.task_thread.error.load(Ordering::SeqCst) != 0
{
if out_delayed.p.data.is_some() || f.task_thread.error.load(Ordering::SeqCst) != 0 {
let first = c.task_thread.first.load(Ordering::SeqCst);
if first + 1 < c.n_fc {
c.task_thread.first.fetch_add(1, Ordering::SeqCst);
Expand All @@ -4695,7 +4694,7 @@ pub unsafe fn rav1d_submit_frame(c: &mut Rav1dContext) -> Rav1dResult {
c.cached_error = mem::replace(&mut error, Ok(()));
*c.cached_error_props.get_mut().unwrap() = out_delayed.p.m.clone();
rav1d_thread_picture_unref(out_delayed);
} else if !out_delayed.p.data.data[0].is_null() {
} else if out_delayed.p.data.is_some() {
let progress = out_delayed.progress.as_ref().unwrap()[1].load(Ordering::Relaxed);
if (out_delayed.visible || c.output_invisible_frames) && progress != FRAME_ERROR {
rav1d_thread_picture_ref(&mut c.out, out_delayed);
Expand Down Expand Up @@ -4756,14 +4755,14 @@ pub unsafe fn rav1d_submit_frame(c: &mut Rav1dContext) -> Rav1dResult {
if frame_hdr.frame_type.is_inter_or_switch() {
if frame_hdr.primary_ref_frame != RAV1D_PRIMARY_REF_NONE {
let pri_ref = frame_hdr.refidx[frame_hdr.primary_ref_frame as usize] as usize;
if c.refs[pri_ref].p.p.data.data[0].is_null() {
if c.refs[pri_ref].p.p.data.is_none() {
on_error(f, c, out);
return Err(EINVAL);
}
}
for i in 0..7 {
let refidx = frame_hdr.refidx[i] as usize;
if c.refs[refidx].p.p.data.data[0].is_null()
if c.refs[refidx].p.p.data.is_none()
|| (frame_hdr.size.width[0] * 2) < c.refs[refidx].p.p.p.w
|| (frame_hdr.size.height * 2) < c.refs[refidx].p.p.p.h
|| frame_hdr.size.width[0] > c.refs[refidx].p.p.p.w * 16
Expand Down
45 changes: 30 additions & 15 deletions src/fg_apply.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,16 +119,20 @@ pub(crate) unsafe fn rav1d_prep_grain<BD: BitDepth>(
let sz = out.p.h as isize * stride;
if sz < 0 {
memcpy(
(out.data.data[0] as *mut u8)
(out.data.as_ref().unwrap().data[0] as *mut u8)
.offset(sz as isize)
.offset(-(stride as isize)) as *mut c_void,
(r#in.data.data[0] as *mut u8)
(r#in.data.as_ref().unwrap().data[0] as *mut u8)
.offset(sz as isize)
.offset(-(stride as isize)) as *const c_void,
-sz as usize,
);
} else {
memcpy(out.data.data[0], r#in.data.data[0], sz as usize);
memcpy(
out.data.as_ref().unwrap().data[0],
r#in.data.as_ref().unwrap().data[0],
sz as usize,
);
}
}

Expand All @@ -140,32 +144,40 @@ pub(crate) unsafe fn rav1d_prep_grain<BD: BitDepth>(
if sz < 0 {
if data.num_uv_points[0] == 0 {
memcpy(
(out.data.data[1] as *mut u8)
(out.data.as_ref().unwrap().data[1] as *mut u8)
.offset(sz as isize)
.offset(-(stride as isize)) as *mut c_void,
(r#in.data.data[1] as *mut u8)
(r#in.data.as_ref().unwrap().data[1] as *mut u8)
.offset(sz as isize)
.offset(-(stride as isize)) as *const c_void,
-sz as usize,
);
}
if data.num_uv_points[1] == 0 {
memcpy(
(out.data.data[2] as *mut u8)
(out.data.as_ref().unwrap().data[2] as *mut u8)
.offset(sz as isize)
.offset(-(stride as isize)) as *mut c_void,
(r#in.data.data[2] as *mut u8)
(r#in.data.as_ref().unwrap().data[2] as *mut u8)
.offset(sz as isize)
.offset(-(stride as isize)) as *const c_void,
-sz as usize,
);
}
} else {
if data.num_uv_points[0] == 0 {
memcpy(out.data.data[1], r#in.data.data[1], sz as usize);
memcpy(
out.data.as_ref().unwrap().data[1],
r#in.data.as_ref().unwrap().data[1],
sz as usize,
);
}
if data.num_uv_points[1] == 0 {
memcpy(out.data.data[2], r#in.data.data[2], sz as usize);
memcpy(
out.data.as_ref().unwrap().data[2],
r#in.data.as_ref().unwrap().data[2],
sz as usize,
);
}
}
}
Expand All @@ -188,15 +200,15 @@ pub(crate) unsafe fn rav1d_apply_grain_row<BD: BitDepth>(
let ss_x = (r#in.p.layout != Rav1dPixelLayout::I444) as usize;
let cpw = out.p.w as usize + ss_x >> ss_x;
let is_id = seq_hdr.mtrx == Rav1dMatrixCoefficients::IDENTITY;
let luma_src = (r#in.data.data[0] as *mut BD::Pixel)
let luma_src = (r#in.data.as_ref().unwrap().data[0] as *mut BD::Pixel)
.offset(((row * 32) as isize * BD::pxstride(r#in.stride[0])) as isize);
let bitdepth_max = (1 << out.p.bpc) - 1;
let bd = BD::from_c(bitdepth_max);

if data.num_y_points != 0 {
let bh = cmp::min(out.p.h as usize - row * 32, 32);
dsp.fgy_32x32xn.call(
(out.data.data[0] as *mut BD::Pixel)
(out.data.as_ref().unwrap().data[0] as *mut BD::Pixel)
.offset(((row * 32) as isize * BD::pxstride(out.stride[0])) as isize),
luma_src.cast(),
out.stride[0],
Expand Down Expand Up @@ -229,8 +241,9 @@ pub(crate) unsafe fn rav1d_apply_grain_row<BD: BitDepth>(
if data.chroma_scaling_from_luma {
for pl in 0..2 {
dsp.fguv_32x32xn[r#in.p.layout.try_into().unwrap()].call(
(out.data.data[1 + pl] as *mut BD::Pixel).offset(uv_off as isize),
(r#in.data.data[1 + pl] as *const BD::Pixel).offset(uv_off as isize),
(out.data.as_ref().unwrap().data[1 + pl] as *mut BD::Pixel).offset(uv_off as isize),
(r#in.data.as_ref().unwrap().data[1 + pl] as *const BD::Pixel)
.offset(uv_off as isize),
r#in.stride[1],
data,
cpw,
Expand All @@ -249,8 +262,10 @@ pub(crate) unsafe fn rav1d_apply_grain_row<BD: BitDepth>(
for pl in 0..2 {
if data.num_uv_points[pl] != 0 {
dsp.fguv_32x32xn[r#in.p.layout.try_into().unwrap()].call(
(out.data.data[1 + pl] as *mut BD::Pixel).offset(uv_off as isize),
(r#in.data.data[1 + pl] as *const BD::Pixel).offset(uv_off as isize),
(out.data.as_ref().unwrap().data[1 + pl] as *mut BD::Pixel)
.offset(uv_off as isize),
(r#in.data.as_ref().unwrap().data[1 + pl] as *const BD::Pixel)
.offset(uv_off as isize),
r#in.stride[1],
data_c,
cpw,
Expand Down
15 changes: 7 additions & 8 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ unsafe fn output_image(c: &mut Rav1dContext, out: &mut Rav1dPicture) -> Rav1dRes
}
rav1d_thread_picture_unref(&mut *r#in);

if !c.all_layers && c.max_spatial_id && !(c.out.p.data.data[0]).is_null() {
if !c.all_layers && c.max_spatial_id && c.out.p.data.is_some() {
rav1d_thread_picture_move_ref(r#in, &mut c.out);
}
res
Expand All @@ -410,7 +410,7 @@ unsafe fn output_picture_ready(c: &mut Rav1dContext, drain: bool) -> bool {
return true;
}
if !c.all_layers && c.max_spatial_id {
if !c.out.p.data.data[0].is_null() && !c.cache.p.data.data[0].is_null() {
if c.out.p.data.is_some() && c.cache.p.data.is_some() {
if c.max_spatial_id == (c.cache.p.frame_hdr.as_ref().unwrap().spatial_id != 0)
|| c.out.flags.contains(PictureFlags::NEW_TEMPORAL_UNIT)
{
Expand All @@ -420,17 +420,17 @@ unsafe fn output_picture_ready(c: &mut Rav1dContext, drain: bool) -> bool {
rav1d_thread_picture_move_ref(&mut c.cache, &mut c.out);
return false;
} else {
if !c.cache.p.data.data[0].is_null() && drain {
if c.cache.p.data.is_some() && drain {
return true;
} else {
if !c.out.p.data.data[0].is_null() {
if c.out.p.data.is_some() {
rav1d_thread_picture_move_ref(&mut c.cache, &mut c.out);
return false;
}
}
}
}
!c.out.p.data.data[0].is_null()
c.out.p.data.is_some()
}

unsafe fn drain_picture(c: &mut Rav1dContext, out: &mut Rav1dPicture) -> Rav1dResult {
Expand All @@ -444,8 +444,7 @@ unsafe fn drain_picture(c: &mut Rav1dContext, out: &mut Rav1dPicture) -> Rav1dRe
task_thread_lock = f.task_thread.cond.wait(task_thread_lock).unwrap();
}
let out_delayed = &mut c.frame_thread.out_delayed[next as usize];
if !out_delayed.p.data.data[0].is_null() || f.task_thread.error.load(Ordering::SeqCst) != 0
{
if out_delayed.p.data.is_some() || f.task_thread.error.load(Ordering::SeqCst) != 0 {
let first: c_uint = c.task_thread.first.load(Ordering::SeqCst);
if first.wrapping_add(1 as c_uint) < c.n_fc {
c.task_thread.first.fetch_add(1, Ordering::SeqCst);
Expand Down Expand Up @@ -478,7 +477,7 @@ unsafe fn drain_picture(c: &mut Rav1dContext, out: &mut Rav1dPicture) -> Rav1dRe
rav1d_thread_picture_unref(out_delayed);
return error;
}
if !(out_delayed.p.data.data[0]).is_null() {
if out_delayed.p.data.is_some() {
let progress = out_delayed.progress.as_ref().unwrap()[1].load(Ordering::Relaxed);
if (out_delayed.visible || c.output_invisible_frames) && progress != FRAME_ERROR {
rav1d_thread_picture_ref(&mut c.out, out_delayed);
Expand Down
Loading

0 comments on commit 741073f

Please sign in to comment.