From 830f0b7d83bf1f2f02848bdc7fd25efe906a6aca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 11 Aug 2017 12:29:23 +0300 Subject: [PATCH] Add VideoInfo and related bindings --- Gir_GstVideo.toml | 7 + gstreamer-video/src/auto/enums.rs | 418 +++++++++++++++++- gstreamer-video/src/auto/flags.rs | 69 ++- gstreamer-video/src/auto/mod.rs | 18 +- gstreamer-video/src/lib.rs | 10 +- gstreamer-video/src/video_info.rs | 687 ++++++++++++++++++++++++++++++ 6 files changed, 1177 insertions(+), 32 deletions(-) create mode 100644 gstreamer-video/src/video_info.rs diff --git a/Gir_GstVideo.toml b/Gir_GstVideo.toml index f31c6231d..d00b9c76d 100644 --- a/Gir_GstVideo.toml +++ b/Gir_GstVideo.toml @@ -21,6 +21,12 @@ generate = [ "GstVideo.VideoInterlaceMode", "GstVideo.VideoFlags", "GstVideo.VideoChromaSite", + "GstVideo.VideoColorMatrix", + "GstVideo.VideoTransferFunction", + "GstVideo.VideoColorPrimaries", + "GstVideo.VideoMultiviewMode", + "GstVideo.VideoMultiviewFlags", + "GstVideo.VideoFieldOrder", ] manual = [ @@ -29,6 +35,7 @@ manual = [ "GstVideo.VideoInfo", "GstVideo.VideoFormatInfo", "GstVideo.VideoColorimetry", + "GstVideo.VideoColorRange", ] [[object]] diff --git a/gstreamer-video/src/auto/enums.rs b/gstreamer-video/src/auto/enums.rs index c21d3b0c2..64bcdb507 100644 --- a/gstreamer-video/src/auto/enums.rs +++ b/gstreamer-video/src/auto/enums.rs @@ -4,11 +4,228 @@ use ffi; use glib::Type; use glib::StaticType; -use glib::value::{FromValue, FromValueOptional, SetValue, Value}; +use glib::value::{Value, SetValue, FromValue, FromValueOptional}; use gobject_ffi; use glib::translate::*; use std; +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] +pub enum VideoColorMatrix { + Unknown, + Rgb, + Fcc, + Bt709, + Bt601, + Smpte240m, + Bt2020, + #[doc(hidden)] + __Unknown(i32), +} + +#[doc(hidden)] +impl ToGlib for VideoColorMatrix { + type GlibType = ffi::GstVideoColorMatrix; + + fn to_glib(&self) -> ffi::GstVideoColorMatrix { + match *self { + VideoColorMatrix::Unknown => ffi::GST_VIDEO_COLOR_MATRIX_UNKNOWN, + VideoColorMatrix::Rgb => ffi::GST_VIDEO_COLOR_MATRIX_RGB, + VideoColorMatrix::Fcc => ffi::GST_VIDEO_COLOR_MATRIX_FCC, + VideoColorMatrix::Bt709 => ffi::GST_VIDEO_COLOR_MATRIX_BT709, + VideoColorMatrix::Bt601 => ffi::GST_VIDEO_COLOR_MATRIX_BT601, + VideoColorMatrix::Smpte240m => ffi::GST_VIDEO_COLOR_MATRIX_SMPTE240M, + VideoColorMatrix::Bt2020 => ffi::GST_VIDEO_COLOR_MATRIX_BT2020, + VideoColorMatrix::__Unknown(value) => unsafe{std::mem::transmute(value)} + } + } +} + +#[doc(hidden)] +impl FromGlib for VideoColorMatrix { + fn from_glib(value: ffi::GstVideoColorMatrix) -> Self { + skip_assert_initialized!(); + match value as i32 { + 0 => VideoColorMatrix::Unknown, + 1 => VideoColorMatrix::Rgb, + 2 => VideoColorMatrix::Fcc, + 3 => VideoColorMatrix::Bt709, + 4 => VideoColorMatrix::Bt601, + 5 => VideoColorMatrix::Smpte240m, + 6 => VideoColorMatrix::Bt2020, + value => VideoColorMatrix::__Unknown(value), + } + } +} + +impl StaticType for VideoColorMatrix { + fn static_type() -> Type { + unsafe { from_glib(ffi::gst_video_color_matrix_get_type()) } + } +} + +impl<'a> FromValueOptional<'a> for VideoColorMatrix { + unsafe fn from_value_optional(value: &Value) -> Option { + Some(FromValue::from_value(value)) + } +} + +impl<'a> FromValue<'a> for VideoColorMatrix { + unsafe fn from_value(value: &Value) -> Self { + from_glib(std::mem::transmute::(gobject_ffi::g_value_get_enum(value.to_glib_none().0))) + } +} + +impl SetValue for VideoColorMatrix { + unsafe fn set_value(value: &mut Value, this: &Self) { + gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, this.to_glib() as i32) + } +} + +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] +pub enum VideoColorPrimaries { + Unknown, + Bt709, + Bt470m, + Bt470bg, + Smpte170m, + Smpte240m, + Film, + Bt2020, + Adobergb, + #[doc(hidden)] + __Unknown(i32), +} + +#[doc(hidden)] +impl ToGlib for VideoColorPrimaries { + type GlibType = ffi::GstVideoColorPrimaries; + + fn to_glib(&self) -> ffi::GstVideoColorPrimaries { + match *self { + VideoColorPrimaries::Unknown => ffi::GST_VIDEO_COLOR_PRIMARIES_UNKNOWN, + VideoColorPrimaries::Bt709 => ffi::GST_VIDEO_COLOR_PRIMARIES_BT709, + VideoColorPrimaries::Bt470m => ffi::GST_VIDEO_COLOR_PRIMARIES_BT470M, + VideoColorPrimaries::Bt470bg => ffi::GST_VIDEO_COLOR_PRIMARIES_BT470BG, + VideoColorPrimaries::Smpte170m => ffi::GST_VIDEO_COLOR_PRIMARIES_SMPTE170M, + VideoColorPrimaries::Smpte240m => ffi::GST_VIDEO_COLOR_PRIMARIES_SMPTE240M, + VideoColorPrimaries::Film => ffi::GST_VIDEO_COLOR_PRIMARIES_FILM, + VideoColorPrimaries::Bt2020 => ffi::GST_VIDEO_COLOR_PRIMARIES_BT2020, + VideoColorPrimaries::Adobergb => ffi::GST_VIDEO_COLOR_PRIMARIES_ADOBERGB, + VideoColorPrimaries::__Unknown(value) => unsafe{std::mem::transmute(value)} + } + } +} + +#[doc(hidden)] +impl FromGlib for VideoColorPrimaries { + fn from_glib(value: ffi::GstVideoColorPrimaries) -> Self { + skip_assert_initialized!(); + match value as i32 { + 0 => VideoColorPrimaries::Unknown, + 1 => VideoColorPrimaries::Bt709, + 2 => VideoColorPrimaries::Bt470m, + 3 => VideoColorPrimaries::Bt470bg, + 4 => VideoColorPrimaries::Smpte170m, + 5 => VideoColorPrimaries::Smpte240m, + 6 => VideoColorPrimaries::Film, + 7 => VideoColorPrimaries::Bt2020, + 8 => VideoColorPrimaries::Adobergb, + value => VideoColorPrimaries::__Unknown(value), + } + } +} + +impl StaticType for VideoColorPrimaries { + fn static_type() -> Type { + unsafe { from_glib(ffi::gst_video_color_primaries_get_type()) } + } +} + +impl<'a> FromValueOptional<'a> for VideoColorPrimaries { + unsafe fn from_value_optional(value: &Value) -> Option { + Some(FromValue::from_value(value)) + } +} + +impl<'a> FromValue<'a> for VideoColorPrimaries { + unsafe fn from_value(value: &Value) -> Self { + from_glib(std::mem::transmute::(gobject_ffi::g_value_get_enum(value.to_glib_none().0))) + } +} + +impl SetValue for VideoColorPrimaries { + unsafe fn set_value(value: &mut Value, this: &Self) { + gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, this.to_glib() as i32) + } +} + +#[cfg(feature = "v1_12")] +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] +pub enum VideoFieldOrder { + Unknown, + TopFieldFirst, + BottomFieldFirst, + #[doc(hidden)] + __Unknown(i32), +} + +#[cfg(feature = "v1_12")] +#[doc(hidden)] +impl ToGlib for VideoFieldOrder { + type GlibType = ffi::GstVideoFieldOrder; + + fn to_glib(&self) -> ffi::GstVideoFieldOrder { + match *self { + VideoFieldOrder::Unknown => ffi::GST_VIDEO_FIELD_ORDER_UNKNOWN, + VideoFieldOrder::TopFieldFirst => ffi::GST_VIDEO_FIELD_ORDER_TOP_FIELD_FIRST, + VideoFieldOrder::BottomFieldFirst => ffi::GST_VIDEO_FIELD_ORDER_BOTTOM_FIELD_FIRST, + VideoFieldOrder::__Unknown(value) => unsafe{std::mem::transmute(value)} + } + } +} + +#[cfg(feature = "v1_12")] +#[doc(hidden)] +impl FromGlib for VideoFieldOrder { + fn from_glib(value: ffi::GstVideoFieldOrder) -> Self { + skip_assert_initialized!(); + match value as i32 { + 0 => VideoFieldOrder::Unknown, + 1 => VideoFieldOrder::TopFieldFirst, + 2 => VideoFieldOrder::BottomFieldFirst, + value => VideoFieldOrder::__Unknown(value), + } + } +} + +#[cfg(feature = "v1_12")] +impl StaticType for VideoFieldOrder { + fn static_type() -> Type { + unsafe { from_glib(ffi::gst_video_field_order_get_type()) } + } +} + +#[cfg(feature = "v1_12")] +impl<'a> FromValueOptional<'a> for VideoFieldOrder { + unsafe fn from_value_optional(value: &Value) -> Option { + Some(FromValue::from_value(value)) + } +} + +#[cfg(feature = "v1_12")] +impl<'a> FromValue<'a> for VideoFieldOrder { + unsafe fn from_value(value: &Value) -> Self { + from_glib(std::mem::transmute::(gobject_ffi::g_value_get_enum(value.to_glib_none().0))) + } +} + +#[cfg(feature = "v1_12")] +impl SetValue for VideoFieldOrder { + unsafe fn set_value(value: &mut Value, this: &Self) { + gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, this.to_glib() as i32) + } +} + #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] pub enum VideoFormat { Unknown, @@ -177,7 +394,7 @@ impl ToGlib for VideoFormat { VideoFormat::I42212le => ffi::GST_VIDEO_FORMAT_I422_12LE, VideoFormat::Y44412be => ffi::GST_VIDEO_FORMAT_Y444_12BE, VideoFormat::Y44412le => ffi::GST_VIDEO_FORMAT_Y444_12LE, - VideoFormat::__Unknown(value) => unsafe { std::mem::transmute(value) }, + VideoFormat::__Unknown(value) => unsafe{std::mem::transmute(value)} } } } @@ -284,9 +501,7 @@ impl<'a> FromValueOptional<'a> for VideoFormat { impl<'a> FromValue<'a> for VideoFormat { unsafe fn from_value(value: &Value) -> Self { - from_glib(std::mem::transmute::( - gobject_ffi::g_value_get_enum(value.to_glib_none().0), - )) + from_glib(std::mem::transmute::(gobject_ffi::g_value_get_enum(value.to_glib_none().0))) } } @@ -316,7 +531,7 @@ impl ToGlib for VideoInterlaceMode { VideoInterlaceMode::Interleaved => ffi::GST_VIDEO_INTERLACE_MODE_INTERLEAVED, VideoInterlaceMode::Mixed => ffi::GST_VIDEO_INTERLACE_MODE_MIXED, VideoInterlaceMode::Fields => ffi::GST_VIDEO_INTERLACE_MODE_FIELDS, - VideoInterlaceMode::__Unknown(value) => unsafe { std::mem::transmute(value) }, + VideoInterlaceMode::__Unknown(value) => unsafe{std::mem::transmute(value)} } } } @@ -349,9 +564,7 @@ impl<'a> FromValueOptional<'a> for VideoInterlaceMode { impl<'a> FromValue<'a> for VideoInterlaceMode { unsafe fn from_value(value: &Value) -> Self { - from_glib(std::mem::transmute::( - gobject_ffi::g_value_get_enum(value.to_glib_none().0), - )) + from_glib(std::mem::transmute::(gobject_ffi::g_value_get_enum(value.to_glib_none().0))) } } @@ -361,6 +574,96 @@ impl SetValue for VideoInterlaceMode { } } +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] +pub enum VideoMultiviewMode { + None, + Mono, + Left, + Right, + SideBySide, + SideBySideQuincunx, + ColumnInterleaved, + RowInterleaved, + TopBottom, + Checkerboard, + FrameByFrame, + MultiviewFrameByFrame, + Separated, + #[doc(hidden)] + __Unknown(i32), +} + +#[doc(hidden)] +impl ToGlib for VideoMultiviewMode { + type GlibType = ffi::GstVideoMultiviewMode; + + fn to_glib(&self) -> ffi::GstVideoMultiviewMode { + match *self { + VideoMultiviewMode::None => ffi::GST_VIDEO_MULTIVIEW_MODE_NONE, + VideoMultiviewMode::Mono => ffi::GST_VIDEO_MULTIVIEW_MODE_MONO, + VideoMultiviewMode::Left => ffi::GST_VIDEO_MULTIVIEW_MODE_LEFT, + VideoMultiviewMode::Right => ffi::GST_VIDEO_MULTIVIEW_MODE_RIGHT, + VideoMultiviewMode::SideBySide => ffi::GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE, + VideoMultiviewMode::SideBySideQuincunx => ffi::GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE_QUINCUNX, + VideoMultiviewMode::ColumnInterleaved => ffi::GST_VIDEO_MULTIVIEW_MODE_COLUMN_INTERLEAVED, + VideoMultiviewMode::RowInterleaved => ffi::GST_VIDEO_MULTIVIEW_MODE_ROW_INTERLEAVED, + VideoMultiviewMode::TopBottom => ffi::GST_VIDEO_MULTIVIEW_MODE_TOP_BOTTOM, + VideoMultiviewMode::Checkerboard => ffi::GST_VIDEO_MULTIVIEW_MODE_CHECKERBOARD, + VideoMultiviewMode::FrameByFrame => ffi::GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME, + VideoMultiviewMode::MultiviewFrameByFrame => ffi::GST_VIDEO_MULTIVIEW_MODE_MULTIVIEW_FRAME_BY_FRAME, + VideoMultiviewMode::Separated => ffi::GST_VIDEO_MULTIVIEW_MODE_SEPARATED, + VideoMultiviewMode::__Unknown(value) => unsafe{std::mem::transmute(value)} + } + } +} + +#[doc(hidden)] +impl FromGlib for VideoMultiviewMode { + fn from_glib(value: ffi::GstVideoMultiviewMode) -> Self { + skip_assert_initialized!(); + match value as i32 { + -1 => VideoMultiviewMode::None, + 0 => VideoMultiviewMode::Mono, + 1 => VideoMultiviewMode::Left, + 2 => VideoMultiviewMode::Right, + 3 => VideoMultiviewMode::SideBySide, + 4 => VideoMultiviewMode::SideBySideQuincunx, + 5 => VideoMultiviewMode::ColumnInterleaved, + 6 => VideoMultiviewMode::RowInterleaved, + 7 => VideoMultiviewMode::TopBottom, + 8 => VideoMultiviewMode::Checkerboard, + 32 => VideoMultiviewMode::FrameByFrame, + 33 => VideoMultiviewMode::MultiviewFrameByFrame, + 34 => VideoMultiviewMode::Separated, + value => VideoMultiviewMode::__Unknown(value), + } + } +} + +impl StaticType for VideoMultiviewMode { + fn static_type() -> Type { + unsafe { from_glib(ffi::gst_video_multiview_mode_get_type()) } + } +} + +impl<'a> FromValueOptional<'a> for VideoMultiviewMode { + unsafe fn from_value_optional(value: &Value) -> Option { + Some(FromValue::from_value(value)) + } +} + +impl<'a> FromValue<'a> for VideoMultiviewMode { + unsafe fn from_value(value: &Value) -> Self { + from_glib(std::mem::transmute::(gobject_ffi::g_value_get_enum(value.to_glib_none().0))) + } +} + +impl SetValue for VideoMultiviewMode { + unsafe fn set_value(value: &mut Value, this: &Self) { + gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, this.to_glib() as i32) + } +} + #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] pub enum VideoTileMode { Unknown, @@ -377,7 +680,7 @@ impl ToGlib for VideoTileMode { match *self { VideoTileMode::Unknown => ffi::GST_VIDEO_TILE_MODE_UNKNOWN, VideoTileMode::Zflipz2x2 => ffi::GST_VIDEO_TILE_MODE_ZFLIPZ_2X2, - VideoTileMode::__Unknown(value) => unsafe { std::mem::transmute(value) }, + VideoTileMode::__Unknown(value) => unsafe{std::mem::transmute(value)} } } } @@ -408,9 +711,7 @@ impl<'a> FromValueOptional<'a> for VideoTileMode { impl<'a> FromValue<'a> for VideoTileMode { unsafe fn from_value(value: &Value) -> Self { - from_glib(std::mem::transmute::( - gobject_ffi::g_value_get_enum(value.to_glib_none().0), - )) + from_glib(std::mem::transmute::(gobject_ffi::g_value_get_enum(value.to_glib_none().0))) } } @@ -419,3 +720,94 @@ impl SetValue for VideoTileMode { gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, this.to_glib() as i32) } } + +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] +pub enum VideoTransferFunction { + Unknown, + Gamma10, + Gamma18, + Gamma20, + Gamma22, + Bt709, + Smpte240m, + Srgb, + Gamma28, + Log100, + Log316, + Bt202012, + Adobergb, + #[doc(hidden)] + __Unknown(i32), +} + +#[doc(hidden)] +impl ToGlib for VideoTransferFunction { + type GlibType = ffi::GstVideoTransferFunction; + + fn to_glib(&self) -> ffi::GstVideoTransferFunction { + match *self { + VideoTransferFunction::Unknown => ffi::GST_VIDEO_TRANSFER_UNKNOWN, + VideoTransferFunction::Gamma10 => ffi::GST_VIDEO_TRANSFER_GAMMA10, + VideoTransferFunction::Gamma18 => ffi::GST_VIDEO_TRANSFER_GAMMA18, + VideoTransferFunction::Gamma20 => ffi::GST_VIDEO_TRANSFER_GAMMA20, + VideoTransferFunction::Gamma22 => ffi::GST_VIDEO_TRANSFER_GAMMA22, + VideoTransferFunction::Bt709 => ffi::GST_VIDEO_TRANSFER_BT709, + VideoTransferFunction::Smpte240m => ffi::GST_VIDEO_TRANSFER_SMPTE240M, + VideoTransferFunction::Srgb => ffi::GST_VIDEO_TRANSFER_SRGB, + VideoTransferFunction::Gamma28 => ffi::GST_VIDEO_TRANSFER_GAMMA28, + VideoTransferFunction::Log100 => ffi::GST_VIDEO_TRANSFER_LOG100, + VideoTransferFunction::Log316 => ffi::GST_VIDEO_TRANSFER_LOG316, + VideoTransferFunction::Bt202012 => ffi::GST_VIDEO_TRANSFER_BT2020_12, + VideoTransferFunction::Adobergb => ffi::GST_VIDEO_TRANSFER_ADOBERGB, + VideoTransferFunction::__Unknown(value) => unsafe{std::mem::transmute(value)} + } + } +} + +#[doc(hidden)] +impl FromGlib for VideoTransferFunction { + fn from_glib(value: ffi::GstVideoTransferFunction) -> Self { + skip_assert_initialized!(); + match value as i32 { + 0 => VideoTransferFunction::Unknown, + 1 => VideoTransferFunction::Gamma10, + 2 => VideoTransferFunction::Gamma18, + 3 => VideoTransferFunction::Gamma20, + 4 => VideoTransferFunction::Gamma22, + 5 => VideoTransferFunction::Bt709, + 6 => VideoTransferFunction::Smpte240m, + 7 => VideoTransferFunction::Srgb, + 8 => VideoTransferFunction::Gamma28, + 9 => VideoTransferFunction::Log100, + 10 => VideoTransferFunction::Log316, + 11 => VideoTransferFunction::Bt202012, + 12 => VideoTransferFunction::Adobergb, + value => VideoTransferFunction::__Unknown(value), + } + } +} + +impl StaticType for VideoTransferFunction { + fn static_type() -> Type { + unsafe { from_glib(ffi::gst_video_transfer_function_get_type()) } + } +} + +impl<'a> FromValueOptional<'a> for VideoTransferFunction { + unsafe fn from_value_optional(value: &Value) -> Option { + Some(FromValue::from_value(value)) + } +} + +impl<'a> FromValue<'a> for VideoTransferFunction { + unsafe fn from_value(value: &Value) -> Self { + from_glib(std::mem::transmute::(gobject_ffi::g_value_get_enum(value.to_glib_none().0))) + } +} + +impl SetValue for VideoTransferFunction { + unsafe fn set_value(value: &mut Value, this: &Self) { + gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, this.to_glib() as i32) + } +} + diff --git a/gstreamer-video/src/auto/flags.rs b/gstreamer-video/src/auto/flags.rs index 842a43272..9110d77e4 100644 --- a/gstreamer-video/src/auto/flags.rs +++ b/gstreamer-video/src/auto/flags.rs @@ -4,7 +4,7 @@ use ffi; use glib::Type; use glib::StaticType; -use glib::value::{FromValue, FromValueOptional, SetValue, Value}; +use glib::value::{Value, SetValue, FromValue, FromValueOptional}; use gobject_ffi; use glib::translate::*; @@ -53,9 +53,7 @@ impl<'a> FromValueOptional<'a> for VideoChromaSite { impl<'a> FromValue<'a> for VideoChromaSite { unsafe fn from_value(value: &Value) -> Self { - from_glib(ffi::GstVideoChromaSite::from_bits_truncate( - gobject_ffi::g_value_get_flags(value.to_glib_none().0), - )) + from_glib(ffi::GstVideoChromaSite::from_bits_truncate(gobject_ffi::g_value_get_flags(value.to_glib_none().0))) } } @@ -104,9 +102,7 @@ impl<'a> FromValueOptional<'a> for VideoFlags { impl<'a> FromValue<'a> for VideoFlags { unsafe fn from_value(value: &Value) -> Self { - from_glib(ffi::GstVideoFlags::from_bits_truncate( - gobject_ffi::g_value_get_flags(value.to_glib_none().0), - )) + from_glib(ffi::GstVideoFlags::from_bits_truncate(gobject_ffi::g_value_get_flags(value.to_glib_none().0))) } } @@ -161,9 +157,7 @@ impl<'a> FromValueOptional<'a> for VideoFormatFlags { impl<'a> FromValue<'a> for VideoFormatFlags { unsafe fn from_value(value: &Value) -> Self { - from_glib(ffi::GstVideoFormatFlags::from_bits_truncate( - gobject_ffi::g_value_get_flags(value.to_glib_none().0), - )) + from_glib(ffi::GstVideoFormatFlags::from_bits_truncate(gobject_ffi::g_value_get_flags(value.to_glib_none().0))) } } @@ -172,3 +166,58 @@ impl SetValue for VideoFormatFlags { gobject_ffi::g_value_set_flags(value.to_glib_none_mut().0, this.to_glib().bits()) } } + +bitflags! { + pub struct VideoMultiviewFlags: u32 { + const VIDEO_MULTIVIEW_FLAGS_NONE = 0; + const VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST = 1; + const VIDEO_MULTIVIEW_FLAGS_LEFT_FLIPPED = 2; + const VIDEO_MULTIVIEW_FLAGS_LEFT_FLOPPED = 4; + const VIDEO_MULTIVIEW_FLAGS_RIGHT_FLIPPED = 8; + const VIDEO_MULTIVIEW_FLAGS_RIGHT_FLOPPED = 16; + const VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT = 16384; + const VIDEO_MULTIVIEW_FLAGS_MIXED_MONO = 32768; + } +} + +#[doc(hidden)] +impl ToGlib for VideoMultiviewFlags { + type GlibType = ffi::GstVideoMultiviewFlags; + + fn to_glib(&self) -> ffi::GstVideoMultiviewFlags { + ffi::GstVideoMultiviewFlags::from_bits_truncate(self.bits()) + } +} + +#[doc(hidden)] +impl FromGlib for VideoMultiviewFlags { + fn from_glib(value: ffi::GstVideoMultiviewFlags) -> VideoMultiviewFlags { + skip_assert_initialized!(); + VideoMultiviewFlags::from_bits_truncate(value.bits()) + } +} + +impl StaticType for VideoMultiviewFlags { + fn static_type() -> Type { + unsafe { from_glib(ffi::gst_video_multiview_flags_get_type()) } + } +} + +impl<'a> FromValueOptional<'a> for VideoMultiviewFlags { + unsafe fn from_value_optional(value: &Value) -> Option { + Some(FromValue::from_value(value)) + } +} + +impl<'a> FromValue<'a> for VideoMultiviewFlags { + unsafe fn from_value(value: &Value) -> Self { + from_glib(ffi::GstVideoMultiviewFlags::from_bits_truncate(gobject_ffi::g_value_get_flags(value.to_glib_none().0))) + } +} + +impl SetValue for VideoMultiviewFlags { + unsafe fn set_value(value: &mut Value, this: &Self) { + gobject_ffi::g_value_set_flags(value.to_glib_none_mut().0, this.to_glib().bits()) + } +} + diff --git a/gstreamer-video/src/auto/mod.rs b/gstreamer-video/src/auto/mod.rs index bd3100668..9d1715a6d 100644 --- a/gstreamer-video/src/auto/mod.rs +++ b/gstreamer-video/src/auto/mod.rs @@ -2,9 +2,15 @@ // DO NOT EDIT mod enums; +pub use self::enums::VideoColorMatrix; +pub use self::enums::VideoColorPrimaries; +#[cfg(feature = "v1_12")] +pub use self::enums::VideoFieldOrder; pub use self::enums::VideoFormat; pub use self::enums::VideoInterlaceMode; +pub use self::enums::VideoMultiviewMode; pub use self::enums::VideoTileMode; +pub use self::enums::VideoTransferFunction; mod flags; pub use self::flags::VideoChromaSite; @@ -31,6 +37,16 @@ pub use self::flags::VIDEO_FORMAT_FLAG_PALETTE; pub use self::flags::VIDEO_FORMAT_FLAG_COMPLEX; pub use self::flags::VIDEO_FORMAT_FLAG_UNPACK; pub use self::flags::VIDEO_FORMAT_FLAG_TILED; +pub use self::flags::VideoMultiviewFlags; +pub use self::flags::VIDEO_MULTIVIEW_FLAGS_NONE; +pub use self::flags::VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST; +pub use self::flags::VIDEO_MULTIVIEW_FLAGS_LEFT_FLIPPED; +pub use self::flags::VIDEO_MULTIVIEW_FLAGS_LEFT_FLOPPED; +pub use self::flags::VIDEO_MULTIVIEW_FLAGS_RIGHT_FLIPPED; +pub use self::flags::VIDEO_MULTIVIEW_FLAGS_RIGHT_FLOPPED; +pub use self::flags::VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT; +pub use self::flags::VIDEO_MULTIVIEW_FLAGS_MIXED_MONO; #[doc(hidden)] -pub mod traits {} +pub mod traits { +} diff --git a/gstreamer-video/src/lib.rs b/gstreamer-video/src/lib.rs index 3713350af..4af20ec9c 100644 --- a/gstreamer-video/src/lib.rs +++ b/gstreamer-video/src/lib.rs @@ -15,16 +15,8 @@ extern crate gobject_sys as gobject_ffi; extern crate gstreamer_sys as gst_ffi; extern crate gstreamer_video_sys as ffi; extern crate gstreamer as gst; -#[macro_use] extern crate glib; -macro_rules! assert_initialized_main_thread { - () => ( - use gst_ffi; - assert_eq!(unsafe {gst_ffi::gst_is_initialized()}, ::glib_ffi::GTRUE) - ) -} - macro_rules! skip_assert_initialized { () => ( ) @@ -44,3 +36,5 @@ mod video_format; pub use video_format::*; mod video_format_info; pub use video_format_info::*; +mod video_info; +pub use video_info::*; diff --git a/gstreamer-video/src/video_info.rs b/gstreamer-video/src/video_info.rs new file mode 100644 index 000000000..b12419f12 --- /dev/null +++ b/gstreamer-video/src/video_info.rs @@ -0,0 +1,687 @@ +// Copyright (C) 2017 Sebastian Dröge +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use ffi; +use glib_ffi; +use gobject_ffi; + +use gst; +use gst::miniobject::MiniObject; +use glib; +use glib::translate::{from_glib, from_glib_full, from_glib_none, FromGlib, FromGlibPtrNone, + ToGlib, ToGlibPtr, ToGlibPtrMut}; + +use std::mem; +use std::ptr; +use std::str; +use std::fmt; + +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] +pub enum VideoColorRange { + Unknown, + Range0255, + Range16235, + #[doc(hidden)] + __Unknown(i32), +} + +#[doc(hidden)] +impl ToGlib for VideoColorRange { + type GlibType = ffi::GstVideoColorRange; + + fn to_glib(&self) -> ffi::GstVideoColorRange { + match *self { + VideoColorRange::Unknown => ffi::GST_VIDEO_COLOR_RANGE_UNKNOWN, + VideoColorRange::Range0255 => ffi::GST_VIDEO_COLOR_RANGE_0_255, + VideoColorRange::Range16235 => ffi::GST_VIDEO_COLOR_RANGE_16_235, + VideoColorRange::__Unknown(value) => unsafe { mem::transmute(value) }, + } + } +} + +#[doc(hidden)] +impl FromGlib for VideoColorRange { + fn from_glib(value: ffi::GstVideoColorRange) -> Self { + skip_assert_initialized!(); + match value as i32 { + 0 => VideoColorRange::Unknown, + 1 => VideoColorRange::Range0255, + 2 => VideoColorRange::Range16235, + value => VideoColorRange::__Unknown(value), + } + } +} + +impl glib::StaticType for VideoColorRange { + fn static_type() -> glib::Type { + unsafe { from_glib(ffi::gst_video_color_range_get_type()) } + } +} + +impl<'a> glib::value::FromValueOptional<'a> for VideoColorRange { + unsafe fn from_value_optional(value: &glib::value::Value) -> Option { + Some(glib::value::FromValue::from_value(value)) + } +} + +impl<'a> glib::value::FromValue<'a> for VideoColorRange { + unsafe fn from_value(value: &glib::value::Value) -> Self { + from_glib(mem::transmute::( + gobject_ffi::g_value_get_enum(value.to_glib_none().0), + )) + } +} + +impl glib::value::SetValue for VideoColorRange { + unsafe fn set_value(value: &mut glib::value::Value, this: &Self) { + gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, this.to_glib() as i32) + } +} + +pub struct VideoColorimetry(ffi::GstVideoColorimetry); + +impl VideoColorimetry { + pub fn new( + range: VideoColorRange, + matrix: ::VideoColorMatrix, + transfer: ::VideoTransferFunction, + primaries: ::VideoColorPrimaries, + ) -> Self { + + let colorimetry = unsafe { + let mut colorimetry: ffi::GstVideoColorimetry = mem::zeroed(); + + colorimetry.range = range.to_glib(); + colorimetry.matrix = matrix.to_glib(); + colorimetry.transfer = transfer.to_glib(); + colorimetry.primaries = primaries.to_glib(); + + colorimetry + }; + + VideoColorimetry(colorimetry) + } + + pub fn to_string(&self) -> String { + unsafe { from_glib_full(ffi::gst_video_colorimetry_to_string(&self.0)) } + } + + pub fn from_string(s: &str) -> Option { + unsafe { + let mut colorimetry = mem::zeroed(); + let valid: bool = from_glib(ffi::gst_video_colorimetry_from_string( + &mut colorimetry, + s.to_glib_none().0, + )); + if valid { + Some(VideoColorimetry(colorimetry)) + } else { + None + } + } + } +} + +impl Clone for VideoColorimetry { + fn clone(&self) -> Self { + unsafe { VideoColorimetry(ptr::read(&self.0)) } + } +} + +impl PartialEq for VideoColorimetry { + fn eq(&self, other: &Self) -> bool { + unsafe { from_glib(ffi::gst_video_colorimetry_is_equal(&self.0, &other.0)) } + } +} + +impl Eq for VideoColorimetry {} + +impl str::FromStr for ::VideoColorimetry { + type Err = (); + + fn from_str(s: &str) -> Result { + Self::from_string(s).ok_or(()) + } +} + +impl fmt::Debug for ::VideoColorimetry { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + f.write_str(&self.to_string()) + } +} + +impl fmt::Display for ::VideoColorimetry { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + f.write_str(&self.to_string()) + } +} + +pub struct VideoInfo(ffi::GstVideoInfo); + +pub struct VideoInfoBuilder<'a> { + format: ::VideoFormat, + width: u32, + height: u32, + interlace_mode: Option<::VideoInterlaceMode>, + flags: Option<::VideoFlags>, + size: Option, + views: Option, + chroma_site: Option<::VideoChromaSite>, + colorimetry: Option<&'a ::VideoColorimetry>, + par: Option, + fps: Option, + offset: Option<&'a [usize]>, + stride: Option<&'a [i32]>, + multiview_mode: Option<::VideoMultiviewMode>, + multiview_flags: Option<::VideoMultiviewFlags>, + #[cfg(feature = "v1_12")] + field_order: Option<::VideoFieldOrder>, +} + +impl<'a> VideoInfoBuilder<'a> { + pub fn build(self) -> Option { + unsafe { + let mut info = mem::uninitialized(); + + ffi::gst_video_info_set_format( + &mut info, + self.format.to_glib(), + self.width, + self.height, + ); + + if info.finfo.is_null() || info.width <= 0 || info.width <= 0 { + return None; + } + + if let Some(interlace_mode) = self.interlace_mode { + info.interlace_mode = interlace_mode.to_glib(); + } + + if let Some(flags) = self.flags { + info.flags = flags.to_glib(); + } + + if let Some(size) = self.size { + info.size = size; + } + + if let Some(views) = self.views { + info.views = views as i32; + } + + if let Some(chroma_site) = self.chroma_site { + info.chroma_site = chroma_site.to_glib(); + } + + if let Some(colorimetry) = self.colorimetry { + ptr::write(&mut info.colorimetry, ptr::read(&colorimetry.0)); + } + + if let Some(par) = self.par { + info.par_n = *par.numer(); + info.par_d = *par.denom(); + } + + if let Some(fps) = self.fps { + info.fps_n = *fps.numer(); + info.fps_d = *fps.denom(); + } + + if let Some(offset) = self.offset { + if offset.len() != ((*info.finfo).n_planes as usize) { + return None; + } + + for i in 0..((*info.finfo).n_planes as usize) { + info.offset[i] = offset[i]; + } + } + + if let Some(stride) = self.stride { + if stride.len() != ((*info.finfo).n_planes as usize) { + return None; + } + + for i in 0..((*info.finfo).n_planes as usize) { + info.stride[i] = stride[i]; + } + } + + if let Some(multiview_mode) = self.multiview_mode { + let ptr = &mut info._gst_reserved as *mut _ as *mut i32; + ptr::write(ptr.offset(0), mem::transmute(multiview_mode.to_glib())); + } + + if let Some(multiview_flags) = self.multiview_flags { + let ptr = &mut info._gst_reserved as *mut _ as *mut u32; + ptr::write(ptr.offset(1), multiview_flags.to_glib().bits()); + } + + #[cfg(feature = "v1_12")] + { + if let Some(field_order) = self.field_order { + let ptr = &mut info._gst_reserved as *mut _ as *mut i32; + ptr::write(ptr.offset(2), mem::transmute(field_order.to_glib())); + } + } + + Some(VideoInfo(info)) + } + } + + pub fn interlace_mode(self, interlace_mode: ::VideoInterlaceMode) -> VideoInfoBuilder<'a> { + Self { + interlace_mode: Some(interlace_mode), + ..self + } + } + + pub fn flags(self, flags: ::VideoFlags) -> Self { + Self { + flags: Some(flags), + ..self + } + } + + pub fn size(self, size: usize) -> Self { + Self { + size: Some(size), + ..self + } + } + + pub fn views(self, views: u32) -> Self { + Self { + views: Some(views), + ..self + } + } + + pub fn chroma_site(self, chroma_site: ::VideoChromaSite) -> Self { + Self { + chroma_site: Some(chroma_site), + ..self + } + } + + pub fn colorimetry(self, colorimetry: &'a ::VideoColorimetry) -> VideoInfoBuilder<'a> { + Self { + colorimetry: Some(colorimetry), + ..self + } + } + + pub fn par(self, par: gst::Fraction) -> Self { + Self { + par: Some(par), + ..self + } + } + + pub fn fps(self, fps: gst::Fraction) -> Self { + Self { + fps: Some(fps), + ..self + } + } + + pub fn offset(self, offset: &'a [usize]) -> VideoInfoBuilder<'a> { + Self { + offset: Some(offset), + ..self + } + } + + pub fn stride(self, stride: &'a [i32]) -> VideoInfoBuilder<'a> { + Self { + stride: Some(stride), + ..self + } + } + + pub fn multiview_mode(self, multiview_mode: ::VideoMultiviewMode) -> Self { + Self { + multiview_mode: Some(multiview_mode), + ..self + } + } + + pub fn multiview_flags(self, multiview_flags: ::VideoMultiviewFlags) -> Self { + Self { + multiview_flags: Some(multiview_flags), + ..self + } + } + + #[cfg(feature = "v1_12")] + pub fn field_order(self, field_order: ::VideoFieldOrder) -> Self { + Self { + field_order: Some(field_order), + ..self + } + } +} + +impl VideoInfo { + pub fn new<'a>(format: ::VideoFormat, width: u32, height: u32) -> VideoInfoBuilder<'a> { + #[cfg(not(feature = "v1_12"))] + { + VideoInfoBuilder { + format: format, + width: width, + height: height, + interlace_mode: None, + flags: None, + size: None, + views: None, + chroma_site: None, + colorimetry: None, + par: None, + fps: None, + offset: None, + stride: None, + multiview_mode: None, + multiview_flags: None, + } + } + #[cfg(feature = "v1_12")] + { + VideoInfoBuilder { + format: format, + width: width, + height: height, + interlace_mode: None, + flags: None, + size: None, + views: None, + chroma_site: None, + colorimetry: None, + par: None, + fps: None, + offset: None, + stride: None, + multiview_mode: None, + multiview_flags: None, + field_order: None, + } + } + } + + pub fn from_caps(caps: &gst::Caps) -> Option { + unsafe { + let mut info = mem::uninitialized(); + if from_glib(ffi::gst_video_info_from_caps(&mut info, caps.as_ptr())) { + Some(VideoInfo(info)) + } else { + None + } + } + } + + pub fn to_caps(&self) -> Option { + unsafe { + let caps = ffi::gst_video_info_to_caps(&self.0 as *const _ as *mut _); + if caps.is_null() { + None + } else { + Some(from_glib_full(caps)) + } + } + } + + pub fn format(&self) -> ::VideoFormat { + unsafe { from_glib((*self.0.finfo).format) } + } + + pub fn format_info(&self) -> ::VideoFormatInfo { + ::VideoFormatInfo::from_format(self.format()) + } + + pub fn width(&self) -> u32 { + self.0.width as u32 + } + + pub fn height(&self) -> u32 { + self.0.height as u32 + } + + pub fn interlace_mode(&self) -> ::VideoInterlaceMode { + from_glib(self.0.interlace_mode) + } + + pub fn flags(&self) -> ::VideoFlags { + from_glib(self.0.flags) + } + + pub fn size(&self) -> usize { + self.0.size + } + + pub fn views(&self) -> u32 { + self.0.views as u32 + } + + pub fn chroma_site(&self) -> ::VideoChromaSite { + from_glib(self.0.chroma_site) + } + + pub fn colorimetry(&self) -> VideoColorimetry { + unsafe { VideoColorimetry(ptr::read(&self.0.colorimetry)) } + } + + pub fn par(&self) -> gst::Fraction { + gst::Fraction::new(self.0.par_n, self.0.par_d) + } + + pub fn fps(&self) -> gst::Fraction { + gst::Fraction::new(self.0.fps_n, self.0.fps_d) + } + + pub fn offset(&self) -> &[usize] { + &self.0.offset[0..(self.format_info().n_planes() as usize)] + } + + pub fn stride(&self) -> &[i32] { + &self.0.stride[0..(self.format_info().n_planes() as usize)] + } + + pub fn multiview_mode(&self) -> ::VideoMultiviewMode { + unsafe { + let ptr = &self.0._gst_reserved as *const _ as *const i32; + from_glib(mem::transmute(ptr::read(ptr.offset(0)))) + } + } + + pub fn multiview_flags(&self) -> ::VideoMultiviewFlags { + unsafe { + let ptr = &self.0._gst_reserved as *const _ as *const u32; + from_glib(mem::transmute(ptr::read(ptr.offset(1)))) + } + } + + #[cfg(feature = "v1_12")] + pub fn field_order(&self) -> ::VideoFieldOrder { + unsafe { + let ptr = &self.0._gst_reserved as *const _ as *const i32; + from_glib(mem::transmute(ptr::read(ptr.offset(2)))) + } + } +} + +impl Clone for VideoInfo { + fn clone(&self) -> Self { + unsafe { VideoInfo(ptr::read(&self.0)) } + } +} + +impl PartialEq for VideoInfo { + fn eq(&self, other: &Self) -> bool { + unsafe { from_glib(ffi::gst_video_info_is_equal(&self.0, &other.0)) } + } +} + +impl Eq for VideoInfo {} + +impl glib::types::StaticType for VideoInfo { + fn static_type() -> glib::types::Type { + unsafe { glib::translate::from_glib(ffi::gst_video_info_get_type()) } + } +} + +#[doc(hidden)] +impl<'a> glib::value::FromValueOptional<'a> for VideoInfo { + unsafe fn from_value_optional(value: &glib::Value) -> Option { + Option::::from_glib_none( + gobject_ffi::g_value_get_boxed(value.to_glib_none().0) as *mut ffi::GstVideoInfo, + ) + } +} + +#[doc(hidden)] +impl glib::value::SetValue for VideoInfo { + unsafe fn set_value(value: &mut glib::Value, this: &Self) { + gobject_ffi::g_value_set_boxed( + value.to_glib_none_mut().0, + glib::translate::ToGlibPtr::<*const ffi::GstVideoInfo>::to_glib_none(this).0 as + glib_ffi::gpointer, + ) + } +} + +#[doc(hidden)] +impl glib::value::SetValueOptional for VideoInfo { + unsafe fn set_value_optional(value: &mut glib::Value, this: Option<&Self>) { + gobject_ffi::g_value_set_boxed( + value.to_glib_none_mut().0, + glib::translate::ToGlibPtr::<*const ffi::GstVideoInfo>::to_glib_none(&this).0 as + glib_ffi::gpointer, + ) + } +} + +#[doc(hidden)] +impl glib::translate::Uninitialized for VideoInfo { + unsafe fn uninitialized() -> Self { + mem::zeroed() + } +} + +#[doc(hidden)] +impl glib::translate::GlibPtrDefault for VideoInfo { + type GlibType = *mut ffi::GstVideoInfo; +} + +#[doc(hidden)] +impl<'a> glib::translate::ToGlibPtr<'a, *const ffi::GstVideoInfo> for VideoInfo { + type Storage = &'a VideoInfo; + + fn to_glib_none(&'a self) -> glib::translate::Stash<'a, *const ffi::GstVideoInfo, Self> { + glib::translate::Stash(&self.0, self) + } + + fn to_glib_full(&self) -> *const ffi::GstVideoInfo { + unimplemented!() + } +} + +#[doc(hidden)] +impl glib::translate::FromGlibPtrNone<*mut ffi::GstVideoInfo> for VideoInfo { + #[inline] + unsafe fn from_glib_none(ptr: *mut ffi::GstVideoInfo) -> Self { + VideoInfo(ptr::read(ptr)) + } +} + +#[doc(hidden)] +impl glib::translate::FromGlibPtrFull<*mut ffi::GstVideoInfo> for VideoInfo { + #[inline] + unsafe fn from_glib_full(ptr: *mut ffi::GstVideoInfo) -> Self { + let info = from_glib_none(ptr); + glib_ffi::g_free(ptr as *mut _); + info + } +} + +#[cfg(test)] +mod tests { + use super::*; + use gst; + + #[test] + fn test_new() { + gst::init().unwrap(); + + let info = VideoInfo::new(::VideoFormat::I420, 320, 240) + .build() + .unwrap(); + assert_eq!(info.format(), ::VideoFormat::I420); + assert_eq!(info.width(), 320); + assert_eq!(info.height(), 240); + assert_eq!(info.size(), 320 * 240 + 2 * 160 * 120); + assert_eq!(info.multiview_mode(), ::VideoMultiviewMode::None); + assert_eq!(&info.offset(), &[0, 320 * 240, 320 * 240 + 160 * 120]); + assert_eq!(&info.stride(), &[320, 160, 160]); + + let offsets = [0, 640 * 240 + 16, 640 * 240 + 16 + 320 * 120 + 16]; + let strides = [640, 320, 320]; + let info = VideoInfo::new(::VideoFormat::I420, 320, 240) + .offset(&offsets) + .stride(&strides) + .size(640 * 240 + 16 + 320 * 120 + 16 + 320 * 120 + 16) + .multiview_mode(::VideoMultiviewMode::SideBySide) + .build() + .unwrap(); + assert_eq!(info.format(), ::VideoFormat::I420); + assert_eq!(info.width(), 320); + assert_eq!(info.height(), 240); + assert_eq!( + info.size(), + 640 * 240 + 16 + 320 * 120 + 16 + 320 * 120 + 16 + ); + assert_eq!(info.multiview_mode(), ::VideoMultiviewMode::SideBySide); + assert_eq!( + &info.offset(), + &[0, 640 * 240 + 16, 640 * 240 + 16 + 320 * 120 + 16] + ); + assert_eq!(&info.stride(), &[640, 320, 320]); + } + + #[test] + fn test_from_to_caps() { + gst::init().unwrap(); + + let caps = gst::Caps::new_simple( + "video/x-raw", + &[ + ("format", &"I420"), + ("width", &320), + ("height", &240), + ("framerate", &gst::Fraction::new(30, 1)), + ("pixel-aspect-ratio", &gst::Fraction::new(1, 1)), + ("interlace-mode", &"progressive"), + ("chroma-site", &"mpeg2"), + ("colorimetry", &"bt709"), + ], + ); + let info = VideoInfo::from_caps(&caps).unwrap(); + assert_eq!(info.format(), ::VideoFormat::I420); + assert_eq!(info.width(), 320); + assert_eq!(info.height(), 240); + assert_eq!(info.fps(), gst::Fraction::new(30, 1)); + assert_eq!(info.interlace_mode(), ::VideoInterlaceMode::Progressive); + assert_eq!(info.chroma_site(), ::VIDEO_CHROMA_SITE_MPEG2); + assert_eq!(info.colorimetry(), "bt709".parse().unwrap()); + + let caps2 = info.to_caps().unwrap(); + assert_eq!(caps, caps2); + + let info2 = VideoInfo::from_caps(&caps2).unwrap(); + assert!(info == info2); + } +}