video: Don't panic when passing an invalid video info to VideoMeta::add()

Instead return an error that can be handled by the caller.

Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/issues/259
This commit is contained in:
Sebastian Dröge 2020-06-07 18:15:40 +03:00
parent 926ed2f53d
commit 30d51f0ca6
2 changed files with 51 additions and 12 deletions

View file

@ -169,7 +169,7 @@ fn create_pipeline() -> Result<gst::Pipeline, Error> {
gst_video::VideoFormat::Bgra,
frame_width as u32,
frame_height as u32,
);
).unwrap();
let buffer = buffer.into_mapped_buffer_writable().unwrap();
let buffer = {

View file

@ -29,11 +29,26 @@ impl VideoMeta {
format: ::VideoFormat,
width: u32,
height: u32,
) -> gst::MetaRefMut<Self, gst::meta::Standalone> {
) -> Result<gst::MetaRefMut<Self, gst::meta::Standalone>, glib::BoolError> {
skip_assert_initialized!();
let info = ::VideoInfo::new(format, width, height).build().unwrap();
assert!(buffer.get_size() >= info.size());
if format == ::VideoFormat::Unknown || format == ::VideoFormat::Encoded {
return Err(glib_bool_error!("Unsupported video format {}", format));
}
let info = ::VideoInfo::new(format, width, height).build()?;
if !info.is_valid() {
return Err(glib_bool_error!("Invalid video info"));
}
if buffer.get_size() < info.size() {
return Err(glib_bool_error!(
"Buffer smaller than required frame size ({} < {})",
buffer.get_size(),
info.size()
));
}
unsafe {
let meta = gst_video_sys::gst_buffer_add_video_meta(
@ -44,7 +59,11 @@ impl VideoMeta {
height,
);
Self::from_mut_ptr(buffer, meta)
if meta.is_null() {
return Err(glib_bool_error!("Failed to add video meta"));
}
Ok(Self::from_mut_ptr(buffer, meta))
}
}
@ -56,16 +75,30 @@ impl VideoMeta {
height: u32,
offset: &[usize],
stride: &[i32],
) -> gst::MetaRefMut<'a, Self, gst::meta::Standalone> {
) -> Result<gst::MetaRefMut<'a, Self, gst::meta::Standalone>, glib::BoolError> {
skip_assert_initialized!();
if format == ::VideoFormat::Unknown || format == ::VideoFormat::Encoded {
return Err(glib_bool_error!("Unsupported video format {}", format));
}
let n_planes = offset.len() as u32;
let info = ::VideoInfo::new(format, width, height)
.offset(offset)
.stride(stride)
.build()
.expect("Unable to build VideoInfo for given format, offsets and strides");
assert!(buffer.get_size() >= info.size());
.build()?;
if !info.is_valid() {
return Err(glib_bool_error!("Invalid video info"));
}
if buffer.get_size() < info.size() {
return Err(glib_bool_error!(
"Buffer smaller than required frame size ({} < {})",
buffer.get_size(),
info.size()
));
}
unsafe {
let meta = gst_video_sys::gst_buffer_add_video_meta_full(
@ -79,7 +112,11 @@ impl VideoMeta {
stride.as_ptr() as *mut _,
);
Self::from_mut_ptr(buffer, meta)
if meta.is_null() {
return Err(glib_bool_error!("Failed to add video meta"));
}
Ok(Self::from_mut_ptr(buffer, meta))
}
}
@ -657,7 +694,8 @@ mod tests {
::VideoFormat::Argb,
320,
240,
);
)
.unwrap();
assert_eq!(meta.get_id(), 0);
assert_eq!(meta.get_flags(), ::VideoFrameFlags::NONE);
assert_eq!(meta.get_format(), ::VideoFormat::Argb);
@ -695,7 +733,8 @@ mod tests {
240,
&[0],
&[320 * 4],
);
)
.unwrap();
assert_eq!(meta.get_id(), 0);
assert_eq!(meta.get_flags(), ::VideoFrameFlags::NONE);
assert_eq!(meta.get_format(), ::VideoFormat::Argb);