mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2025-09-02 09:43:48 +00:00
video/gtk4: Copy non-contiguous sysmem buffers
As the texture builder only supports contiguous buffers. This follows the gtkgstsink implementation. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/2271>
This commit is contained in:
parent
d2308a964e
commit
7b561354eb
2 changed files with 45 additions and 11 deletions
|
@ -9,9 +9,10 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use gst_video::prelude::*;
|
use crate::sink::imp::PaintableSink;
|
||||||
|
use crate::sink::imp::CAT;
|
||||||
use gst_gl::prelude::*;
|
use gst_gl::prelude::*;
|
||||||
|
use gst_video::subclass::prelude::*;
|
||||||
use gtk::{gdk, glib};
|
use gtk::{gdk, glib};
|
||||||
use std::{
|
use std::{
|
||||||
collections::{HashMap, HashSet},
|
collections::{HashMap, HashSet},
|
||||||
|
@ -692,6 +693,7 @@ impl Frame {
|
||||||
|
|
||||||
impl Frame {
|
impl Frame {
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
|
dbg_obj: &PaintableSink,
|
||||||
buffer: &gst::Buffer,
|
buffer: &gst::Buffer,
|
||||||
info: &VideoInfo,
|
info: &VideoInfo,
|
||||||
orientation: Orientation,
|
orientation: Orientation,
|
||||||
|
@ -809,11 +811,44 @@ impl Frame {
|
||||||
let mut frame = Self {
|
let mut frame = Self {
|
||||||
frame: match frame {
|
frame: match frame {
|
||||||
Some(frame) => frame,
|
Some(frame) => frame,
|
||||||
None => MappedFrame::SysMem {
|
None => {
|
||||||
frame: gst_video::VideoFrame::from_buffer_readable(buffer.clone(), info)
|
let readable_frame = match buffer.n_memory() {
|
||||||
.map_err(|_| gst::FlowError::Error)?,
|
1 => buffer.clone(),
|
||||||
orientation,
|
_ => {
|
||||||
},
|
gst::debug!(CAT, imp = dbg_obj, "Buffer is not contiguous, copying");
|
||||||
|
|
||||||
|
let mut copy_buffer = gst::Buffer::with_size(info.size()).unwrap();
|
||||||
|
|
||||||
|
{
|
||||||
|
let copy_buffer = copy_buffer.get_mut().unwrap();
|
||||||
|
|
||||||
|
buffer
|
||||||
|
.copy_into(copy_buffer, gst::BUFFER_COPY_METADATA, 0..0)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let frame = gst_video::VideoFrameRef::from_buffer_ref_readable(
|
||||||
|
buffer, info,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
let mut copy_frame =
|
||||||
|
gst_video::VideoFrameRef::from_buffer_ref_writable(
|
||||||
|
copy_buffer,
|
||||||
|
info,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
frame.copy(&mut copy_frame).unwrap();
|
||||||
|
}
|
||||||
|
copy_buffer
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
MappedFrame::SysMem {
|
||||||
|
frame: gst_video::VideoFrame::from_buffer_readable(readable_frame, info)
|
||||||
|
.map_err(|_| gst::FlowError::Error)?,
|
||||||
|
orientation,
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
overlays: vec![],
|
overlays: vec![],
|
||||||
};
|
};
|
||||||
|
|
|
@ -719,11 +719,10 @@ impl VideoSinkImpl for PaintableSink {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let frame = Frame::new(buffer, info, orientation, wrapped_context.as_ref()).inspect_err(
|
let frame = Frame::new(self, buffer, info, orientation, wrapped_context.as_ref())
|
||||||
|_err| {
|
.inspect_err(|_err| {
|
||||||
gst::error!(CAT, imp = self, "Failed to map video frame");
|
gst::error!(CAT, imp = self, "Failed to map video frame");
|
||||||
},
|
})?;
|
||||||
)?;
|
|
||||||
self.pending_frame.lock().unwrap().replace(frame);
|
self.pending_frame.lock().unwrap().replace(frame);
|
||||||
|
|
||||||
let sender = self.sender.lock().unwrap();
|
let sender = self.sender.lock().unwrap();
|
||||||
|
|
Loading…
Reference in a new issue