Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2021-10-16 15:24:00 +0300
committerSebastian Dröge <sebastian@centricular.com>2021-10-16 15:24:00 +0300
commit76a33e8f472465391dfcc76a5bfce4af89e901ee (patch)
tree8d505f79f205846c94835964e2920e93c8de536d /tutorial
parentcf637d0288af1186bc927a5ef7cf1eb5d7d1241c (diff)
tutorial: Port Rgb2Gray to VideoFilter base class
Diffstat (limited to 'tutorial')
-rw-r--r--tutorial/src/rgb2gray/imp.rs113
1 files changed, 8 insertions, 105 deletions
diff --git a/tutorial/src/rgb2gray/imp.rs b/tutorial/src/rgb2gray/imp.rs
index 3f5e724dc..431e258c6 100644
--- a/tutorial/src/rgb2gray/imp.rs
+++ b/tutorial/src/rgb2gray/imp.rs
@@ -11,6 +11,7 @@ use gst::prelude::*;
use gst::subclass::prelude::*;
use gst::{gst_debug, gst_info};
use gst_base::subclass::prelude::*;
+use gst_video::subclass::prelude::*;
use std::i32;
use std::sync::Mutex;
@@ -47,17 +48,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
#[derive(Default)]
pub struct Rgb2Gray {
settings: Mutex<Settings>,
- state: Mutex<Option<State>>,
}
impl Rgb2Gray {
@@ -94,7 +88,7 @@ impl Rgb2Gray {
impl ObjectSubclass for Rgb2Gray {
const NAME: &'static str = "RsRgb2Gray";
type Type = super::Rgb2Gray;
- type ParentType = gst_base::BaseTransform;
+ type ParentType = gst_video::VideoFilter;
}
// Implementation of glib::Object virtual methods
@@ -347,112 +341,21 @@ impl BaseTransformImpl for Rgb2Gray {
Some(other_caps)
}
}
+}
- // Returns the size of one processing unit (i.e. a frame in our case) corresponding
- // to the given caps. This is used for allocating a big enough output buffer and
- // sanity checking the input buffer size, among other things.
- fn unit_size(&self, _element: &Self::Type, caps: &gst::Caps) -> Option<usize> {
- gst_video::VideoInfo::from_caps(caps)
- .map(|info| info.size())
- .ok()
- }
-
- // Called whenever the input/output caps are changing, i.e. in the very beginning before data
- // flow happens and whenever the situation in the pipeline is changing. All buffers after this
- // call have the caps given here.
- //
- // We simply remember the resulting VideoInfo from the caps to be able to use this for knowing
- // the width, stride, etc when transforming buffers
- fn set_caps(
- &self,
- element: &Self::Type,
- incaps: &gst::Caps,
- 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.lock().unwrap() = Some(State { in_info, out_info });
-
- Ok(())
- }
-
- // Called when shutting down the element so we can release all stream-related state
- // There's also start(), which is called whenever starting the element again
- fn stop(&self, element: &Self::Type) -> Result<(), gst::ErrorMessage> {
- // Drop state
- let _ = self.state.lock().unwrap().take();
-
- gst_info!(CAT, obj: element, "Stopped");
-
- Ok(())
- }
-
+impl VideoFilterImpl for Rgb2Gray {
// Does the actual transformation of the input buffer to the output buffer
- fn transform(
+ fn transform_frame(
&self,
- element: &Self::Type,
- inbuf: &gst::Buffer,
- outbuf: &mut gst::BufferRef,
+ _element: &Self::Type,
+ in_frame: &gst_video::VideoFrameRef<&gst::BufferRef>,
+ out_frame: &mut gst_video::VideoFrameRef<&mut gst::BufferRef>,
) -> Result<gst::FlowSuccess, gst::FlowError> {
// Keep a local copy of the values of all our properties at this very moment. This
// ensures that the mutex is never locked for long and the application wouldn't
// have to block until this function returns when getting/setting property values
let settings = *self.settings.lock().unwrap();
- // Get a locked reference to our state, i.e. the input and output VideoInfo
- let mut state_guard = self.state.lock().unwrap();
- let state = state_guard.as_mut().ok_or_else(|| {
- gst::element_error!(element, gst::CoreError::Negotiation, ["Have no state yet"]);
- gst::FlowError::NotNegotiated
- })?;
-
- // Map the input buffer as a VideoFrameRef. This is similar to directly mapping
- // the buffer with inbuf.map_readable() but in addition extracts various video
- // specific metadata and sets up a convenient data structure that directly gives
- // pointers to the different planes and has all the information about the raw
- // video frame, like width, height, stride, video format, etc.
- //
- // This fails if the buffer can't be read or is invalid in relation to the video
- // info that is passed here
- 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
- },
- )?;
-
// Keep the various metadata we need for working with the video frames in
// local variables. This saves some typing below.
let width = in_frame.width() as usize;