mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer-rs.git
synced 2024-12-22 16:16:37 +00:00
gstreamer: buffer: Use ranges instead of offset/length parameter pairs
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/issues/497 Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/merge_requests/1363>
This commit is contained in:
parent
cd30854c2b
commit
96de51a7b7
6 changed files with 99 additions and 91 deletions
|
@ -352,7 +352,7 @@ pub trait BaseSrcImplExt: sealed::Sealed + ObjectSubclass {
|
|||
passed_buffer.set_size(copied_size);
|
||||
}
|
||||
|
||||
match new_buffer.copy_into(passed_buffer, gst::BUFFER_COPY_METADATA, 0, None) {
|
||||
match new_buffer.copy_into(passed_buffer, gst::BUFFER_COPY_METADATA, ..) {
|
||||
Ok(_) => Ok(CreateSuccess::FilledBuffer),
|
||||
Err(_) => {
|
||||
gst::error!(
|
||||
|
@ -775,12 +775,7 @@ unsafe extern "C" fn base_src_create<T: BaseSrcImpl>(
|
|||
passed_buffer.set_size(copied_size);
|
||||
}
|
||||
|
||||
match new_buffer.copy_into(
|
||||
passed_buffer,
|
||||
gst::BUFFER_COPY_METADATA,
|
||||
0,
|
||||
None,
|
||||
) {
|
||||
match new_buffer.copy_into(passed_buffer, gst::BUFFER_COPY_METADATA, ..) {
|
||||
Ok(_) => gst::FlowReturn::Ok,
|
||||
Err(_) => {
|
||||
gst::error!(
|
||||
|
|
|
@ -154,7 +154,7 @@ pub trait PushSrcImplExt: sealed::Sealed + ObjectSubclass {
|
|||
passed_buffer.set_size(copied_size);
|
||||
}
|
||||
|
||||
match new_buffer.copy_into(passed_buffer, gst::BUFFER_COPY_METADATA, 0, None) {
|
||||
match new_buffer.copy_into(passed_buffer, gst::BUFFER_COPY_METADATA, ..) {
|
||||
Ok(_) => Ok(CreateSuccess::FilledBuffer),
|
||||
Err(_) => {
|
||||
gst::error!(
|
||||
|
@ -282,12 +282,7 @@ unsafe extern "C" fn push_src_create<T: PushSrcImpl>(
|
|||
passed_buffer.set_size(copied_size);
|
||||
}
|
||||
|
||||
match new_buffer.copy_into(
|
||||
passed_buffer,
|
||||
gst::BUFFER_COPY_METADATA,
|
||||
0,
|
||||
None,
|
||||
) {
|
||||
match new_buffer.copy_into(passed_buffer, gst::BUFFER_COPY_METADATA, ..) {
|
||||
Ok(_) => gst::FlowReturn::Ok,
|
||||
Err(_) => {
|
||||
gst::error!(
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::{
|
|||
cmp, fmt,
|
||||
marker::PhantomData,
|
||||
mem, ops,
|
||||
ops::{Bound, ControlFlow, RangeBounds},
|
||||
ops::{Bound, ControlFlow, Range, RangeBounds},
|
||||
ptr, slice, u64, usize,
|
||||
};
|
||||
|
||||
|
@ -299,20 +299,53 @@ impl BufferRef {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn byte_range_into_offset_len(
|
||||
&self,
|
||||
range: impl RangeBounds<usize>,
|
||||
) -> Result<(usize, usize), glib::BoolError> {
|
||||
let size = self.size();
|
||||
|
||||
let start_idx = match range.start_bound() {
|
||||
ops::Bound::Included(idx) if *idx >= size => {
|
||||
return Err(glib::bool_error!("Invalid range start"));
|
||||
}
|
||||
ops::Bound::Included(idx) => *idx,
|
||||
ops::Bound::Excluded(idx) if idx.checked_add(1).map_or(true, |idx| idx >= size) => {
|
||||
return Err(glib::bool_error!("Invalid range start"));
|
||||
}
|
||||
ops::Bound::Excluded(idx) => *idx + 1,
|
||||
ops::Bound::Unbounded => 0,
|
||||
};
|
||||
|
||||
let end_idx = match range.end_bound() {
|
||||
ops::Bound::Included(idx) if idx.checked_add(1).map_or(true, |idx| idx >= size) => {
|
||||
return Err(glib::bool_error!("Invalid range end"));
|
||||
}
|
||||
ops::Bound::Included(idx) => *idx + 1,
|
||||
ops::Bound::Excluded(idx) if *idx >= size => {
|
||||
return Err(glib::bool_error!("Invalid range end"));
|
||||
}
|
||||
ops::Bound::Excluded(idx) => *idx,
|
||||
ops::Bound::Unbounded => size,
|
||||
};
|
||||
|
||||
Ok((start_idx, end_idx - start_idx))
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_buffer_copy_region")]
|
||||
pub fn copy_region(
|
||||
&self,
|
||||
flags: crate::BufferCopyFlags,
|
||||
offset: usize,
|
||||
size: Option<usize>,
|
||||
range: impl RangeBounds<usize>,
|
||||
) -> Result<Buffer, glib::BoolError> {
|
||||
let size_real = size.unwrap_or(usize::MAX);
|
||||
let (offset, size) = self.byte_range_into_offset_len(range)?;
|
||||
|
||||
unsafe {
|
||||
Option::<_>::from_glib_full(ffi::gst_buffer_copy_region(
|
||||
self.as_mut_ptr(),
|
||||
flags.into_glib(),
|
||||
offset,
|
||||
size_real,
|
||||
size,
|
||||
))
|
||||
.ok_or_else(|| glib::bool_error!("Failed to copy region of buffer"))
|
||||
}
|
||||
|
@ -323,10 +356,10 @@ impl BufferRef {
|
|||
&self,
|
||||
dest: &mut BufferRef,
|
||||
flags: crate::BufferCopyFlags,
|
||||
offset: usize,
|
||||
size: Option<usize>,
|
||||
range: impl RangeBounds<usize>,
|
||||
) -> Result<(), glib::BoolError> {
|
||||
let size_real = size.unwrap_or(usize::MAX);
|
||||
let (offset, size) = self.byte_range_into_offset_len(range)?;
|
||||
|
||||
unsafe {
|
||||
glib::result_from_gboolean!(
|
||||
ffi::gst_buffer_copy_into(
|
||||
|
@ -334,7 +367,7 @@ impl BufferRef {
|
|||
self.as_mut_ptr(),
|
||||
flags.into_glib(),
|
||||
offset,
|
||||
size_real,
|
||||
size,
|
||||
),
|
||||
"Failed to copy into destination buffer",
|
||||
)
|
||||
|
@ -623,7 +656,9 @@ impl BufferRef {
|
|||
}
|
||||
|
||||
#[doc(alias = "gst_buffer_find_memory")]
|
||||
pub fn find_memory(&self, offset: usize, size: Option<usize>) -> Option<(u32, u32, usize)> {
|
||||
pub fn find_memory(&self, range: impl RangeBounds<usize>) -> Option<(Range<u32>, usize)> {
|
||||
let (offset, size) = self.byte_range_into_offset_len(range).ok()?;
|
||||
|
||||
unsafe {
|
||||
let mut idx = mem::MaybeUninit::uninit();
|
||||
let mut length = mem::MaybeUninit::uninit();
|
||||
|
@ -632,14 +667,17 @@ impl BufferRef {
|
|||
let res = from_glib(ffi::gst_buffer_find_memory(
|
||||
self.as_mut_ptr(),
|
||||
offset,
|
||||
size.unwrap_or(usize::MAX),
|
||||
size,
|
||||
idx.as_mut_ptr(),
|
||||
length.as_mut_ptr(),
|
||||
skip.as_mut_ptr(),
|
||||
));
|
||||
|
||||
if res {
|
||||
Some((idx.assume_init(), length.assume_init(), skip.assume_init()))
|
||||
let idx = idx.assume_init();
|
||||
let length = length.assume_init();
|
||||
let skip = skip.assume_init();
|
||||
Some((idx..(idx + length), skip))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -684,17 +722,11 @@ impl BufferRef {
|
|||
|
||||
#[doc(alias = "get_memory_range")]
|
||||
#[doc(alias = "gst_buffer_get_memory_range")]
|
||||
pub fn memory_range(&self, idx: u32, length: Option<u32>) -> Option<Memory> {
|
||||
assert!(idx + length.unwrap_or(0) < self.n_memory());
|
||||
pub fn memory_range(&self, range: impl RangeBounds<u32>) -> Option<Memory> {
|
||||
let (idx, len) = self.memory_range_into_idx_len(range).ok()?;
|
||||
|
||||
unsafe {
|
||||
let res = ffi::gst_buffer_get_memory_range(
|
||||
self.as_mut_ptr(),
|
||||
idx,
|
||||
match length {
|
||||
Some(val) => val as i32,
|
||||
None => -1,
|
||||
},
|
||||
);
|
||||
let res = ffi::gst_buffer_get_memory_range(self.as_mut_ptr(), idx, len);
|
||||
if res.is_null() {
|
||||
None
|
||||
} else {
|
||||
|
@ -704,17 +736,9 @@ impl BufferRef {
|
|||
}
|
||||
|
||||
#[doc(alias = "gst_buffer_insert_memory")]
|
||||
pub fn insert_memory(&mut self, idx: Option<u32>, mem: Memory) {
|
||||
unsafe {
|
||||
ffi::gst_buffer_insert_memory(
|
||||
self.as_mut_ptr(),
|
||||
match idx {
|
||||
Some(val) => val as i32,
|
||||
None => -1,
|
||||
},
|
||||
mem.into_glib_ptr(),
|
||||
)
|
||||
}
|
||||
pub fn insert_memory(&mut self, idx: u32, mem: Memory) {
|
||||
assert!(idx <= self.n_memory());
|
||||
unsafe { ffi::gst_buffer_insert_memory(self.as_mut_ptr(), idx as i32, mem.into_glib_ptr()) }
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_buffer_is_all_memory_writable")]
|
||||
|
@ -723,15 +747,16 @@ impl BufferRef {
|
|||
}
|
||||
|
||||
#[doc(alias = "gst_buffer_is_memory_range_writable")]
|
||||
pub fn is_memory_range_writable(&self, idx: u32, length: Option<u16>) -> bool {
|
||||
pub fn is_memory_range_writable(&self, range: impl RangeBounds<u32>) -> bool {
|
||||
let Some((idx, len)) = self.memory_range_into_idx_len(range).ok() else {
|
||||
return false;
|
||||
};
|
||||
|
||||
unsafe {
|
||||
from_glib(ffi::gst_buffer_is_memory_range_writable(
|
||||
self.as_mut_ptr(),
|
||||
idx,
|
||||
match length {
|
||||
Some(val) => val as i32,
|
||||
None => -1,
|
||||
},
|
||||
len,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
@ -780,18 +805,12 @@ impl BufferRef {
|
|||
}
|
||||
|
||||
#[doc(alias = "gst_buffer_remove_memory_range")]
|
||||
pub fn remove_memory_range(&mut self, idx: u32, length: Option<u32>) {
|
||||
assert!(idx + length.unwrap_or(0) < self.n_memory());
|
||||
unsafe {
|
||||
ffi::gst_buffer_remove_memory_range(
|
||||
self.as_mut_ptr(),
|
||||
idx,
|
||||
match length {
|
||||
Some(val) => val as i32,
|
||||
None => -1,
|
||||
},
|
||||
)
|
||||
}
|
||||
pub fn remove_memory_range(&mut self, range: impl RangeBounds<u32>) {
|
||||
let (idx, len) = self
|
||||
.memory_range_into_idx_len(range)
|
||||
.expect("Invalid memory range");
|
||||
|
||||
unsafe { ffi::gst_buffer_remove_memory_range(self.as_mut_ptr(), idx, len) }
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_buffer_replace_all_memory")]
|
||||
|
@ -806,18 +825,13 @@ impl BufferRef {
|
|||
}
|
||||
|
||||
#[doc(alias = "gst_buffer_replace_memory_range")]
|
||||
pub fn replace_memory_range(&mut self, idx: u32, length: Option<u32>, mem: Memory) {
|
||||
assert!(idx + length.unwrap_or(0) < self.n_memory());
|
||||
pub fn replace_memory_range(&mut self, range: impl RangeBounds<u32>, mem: Memory) {
|
||||
let (idx, len) = self
|
||||
.memory_range_into_idx_len(range)
|
||||
.expect("Invalid memory range");
|
||||
|
||||
unsafe {
|
||||
ffi::gst_buffer_replace_memory_range(
|
||||
self.as_mut_ptr(),
|
||||
idx,
|
||||
match length {
|
||||
Some(val) => val as i32,
|
||||
None => -1,
|
||||
},
|
||||
mem.into_glib_ptr(),
|
||||
)
|
||||
ffi::gst_buffer_replace_memory_range(self.as_mut_ptr(), idx, len, mem.into_glib_ptr())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1528,14 +1542,14 @@ impl<'a> Dump<'a> {
|
|||
}
|
||||
|
||||
// This can't really fail because of the above
|
||||
let (idx, _, skip) = self
|
||||
let (memory_range, skip) = self
|
||||
.buffer
|
||||
.find_memory(start_idx, None)
|
||||
.find_memory(start_idx..)
|
||||
.expect("can't find memory");
|
||||
|
||||
let chunks = BufferChunked16Iter {
|
||||
buffer: self.buffer,
|
||||
mem_idx: idx,
|
||||
mem_idx: memory_range.start,
|
||||
mem_len: n_memory,
|
||||
map: None,
|
||||
map_offset: skip,
|
||||
|
|
|
@ -69,18 +69,18 @@ macro_rules! define_seek_impl(
|
|||
|
||||
// Work around lifetime annotation issues with closures
|
||||
let buffer_ref: fn(&Self) -> &BufferRef = $get_buffer_ref;
|
||||
let (idx, _, skip) = buffer_ref(self)
|
||||
.find_memory(self.cur_offset as usize, None)
|
||||
let (range, skip) = buffer_ref(self)
|
||||
.find_memory(self.cur_offset as usize..)
|
||||
.expect("Failed to find memory");
|
||||
|
||||
if idx != self.cur_mem_idx && !self.map_info.memory.is_null() {
|
||||
if range.start != self.cur_mem_idx && !self.map_info.memory.is_null() {
|
||||
unsafe {
|
||||
ffi::gst_memory_unmap(self.map_info.memory, &mut self.map_info);
|
||||
self.map_info.memory = ptr::null_mut();
|
||||
}
|
||||
}
|
||||
|
||||
self.cur_mem_idx = idx;
|
||||
self.cur_mem_idx = range.start;
|
||||
self.cur_mem_offset = skip;
|
||||
|
||||
Ok(self.cur_offset)
|
||||
|
|
|
@ -3,7 +3,11 @@
|
|||
#[cfg(feature = "v1_20")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
|
||||
use std::ptr;
|
||||
use std::{fmt, marker::PhantomData, ops};
|
||||
use std::{
|
||||
fmt,
|
||||
marker::PhantomData,
|
||||
ops::{self, RangeBounds},
|
||||
};
|
||||
|
||||
use glib::translate::*;
|
||||
|
||||
|
@ -228,8 +232,7 @@ impl<'a, T> MetaRef<'a, T> {
|
|||
&self,
|
||||
buffer: &mut BufferRef,
|
||||
region: bool,
|
||||
offset: usize,
|
||||
size: Option<usize>,
|
||||
range: impl RangeBounds<usize>,
|
||||
) -> Result<(), glib::BoolError>
|
||||
where
|
||||
T: MetaAPI,
|
||||
|
@ -238,6 +241,8 @@ impl<'a, T> MetaRef<'a, T> {
|
|||
|
||||
static TRANSFORM_COPY: Lazy<glib::Quark> = Lazy::new(|| glib::Quark::from_str("gst-copy"));
|
||||
|
||||
let (offset, size) = self.buffer.byte_range_into_offset_len(range)?;
|
||||
|
||||
unsafe {
|
||||
let info = *(*self.upcast_ref().as_ptr()).info;
|
||||
let Some(transform_func) = info.transform_func else {
|
||||
|
@ -249,7 +254,7 @@ impl<'a, T> MetaRef<'a, T> {
|
|||
let mut copy_data = ffi::GstMetaTransformCopy {
|
||||
region: region.into_glib(),
|
||||
offset,
|
||||
size: size.unwrap_or(usize::MAX),
|
||||
size,
|
||||
};
|
||||
|
||||
glib::result_from_gboolean!(
|
||||
|
@ -361,13 +366,12 @@ impl<'a, T, U> MetaRefMut<'a, T, U> {
|
|||
&self,
|
||||
buffer: &mut BufferRef,
|
||||
region: bool,
|
||||
offset: usize,
|
||||
size: Option<usize>,
|
||||
range: impl RangeBounds<usize>,
|
||||
) -> Result<(), glib::BoolError>
|
||||
where
|
||||
T: MetaAPI,
|
||||
{
|
||||
self.as_meta_ref().copy(buffer, region, offset, size)
|
||||
self.as_meta_ref().copy(buffer, region, range)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -947,7 +951,7 @@ mod tests {
|
|||
{
|
||||
let meta = buffer.meta::<ReferenceTimestampMeta>().unwrap();
|
||||
let buffer_dest = buffer_dest.get_mut().unwrap();
|
||||
meta.copy(buffer_dest, false, 0, None).unwrap();
|
||||
meta.copy(buffer_dest, false, ..).unwrap();
|
||||
}
|
||||
|
||||
let meta = buffer_dest.meta::<ReferenceTimestampMeta>().unwrap();
|
||||
|
|
|
@ -1299,7 +1299,7 @@ where
|
|||
passed_buffer.set_size(copied_size);
|
||||
}
|
||||
|
||||
match new_buffer.copy_into(passed_buffer, crate::BUFFER_COPY_METADATA, 0, None) {
|
||||
match new_buffer.copy_into(passed_buffer, crate::BUFFER_COPY_METADATA, ..) {
|
||||
Ok(_) => FlowReturn::Ok.into_glib(),
|
||||
Err(_) => {
|
||||
crate::error!(
|
||||
|
|
Loading…
Reference in a new issue