Add API for mapping GL buffers as VideoFrameRef in addition to a full VideoFrame

This commit is contained in:
Sebastian Dröge 2018-12-08 11:45:23 +02:00 committed by Sebastian Dröge
parent 36bcb5630a
commit 43f5a10f9c
2 changed files with 80 additions and 0 deletions

View file

@ -26,10 +26,35 @@ pub trait VideoFrameGLExt {
info: &VideoInfo, info: &VideoInfo,
) -> Result<VideoFrame<Readable>, gst::Buffer>; ) -> 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>; fn get_texture_id(&self, idx: u32) -> Option<u32>;
} }
impl VideoFrameGLExt for VideoFrame<Readable> { 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( fn from_buffer_readable_gl(
buffer: gst::Buffer, buffer: gst::Buffer,
info: &VideoInfo, 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> { fn get_texture_id(&self, idx: u32) -> Option<u32> {
let len = buffer_n_gl_memory(self.buffer())?; let len = buffer_n_gl_memory(self.buffer())?;

View file

@ -345,6 +345,15 @@ impl<'a> VideoFrameRef<&'a gst::BufferRef> {
&self.0 &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>( pub fn from_buffer_ref_readable<'b>(
buffer: &'a gst::BufferRef, buffer: &'a gst::BufferRef,
info: &'b ::VideoInfo, info: &'b ::VideoInfo,
@ -523,6 +532,15 @@ impl<'a> VideoFrameRef<&'a gst::BufferRef> {
} }
impl<'a> VideoFrameRef<&'a mut 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>( pub fn from_buffer_ref_writable<'b>(
buffer: &'a mut gst::BufferRef, buffer: &'a mut gst::BufferRef,
info: &'b ::VideoInfo, info: &'b ::VideoInfo,