Add various new 1.18 APIs

This commit is contained in:
Sebastian Dröge 2020-08-11 10:04:09 +03:00
parent 2624e2a6d1
commit a0887f197f
4 changed files with 374 additions and 0 deletions

View file

@ -28,6 +28,13 @@ pub trait AggregatorExtManual: 'static {
fn get_allocator(&self) -> (Option<gst::Allocator>, gst::AllocationParams); fn get_allocator(&self) -> (Option<gst::Allocator>, gst::AllocationParams);
fn finish_buffer(&self, buffer: gst::Buffer) -> Result<gst::FlowSuccess, gst::FlowError>; fn finish_buffer(&self, buffer: gst::Buffer) -> Result<gst::FlowSuccess, gst::FlowError>;
#[cfg(any(feature = "v1_18", feature = "dox"))]
fn finish_buffer_list(
&self,
bufferlist: gst::BufferList,
) -> Result<gst::FlowSuccess, gst::FlowError>;
#[cfg(any(feature = "v1_16", feature = "dox"))] #[cfg(any(feature = "v1_16", feature = "dox"))]
fn get_property_min_upstream_latency(&self) -> gst::ClockTime; fn get_property_min_upstream_latency(&self) -> gst::ClockTime;
@ -42,6 +49,35 @@ pub trait AggregatorExtManual: 'static {
#[cfg(any(feature = "v1_18", feature = "dox"))] #[cfg(any(feature = "v1_18", feature = "dox"))]
fn update_segment<F: gst::FormattedValue>(&self, segment: &gst::FormattedSegment<F>); fn update_segment<F: gst::FormattedValue>(&self, segment: &gst::FormattedSegment<F>);
#[cfg(any(feature = "v1_18", feature = "dox"))]
fn selected_samples(
&self,
pts: gst::ClockTime,
dts: gst::ClockTime,
duration: gst::ClockTime,
info: Option<&gst::StructureRef>,
);
#[cfg(any(feature = "v1_18", feature = "dox"))]
fn connect_samples_selected<
P,
F: Fn(
&P,
&gst::Segment,
gst::ClockTime,
gst::ClockTime,
gst::ClockTime,
Option<&gst::StructureRef>,
) + Send
+ Sync
+ 'static,
>(
&self,
f: F,
) -> SignalHandlerId
where
P: IsA<Aggregator>;
} }
impl<O: IsA<Aggregator>> AggregatorExtManual for O { impl<O: IsA<Aggregator>> AggregatorExtManual for O {
@ -68,6 +104,20 @@ impl<O: IsA<Aggregator>> AggregatorExtManual for O {
ret.into_result() ret.into_result()
} }
#[cfg(any(feature = "v1_18", feature = "dox"))]
fn finish_buffer_list(
&self,
bufferlist: gst::BufferList,
) -> Result<gst::FlowSuccess, gst::FlowError> {
let ret: gst::FlowReturn = unsafe {
from_glib(gst_base_sys::gst_aggregator_finish_buffer_list(
self.as_ref().to_glib_none().0,
bufferlist.into_ptr(),
))
};
ret.into_result()
}
#[cfg(any(feature = "v1_16", feature = "dox"))] #[cfg(any(feature = "v1_16", feature = "dox"))]
fn get_property_min_upstream_latency(&self) -> gst::ClockTime { fn get_property_min_upstream_latency(&self) -> gst::ClockTime {
unsafe { unsafe {
@ -121,6 +171,98 @@ impl<O: IsA<Aggregator>> AggregatorExtManual for O {
) )
} }
} }
#[cfg(any(feature = "v1_18", feature = "dox"))]
fn selected_samples(
&self,
pts: gst::ClockTime,
dts: gst::ClockTime,
duration: gst::ClockTime,
info: Option<&gst::StructureRef>,
) {
unsafe {
gst_base_sys::gst_aggregator_selected_samples(
self.as_ref().to_glib_none().0,
pts.to_glib(),
dts.to_glib(),
duration.to_glib(),
info.as_ref()
.map(|s| s.as_ptr() as *mut _)
.unwrap_or(ptr::null_mut()),
);
}
}
#[cfg(any(feature = "v1_18", feature = "dox"))]
fn connect_samples_selected<
P,
F: Fn(
&P,
&gst::Segment,
gst::ClockTime,
gst::ClockTime,
gst::ClockTime,
Option<&gst::StructureRef>,
) + Send
+ Sync
+ 'static,
>(
&self,
f: F,
) -> SignalHandlerId
where
P: IsA<Aggregator>,
{
unsafe extern "C" fn samples_selected_trampoline<
P,
F: Fn(
&P,
&gst::Segment,
gst::ClockTime,
gst::ClockTime,
gst::ClockTime,
Option<&gst::StructureRef>,
) + Send
+ Sync
+ 'static,
>(
this: *mut gst_base_sys::GstAggregator,
segment: *mut gst_sys::GstSegment,
pts: gst_sys::GstClockTime,
dts: gst_sys::GstClockTime,
duration: gst_sys::GstClockTime,
info: *mut gst_sys::GstStructure,
f: glib_sys::gpointer,
) where
P: IsA<Aggregator>,
{
let f: &F = &*(f as *const F);
f(
&Aggregator::from_glib_borrow(this).unsafe_cast_ref(),
&gst::Segment::from_glib_borrow(segment),
from_glib(pts),
from_glib(dts),
from_glib(duration),
if info.is_null() {
None
} else {
Some(gst::StructureRef::from_glib_borrow(info))
},
)
}
unsafe {
let f: Box_<F> = Box_::new(f);
connect_raw(
self.as_ptr() as *mut _,
b"samples-selected\0".as_ptr() as *const _,
Some(transmute::<_, unsafe extern "C" fn()>(
samples_selected_trampoline::<P, F> as *const (),
)),
Box_::into_raw(f),
)
}
}
} }
#[cfg(any(feature = "v1_16", feature = "dox"))] #[cfg(any(feature = "v1_16", feature = "dox"))]

