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

fn Rav1dPictureDataComponentInner::wrap_buf: Attempt to add lifetimes #1317

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
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
3 changes: 2 additions & 1 deletion include/common/bitdepth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,8 @@ pub trait BitDepth: Clone + Copy {
const BPC: BPC;
const BITDEPTH: u8 = Self::BPC.bitdepth();

type Pixel: Copy
type Pixel: 'static
+ Copy
+ Ord
+ Add<Output = Self::Pixel>
+ Mul<Output = Self::Pixel>
Expand Down
81 changes: 56 additions & 25 deletions include/dav1d/picture.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#![deny(unsafe_op_in_unsafe_fn)]
#![deny(elided_lifetimes_in_paths)]

use crate::include::common::bitdepth::BitDepth;
use crate::include::common::validate::validate_input;
Expand Down Expand Up @@ -34,6 +35,7 @@ use libc::uintptr_t;
use std::array;
use std::ffi::c_int;
use std::ffi::c_void;
use std::marker::PhantomData;
use std::mem;
use std::ptr::NonNull;
use std::sync::Arc;
Expand Down Expand Up @@ -128,13 +130,15 @@ const RAV1D_PICTURE_GUARANTEED_MULTIPLE: usize = 64;
/// though wrapped buffers may only be [`RAV1D_PICTURE_GUARANTEED_MULTIPLE`].
const RAV1D_PICTURE_MULTIPLE: usize = 64 * 64;

pub struct Rav1dPictureDataComponentInner {
pub struct Rav1dPictureDataComponentInner<'a> {
/// A ptr to the start of this slice of [`BitDepth::Pixel`]s*,
/// even if [`Self::stride`] is negative.
///
/// It is aligned to [`RAV1D_PICTURE_ALIGNMENT`].
ptr: NonNull<u8>,

_phantom: PhantomData<&'a ()>,

/// The length of [`Self::ptr`] in [`u8`] bytes.
///
/// It is a multiple of [`RAV1D_PICTURE_GUARANTEED_MULTIPLE`].
Expand All @@ -144,7 +148,7 @@ pub struct Rav1dPictureDataComponentInner {
stride: isize,
}

impl Rav1dPictureDataComponentInner {
impl<'a> Rav1dPictureDataComponentInner<'a> {
/// `len` and `stride` are in terms of [`u8`] bytes.
///
/// # Safety
Expand All @@ -156,6 +160,7 @@ impl Rav1dPictureDataComponentInner {
return Self {
// Ensure it is aligned enough.
ptr: NonNull::<AlignedPixelChunk>::dangling().cast(),
_phantom: PhantomData,
len: 0,
stride,
};
Expand All @@ -179,26 +184,37 @@ impl Rav1dPictureDataComponentInner {
};
// Guaranteed by `Dav1dPicAllocator::alloc_picture_callback`.
assert!(len % RAV1D_PICTURE_MULTIPLE == 0);
Self { ptr, len, stride }

Self {
ptr,
_phantom: PhantomData,
len,
stride,
}
}

/// # Safety
///
/// As opposed to [`Self::new`], this is safe because `buf` is a `&mut` and thus unique,
/// so it is sound to further subdivide it into disjoint `&mut`s.
pub fn wrap_buf<BD: BitDepth>(buf: &mut [BD::Pixel], stride: usize) -> Self {
pub fn wrap_buf<BD: BitDepth>(buf: &'a mut [BD::Pixel], stride: usize) -> Self {
let buf = AsBytes::as_bytes_mut(buf);
let ptr = NonNull::new(buf.as_mut_ptr()).unwrap();
assert!(ptr.cast::<AlignedPixelChunk>().is_aligned());
let len = buf.len();
assert!(len % RAV1D_PICTURE_GUARANTEED_MULTIPLE == 0);
let stride = (stride * mem::size_of::<BD::Pixel>()) as isize;
Self { ptr, len, stride }
Self {
ptr,
_phantom: PhantomData,
len,
stride,
}
}
}

// SAFETY: We only store the raw pointer, so we never materialize a `&mut`.
unsafe impl AsMutPtr for Rav1dPictureDataComponentInner {
unsafe impl AsMutPtr for Rav1dPictureDataComponentInner<'_> {
type Target = u8;

#[inline] // Inline so callers can see the assume.
Expand All @@ -224,9 +240,9 @@ unsafe impl AsMutPtr for Rav1dPictureDataComponentInner {
}
}

pub struct Rav1dPictureDataComponent(DisjointMut<Rav1dPictureDataComponentInner>);
pub struct Rav1dPictureDataComponent<'buf>(DisjointMut<Rav1dPictureDataComponentInner<'buf>>);

impl Pixels for Rav1dPictureDataComponent {
impl Pixels for Rav1dPictureDataComponent<'_> {
fn byte_len(&self) -> usize {
self.0.len()
}
Expand All @@ -236,15 +252,15 @@ impl Pixels for Rav1dPictureDataComponent {
}
}

impl Strided for Rav1dPictureDataComponent {
impl Strided for Rav1dPictureDataComponent<'_> {
fn stride(&self) -> isize {
// SAFETY: We're only accessing the `stride` fields, not `ptr`.
unsafe { (*self.0.inner()).stride }
}
}

impl Rav1dPictureDataComponent {
pub fn wrap_buf<BD: BitDepth>(buf: &mut [BD::Pixel], stride: usize) -> Self {
impl<'buf> Rav1dPictureDataComponent<'buf> {
pub fn wrap_buf<BD: BitDepth>(buf: &'buf mut [BD::Pixel], stride: usize) -> Self {
Self(DisjointMut::new(
Rav1dPictureDataComponentInner::wrap_buf::<BD>(buf, stride),
))
Expand All @@ -258,7 +274,10 @@ impl Rav1dPictureDataComponent {
BD::pxstride(self.byte_len() - (-stride) as usize)
}

pub fn with_offset<BD: BitDepth>(&self) -> Rav1dPictureDataComponentOffset {
pub fn with_offset<'a, BD: BitDepth>(&'a self) -> Rav1dPictureDataComponentOffset<'a, 'buf>
where
'buf: 'a,
{
Rav1dPictureDataComponentOffset {
data: self,
offset: self.pixel_offset::<BD>(),
Expand Down Expand Up @@ -310,7 +329,10 @@ impl Rav1dPictureDataComponent {
pub fn index<'a, BD: BitDepth>(
&'a self,
index: usize,
) -> DisjointImmutGuard<'a, Rav1dPictureDataComponentInner, BD::Pixel> {
) -> DisjointImmutGuard<'a, Rav1dPictureDataComponentInner<'buf>, BD::Pixel>
where
'buf: 'a,
{
self.0.element_as(index)
}

Expand All @@ -319,7 +341,10 @@ impl Rav1dPictureDataComponent {
pub fn index_mut<'a, BD: BitDepth>(
&'a self,
index: usize,
) -> DisjointMutGuard<'a, Rav1dPictureDataComponentInner, BD::Pixel> {
) -> DisjointMutGuard<'a, Rav1dPictureDataComponentInner<'buf>, BD::Pixel>
where
'buf: 'a,
{
self.0.mut_element_as(index)
}

Expand All @@ -328,8 +353,9 @@ impl Rav1dPictureDataComponent {
pub fn slice<'a, BD, I>(
&'a self,
index: I,
) -> DisjointImmutGuard<'a, Rav1dPictureDataComponentInner, [BD::Pixel]>
) -> DisjointImmutGuard<'a, Rav1dPictureDataComponentInner<'buf>, [BD::Pixel]>
where
'buf: 'a,
BD: BitDepth,
I: SliceBounds,
{
Expand All @@ -341,31 +367,33 @@ impl Rav1dPictureDataComponent {
pub fn slice_mut<'a, BD, I>(
&'a self,
index: I,
) -> DisjointMutGuard<'a, Rav1dPictureDataComponentInner, [BD::Pixel]>
) -> DisjointMutGuard<'a, Rav1dPictureDataComponentInner<'buf>, [BD::Pixel]>
where
'buf: 'a,
BD: BitDepth,
I: SliceBounds,
{
self.0.mut_slice_as(index)
}
}

pub type Rav1dPictureDataComponentOffset<'a> = WithOffset<&'a Rav1dPictureDataComponent>;
pub type Rav1dPictureDataComponentOffset<'a, 'buf> =
WithOffset<&'a Rav1dPictureDataComponent<'buf>>;

impl<'a> Rav1dPictureDataComponentOffset<'a> {
impl<'a, 'buf> Rav1dPictureDataComponentOffset<'a, 'buf> {
#[inline] // Inline to see bounds checks in order to potentially elide them.
#[cfg_attr(debug_assertions, track_caller)]
pub fn index<BD: BitDepth>(
&self,
) -> DisjointImmutGuard<'a, Rav1dPictureDataComponentInner, BD::Pixel> {
) -> DisjointImmutGuard<'a, Rav1dPictureDataComponentInner<'buf>, BD::Pixel> {
self.data.index::<BD>(self.offset)
}

#[inline] // Inline to see bounds checks in order to potentially elide them.
#[cfg_attr(debug_assertions, track_caller)]
pub fn index_mut<BD: BitDepth>(
&self,
) -> DisjointMutGuard<'a, Rav1dPictureDataComponentInner, BD::Pixel> {
) -> DisjointMutGuard<'a, Rav1dPictureDataComponentInner<'buf>, BD::Pixel> {
self.data.index_mut::<BD>(self.offset)
}

Expand All @@ -374,7 +402,7 @@ impl<'a> Rav1dPictureDataComponentOffset<'a> {
pub fn slice<BD: BitDepth>(
&self,
len: usize,
) -> DisjointImmutGuard<'a, Rav1dPictureDataComponentInner, [BD::Pixel]> {
) -> DisjointImmutGuard<'a, Rav1dPictureDataComponentInner<'buf>, [BD::Pixel]> {
self.data.slice::<BD, _>((self.offset.., ..len))
}

Expand All @@ -383,13 +411,13 @@ impl<'a> Rav1dPictureDataComponentOffset<'a> {
pub fn slice_mut<BD: BitDepth>(
&self,
len: usize,
) -> DisjointMutGuard<'a, Rav1dPictureDataComponentInner, [BD::Pixel]> {
) -> DisjointMutGuard<'a, Rav1dPictureDataComponentInner<'buf>, [BD::Pixel]> {
self.data.slice_mut::<BD, _>((self.offset.., ..len))
}
}

pub struct Rav1dPictureData {
pub data: [Rav1dPictureDataComponent; 3],
pub data: [Rav1dPictureDataComponent<'static>; 3],
pub(crate) allocator_data: Option<NonNull<c_void>>,
pub(crate) allocator: Rav1dPicAllocator,
}
Expand Down Expand Up @@ -529,7 +557,10 @@ impl From<Rav1dPicture> for Dav1dPicture {
}

impl Rav1dPicture {
pub fn lf_offsets<BD: BitDepth>(&self, y: c_int) -> [Rav1dPictureDataComponentOffset; 3] {
pub fn lf_offsets<'a, BD: BitDepth>(
&'a self,
y: c_int,
) -> [Rav1dPictureDataComponentOffset<'a, 'static>; 3] {
// Init loopfilter offsets. Point the chroma offsets in 4:0:0 to the luma
// plane here to avoid having additional in-loop branches in various places.
// We never use those values, so it doesn't really matter what they point
Expand Down Expand Up @@ -780,7 +811,7 @@ impl Rav1dPicAllocator {

pub fn dealloc_picture_data(
&self,
data: &mut [Rav1dPictureDataComponent; 3],
data: &mut [Rav1dPictureDataComponent<'static>; 3],
allocator_data: Option<NonNull<c_void>>,
) {
let data = data.each_mut().map(|data| data.as_dav1d());
Expand Down
2 changes: 1 addition & 1 deletion src/cdef.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ wrap_fn_ptr!(pub unsafe extern "C" fn cdef(
) -> ());

pub type CdefTop<'a> = WithOffset<&'a DisjointMut<AlignedVec64<u8>>>;
pub type CdefBottom<'a> = WithOffset<PicOrBuf<'a, AlignedVec64<u8>>>;
pub type CdefBottom<'a, 'buf> = WithOffset<PicOrBuf<'a, 'buf, AlignedVec64<u8>>>;

impl cdef::Fn {
/// CDEF operates entirely on pre-filter data.
Expand Down
30 changes: 15 additions & 15 deletions src/filmgrain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,15 +106,15 @@ wrap_fn_ptr!(pub unsafe extern "C" fn fgy_32x32xn(
bh: c_int,
row_num: c_int,
bitdepth_max: c_int,
_dst_row: *const FFISafe<Rav1dPictureDataComponentOffset>,
_src_src: *const FFISafe<Rav1dPictureDataComponentOffset>,
_dst_row: *const FFISafe<Rav1dPictureDataComponentOffset<'_, 'static>>,
_src_src: *const FFISafe<Rav1dPictureDataComponentOffset<'_, 'static>>,
) -> ());

impl fgy_32x32xn::Fn {
pub fn call<BD: BitDepth>(
&self,
dst: &Rav1dPictureDataComponent,
src: &Rav1dPictureDataComponent,
dst: &Rav1dPictureDataComponent<'static>,
src: &Rav1dPictureDataComponent<'static>,
data: &Rav1dFilmGrainData,
pw: usize,
scaling: &BD::Scaling,
Expand Down Expand Up @@ -172,24 +172,24 @@ wrap_fn_ptr!(pub unsafe extern "C" fn fguv_32x32xn(
uv_pl: c_int,
is_id: c_int,
bitdepth_max: c_int,
_dst_row: *const FFISafe<Rav1dPictureDataComponentOffset>,
_src_row: *const FFISafe<Rav1dPictureDataComponentOffset>,
_luma_row: *const FFISafe<Rav1dPictureDataComponentOffset>,
_dst_row: *const FFISafe<Rav1dPictureDataComponentOffset<'_, 'static>>,
_src_row: *const FFISafe<Rav1dPictureDataComponentOffset<'_, 'static>>,
_luma_row: *const FFISafe<Rav1dPictureDataComponentOffset<'_, 'static>>,
) -> ());

impl fguv_32x32xn::Fn {
pub fn call<BD: BitDepth>(
&self,
layout: Rav1dPixelLayoutSubSampled,
dst: &Rav1dPictureDataComponent,
src: &Rav1dPictureDataComponent,
dst: &Rav1dPictureDataComponent<'static>,
src: &Rav1dPictureDataComponent<'static>,
data: &Rav1dFilmGrainData,
pw: usize,
scaling: &BD::Scaling,
grain_lut: &GrainLut<BD::Entry>,
bh: usize,
row_num: usize,
luma: &Rav1dPictureDataComponent,
luma: &Rav1dPictureDataComponent<'static>,
is_uv: bool,
is_id: bool,
bd: BD,
Expand Down Expand Up @@ -538,8 +538,8 @@ unsafe extern "C" fn fgy_32x32xn_c_erased<BD: BitDepth>(
bh: c_int,
row_num: c_int,
bitdepth_max: c_int,
dst_row: *const FFISafe<Rav1dPictureDataComponentOffset>,
src_row: *const FFISafe<Rav1dPictureDataComponentOffset>,
dst_row: *const FFISafe<Rav1dPictureDataComponentOffset<'_, 'static>>,
src_row: *const FFISafe<Rav1dPictureDataComponentOffset<'_, 'static>>,
) {
// SAFETY: Was passed as `FFISafe::new(_)` in `fgy_32x32xn::Fn::call`.
let [dst_row, src_row] = [dst_row, src_row].map(|it| *unsafe { FFISafe::get(it) });
Expand Down Expand Up @@ -877,9 +877,9 @@ unsafe extern "C" fn fguv_32x32xn_c_erased<
uv_pl: c_int,
is_id: c_int,
bitdepth_max: c_int,
dst_row: *const FFISafe<Rav1dPictureDataComponentOffset>,
src_row: *const FFISafe<Rav1dPictureDataComponentOffset>,
luma_row: *const FFISafe<Rav1dPictureDataComponentOffset>,
dst_row: *const FFISafe<Rav1dPictureDataComponentOffset<'_, 'static>>,
src_row: *const FFISafe<Rav1dPictureDataComponentOffset<'_, 'static>>,
luma_row: *const FFISafe<Rav1dPictureDataComponentOffset<'_, 'static>>,
) {
let [dst_row, src_row, luma_row] = [dst_row, src_row, luma_row].map(|row| {
// SAFETY: Was passed as `FFISafe::new(_)` in `fguv_32x32xn::Fn::call`.
Expand Down
2 changes: 1 addition & 1 deletion src/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -998,7 +998,7 @@ pub const EMU_EDGE_LEN: usize = 320 * (256 + 7);
pub struct ScratchEmuEdge([u8; EMU_EDGE_LEN * 2]);

impl ScratchEmuEdge {
pub fn buf_mut<BD: BitDepth>(&mut self) -> &mut [BD::Pixel; EMU_EDGE_LEN] {
pub fn buf_mut<'a, BD: BitDepth>(&'a mut self) -> &'a mut [BD::Pixel; EMU_EDGE_LEN] {
FromBytes::mut_from_prefix(&mut self.0).unwrap()
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/ipred_prepare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,15 +161,15 @@ static av1_intra_prediction_edges: [Av1IntraPredictionEdge; N_IMPL_INTRA_PRED_MO
/// If edges are not available (because the edge position
/// is outside the tile dimensions or because edge_flags indicates lack of edge availability),
/// they will be extended from nearby edges as defined by the AV1 spec.
pub fn rav1d_prepare_intra_edges<BD: BitDepth>(
pub fn rav1d_prepare_intra_edges<'a, 'buf, BD: BitDepth>(
x: c_int,
have_left: bool,
y: c_int,
have_top: bool,
w: c_int,
h: c_int,
edge_flags: EdgeFlags,
dst: Rav1dPictureDataComponentOffset,
dst: Rav1dPictureDataComponentOffset<'a, 'buf>,
// Buffer and offset pair. `isize` value is the base offset that should be used
// when indexing into the buffer.
prefilter_toplevel_sb_edge: Option<(&DisjointMut<AlignedVec64<u8>>, isize)>,
Expand Down
Loading
Loading