1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// Take a look at the license at the top of the repository in the LICENSE file.

use std::ffi::CStr;
use std::mem;

use glib::translate::*;

use once_cell::sync::Lazy;

pub static BUFFER_POOL_OPTION_VIDEO_AFFINE_TRANSFORMATION_META: Lazy<&'static str> =
    Lazy::new(|| unsafe {
        CStr::from_ptr(ffi::GST_BUFFER_POOL_OPTION_VIDEO_AFFINE_TRANSFORMATION_META)
            .to_str()
            .unwrap()
    });
/// A bufferpool option to enable extra padding. When a bufferpool supports this
/// option, `gst_buffer_pool_config_set_video_alignment()` can be called.
///
/// When this option is enabled on the bufferpool,
/// `GST_BUFFER_POOL_OPTION_VIDEO_META` should also be enabled.
pub static BUFFER_POOL_OPTION_VIDEO_ALIGNMENT: Lazy<&'static str> = Lazy::new(|| unsafe {
    CStr::from_ptr(ffi::GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT)
        .to_str()
        .unwrap()
});
/// An option that can be activated on a bufferpool to request gl texture upload
/// meta on buffers from the pool.
///
/// When this option is enabled on the bufferpool,
/// `GST_BUFFER_POOL_OPTION_VIDEO_META` should also be enabled.
pub static BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META: Lazy<&'static str> =
    Lazy::new(|| unsafe {
        CStr::from_ptr(ffi::GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META)
            .to_str()
            .unwrap()
    });
/// An option that can be activated on bufferpool to request video metadata
/// on buffers from the pool.
pub static BUFFER_POOL_OPTION_VIDEO_META: Lazy<&'static str> = Lazy::new(|| unsafe {
    CStr::from_ptr(ffi::GST_BUFFER_POOL_OPTION_VIDEO_META)
        .to_str()
        .unwrap()
});

#[derive(Debug, Clone)]
#[doc(alias = "GstVideoAlignment")]
pub struct VideoAlignment(pub(crate) ffi::GstVideoAlignment);

impl VideoAlignment {
    #[doc(alias = "get_padding_top")]
    pub fn padding_top(&self) -> u32 {
        self.0.padding_top
    }
    #[doc(alias = "get_padding_bottom")]
    pub fn padding_bottom(&self) -> u32 {
        self.0.padding_bottom
    }
    #[doc(alias = "get_padding_left")]
    pub fn padding_left(&self) -> u32 {
        self.0.padding_left
    }
    #[doc(alias = "get_padding_right")]
    pub fn padding_right(&self) -> u32 {
        self.0.padding_right
    }
    #[doc(alias = "get_stride_align")]
    pub fn stride_align(&self) -> &[u32; ffi::GST_VIDEO_MAX_PLANES as usize] {
        &self.0.stride_align
    }

    pub fn new(
        padding_top: u32,
        padding_bottom: u32,
        padding_left: u32,
        padding_right: u32,
        stride_align: &[u32; ffi::GST_VIDEO_MAX_PLANES as usize],
    ) -> Self {
        assert_initialized_main_thread!();

        let videoalignment = ffi::GstVideoAlignment {
            padding_top,
            padding_bottom,
            padding_left,
            padding_right,
            stride_align: *stride_align,
        };

        Self(videoalignment)
    }
}

impl PartialEq for VideoAlignment {
    fn eq(&self, other: &Self) -> bool {
        self.padding_top() == other.padding_top()
            && self.padding_bottom() == other.padding_bottom()
            && self.padding_left() == other.padding_left()
            && self.padding_right() == other.padding_right()
            && self.stride_align() == other.stride_align()
    }
}

impl Eq for VideoAlignment {}

#[doc(hidden)]
impl<'a> ToGlibPtr<'a, *const ffi::GstVideoAlignment> for VideoAlignment {
    type Storage = &'a Self;

    fn to_glib_none(&'a self) -> Stash<*const ffi::GstVideoAlignment, Self> {
        Stash(&self.0, self)
    }
}

pub trait VideoBufferPoolConfig {
    #[doc(alias = "get_video_alignment")]
    fn video_alignment(&self) -> Option<VideoAlignment>;

    fn set_video_alignment(&mut self, align: &VideoAlignment);
}

impl VideoBufferPoolConfig for gst::BufferPoolConfig {
    #[doc(alias = "gst_buffer_pool_config_get_video_alignment")]
    fn video_alignment(&self) -> Option<VideoAlignment> {
        unsafe {
            let mut alignment = mem::MaybeUninit::zeroed();
            let ret = from_glib(ffi::gst_buffer_pool_config_get_video_alignment(
                self.as_ref().as_mut_ptr(),
                alignment.as_mut_ptr(),
            ));
            if ret {
                Some(VideoAlignment(alignment.assume_init()))
            } else {
                None
            }
        }
    }

    #[doc(alias = "gst_buffer_pool_config_set_video_alignment")]
    fn set_video_alignment(&mut self, align: &VideoAlignment) {
        unsafe {
            ffi::gst_buffer_pool_config_set_video_alignment(
                self.as_mut().as_mut_ptr(),
                &align.0 as *const _ as *mut _,
            )
        }
    }
}