View file

@ -27,6 +27,9 @@ pub trait BaseSrcExtManual: 'static {
fn wait_playing(&self) -> Result<gst::FlowSuccess, gst::FlowError>; fn wait_playing(&self) -> Result<gst::FlowSuccess, gst::FlowError>;
fn query_latency(&self) -> Result<(bool, gst::ClockTime, gst::ClockTime), glib::BoolError>; fn query_latency(&self) -> Result<(bool, gst::ClockTime, gst::ClockTime), glib::BoolError>;
#[cfg(any(feature = "v1_18", feature = "dox"))]
fn new_segment(&self, segment: &gst::Segment) -> Result<(), glib::BoolError>;
} }
impl<O: IsA<BaseSrc>> BaseSrcExtManual for O { impl<O: IsA<BaseSrc>> BaseSrcExtManual for O {
@ -104,4 +107,20 @@ impl<O: IsA<BaseSrc>> BaseSrcExtManual for O {
} }
} }
} }
#[cfg(any(feature = "v1_18", feature = "dox"))]
fn new_segment(&self, segment: &gst::Segment) -> Result<(), glib::BoolError> {
unsafe {
let ret = from_glib(gst_base_sys::gst_base_src_new_segment(
self.as_ref().to_glib_none().0,
segment.to_glib_none().0,
));
if ret {
Ok(())
} else {
Err(glib_bool_error!("Failed to configure new segment"))
}
}
}
} }

View file

@ -38,6 +38,15 @@ pub trait AggregatorImpl: AggregatorImplExt + ElementImpl + Send + Sync + 'stati
self.parent_clip(aggregator, aggregator_pad, buffer) self.parent_clip(aggregator, aggregator_pad, buffer)
} }
#[cfg(any(feature = "v1_18", feature = "dox"))]
fn finish_buffer_list(
&self,
aggregator: &Aggregator,
buffer_list: gst::BufferList,
) -> Result<gst::FlowSuccess, gst::FlowError> {
self.parent_finish_buffer_list(aggregator, buffer_list)
}
fn finish_buffer( fn finish_buffer(
&self, &self,
aggregator: &Aggregator, aggregator: &Aggregator,
@ -155,6 +164,15 @@ pub trait AggregatorImpl: AggregatorImplExt + ElementImpl + Send + Sync + 'stati
fn negotiate(&self, aggregator: &Aggregator) -> bool { fn negotiate(&self, aggregator: &Aggregator) -> bool {
self.parent_negotiate(aggregator) self.parent_negotiate(aggregator)
} }
#[cfg(any(feature = "v1_18", feature = "dox"))]
fn peek_next_sample(
&self,
aggregator: &Aggregator,
pad: &AggregatorPad,
) -> Option<gst::Sample> {
self.parent_peek_next_sample(aggregator, pad)
}
} }
pub trait AggregatorImplExt { pub trait AggregatorImplExt {
@ -173,6 +191,13 @@ pub trait AggregatorImplExt {
buffer: gst::Buffer, buffer: gst::Buffer,
) -> Result<gst::FlowSuccess, gst::FlowError>; ) -> Result<gst::FlowSuccess, gst::FlowError>;
#[cfg(any(feature = "v1_18", feature = "dox"))]
fn parent_finish_buffer_list(
&self,
aggregator: &Aggregator,
buffer_list: gst::BufferList,
) -> Result<gst::FlowSuccess, gst::FlowError>;
fn parent_sink_event( fn parent_sink_event(
&self, &self,
aggregator: &Aggregator, aggregator: &Aggregator,
@ -250,6 +275,13 @@ pub trait AggregatorImplExt {
#[cfg(any(feature = "v1_18", feature = "dox"))] #[cfg(any(feature = "v1_18", feature = "dox"))]
fn parent_negotiate(&self, aggregator: &Aggregator) -> bool; fn parent_negotiate(&self, aggregator: &Aggregator) -> bool;
#[cfg(any(feature = "v1_18", feature = "dox"))]
fn parent_peek_next_sample(
&self,
aggregator: &Aggregator,
pad: &AggregatorPad,
) -> Option<gst::Sample>;
} }
impl<T: AggregatorImpl + ObjectImpl> AggregatorImplExt for T { impl<T: AggregatorImpl + ObjectImpl> AggregatorImplExt for T {
@ -304,6 +336,24 @@ impl<T: AggregatorImpl + ObjectImpl> AggregatorImplExt for T {
} }
} }
#[cfg(any(feature = "v1_18", feature = "dox"))]
fn parent_finish_buffer_list(
&self,
aggregator: &Aggregator,
buffer_list: gst::BufferList,
) -> Result<gst::FlowSuccess, gst::FlowError> {
unsafe {
let data = self.get_type_data();
let parent_class =
data.as_ref().get_parent_class() as *mut gst_base_sys::GstAggregatorClass;
let f = (*parent_class)
.finish_buffer_list
.expect("Missing parent function `finish_buffer_list`");
gst::FlowReturn::from_glib(f(aggregator.to_glib_none().0, buffer_list.into_ptr()))
.into_result()
}
}
fn parent_sink_event( fn parent_sink_event(
&self, &self,
aggregator: &Aggregator, aggregator: &Aggregator,
@ -604,6 +654,23 @@ impl<T: AggregatorImpl + ObjectImpl> AggregatorImplExt for T {
.unwrap_or(true) .unwrap_or(true)
} }
} }
#[cfg(any(feature = "v1_18", feature = "dox"))]
fn parent_peek_next_sample(
&self,
aggregator: &Aggregator,
pad: &AggregatorPad,
) -> Option<gst::Sample> {
unsafe {
let data = self.get_type_data();
let parent_class =
data.as_ref().get_parent_class() as *mut gst_base_sys::GstAggregatorClass;
(*parent_class)
.peek_next_sample
.map(|f| from_glib_full(f(aggregator.to_glib_none().0, pad.to_glib_none().0)))
.unwrap_or(None)
}
}
} }
unsafe impl<T: ObjectSubclass + AggregatorImpl> IsSubclassable<T> for AggregatorClass unsafe impl<T: ObjectSubclass + AggregatorImpl> IsSubclassable<T> for AggregatorClass
@ -635,6 +702,8 @@ where
klass.sink_event_pre_queue = Some(aggregator_sink_event_pre_queue::<T>); klass.sink_event_pre_queue = Some(aggregator_sink_event_pre_queue::<T>);
klass.sink_query_pre_queue = Some(aggregator_sink_query_pre_queue::<T>); klass.sink_query_pre_queue = Some(aggregator_sink_query_pre_queue::<T>);
klass.negotiate = Some(aggregator_negotiate::<T>); klass.negotiate = Some(aggregator_negotiate::<T>);
klass.peek_next_sample = Some(aggregator_peek_next_sample::<T>);
klass.finish_buffer_list = Some(aggregator_finish_buffer_list::<T>);
} }
} }
} }
@ -699,6 +768,26 @@ where
.to_glib() .to_glib()
} }
#[cfg(any(feature = "v1_18", feature = "dox"))]
unsafe extern "C" fn aggregator_finish_buffer_list<T: ObjectSubclass>(
ptr: *mut gst_base_sys::GstAggregator,
buffer_list: *mut gst_sys::GstBufferList,
) -> gst_sys::GstFlowReturn
where
T: AggregatorImpl,
T::Instance: PanicPoison,
{
let instance = &*(ptr as *mut T::Instance);
let imp = instance.get_impl();
let wrap: Borrowed<Aggregator> = from_glib_borrow(ptr);
gst_panic_to_error!(&wrap, &instance.panicked(), gst::FlowReturn::Error, {
imp.finish_buffer_list(&wrap, from_glib_full(buffer_list))
.into()
})
.to_glib()
}
unsafe extern "C" fn aggregator_sink_event<T: ObjectSubclass>( unsafe extern "C" fn aggregator_sink_event<T: ObjectSubclass>(
ptr: *mut gst_base_sys::GstAggregator, ptr: *mut gst_base_sys::GstAggregator,
aggregator_pad: *mut gst_base_sys::GstAggregatorPad, aggregator_pad: *mut gst_base_sys::GstAggregatorPad,
@ -1048,3 +1137,22 @@ where
gst_panic_to_error!(&wrap, &instance.panicked(), false, { imp.negotiate(&wrap) }).to_glib() gst_panic_to_error!(&wrap, &instance.panicked(), false, { imp.negotiate(&wrap) }).to_glib()
} }
#[cfg(any(feature = "v1_18", feature = "dox"))]
unsafe extern "C" fn aggregator_peek_next_sample<T: ObjectSubclass>(
ptr: *mut gst_base_sys::GstAggregator,
pad: *mut gst_base_sys::GstAggregatorPad,
) -> *mut gst_sys::GstSample
where
T: AggregatorImpl,
T::Instance: PanicPoison,
{
let instance = &*(ptr as *mut T::Instance);
let imp = instance.get_impl();
let wrap: Borrowed<Aggregator> = from_glib_borrow(ptr);
gst_panic_to_error!(&wrap, &instance.panicked(), None, {
imp.peek_next_sample(&wrap, &from_glib_borrow(pad))
})
.to_glib_full()
}

View file

@ -187,6 +187,111 @@ impl fmt::Display for ::VideoColorimetry {
} }
} }
impl str::FromStr for ::VideoChromaSite {
type Err = glib::error::BoolError;
fn from_str(s: &str) -> Result<Self, glib::error::BoolError> {
assert_initialized_main_thread!();
unsafe {
let chroma_site = from_glib(gst_video_sys::gst_video_chroma_from_string(
s.to_glib_none().0,
));
if chroma_site == ::VideoChromaSite::empty() {
Err(glib_bool_error!("Invalid chroma site"))
} else {
Ok(chroma_site)
}
}
}
}
impl fmt::Display for ::VideoChromaSite {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
let s = unsafe {
glib::GString::from_glib_full(gst_video_sys::gst_video_chroma_to_string(self.to_glib()))
};
f.write_str(&s)
}
}
impl ::VideoTransferFunction {
#[cfg(any(feature = "v1_18", feature = "dox"))]
pub fn from_iso(iso: u32) -> Result<::VideoTransferFunction, glib::BoolError> {
assert_initialized_main_thread!();
unsafe {
let value = from_glib(gst_video_sys::gst_video_color_transfer_from_iso(iso));
match value {
::VideoTransferFunction::__Unknown(_) => Err(glib_bool_error!("Invalid ISO value")),
_ => Ok(value),
}
}
}
#[cfg(any(feature = "v1_18", feature = "dox"))]
pub fn to_iso(&self) -> u32 {
unsafe { gst_video_sys::gst_video_color_transfer_to_iso(self.to_glib()) }
}
#[cfg(any(feature = "v1_18", feature = "dox"))]
pub fn is_equivalent(
&self,
from_bpp: u32,
to_func: ::VideoTransferFunction,
to_bpp: u32,
) -> bool {
unsafe {
from_glib(gst_video_sys::gst_video_color_transfer_is_equivalent(
self.to_glib(),
from_bpp,
to_func.to_glib(),
to_bpp,
))
}
}
}
impl ::VideoColorMatrix {
#[cfg(any(feature = "v1_18", feature = "dox"))]
pub fn from_iso(iso: u32) -> Result<::VideoColorMatrix, glib::BoolError> {
assert_initialized_main_thread!();
unsafe {
let value = from_glib(gst_video_sys::gst_video_color_matrix_from_iso(iso));
match value {
::VideoColorMatrix::__Unknown(_) => Err(glib_bool_error!("Invalid ISO value")),
_ => Ok(value),
}
}
}
#[cfg(any(feature = "v1_18", feature = "dox"))]
pub fn to_iso(&self) -> u32 {
unsafe { gst_video_sys::gst_video_color_matrix_to_iso(self.to_glib()) }
}
}
impl ::VideoColorPrimaries {
#[cfg(any(feature = "v1_18", feature = "dox"))]
pub fn from_iso(iso: u32) -> Result<::VideoColorPrimaries, glib::BoolError> {
assert_initialized_main_thread!();
unsafe {
let value = from_glib(gst_video_sys::gst_video_color_primaries_from_iso(iso));
match value {
::VideoColorPrimaries::__Unknown(_) => Err(glib_bool_error!("Invalid ISO value")),
_ => Ok(value),
}
}
}
#[cfg(any(feature = "v1_18", feature = "dox"))]
pub fn to_iso(&self) -> u32 {
unsafe { gst_video_sys::gst_video_color_primaries_to_iso(self.to_glib()) }
}
}
impl From<::VideoMultiviewFramePacking> for ::VideoMultiviewMode { impl From<::VideoMultiviewFramePacking> for ::VideoMultiviewMode {
fn from(v: ::VideoMultiviewFramePacking) -> Self { fn from(v: ::VideoMultiviewFramePacking) -> Self {
skip_assert_initialized!(); skip_assert_initialized!();