mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-11-29 15:01:07 +00:00
hsv: Port detecter/filter to VideoFilter base class
This commit is contained in:
parent
76a33e8f47
commit
cecacf5430
3 changed files with 58 additions and 194 deletions
|
@ -13,7 +13,6 @@ gst-base = { package = "gstreamer-base", git = "https://gitlab.freedesktop.org/g
|
||||||
gst-video = { package = "gstreamer-video", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs" }
|
gst-video = { package = "gstreamer-video", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs" }
|
||||||
gst-audio = { package = "gstreamer-audio", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs" }
|
gst-audio = { package = "gstreamer-audio", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs" }
|
||||||
byte-slice-cast = "1.0"
|
byte-slice-cast = "1.0"
|
||||||
atomic_refcell = "0.1"
|
|
||||||
num-traits = "0.2"
|
num-traits = "0.2"
|
||||||
once_cell = "1.0"
|
once_cell = "1.0"
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,8 @@ use gst::subclass::prelude::*;
|
||||||
|
|
||||||
use gst::{gst_debug, gst_info};
|
use gst::{gst_debug, gst_info};
|
||||||
use gst_base::subclass::prelude::*;
|
use gst_base::subclass::prelude::*;
|
||||||
|
use gst_video::subclass::prelude::*;
|
||||||
|
|
||||||
use atomic_refcell::AtomicRefCell;
|
|
||||||
use std::i32;
|
use std::i32;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
|
@ -54,17 +54,10 @@ impl Default for Settings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stream-specific state, i.e. video format configuration
|
|
||||||
struct State {
|
|
||||||
in_info: gst_video::VideoInfo,
|
|
||||||
out_info: gst_video::VideoInfo,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Struct containing all the element data
|
// Struct containing all the element data
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct HsvDetector {
|
pub struct HsvDetector {
|
||||||
settings: Mutex<Settings>,
|
settings: Mutex<Settings>,
|
||||||
state: AtomicRefCell<Option<State>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
|
static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
|
||||||
|
@ -79,7 +72,7 @@ static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
|
||||||
impl ObjectSubclass for HsvDetector {
|
impl ObjectSubclass for HsvDetector {
|
||||||
const NAME: &'static str = "HsvDetector";
|
const NAME: &'static str = "HsvDetector";
|
||||||
type Type = super::HsvDetector;
|
type Type = super::HsvDetector;
|
||||||
type ParentType = gst_base::BaseTransform;
|
type ParentType = gst_video::VideoFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn video_input_formats() -> Vec<glib::SendValue> {
|
fn video_input_formats() -> Vec<glib::SendValue> {
|
||||||
|
@ -463,90 +456,22 @@ impl BaseTransformImpl for HsvDetector {
|
||||||
Some(other_caps)
|
Some(other_caps)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn unit_size(&self, _element: &Self::Type, caps: &gst::Caps) -> Option<usize> {
|
impl VideoFilterImpl for HsvDetector {
|
||||||
gst_video::VideoInfo::from_caps(caps)
|
fn transform_frame(
|
||||||
.map(|info| info.size())
|
|
||||||
.ok()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_caps(
|
|
||||||
&self,
|
&self,
|
||||||
element: &Self::Type,
|
_element: &Self::Type,
|
||||||
incaps: &gst::Caps,
|
in_frame: &gst_video::VideoFrameRef<&gst::BufferRef>,
|
||||||
outcaps: &gst::Caps,
|
out_frame: &mut gst_video::VideoFrameRef<&mut gst::BufferRef>,
|
||||||
) -> Result<(), gst::LoggableError> {
|
|
||||||
let in_info = match gst_video::VideoInfo::from_caps(incaps) {
|
|
||||||
Err(_) => return Err(gst::loggable_error!(CAT, "Failed to parse input caps")),
|
|
||||||
Ok(info) => info,
|
|
||||||
};
|
|
||||||
let out_info = match gst_video::VideoInfo::from_caps(outcaps) {
|
|
||||||
Err(_) => return Err(gst::loggable_error!(CAT, "Failed to parse output caps")),
|
|
||||||
Ok(info) => info,
|
|
||||||
};
|
|
||||||
|
|
||||||
gst_debug!(
|
|
||||||
CAT,
|
|
||||||
obj: element,
|
|
||||||
"Configured for caps {} to {}",
|
|
||||||
incaps,
|
|
||||||
outcaps
|
|
||||||
);
|
|
||||||
|
|
||||||
*self.state.borrow_mut() = Some(State { in_info, out_info });
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn stop(&self, element: &Self::Type) -> Result<(), gst::ErrorMessage> {
|
|
||||||
// Drop state
|
|
||||||
*self.state.borrow_mut() = None;
|
|
||||||
|
|
||||||
gst_info!(CAT, obj: element, "Stopped");
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn transform(
|
|
||||||
&self,
|
|
||||||
element: &Self::Type,
|
|
||||||
inbuf: &gst::Buffer,
|
|
||||||
outbuf: &mut gst::BufferRef,
|
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
let mut state_guard = self.state.borrow_mut();
|
match in_frame.format() {
|
||||||
let state = state_guard.as_mut().ok_or(gst::FlowError::NotNegotiated)?;
|
|
||||||
|
|
||||||
let in_frame =
|
|
||||||
gst_video::VideoFrameRef::from_buffer_ref_readable(inbuf.as_ref(), &state.in_info)
|
|
||||||
.map_err(|_| {
|
|
||||||
gst::element_error!(
|
|
||||||
element,
|
|
||||||
gst::CoreError::Failed,
|
|
||||||
["Failed to map input buffer readable"]
|
|
||||||
);
|
|
||||||
gst::FlowError::Error
|
|
||||||
})?;
|
|
||||||
|
|
||||||
// And now map the output buffer writable, so we can fill it.
|
|
||||||
let mut out_frame =
|
|
||||||
gst_video::VideoFrameRef::from_buffer_ref_writable(outbuf, &state.out_info).map_err(
|
|
||||||
|_| {
|
|
||||||
gst::element_error!(
|
|
||||||
element,
|
|
||||||
gst::CoreError::Failed,
|
|
||||||
["Failed to map output buffer writable"]
|
|
||||||
);
|
|
||||||
gst::FlowError::Error
|
|
||||||
},
|
|
||||||
)?;
|
|
||||||
|
|
||||||
match state.in_info.format() {
|
|
||||||
gst_video::VideoFormat::Rgbx | gst_video::VideoFormat::Rgb => {
|
gst_video::VideoFormat::Rgbx | gst_video::VideoFormat::Rgb => {
|
||||||
match state.out_info.format() {
|
match out_frame.format() {
|
||||||
gst_video::VideoFormat::Rgba => {
|
gst_video::VideoFormat::Rgba => {
|
||||||
self.hsv_detect(
|
self.hsv_detect(
|
||||||
&in_frame,
|
in_frame,
|
||||||
&mut out_frame,
|
out_frame,
|
||||||
|in_p| {
|
|in_p| {
|
||||||
hsvutils::from_rgb(
|
hsvutils::from_rgb(
|
||||||
in_p[..3].try_into().expect("slice with incorrect length"),
|
in_p[..3].try_into().expect("slice with incorrect length"),
|
||||||
|
@ -560,8 +485,8 @@ impl BaseTransformImpl for HsvDetector {
|
||||||
}
|
}
|
||||||
gst_video::VideoFormat::Argb => {
|
gst_video::VideoFormat::Argb => {
|
||||||
self.hsv_detect(
|
self.hsv_detect(
|
||||||
&in_frame,
|
in_frame,
|
||||||
&mut out_frame,
|
out_frame,
|
||||||
|in_p| {
|
|in_p| {
|
||||||
hsvutils::from_rgb(
|
hsvutils::from_rgb(
|
||||||
in_p[..3].try_into().expect("slice with incorrect length"),
|
in_p[..3].try_into().expect("slice with incorrect length"),
|
||||||
|
@ -575,8 +500,8 @@ impl BaseTransformImpl for HsvDetector {
|
||||||
}
|
}
|
||||||
gst_video::VideoFormat::Bgra => {
|
gst_video::VideoFormat::Bgra => {
|
||||||
self.hsv_detect(
|
self.hsv_detect(
|
||||||
&in_frame,
|
in_frame,
|
||||||
&mut out_frame,
|
out_frame,
|
||||||
|in_p| {
|
|in_p| {
|
||||||
hsvutils::from_rgb(
|
hsvutils::from_rgb(
|
||||||
in_p[..3].try_into().expect("slice with incorrect length"),
|
in_p[..3].try_into().expect("slice with incorrect length"),
|
||||||
|
@ -592,8 +517,8 @@ impl BaseTransformImpl for HsvDetector {
|
||||||
}
|
}
|
||||||
gst_video::VideoFormat::Abgr => {
|
gst_video::VideoFormat::Abgr => {
|
||||||
self.hsv_detect(
|
self.hsv_detect(
|
||||||
&in_frame,
|
in_frame,
|
||||||
&mut out_frame,
|
out_frame,
|
||||||
|in_p| {
|
|in_p| {
|
||||||
hsvutils::from_rgb(
|
hsvutils::from_rgb(
|
||||||
in_p[..3].try_into().expect("slice with incorrect length"),
|
in_p[..3].try_into().expect("slice with incorrect length"),
|
||||||
|
@ -611,11 +536,11 @@ impl BaseTransformImpl for HsvDetector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gst_video::VideoFormat::Xrgb => {
|
gst_video::VideoFormat::Xrgb => {
|
||||||
match state.out_info.format() {
|
match out_frame.format() {
|
||||||
gst_video::VideoFormat::Rgba => {
|
gst_video::VideoFormat::Rgba => {
|
||||||
self.hsv_detect(
|
self.hsv_detect(
|
||||||
&in_frame,
|
in_frame,
|
||||||
&mut out_frame,
|
out_frame,
|
||||||
|in_p| {
|
|in_p| {
|
||||||
hsvutils::from_rgb(
|
hsvutils::from_rgb(
|
||||||
in_p[1..4].try_into().expect("slice with incorrect length"),
|
in_p[1..4].try_into().expect("slice with incorrect length"),
|
||||||
|
@ -629,8 +554,8 @@ impl BaseTransformImpl for HsvDetector {
|
||||||
}
|
}
|
||||||
gst_video::VideoFormat::Argb => {
|
gst_video::VideoFormat::Argb => {
|
||||||
self.hsv_detect(
|
self.hsv_detect(
|
||||||
&in_frame,
|
in_frame,
|
||||||
&mut out_frame,
|
out_frame,
|
||||||
|in_p| {
|
|in_p| {
|
||||||
hsvutils::from_rgb(
|
hsvutils::from_rgb(
|
||||||
in_p[1..4].try_into().expect("slice with incorrect length"),
|
in_p[1..4].try_into().expect("slice with incorrect length"),
|
||||||
|
@ -644,8 +569,8 @@ impl BaseTransformImpl for HsvDetector {
|
||||||
}
|
}
|
||||||
gst_video::VideoFormat::Bgra => {
|
gst_video::VideoFormat::Bgra => {
|
||||||
self.hsv_detect(
|
self.hsv_detect(
|
||||||
&in_frame,
|
in_frame,
|
||||||
&mut out_frame,
|
out_frame,
|
||||||
|in_p| {
|
|in_p| {
|
||||||
hsvutils::from_rgb(
|
hsvutils::from_rgb(
|
||||||
in_p[1..4].try_into().expect("slice with incorrect length"),
|
in_p[1..4].try_into().expect("slice with incorrect length"),
|
||||||
|
@ -661,8 +586,8 @@ impl BaseTransformImpl for HsvDetector {
|
||||||
}
|
}
|
||||||
gst_video::VideoFormat::Abgr => {
|
gst_video::VideoFormat::Abgr => {
|
||||||
self.hsv_detect(
|
self.hsv_detect(
|
||||||
&in_frame,
|
in_frame,
|
||||||
&mut out_frame,
|
out_frame,
|
||||||
|in_p| {
|
|in_p| {
|
||||||
hsvutils::from_rgb(
|
hsvutils::from_rgb(
|
||||||
in_p[1..4].try_into().expect("slice with incorrect length"),
|
in_p[1..4].try_into().expect("slice with incorrect length"),
|
||||||
|
@ -680,11 +605,11 @@ impl BaseTransformImpl for HsvDetector {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
gst_video::VideoFormat::Bgrx | gst_video::VideoFormat::Bgr => {
|
gst_video::VideoFormat::Bgrx | gst_video::VideoFormat::Bgr => {
|
||||||
match state.out_info.format() {
|
match out_frame.format() {
|
||||||
gst_video::VideoFormat::Rgba => {
|
gst_video::VideoFormat::Rgba => {
|
||||||
self.hsv_detect(
|
self.hsv_detect(
|
||||||
&in_frame,
|
in_frame,
|
||||||
&mut out_frame,
|
out_frame,
|
||||||
|in_p| {
|
|in_p| {
|
||||||
hsvutils::from_bgr(
|
hsvutils::from_bgr(
|
||||||
in_p[..3].try_into().expect("slice with incorrect length"),
|
in_p[..3].try_into().expect("slice with incorrect length"),
|
||||||
|
@ -700,8 +625,8 @@ impl BaseTransformImpl for HsvDetector {
|
||||||
}
|
}
|
||||||
gst_video::VideoFormat::Argb => {
|
gst_video::VideoFormat::Argb => {
|
||||||
self.hsv_detect(
|
self.hsv_detect(
|
||||||
&in_frame,
|
in_frame,
|
||||||
&mut out_frame,
|
out_frame,
|
||||||
|in_p| {
|
|in_p| {
|
||||||
hsvutils::from_bgr(
|
hsvutils::from_bgr(
|
||||||
in_p[..3].try_into().expect("slice with incorrect length"),
|
in_p[..3].try_into().expect("slice with incorrect length"),
|
||||||
|
@ -717,8 +642,8 @@ impl BaseTransformImpl for HsvDetector {
|
||||||
}
|
}
|
||||||
gst_video::VideoFormat::Bgra => {
|
gst_video::VideoFormat::Bgra => {
|
||||||
self.hsv_detect(
|
self.hsv_detect(
|
||||||
&in_frame,
|
in_frame,
|
||||||
&mut out_frame,
|
out_frame,
|
||||||
|in_p| {
|
|in_p| {
|
||||||
hsvutils::from_bgr(
|
hsvutils::from_bgr(
|
||||||
in_p[..3].try_into().expect("slice with incorrect length"),
|
in_p[..3].try_into().expect("slice with incorrect length"),
|
||||||
|
@ -732,8 +657,8 @@ impl BaseTransformImpl for HsvDetector {
|
||||||
}
|
}
|
||||||
gst_video::VideoFormat::Abgr => {
|
gst_video::VideoFormat::Abgr => {
|
||||||
self.hsv_detect(
|
self.hsv_detect(
|
||||||
&in_frame,
|
in_frame,
|
||||||
&mut out_frame,
|
out_frame,
|
||||||
|in_p| {
|
|in_p| {
|
||||||
hsvutils::from_bgr(
|
hsvutils::from_bgr(
|
||||||
in_p[..3].try_into().expect("slice with incorrect length"),
|
in_p[..3].try_into().expect("slice with incorrect length"),
|
||||||
|
@ -748,11 +673,11 @@ impl BaseTransformImpl for HsvDetector {
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gst_video::VideoFormat::Xbgr => match state.out_info.format() {
|
gst_video::VideoFormat::Xbgr => match out_frame.format() {
|
||||||
gst_video::VideoFormat::Rgba => {
|
gst_video::VideoFormat::Rgba => {
|
||||||
self.hsv_detect(
|
self.hsv_detect(
|
||||||
&in_frame,
|
in_frame,
|
||||||
&mut out_frame,
|
out_frame,
|
||||||
|in_p| {
|
|in_p| {
|
||||||
hsvutils::from_bgr(
|
hsvutils::from_bgr(
|
||||||
in_p[1..4].try_into().expect("slice with incorrect length"),
|
in_p[1..4].try_into().expect("slice with incorrect length"),
|
||||||
|
@ -768,8 +693,8 @@ impl BaseTransformImpl for HsvDetector {
|
||||||
}
|
}
|
||||||
gst_video::VideoFormat::Argb => {
|
gst_video::VideoFormat::Argb => {
|
||||||
self.hsv_detect(
|
self.hsv_detect(
|
||||||
&in_frame,
|
in_frame,
|
||||||
&mut out_frame,
|
out_frame,
|
||||||
|in_p| {
|
|in_p| {
|
||||||
hsvutils::from_bgr(
|
hsvutils::from_bgr(
|
||||||
in_p[1..4].try_into().expect("slice with incorrect length"),
|
in_p[1..4].try_into().expect("slice with incorrect length"),
|
||||||
|
@ -785,8 +710,8 @@ impl BaseTransformImpl for HsvDetector {
|
||||||
}
|
}
|
||||||
gst_video::VideoFormat::Bgra => {
|
gst_video::VideoFormat::Bgra => {
|
||||||
self.hsv_detect(
|
self.hsv_detect(
|
||||||
&in_frame,
|
in_frame,
|
||||||
&mut out_frame,
|
out_frame,
|
||||||
|in_p| {
|
|in_p| {
|
||||||
hsvutils::from_bgr(
|
hsvutils::from_bgr(
|
||||||
in_p[1..4].try_into().expect("slice with incorrect length"),
|
in_p[1..4].try_into().expect("slice with incorrect length"),
|
||||||
|
@ -800,8 +725,8 @@ impl BaseTransformImpl for HsvDetector {
|
||||||
}
|
}
|
||||||
gst_video::VideoFormat::Abgr => {
|
gst_video::VideoFormat::Abgr => {
|
||||||
self.hsv_detect(
|
self.hsv_detect(
|
||||||
&in_frame,
|
in_frame,
|
||||||
&mut out_frame,
|
out_frame,
|
||||||
|in_p| {
|
|in_p| {
|
||||||
hsvutils::from_bgr(
|
hsvutils::from_bgr(
|
||||||
in_p[1..4].try_into().expect("slice with incorrect length"),
|
in_p[1..4].try_into().expect("slice with incorrect length"),
|
||||||
|
|
|
@ -7,12 +7,12 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use gst::glib;
|
use gst::glib;
|
||||||
|
use gst::gst_info;
|
||||||
use gst::prelude::*;
|
use gst::prelude::*;
|
||||||
use gst::subclass::prelude::*;
|
use gst::subclass::prelude::*;
|
||||||
use gst::{gst_debug, gst_info};
|
|
||||||
use gst_base::subclass::prelude::*;
|
use gst_base::subclass::prelude::*;
|
||||||
|
use gst_video::subclass::prelude::*;
|
||||||
|
|
||||||
use atomic_refcell::AtomicRefCell;
|
|
||||||
use std::i32;
|
use std::i32;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
|
@ -50,16 +50,10 @@ impl Default for Settings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stream-specific state, i.e. video format configuration
|
|
||||||
struct State {
|
|
||||||
info: gst_video::VideoInfo,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Struct containing all the element data
|
// Struct containing all the element data
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct HsvFilter {
|
pub struct HsvFilter {
|
||||||
settings: Mutex<Settings>,
|
settings: Mutex<Settings>,
|
||||||
state: AtomicRefCell<Option<State>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
|
static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
|
||||||
|
@ -74,7 +68,7 @@ static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
|
||||||
impl ObjectSubclass for HsvFilter {
|
impl ObjectSubclass for HsvFilter {
|
||||||
const NAME: &'static str = "HsvFilter";
|
const NAME: &'static str = "HsvFilter";
|
||||||
type Type = super::HsvFilter;
|
type Type = super::HsvFilter;
|
||||||
type ParentType = gst_base::BaseTransform;
|
type ParentType = gst_video::VideoFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HsvFilter {
|
impl HsvFilter {
|
||||||
|
@ -357,74 +351,20 @@ impl BaseTransformImpl for HsvFilter {
|
||||||
gst_base::subclass::BaseTransformMode::AlwaysInPlace;
|
gst_base::subclass::BaseTransformMode::AlwaysInPlace;
|
||||||
const PASSTHROUGH_ON_SAME_CAPS: bool = false;
|
const PASSTHROUGH_ON_SAME_CAPS: bool = false;
|
||||||
const TRANSFORM_IP_ON_PASSTHROUGH: bool = false;
|
const TRANSFORM_IP_ON_PASSTHROUGH: bool = false;
|
||||||
|
}
|
||||||
|
|
||||||
fn unit_size(&self, _element: &Self::Type, caps: &gst::Caps) -> Option<usize> {
|
impl VideoFilterImpl for HsvFilter {
|
||||||
gst_video::VideoInfo::from_caps(caps)
|
fn transform_frame_ip(
|
||||||
.map(|info| info.size())
|
|
||||||
.ok()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_caps(
|
|
||||||
&self,
|
&self,
|
||||||
element: &Self::Type,
|
_element: &Self::Type,
|
||||||
incaps: &gst::Caps,
|
frame: &mut gst_video::VideoFrameRef<&mut gst::BufferRef>,
|
||||||
outcaps: &gst::Caps,
|
|
||||||
) -> Result<(), gst::LoggableError> {
|
|
||||||
let _in_info = match gst_video::VideoInfo::from_caps(incaps) {
|
|
||||||
Err(_) => return Err(gst::loggable_error!(CAT, "Failed to parse input caps")),
|
|
||||||
Ok(info) => info,
|
|
||||||
};
|
|
||||||
let out_info = match gst_video::VideoInfo::from_caps(outcaps) {
|
|
||||||
Err(_) => return Err(gst::loggable_error!(CAT, "Failed to parse output caps")),
|
|
||||||
Ok(info) => info,
|
|
||||||
};
|
|
||||||
|
|
||||||
gst_debug!(
|
|
||||||
CAT,
|
|
||||||
obj: element,
|
|
||||||
"Configured for caps {} to {}",
|
|
||||||
incaps,
|
|
||||||
outcaps
|
|
||||||
);
|
|
||||||
|
|
||||||
*self.state.borrow_mut() = Some(State { info: out_info });
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn stop(&self, element: &Self::Type) -> Result<(), gst::ErrorMessage> {
|
|
||||||
// Drop state
|
|
||||||
*self.state.borrow_mut() = None;
|
|
||||||
|
|
||||||
gst_info!(CAT, obj: element, "Stopped");
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn transform_ip(
|
|
||||||
&self,
|
|
||||||
element: &Self::Type,
|
|
||||||
buf: &mut gst::BufferRef,
|
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
let mut state_guard = self.state.borrow_mut();
|
match frame.format() {
|
||||||
let state = state_guard.as_mut().ok_or(gst::FlowError::NotNegotiated)?;
|
|
||||||
|
|
||||||
let mut frame = gst_video::VideoFrameRef::from_buffer_ref_writable(buf, &state.info)
|
|
||||||
.map_err(|_| {
|
|
||||||
gst::element_error!(
|
|
||||||
element,
|
|
||||||
gst::CoreError::Failed,
|
|
||||||
["Failed to map output buffer writable"]
|
|
||||||
);
|
|
||||||
gst::FlowError::Error
|
|
||||||
})?;
|
|
||||||
|
|
||||||
match state.info.format() {
|
|
||||||
gst_video::VideoFormat::Rgbx
|
gst_video::VideoFormat::Rgbx
|
||||||
| gst_video::VideoFormat::Rgba
|
| gst_video::VideoFormat::Rgba
|
||||||
| gst_video::VideoFormat::Rgb => {
|
| gst_video::VideoFormat::Rgb => {
|
||||||
self.hsv_filter(
|
self.hsv_filter(
|
||||||
&mut frame,
|
frame,
|
||||||
|p| hsvutils::from_rgb(p[..3].try_into().expect("slice with incorrect length")),
|
|p| hsvutils::from_rgb(p[..3].try_into().expect("slice with incorrect length")),
|
||||||
|hsv, p| {
|
|hsv, p| {
|
||||||
p[..3].copy_from_slice(&hsvutils::to_rgb(hsv));
|
p[..3].copy_from_slice(&hsvutils::to_rgb(hsv));
|
||||||
|
@ -433,7 +373,7 @@ impl BaseTransformImpl for HsvFilter {
|
||||||
}
|
}
|
||||||
gst_video::VideoFormat::Xrgb | gst_video::VideoFormat::Argb => {
|
gst_video::VideoFormat::Xrgb | gst_video::VideoFormat::Argb => {
|
||||||
self.hsv_filter(
|
self.hsv_filter(
|
||||||
&mut frame,
|
frame,
|
||||||
|p| {
|
|p| {
|
||||||
hsvutils::from_rgb(p[1..4].try_into().expect("slice with incorrect length"))
|
hsvutils::from_rgb(p[1..4].try_into().expect("slice with incorrect length"))
|
||||||
},
|
},
|
||||||
|
@ -446,7 +386,7 @@ impl BaseTransformImpl for HsvFilter {
|
||||||
| gst_video::VideoFormat::Bgra
|
| gst_video::VideoFormat::Bgra
|
||||||
| gst_video::VideoFormat::Bgr => {
|
| gst_video::VideoFormat::Bgr => {
|
||||||
self.hsv_filter(
|
self.hsv_filter(
|
||||||
&mut frame,
|
frame,
|
||||||
|p| hsvutils::from_bgr(p[..3].try_into().expect("slice with incorrect length")),
|
|p| hsvutils::from_bgr(p[..3].try_into().expect("slice with incorrect length")),
|
||||||
|hsv, p| {
|
|hsv, p| {
|
||||||
p[..3].copy_from_slice(&hsvutils::to_bgr(hsv));
|
p[..3].copy_from_slice(&hsvutils::to_bgr(hsv));
|
||||||
|
@ -455,7 +395,7 @@ impl BaseTransformImpl for HsvFilter {
|
||||||
}
|
}
|
||||||
gst_video::VideoFormat::Xbgr | gst_video::VideoFormat::Abgr => {
|
gst_video::VideoFormat::Xbgr | gst_video::VideoFormat::Abgr => {
|
||||||
self.hsv_filter(
|
self.hsv_filter(
|
||||||
&mut frame,
|
frame,
|
||||||
|p| {
|
|p| {
|
||||||
hsvutils::from_bgr(p[1..4].try_into().expect("slice with incorrect length"))
|
hsvutils::from_bgr(p[1..4].try_into().expect("slice with incorrect length"))
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue