Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

struct Rav1dPictureData: Arcify #992

Merged
merged 1 commit into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 {
kkysen marked this conversation as resolved.
Show resolved Hide resolved
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
Loading