mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer-rs.git
synced 2024-11-22 17:41:05 +00:00
video: extract common videoframe methods to trait
In preparation to make a more specialized VideoFrameGL this extracts common helper functions valid for all VideoFrames into a trait that can be implemented without too much code duplication. Note that this is a breaking change, now VideoFrame and VideoFrameRef cannot really be used without include the gst_video prelude. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/merge_requests/1312>
This commit is contained in:
parent
8e3994f641
commit
2a00236a1f
5 changed files with 141 additions and 245 deletions
|
@ -13,6 +13,7 @@
|
||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
use derive_more::{Display, Error};
|
use derive_more::{Display, Error};
|
||||||
use gst::prelude::*;
|
use gst::prelude::*;
|
||||||
|
use gst_video::prelude::*;
|
||||||
|
|
||||||
#[path = "../examples-common.rs"]
|
#[path = "../examples-common.rs"]
|
||||||
mod examples_common;
|
mod examples_common;
|
||||||
|
|
|
@ -364,7 +364,7 @@ mod video_filter {
|
||||||
use glib::once_cell::sync::Lazy;
|
use glib::once_cell::sync::Lazy;
|
||||||
use gst::{subclass::prelude::*, PadDirection, PadPresence, PadTemplate};
|
use gst::{subclass::prelude::*, PadDirection, PadPresence, PadTemplate};
|
||||||
use gst_app::gst_base::subclass::BaseTransformMode;
|
use gst_app::gst_base::subclass::BaseTransformMode;
|
||||||
use gst_video::{subclass::prelude::*, VideoFrameRef};
|
use gst_video::{prelude::*, subclass::prelude::*, VideoFrameRef};
|
||||||
use memmap2::MmapMut;
|
use memmap2::MmapMut;
|
||||||
|
|
||||||
static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
|
static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
use derive_more::{Display, Error};
|
use derive_more::{Display, Error};
|
||||||
use gst::{element_error, prelude::*};
|
use gst::{element_error, prelude::*};
|
||||||
|
use gst_video::prelude::*;
|
||||||
|
|
||||||
#[path = "../examples-common.rs"]
|
#[path = "../examples-common.rs"]
|
||||||
mod examples_common;
|
mod examples_common;
|
||||||
|
|
|
@ -60,7 +60,7 @@ mod video_info_dma_drm;
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "v1_24")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "v1_24")))]
|
||||||
pub use crate::video_info_dma_drm::*;
|
pub use crate::video_info_dma_drm::*;
|
||||||
pub mod video_frame;
|
pub mod video_frame;
|
||||||
pub use crate::video_frame::{VideoFrame, VideoFrameRef};
|
pub use crate::video_frame::{VideoFrame, VideoFrameExt, VideoFrameRef};
|
||||||
mod video_overlay;
|
mod video_overlay;
|
||||||
pub use crate::video_overlay::is_video_overlay_prepare_window_handle_message;
|
pub use crate::video_overlay::is_video_overlay_prepare_window_handle_message;
|
||||||
|
|
||||||
|
@ -151,6 +151,7 @@ pub mod prelude {
|
||||||
#[cfg(feature = "v1_16")]
|
#[cfg(feature = "v1_16")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
|
||||||
pub use crate::video_aggregator_pad::VideoAggregatorPadExtManual;
|
pub use crate::video_aggregator_pad::VideoAggregatorPadExtManual;
|
||||||
|
pub use crate::VideoFrameExt;
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
auto::traits::*, video_buffer_pool::VideoBufferPoolConfig,
|
auto::traits::*, video_buffer_pool::VideoBufferPoolConfig,
|
||||||
video_decoder::VideoDecoderExtManual, video_encoder::VideoEncoderExtManual,
|
video_decoder::VideoDecoderExtManual, video_encoder::VideoEncoderExtManual,
|
||||||
|
|
|
@ -27,22 +27,147 @@ impl<T> fmt::Debug for VideoFrame<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> VideoFrame<T> {
|
pub trait VideoFrameExt {
|
||||||
|
fn id(&self) -> i32;
|
||||||
|
fn info(&self) -> &crate::VideoInfo;
|
||||||
|
fn flags(&self) -> crate::VideoFrameFlags;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn info(&self) -> &crate::VideoInfo {
|
fn format(&self) -> crate::VideoFormat {
|
||||||
|
self.info().format()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn format_info(&self) -> crate::VideoFormatInfo {
|
||||||
|
self.info().format_info()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn width(&self) -> u32 {
|
||||||
|
self.info().width()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn height(&self) -> u32 {
|
||||||
|
self.info().height()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn size(&self) -> usize {
|
||||||
|
self.info().size()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_interlaced(&self) -> bool {
|
||||||
|
self.flags().contains(crate::VideoFrameFlags::INTERLACED)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_tff(&self) -> bool {
|
||||||
|
self.flags().contains(crate::VideoFrameFlags::TFF)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_rff(&self) -> bool {
|
||||||
|
self.flags().contains(crate::VideoFrameFlags::RFF)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_onefield(&self) -> bool {
|
||||||
|
self.flags().contains(crate::VideoFrameFlags::ONEFIELD)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_bottom_field(&self) -> bool {
|
||||||
|
self.flags().contains(crate::VideoFrameFlags::ONEFIELD)
|
||||||
|
&& !self.flags().contains(crate::VideoFrameFlags::TFF)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_top_field(&self) -> bool {
|
||||||
|
self.flags().contains(crate::VideoFrameFlags::ONEFIELD)
|
||||||
|
&& self.flags().contains(crate::VideoFrameFlags::TFF)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn n_planes(&self) -> u32 {
|
||||||
|
self.info().n_planes()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn n_components(&self) -> u32 {
|
||||||
|
self.info().n_components()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn plane_stride(&self) -> &[i32] {
|
||||||
|
self.info().stride()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn plane_offset(&self) -> &[usize] {
|
||||||
|
self.info().offset()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn comp_depth(&self, component: u32) -> u32 {
|
||||||
|
self.info().comp_depth(component as u8)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn comp_height(&self, component: u32) -> u32 {
|
||||||
|
self.info().comp_height(component as u8)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn comp_width(&self, component: u32) -> u32 {
|
||||||
|
self.info().comp_width(component as u8)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn comp_offset(&self, component: u32) -> usize {
|
||||||
|
self.info().comp_offset(component as u8)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn comp_poffset(&self, component: u32) -> u32 {
|
||||||
|
self.info().comp_poffset(component as u8)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn comp_pstride(&self, component: u32) -> i32 {
|
||||||
|
self.info().comp_pstride(component as u8)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn comp_stride(&self, component: u32) -> i32 {
|
||||||
|
self.info().comp_stride(component as u8)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn comp_plane(&self, component: u32) -> u32 {
|
||||||
|
self.info().comp_plane(component as u8)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> VideoFrameExt for VideoFrame<T> {
|
||||||
|
#[inline]
|
||||||
|
fn info(&self) -> &crate::VideoInfo {
|
||||||
unsafe { &*(&self.frame.info as *const ffi::GstVideoInfo as *const crate::VideoInfo) }
|
unsafe { &*(&self.frame.info as *const ffi::GstVideoInfo as *const crate::VideoInfo) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn flags(&self) -> crate::VideoFrameFlags {
|
fn flags(&self) -> crate::VideoFrameFlags {
|
||||||
unsafe { from_glib(self.frame.flags) }
|
unsafe { from_glib(self.frame.flags) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn id(&self) -> i32 {
|
fn id(&self) -> i32 {
|
||||||
self.frame.id
|
self.frame.id
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> VideoFrame<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn into_buffer(self) -> gst::Buffer {
|
pub fn into_buffer(self) -> gst::Buffer {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -87,83 +212,6 @@ impl<T> VideoFrame<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn format(&self) -> crate::VideoFormat {
|
|
||||||
self.info().format()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn format_info(&self) -> crate::VideoFormatInfo {
|
|
||||||
self.info().format_info()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn width(&self) -> u32 {
|
|
||||||
self.info().width()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn height(&self) -> u32 {
|
|
||||||
self.info().height()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn size(&self) -> usize {
|
|
||||||
self.info().size()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn is_interlaced(&self) -> bool {
|
|
||||||
self.flags().contains(crate::VideoFrameFlags::INTERLACED)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn is_tff(&self) -> bool {
|
|
||||||
self.flags().contains(crate::VideoFrameFlags::TFF)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn is_rff(&self) -> bool {
|
|
||||||
self.flags().contains(crate::VideoFrameFlags::RFF)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn is_onefield(&self) -> bool {
|
|
||||||
self.flags().contains(crate::VideoFrameFlags::ONEFIELD)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn is_bottom_field(&self) -> bool {
|
|
||||||
self.flags().contains(crate::VideoFrameFlags::ONEFIELD)
|
|
||||||
&& !self.flags().contains(crate::VideoFrameFlags::TFF)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn is_top_field(&self) -> bool {
|
|
||||||
self.flags().contains(crate::VideoFrameFlags::ONEFIELD)
|
|
||||||
&& self.flags().contains(crate::VideoFrameFlags::TFF)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn n_planes(&self) -> u32 {
|
|
||||||
self.info().n_planes()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn n_components(&self) -> u32 {
|
|
||||||
self.info().n_components()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn plane_stride(&self) -> &[i32] {
|
|
||||||
self.info().stride()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn plane_offset(&self) -> &[usize] {
|
|
||||||
self.info().offset()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn comp_data(&self, component: u32) -> Result<&[u8], glib::BoolError> {
|
pub fn comp_data(&self, component: u32) -> Result<&[u8], glib::BoolError> {
|
||||||
let poffset = self.info().comp_poffset(component as u8) as usize;
|
let poffset = self.info().comp_poffset(component as u8) as usize;
|
||||||
|
@ -171,47 +219,7 @@ impl<T> VideoFrame<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn comp_depth(&self, component: u32) -> u32 {
|
fn buffer(&self) -> &gst::BufferRef {
|
||||||
self.info().comp_depth(component as u8)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn comp_height(&self, component: u32) -> u32 {
|
|
||||||
self.info().comp_height(component as u8)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn comp_width(&self, component: u32) -> u32 {
|
|
||||||
self.info().comp_width(component as u8)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn comp_offset(&self, component: u32) -> usize {
|
|
||||||
self.info().comp_offset(component as u8)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn comp_poffset(&self, component: u32) -> u32 {
|
|
||||||
self.info().comp_poffset(component as u8)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn comp_pstride(&self, component: u32) -> i32 {
|
|
||||||
self.info().comp_pstride(component as u8)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn comp_stride(&self, component: u32) -> i32 {
|
|
||||||
self.info().comp_stride(component as u8)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn comp_plane(&self, component: u32) -> u32 {
|
|
||||||
self.info().comp_plane(component as u8)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn buffer(&self) -> &gst::BufferRef {
|
|
||||||
unsafe { gst::BufferRef::from_ptr(self.frame.buffer) }
|
unsafe { gst::BufferRef::from_ptr(self.frame.buffer) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,22 +524,24 @@ impl<T> fmt::Debug for VideoFrameRef<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> VideoFrameRef<T> {
|
impl<T> VideoFrameExt for VideoFrameRef<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn info(&self) -> &crate::VideoInfo {
|
fn info(&self) -> &crate::VideoInfo {
|
||||||
unsafe { &*(&self.frame.info as *const ffi::GstVideoInfo as *const crate::VideoInfo) }
|
unsafe { &*(&self.frame.info as *const ffi::GstVideoInfo as *const crate::VideoInfo) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn flags(&self) -> crate::VideoFrameFlags {
|
fn flags(&self) -> crate::VideoFrameFlags {
|
||||||
unsafe { from_glib(self.frame.flags) }
|
unsafe { from_glib(self.frame.flags) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn id(&self) -> i32 {
|
fn id(&self) -> i32 {
|
||||||
self.frame.id
|
self.frame.id
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> VideoFrameRef<T> {
|
||||||
#[doc(alias = "gst_video_frame_copy")]
|
#[doc(alias = "gst_video_frame_copy")]
|
||||||
pub fn copy(
|
pub fn copy(
|
||||||
&self,
|
&self,
|
||||||
|
@ -569,128 +579,11 @@ impl<T> VideoFrameRef<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn format(&self) -> crate::VideoFormat {
|
|
||||||
self.info().format()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn format_info(&self) -> crate::VideoFormatInfo {
|
|
||||||
self.info().format_info()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn width(&self) -> u32 {
|
|
||||||
self.info().width()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn height(&self) -> u32 {
|
|
||||||
self.info().height()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn size(&self) -> usize {
|
|
||||||
self.info().size()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn is_interlaced(&self) -> bool {
|
|
||||||
self.flags().contains(crate::VideoFrameFlags::INTERLACED)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn is_tff(&self) -> bool {
|
|
||||||
self.flags().contains(crate::VideoFrameFlags::TFF)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn is_rff(&self) -> bool {
|
|
||||||
self.flags().contains(crate::VideoFrameFlags::RFF)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn is_onefield(&self) -> bool {
|
|
||||||
self.flags().contains(crate::VideoFrameFlags::ONEFIELD)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn is_bottom_field(&self) -> bool {
|
|
||||||
self.flags().contains(crate::VideoFrameFlags::ONEFIELD)
|
|
||||||
&& !self.flags().contains(crate::VideoFrameFlags::TFF)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn is_top_field(&self) -> bool {
|
|
||||||
self.flags().contains(crate::VideoFrameFlags::ONEFIELD)
|
|
||||||
&& self.flags().contains(crate::VideoFrameFlags::TFF)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn n_planes(&self) -> u32 {
|
|
||||||
self.info().n_planes()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn n_components(&self) -> u32 {
|
|
||||||
self.info().n_components()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn plane_stride(&self) -> &[i32] {
|
|
||||||
self.info().stride()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn plane_offset(&self) -> &[usize] {
|
|
||||||
self.info().offset()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn comp_data(&self, component: u32) -> Result<&[u8], glib::BoolError> {
|
pub fn comp_data(&self, component: u32) -> Result<&[u8], glib::BoolError> {
|
||||||
let poffset = self.info().comp_poffset(component as u8) as usize;
|
let poffset = self.info().comp_poffset(component as u8) as usize;
|
||||||
Ok(&self.plane_data(self.format_info().plane()[component as usize])?[poffset..])
|
Ok(&self.plane_data(self.format_info().plane()[component as usize])?[poffset..])
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn comp_depth(&self, component: u32) -> u32 {
|
|
||||||
self.info().comp_depth(component as u8)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn comp_height(&self, component: u32) -> u32 {
|
|
||||||
self.info().comp_height(component as u8)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn comp_width(&self, component: u32) -> u32 {
|
|
||||||
self.info().comp_width(component as u8)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn comp_offset(&self, component: u32) -> usize {
|
|
||||||
self.info().comp_offset(component as u8)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn comp_poffset(&self, component: u32) -> u32 {
|
|
||||||
self.info().comp_poffset(component as u8)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn comp_pstride(&self, component: u32) -> i32 {
|
|
||||||
self.info().comp_pstride(component as u8)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn comp_stride(&self, component: u32) -> i32 {
|
|
||||||
self.info().comp_stride(component as u8)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn comp_plane(&self, component: u32) -> u32 {
|
|
||||||
self.info().comp_plane(component as u8)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn plane_data(&self, plane: u32) -> Result<&[u8], glib::BoolError> {
|
pub fn plane_data(&self, plane: u32) -> Result<&[u8], glib::BoolError> {
|
||||||
if plane >= self.n_planes() {
|
if plane >= self.n_planes() {
|
||||||
return Err(glib::bool_error!(
|
return Err(glib::bool_error!(
|
||||||
|
|
Loading…
Reference in a new issue