forked from mirrors/gstreamer-rs
Add API for mapping GL buffers as VideoFrameRef in addition to a full VideoFrame
This commit is contained in:
parent
36bcb5630a
commit
43f5a10f9c
2 changed files with 80 additions and 0 deletions
|
@ -26,10 +26,35 @@ pub trait VideoFrameGLExt {
|
|||
info: &VideoInfo,
|
||||
) -> Result<VideoFrame<Readable>, gst::Buffer>;
|
||||
|
||||
fn from_buffer_ref_readable_gl<'a, 'b>(
|
||||
buffer: &'a gst::BufferRef,
|
||||
info: &'b VideoInfo,
|
||||
) -> Option<VideoFrameRef<&'a gst::BufferRef>>;
|
||||
|
||||
fn get_texture_id(&self, idx: u32) -> Option<u32>;
|
||||
}
|
||||
|
||||
impl VideoFrameGLExt for VideoFrame<Readable> {
|
||||
fn from_buffer_readable_gl(
|
||||
buffer: gst::Buffer,
|
||||
info: &VideoInfo,
|
||||
) -> Result<VideoFrame<Readable>, gst::Buffer> {
|
||||
VideoFrameRef::<&gst::BufferRef>::from_buffer_readable_gl(buffer, info)
|
||||
}
|
||||
|
||||
fn from_buffer_ref_readable_gl<'a, 'b>(
|
||||
buffer: &'a gst::BufferRef,
|
||||
info: &'b VideoInfo,
|
||||
) -> Option<VideoFrameRef<&'a gst::BufferRef>> {
|
||||
VideoFrameRef::<&gst::BufferRef>::from_buffer_ref_readable_gl(buffer, info)
|
||||
}
|
||||
|
||||
fn get_texture_id(&self, idx: u32) -> Option<u32> {
|
||||
self.as_video_frame_ref().get_texture_id(idx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> VideoFrameGLExt for VideoFrameRef<&'a gst::BufferRef> {
|
||||
fn from_buffer_readable_gl(
|
||||
buffer: gst::Buffer,
|
||||
info: &VideoInfo,
|
||||
|
@ -67,6 +92,43 @@ impl VideoFrameGLExt for VideoFrame<Readable> {
|
|||
}
|
||||
}
|
||||
|
||||
fn from_buffer_ref_readable_gl<'b, 'c>(
|
||||
buffer: &'b gst::BufferRef,
|
||||
info: &'c VideoInfo,
|
||||
) -> Option<VideoFrameRef<&'b gst::BufferRef>> {
|
||||
skip_assert_initialized!();
|
||||
|
||||
let n_mem = match buffer_n_gl_memory(buffer) {
|
||||
Some(n) => n,
|
||||
None => return None,
|
||||
};
|
||||
|
||||
// FIXME: planes are not memories, in multiview use case,
|
||||
// number of memories = planes * views, but the raw memory is
|
||||
// not exposed in videoframe
|
||||
if n_mem != info.n_planes() {
|
||||
return None;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let mut frame = mem::zeroed();
|
||||
let res: bool = from_glib(gst_video_ffi::gst_video_frame_map(
|
||||
&mut frame,
|
||||
info.to_glib_none().0 as *mut _,
|
||||
buffer.as_mut_ptr(),
|
||||
gst_video_ffi::GST_VIDEO_FRAME_MAP_FLAG_NO_REF
|
||||
| gst_ffi::GST_MAP_READ
|
||||
| ffi::GST_MAP_GL as u32,
|
||||
));
|
||||
|
||||
if !res {
|
||||
None
|
||||
} else {
|
||||
Some(VideoFrameRef::from_glib_borrow(&frame))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_texture_id(&self, idx: u32) -> Option<u32> {
|
||||
let len = buffer_n_gl_memory(self.buffer())?;
|
||||
|
||||
|
|
|
@ -345,6 +345,15 @@ impl<'a> VideoFrameRef<&'a gst::BufferRef> {
|
|||
&self.0
|
||||
}
|
||||
|
||||
pub unsafe fn from_glib_borrow(frame: *const ffi::GstVideoFrame) -> Self {
|
||||
assert!(!frame.is_null());
|
||||
|
||||
let frame = ptr::read(frame);
|
||||
let info = ::VideoInfo(ptr::read(&frame.info));
|
||||
let buffer = gst::BufferRef::from_ptr(frame.buffer);
|
||||
VideoFrameRef(frame, Some(buffer), info, false)
|
||||
}
|
||||
|
||||
pub fn from_buffer_ref_readable<'b>(
|
||||
buffer: &'a gst::BufferRef,
|
||||
info: &'b ::VideoInfo,
|
||||
|
@ -523,6 +532,15 @@ impl<'a> VideoFrameRef<&'a gst::BufferRef> {
|
|||
}
|
||||
|
||||
impl<'a> VideoFrameRef<&'a mut gst::BufferRef> {
|
||||
pub unsafe fn from_glib_borrow_mut(frame: *mut ffi::GstVideoFrame) -> Self {
|
||||
assert!(!frame.is_null());
|
||||
|
||||
let frame = ptr::read(frame);
|
||||
let info = ::VideoInfo(ptr::read(&frame.info));
|
||||
let buffer = gst::BufferRef::from_mut_ptr(frame.buffer);
|
||||
VideoFrameRef(frame, Some(buffer), info, false)
|
||||
}
|
||||
|
||||
pub fn from_buffer_ref_writable<'b>(
|
||||
buffer: &'a mut gst::BufferRef,
|
||||
info: &'b ::VideoInfo,
|
||||
|
|
Loading…
Reference in a new issue