mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-11-22 03:21:00 +00:00
Update for VideoFrame
/ GLVideoFrame
API changes
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1345>
This commit is contained in:
parent
95581d7fbc
commit
450ffbe452
8 changed files with 85 additions and 36 deletions
|
@ -9,6 +9,8 @@ use std::ptr;
|
|||
|
||||
use byte_slice_cast::*;
|
||||
|
||||
use gst_video::prelude::*;
|
||||
|
||||
pub fn load() -> Result<(), glib::BoolError> {
|
||||
ndisys::load()
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ use gst::glib;
|
|||
use gst::prelude::*;
|
||||
use gst::subclass::prelude::*;
|
||||
use gst_base::subclass::prelude::*;
|
||||
use gst_video::prelude::*;
|
||||
use gst_video::subclass::prelude::*;
|
||||
|
||||
use std::sync::Mutex;
|
||||
|
|
|
@ -17,11 +17,53 @@ use gtk::{gdk, glib};
|
|||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct Frame {
|
||||
frame: gst_video::VideoFrame<gst_video::video_frame::Readable>,
|
||||
overlays: Vec<Overlay>,
|
||||
enum MappedFrame {
|
||||
SysMem(gst_video::VideoFrame<gst_video::video_frame::Readable>),
|
||||
#[cfg(any(target_os = "macos", target_os = "windows", feature = "gst_gl"))]
|
||||
wrapped_context: Option<gst_gl::GLContext>,
|
||||
GL {
|
||||
frame: gst_gl::GLVideoFrame<gst_gl::gl_video_frame::Readable>,
|
||||
wrapped_context: gst_gl::GLContext,
|
||||
},
|
||||
}
|
||||
|
||||
impl MappedFrame {
|
||||
fn buffer(&self) -> &gst::BufferRef {
|
||||
match self {
|
||||
MappedFrame::SysMem(frame) => frame.buffer(),
|
||||
#[cfg(any(target_os = "macos", target_os = "windows", feature = "gst_gl"))]
|
||||
MappedFrame::GL { frame, .. } => frame.buffer(),
|
||||
}
|
||||
}
|
||||
|
||||
fn width(&self) -> u32 {
|
||||
match self {
|
||||
MappedFrame::SysMem(frame) => frame.width(),
|
||||
#[cfg(any(target_os = "macos", target_os = "windows", feature = "gst_gl"))]
|
||||
MappedFrame::GL { frame, .. } => frame.width(),
|
||||
}
|
||||
}
|
||||
|
||||
fn height(&self) -> u32 {
|
||||
match self {
|
||||
MappedFrame::SysMem(frame) => frame.height(),
|
||||
#[cfg(any(target_os = "macos", target_os = "windows", feature = "gst_gl"))]
|
||||
MappedFrame::GL { frame, .. } => frame.height(),
|
||||
}
|
||||
}
|
||||
|
||||
fn format_info(&self) -> gst_video::VideoFormatInfo {
|
||||
match self {
|
||||
MappedFrame::SysMem(frame) => frame.format_info(),
|
||||
#[cfg(any(target_os = "macos", target_os = "windows", feature = "gst_gl"))]
|
||||
MappedFrame::GL { frame, .. } => frame.format_info(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct Frame {
|
||||
frame: MappedFrame,
|
||||
overlays: Vec<Overlay>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -97,7 +139,7 @@ fn video_frame_to_memory_texture(
|
|||
|
||||
#[cfg(any(target_os = "macos", target_os = "windows", feature = "gst_gl"))]
|
||||
fn video_frame_to_gl_texture(
|
||||
frame: gst_video::VideoFrame<gst_video::video_frame::Readable>,
|
||||
frame: gst_gl::GLVideoFrame<gst_gl::gl_video_frame::Readable>,
|
||||
cached_textures: &mut HashMap<usize, gdk::Texture>,
|
||||
used_textures: &mut HashSet<usize>,
|
||||
gdk_context: &gdk::GLContext,
|
||||
|
@ -151,30 +193,28 @@ impl Frame {
|
|||
let width = self.frame.width();
|
||||
let height = self.frame.height();
|
||||
let has_alpha = self.frame.format_info().has_alpha();
|
||||
let (texture, pixel_aspect_ratio) = {
|
||||
#[cfg(not(any(target_os = "macos", target_os = "windows", feature = "gst_gl")))]
|
||||
{
|
||||
video_frame_to_memory_texture(self.frame, cached_textures, &mut used_textures)
|
||||
let (texture, pixel_aspect_ratio) = match self.frame {
|
||||
MappedFrame::SysMem(frame) => {
|
||||
video_frame_to_memory_texture(frame, cached_textures, &mut used_textures)
|
||||
}
|
||||
#[cfg(any(target_os = "macos", target_os = "windows", feature = "gst_gl"))]
|
||||
{
|
||||
if let (Some(gdk_ctx), Some(wrapped_ctx)) =
|
||||
(gdk_context, self.wrapped_context.as_ref())
|
||||
{
|
||||
video_frame_to_gl_texture(
|
||||
self.frame,
|
||||
cached_textures,
|
||||
&mut used_textures,
|
||||
gdk_ctx,
|
||||
wrapped_ctx,
|
||||
)
|
||||
} else {
|
||||
MappedFrame::GL {
|
||||
frame,
|
||||
wrapped_context,
|
||||
} => {
|
||||
let Some(gdk_context) = gdk_context else {
|
||||
// This will fail badly if the video frame was actually mapped as GL texture
|
||||
// but this case can't really happen as we only do that if we actually have a
|
||||
// GDK GL context.
|
||||
assert!(self.wrapped_context.is_none());
|
||||
video_frame_to_memory_texture(self.frame, cached_textures, &mut used_textures)
|
||||
}
|
||||
unreachable!();
|
||||
};
|
||||
video_frame_to_gl_texture(
|
||||
frame,
|
||||
cached_textures,
|
||||
&mut used_textures,
|
||||
gdk_context,
|
||||
&wrapped_context,
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -230,8 +270,10 @@ impl Frame {
|
|||
#[cfg(not(any(target_os = "macos", target_os = "windows", feature = "gst_gl")))]
|
||||
{
|
||||
frame = Self {
|
||||
frame: gst_video::VideoFrame::from_buffer_readable(buffer.clone(), info)
|
||||
.map_err(|_| gst::FlowError::Error)?,
|
||||
frame: MappedFrame::SysMem(
|
||||
gst_video::VideoFrame::from_buffer_readable(buffer.clone(), info)
|
||||
.map_err(|_| gst::FlowError::Error)?,
|
||||
),
|
||||
overlays: vec![],
|
||||
};
|
||||
}
|
||||
|
@ -259,7 +301,7 @@ impl Frame {
|
|||
// If there is no GLSyncMeta yet then we need to add one here now, which requires
|
||||
// obtaining a writable buffer.
|
||||
let mapped_frame = if buffer.meta::<gst_gl::GLSyncMeta>().is_some() {
|
||||
gst_video::VideoFrame::from_buffer_readable_gl(buffer.clone(), info)
|
||||
gst_gl::GLVideoFrame::from_buffer_readable(buffer.clone(), info)
|
||||
.map_err(|_| gst::FlowError::Error)?
|
||||
} else {
|
||||
let mut buffer = buffer.clone();
|
||||
|
@ -267,7 +309,7 @@ impl Frame {
|
|||
let buffer = buffer.make_mut();
|
||||
gst_gl::GLSyncMeta::add(buffer, memory_ctx);
|
||||
}
|
||||
gst_video::VideoFrame::from_buffer_readable_gl(buffer, info)
|
||||
gst_gl::GLVideoFrame::from_buffer_readable(buffer, info)
|
||||
.map_err(|_| gst::FlowError::Error)?
|
||||
};
|
||||
|
||||
|
@ -278,16 +320,19 @@ impl Frame {
|
|||
meta.set_sync_point(memory_ctx);
|
||||
|
||||
frame = Self {
|
||||
frame: mapped_frame,
|
||||
frame: MappedFrame::GL {
|
||||
frame: mapped_frame,
|
||||
wrapped_context: wrapped_context.unwrap().clone(),
|
||||
},
|
||||
overlays: vec![],
|
||||
wrapped_context: Some(wrapped_context.unwrap().clone()),
|
||||
};
|
||||
} else {
|
||||
frame = Self {
|
||||
frame: gst_video::VideoFrame::from_buffer_readable(buffer.clone(), info)
|
||||
.map_err(|_| gst::FlowError::Error)?,
|
||||
frame: MappedFrame::SysMem(
|
||||
gst_video::VideoFrame::from_buffer_readable(buffer.clone(), info)
|
||||
.map_err(|_| gst::FlowError::Error)?,
|
||||
),
|
||||
overlays: vec![],
|
||||
wrapped_context: None,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ use crate::sink::frame::Frame;
|
|||
use crate::sink::paintable::Paintable;
|
||||
|
||||
use glib::{thread_guard::ThreadGuard, Sender};
|
||||
use gtk::prelude::GLContextExt;
|
||||
use gtk::prelude::*;
|
||||
use gtk::{gdk, glib};
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ use gst::prelude::*;
|
|||
use gst::subclass::prelude::*;
|
||||
|
||||
use gst_base::subclass::prelude::*;
|
||||
use gst_video::prelude::*;
|
||||
use gst_video::subclass::prelude::*;
|
||||
|
||||
use std::sync::Mutex;
|
||||
|
|
|
@ -12,6 +12,7 @@ use gst::glib;
|
|||
use gst::prelude::*;
|
||||
use gst::subclass::prelude::*;
|
||||
use gst_base::subclass::prelude::*;
|
||||
use gst_video::prelude::*;
|
||||
use gst_video::subclass::prelude::*;
|
||||
|
||||
use std::sync::Mutex;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
use crate::HashAlgorithm;
|
||||
#[cfg(feature = "dssim")]
|
||||
use dssim_core::{Dssim, DssimImage};
|
||||
use gst_video::VideoFormat;
|
||||
use gst_video::{prelude::*, VideoFormat};
|
||||
use image_hasher::{HashAlg, Hasher, HasherConfig, ImageHash};
|
||||
#[cfg(feature = "dssim")]
|
||||
use rgb::FromSlice;
|
||||
|
|
|
@ -14,7 +14,7 @@ use gst::subclass::prelude::*;
|
|||
use gst::{glib, glib::prelude::*, prelude::*};
|
||||
use gst_base::prelude::*;
|
||||
use gst_base::AggregatorPad;
|
||||
use gst_video::prelude::VideoAggregatorPadExtManual;
|
||||
use gst_video::prelude::*;
|
||||
use gst_video::subclass::prelude::*;
|
||||
use gst_video::subclass::AggregateFramesToken;
|
||||
use gst_video::VideoFormat;
|
||||
|
|
Loading…
Reference in a new issue