Skip to content

Commit e5c3261

Browse files
committed
fn Rav1dPictureDataComponent::wrap_buf: make unsafe to enforce buf outlives Self
Adding proper lifetimes is difficult (see #1317), so we instead make this an `unsafe` precondition, that `buf` must outlive the returned `Self`.
1 parent 1be76ea commit e5c3261

File tree

2 files changed

+50
-21
lines changed

2 files changed

+50
-21
lines changed

include/dav1d/picture.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -185,9 +185,15 @@ impl Rav1dPictureDataComponentInner {
185185

186186
/// # Safety
187187
///
188-
/// As opposed to [`Self::new`], this is safe because `buf` is a `&mut` and thus unique,
189-
/// so it is sound to further subdivide it into disjoint `&mut`s.
190-
pub fn wrap_buf<BD: BitDepth>(buf: &mut [BD::Pixel], stride: usize) -> Self {
188+
/// `buf` must outlive the returned [`Self`].
189+
///
190+
/// As opposed to [`Self::new`], `buf` is a `&mut`, so it must be unique,
191+
/// so it is sound to further subdivide it into disjoint `&mut`s as long as its lifetime lasts.
192+
/// However, adding proper lifetimes is difficult
193+
/// (see [#1317](https://github.com/memorysafety/rav1d/pull/1317)),
194+
/// so instead we make this an `unsafe` precondition,
195+
/// that `buf` must outlive the returned [`Self`].
196+
pub unsafe fn wrap_buf<BD: BitDepth>(buf: &mut [BD::Pixel], stride: usize) -> Self {
191197
let buf = AsBytes::as_bytes_mut(buf);
192198
let ptr = NonNull::new(buf.as_mut_ptr()).unwrap();
193199
assert!(ptr.cast::<AlignedPixelChunk>().is_aligned());
@@ -245,9 +251,15 @@ impl Strided for Rav1dPictureDataComponent {
245251
}
246252

247253
impl Rav1dPictureDataComponent {
248-
pub fn wrap_buf<BD: BitDepth>(buf: &mut [BD::Pixel], stride: usize) -> Self {
254+
/// # Safety
255+
///
256+
/// `buf` must outlive the returned [`Self`].
257+
///
258+
/// See [`Rav1dPictureDataComponentInner::wrap_buf`] for more details.
259+
pub unsafe fn wrap_buf<BD: BitDepth>(buf: &mut [BD::Pixel], stride: usize) -> Self {
249260
Self(DisjointMut::new(
250-
Rav1dPictureDataComponentInner::wrap_buf::<BD>(buf, stride),
261+
// SAFETY: Delegated.
262+
unsafe { Rav1dPictureDataComponentInner::wrap_buf::<BD>(buf, stride) },
251263
))
252264
}
253265

src/recon.rs

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1779,7 +1779,8 @@ fn mc<BD: BitDepth>(
17791779
);
17801780
let stride = 192;
17811781
Rav1dPictureDataComponentOffset {
1782-
data: &Rav1dPictureDataComponent::wrap_buf::<BD>(emu_edge_buf, stride),
1782+
// SAFETY: Lifetime extension forces `buf` to outlive it.
1783+
data: &unsafe { Rav1dPictureDataComponent::wrap_buf::<BD>(emu_edge_buf, stride) },
17831784
offset: stride * (my != 0) as usize * 3 + (mx != 0) as usize * 3,
17841785
}
17851786
} else {
@@ -1852,7 +1853,8 @@ fn mc<BD: BitDepth>(
18521853
}
18531854
let stride = 320;
18541855
Rav1dPictureDataComponentOffset {
1855-
data: &Rav1dPictureDataComponent::wrap_buf::<BD>(emu_edge_buf, stride),
1856+
// SAFETY: Lifetime extension forces `buf` to outlive it.
1857+
data: &unsafe { Rav1dPictureDataComponent::wrap_buf::<BD>(emu_edge_buf, stride) },
18561858
offset: stride * 3 + 3,
18571859
}
18581860
} else {
@@ -1920,10 +1922,13 @@ fn obmc<BD: BitDepth>(
19201922
t.b,
19211923
MaybeTempPixels::NonTemp {
19221924
dst: Rav1dPictureDataComponentOffset {
1923-
data: &Rav1dPictureDataComponent::wrap_buf::<BD>(
1924-
lap,
1925-
ow4 as usize * h_mul as usize,
1926-
),
1925+
// SAFETY: Lifetime extension forces `buf` to outlive it.
1926+
data: &unsafe {
1927+
Rav1dPictureDataComponent::wrap_buf::<BD>(
1928+
lap,
1929+
ow4 as usize * h_mul as usize,
1930+
)
1931+
},
19271932
offset: 0,
19281933
},
19291934
},
@@ -1968,10 +1973,13 @@ fn obmc<BD: BitDepth>(
19681973
t.b,
19691974
MaybeTempPixels::NonTemp {
19701975
dst: Rav1dPictureDataComponentOffset {
1971-
data: &Rav1dPictureDataComponent::wrap_buf::<BD>(
1972-
lap,
1973-
ow4 as usize * h_mul as usize,
1974-
),
1976+
// SAFETY: Lifetime extension forces `buf` to outlive it.
1977+
data: &unsafe {
1978+
Rav1dPictureDataComponent::wrap_buf::<BD>(
1979+
lap,
1980+
ow4 as usize * h_mul as usize,
1981+
)
1982+
},
19751983
offset: 0,
19761984
},
19771985
},
@@ -2056,7 +2064,10 @@ fn warp_affine<BD: BitDepth>(
20562064
);
20572065
let stride = 32;
20582066
Rav1dPictureDataComponentOffset {
2059-
data: &Rav1dPictureDataComponent::wrap_buf::<BD>(emu_edge_buf, stride),
2067+
// SAFETY: Lifetime extension forces `buf` to outlive it.
2068+
data: &unsafe {
2069+
Rav1dPictureDataComponent::wrap_buf::<BD>(emu_edge_buf, stride)
2070+
},
20602071
offset: stride * 3 + 3,
20612072
}
20622073
} else {
@@ -3123,7 +3134,10 @@ pub(crate) fn rav1d_recon_b_inter<BD: BitDepth>(
31233134
let tmp = interintra_edge_pal.interintra.buf_mut::<BD>();
31243135
f.dsp.ipred.intra_pred[m as usize].call(
31253136
Rav1dPictureDataComponentOffset {
3126-
data: &Rav1dPictureDataComponent::wrap_buf::<BD>(tmp, 4 * bw4 as usize),
3137+
// SAFETY: Lifetime extension forces `buf` to outlive it.
3138+
data: &unsafe {
3139+
Rav1dPictureDataComponent::wrap_buf::<BD>(tmp, 4 * bw4 as usize)
3140+
},
31273141
offset: 0,
31283142
},
31293143
tl_edge_array,
@@ -3407,10 +3421,13 @@ pub(crate) fn rav1d_recon_b_inter<BD: BitDepth>(
34073421
let tmp = interintra_edge_pal.interintra.buf_mut::<BD>();
34083422
f.dsp.ipred.intra_pred[m as usize].call(
34093423
Rav1dPictureDataComponentOffset {
3410-
data: &Rav1dPictureDataComponent::wrap_buf::<BD>(
3411-
tmp,
3412-
4 * cbw4 as usize,
3413-
),
3424+
// SAFETY: Lifetime extension forces `buf` to outlive it.
3425+
data: &unsafe {
3426+
Rav1dPictureDataComponent::wrap_buf::<BD>(
3427+
tmp,
3428+
4 * cbw4 as usize,
3429+
)
3430+
},
34143431
offset: 0,
34153432
},
34163433
tl_edge_array,

0 commit comments

Comments
 (0)