Add manual implementations for various new 1.16 functions

This commit is contained in:
Sebastian Dröge 2019-04-23 19:53:10 +03:00
parent 54705f959a
commit b2b8bfab52
10 changed files with 288 additions and 57 deletions

View file

@ -486,29 +486,31 @@ impl App {
.new_sample(move |appsink| { .new_sample(move |appsink| {
let sample = appsink.pull_sample().ok_or(gst::FlowError::Eos)?; let sample = appsink.pull_sample().ok_or(gst::FlowError::Eos)?;
let _buffer = sample.get_buffer().ok_or_else(|| { {
gst_element_error!( let _buffer = sample.get_buffer().ok_or_else(|| {
appsink,
gst::ResourceError::Failed,
("Failed to get buffer from appsink")
);
gst::FlowError::Error
})?;
let _info = sample
.get_caps()
.and_then(|caps| gst_video::VideoInfo::from_caps(caps.as_ref()))
.ok_or_else(|| {
gst_element_error!( gst_element_error!(
appsink, appsink,
gst::ResourceError::Failed, gst::ResourceError::Failed,
("Failed to get video info from sample") ("Failed to get buffer from appsink")
); );
gst::FlowError::Error gst::FlowError::Error
})?; })?;
let _info = sample
.get_caps()
.and_then(|caps| gst_video::VideoInfo::from_caps(caps))
.ok_or_else(|| {
gst_element_error!(
appsink,
gst::ResourceError::Failed,
("Failed to get video info from sample")
);
gst::FlowError::Error
})?;
}
sender_clone sender_clone
.lock() .lock()
.unwrap() .unwrap()
@ -638,7 +640,7 @@ fn main_loop(mut app: App) -> Result<(), Error> {
let buffer = sample.get_buffer().unwrap(); let buffer = sample.get_buffer().unwrap();
let info = sample let info = sample
.get_caps() .get_caps()
.and_then(|caps| gst_video::VideoInfo::from_caps(caps.as_ref())) .and_then(|caps| gst_video::VideoInfo::from_caps(caps))
.unwrap(); .unwrap();
{ {
@ -650,11 +652,13 @@ fn main_loop(mut app: App) -> Result<(), Error> {
.get::<gst_gl::GLContext>(); .get::<gst_gl::GLContext>();
} }
let sync_meta = buffer.as_ref().get_meta::<gst_gl::GLSyncMeta>().unwrap(); let sync_meta = buffer.get_meta::<gst_gl::GLSyncMeta>().unwrap();
sync_meta.set_sync_point(gst_gl_context.as_ref().unwrap()); sync_meta.set_sync_point(gst_gl_context.as_ref().unwrap());
} }
if let Ok(frame) = gst_video::VideoFrame::from_buffer_readable_gl(buffer, &info) { if let Ok(frame) =
gst_video::VideoFrame::from_buffer_readable_gl(buffer.to_owned(), &info)
{
curr_frame = Some(Arc::new(frame)); curr_frame = Some(Arc::new(frame));
} }
} }

View file

@ -165,7 +165,7 @@ mod tests {
let res = res.unwrap(); let res = res.unwrap();
let converted_out_caps = res.get_caps().unwrap(); let converted_out_caps = res.get_caps().unwrap();
assert_eq!(out_caps, converted_out_caps); assert_eq!(out_caps.as_ref(), converted_out_caps);
let out_buffer = res.get_buffer().unwrap(); let out_buffer = res.get_buffer().unwrap();
{ {
let data = out_buffer.map_readable().unwrap(); let data = out_buffer.map_readable().unwrap();

View file

@ -208,6 +208,16 @@ impl CapsRef {
} }
} }
#[cfg(any(feature = "v1_16", feature = "dox"))]
pub fn set_features_simple(&mut self, features: Option<CapsFeatures>) {
unsafe {
gst_sys::gst_caps_set_features_simple(
self.as_mut_ptr(),
features.map(|f| f.into_ptr()).unwrap_or(ptr::null_mut()),
)
}
}
pub fn get_size(&self) -> u32 { pub fn get_size(&self) -> u32 {
unsafe { gst_sys::gst_caps_get_size(self.as_ptr()) } unsafe { gst_sys::gst_caps_get_size(self.as_ptr()) }
} }

View file

@ -796,6 +796,20 @@ impl<'a> Seek<'a> {
) )
} }
} }
#[cfg(any(feature = "v1_16", feature = "dox"))]
pub fn get_trickmode_interval(&self) -> ::ClockTime {
unsafe {
let mut trickmode_interval = mem::uninitialized();
gst_sys::gst_event_parse_seek_trickmode_interval(
self.as_mut_ptr(),
&mut trickmode_interval,
);
from_glib(trickmode_interval)
}
}
} }
declare_concrete_event!(Navigation); declare_concrete_event!(Navigation);
@ -1329,6 +1343,8 @@ pub struct SeekBuilder<'a> {
start: GenericFormattedValue, start: GenericFormattedValue,
stop_type: ::SeekType, stop_type: ::SeekType,
stop: GenericFormattedValue, stop: GenericFormattedValue,
#[allow(unused)]
trickmode_interval: Option<::ClockTime>,
} }
impl<'a> SeekBuilder<'a> { impl<'a> SeekBuilder<'a> {
fn new( fn new(
@ -1348,18 +1364,30 @@ impl<'a> SeekBuilder<'a> {
start, start,
stop_type, stop_type,
stop, stop,
trickmode_interval: None,
} }
} }
event_builder_generic_impl!(|s: &Self| gst_sys::gst_event_new_seek( event_builder_generic_impl!(|s: &Self| {
s.rate, let ev = gst_sys::gst_event_new_seek(
s.start.get_format().to_glib(), s.rate,
s.flags.to_glib(), s.start.get_format().to_glib(),
s.start_type.to_glib(), s.flags.to_glib(),
s.start.get_value(), s.start_type.to_glib(),
s.stop_type.to_glib(), s.start.get_value(),
s.stop.get_value(), s.stop_type.to_glib(),
)); s.stop.get_value(),
);
#[cfg(any(feature = "v1_16", feature = "dox"))]
{
if let Some(trickmode_interval) = s.trickmode_interval {
gst_sys::gst_event_set_seek_trickmode_interval(ev, trickmode_interval.to_glib());
}
}
ev
});
} }
pub struct NavigationBuilder<'a> { pub struct NavigationBuilder<'a> {

View file

@ -102,6 +102,7 @@ impl MessageRef {
gst_sys::GST_MESSAGE_STREAMS_SELECTED => { gst_sys::GST_MESSAGE_STREAMS_SELECTED => {
MessageView::StreamsSelected(StreamsSelected(self)) MessageView::StreamsSelected(StreamsSelected(self))
} }
gst_sys::GST_MESSAGE_DEVICE_CHANGED => MessageView::DeviceChanged(DeviceChanged(self)),
_ => MessageView::Other, _ => MessageView::Other,
} }
} }
@ -340,6 +341,15 @@ impl Message {
assert_initialized_main_thread!(); assert_initialized_main_thread!();
RedirectBuilder::new(location) RedirectBuilder::new(location)
} }
#[cfg(any(feature = "v1_16", feature = "dox"))]
pub fn new_device_changed<'a>(
device: &'a ::Device,
changed_device: &'a ::Device,
) -> DeviceChangedBuilder<'a> {
assert_initialized_main_thread!();
DeviceChangedBuilder::new(device, changed_device)
}
} }
impl fmt::Debug for MessageRef { impl fmt::Debug for MessageRef {
@ -396,6 +406,7 @@ pub enum MessageView<'a> {
StreamCollection(StreamCollection<'a>), StreamCollection(StreamCollection<'a>),
StreamsSelected(StreamsSelected<'a>), StreamsSelected(StreamsSelected<'a>),
Redirect(Redirect<'a>), Redirect(Redirect<'a>),
DeviceChanged(DeviceChanged<'a>),
Other, Other,
__NonExhaustive, __NonExhaustive,
} }
@ -1153,6 +1164,25 @@ impl<'a> Redirect<'a> {
} }
} }
declare_concrete_message!(DeviceChanged);
impl<'a> DeviceChanged<'a> {
#[cfg(any(feature = "v1_16", feature = "dox"))]
pub fn get_device_changed(&self) -> (::Device, ::Device) {
unsafe {
let mut device = ptr::null_mut();
let mut changed_device = ptr::null_mut();
gst_sys::gst_message_parse_device_changed(
self.as_mut_ptr(),
&mut device,
&mut changed_device,
);
(from_glib_full(device), from_glib_full(changed_device))
}
}
}
struct MessageBuilder<'a> { struct MessageBuilder<'a> {
src: Option<Object>, src: Option<Object>,
seqnum: Option<Seqnum>, seqnum: Option<Seqnum>,
@ -2365,6 +2395,30 @@ impl<'a> RedirectBuilder<'a> {
}); });
} }
#[cfg(any(feature = "v1_16", feature = "dox"))]
pub struct DeviceChangedBuilder<'a> {
builder: MessageBuilder<'a>,
device: &'a ::Device,
changed_device: &'a ::Device,
}
#[cfg(any(feature = "v1_16", feature = "dox"))]
impl<'a> DeviceChangedBuilder<'a> {
fn new(device: &'a ::Device, changed_device: &'a ::Device) -> Self {
skip_assert_initialized!();
Self {
builder: MessageBuilder::new(),
device,
changed_device,
}
}
message_builder_generic_impl!(|s: &mut Self, src| gst_sys::gst_message_new_device_changed(
src,
s.device.to_glib_none().0,
s.changed_device.to_glib_none().0,
));
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View file

@ -121,6 +121,14 @@ impl<'a, T: MetaAPI> MetaRef<'a, T> {
} }
} }
#[cfg(any(feature = "v1_16", feature = "dox"))]
pub fn get_seqnum(&self) -> u64 {
unsafe {
let meta = self.meta as *const _ as *const gst_sys::GstMeta;
gst_sys::gst_meta_get_seqnum(meta)
}
}
pub fn as_ptr(&self) -> *const T::GstType { pub fn as_ptr(&self) -> *const T::GstType {
self.meta as *const _ as *const <T as MetaAPI>::GstType self.meta as *const _ as *const <T as MetaAPI>::GstType
} }
@ -148,6 +156,14 @@ impl<'a, T: MetaAPI, U> MetaRefMut<'a, T, U> {
} }
} }
#[cfg(any(feature = "v1_16", feature = "dox"))]
pub fn get_seqnum(&self) -> u64 {
unsafe {
let meta = self.meta as *const _ as *const gst_sys::GstMeta;
gst_sys::gst_meta_get_seqnum(meta)
}
}
pub fn as_ptr(&self) -> *const T::GstType { pub fn as_ptr(&self) -> *const T::GstType {
self.meta as *const _ as *const <T as MetaAPI>::GstType self.meta as *const _ as *const <T as MetaAPI>::GstType
} }

View file

@ -99,6 +99,26 @@ impl<T: MiniObject> GstRc<T> {
ptr ptr
} }
#[cfg(any(feature = "v1_16", feature = "dox"))]
pub fn add_parent<U: MiniObject>(&self, parent: &U) {
unsafe {
gst_sys::gst_mini_object_add_parent(
self.as_ptr() as *mut gst_sys::GstMiniObject,
parent.as_ptr() as *mut gst_sys::GstMiniObject,
);
}
}
#[cfg(any(feature = "v1_16", feature = "dox"))]
pub fn remove_parent<U: MiniObject>(&self, parent: &U) {
unsafe {
gst_sys::gst_mini_object_remove_parent(
self.as_ptr() as *mut gst_sys::GstMiniObject,
parent.as_ptr() as *mut gst_sys::GstMiniObject,
);
}
}
} }
impl<T: MiniObject> ops::Deref for GstRc<T> { impl<T: MiniObject> ops::Deref for GstRc<T> {
@ -120,15 +140,6 @@ impl<T: MiniObject> borrow::Borrow<T> for GstRc<T> {
} }
} }
// FIXME: Not generally possible because neither T nor ToOwned are defined here...
//impl<T: MiniObject> ToOwned for T {
// type Owned = GstRc<T>;
//
// fn to_owned(&self) -> GstRc<T> {
// unsafe { GstRc::from_unowned_ptr(self.as_ptr()) }
// }
//}
impl<T: MiniObject> Clone for GstRc<T> { impl<T: MiniObject> Clone for GstRc<T> {
fn clone(&self) -> GstRc<T> { fn clone(&self) -> GstRc<T> {
unsafe { GstRc::from_glib_none(self.as_ptr()) } unsafe { GstRc::from_glib_none(self.as_ptr()) }

View file

@ -158,6 +158,12 @@ impl Query {
))) )))
} }
} }
#[cfg(any(feature = "v1_16", feature = "dox"))]
pub fn new_bitrate() -> Bitrate<Self> {
assert_initialized_main_thread!();
unsafe { Bitrate::<Self>(from_glib_full(gst_sys::gst_query_new_bitrate())) }
}
} }
impl QueryRef { impl QueryRef {
@ -213,6 +219,7 @@ impl QueryRef {
gst_sys::GST_QUERY_CAPS => QueryView::Caps(Caps(self)), gst_sys::GST_QUERY_CAPS => QueryView::Caps(Caps(self)),
gst_sys::GST_QUERY_DRAIN => QueryView::Drain(Drain(self)), gst_sys::GST_QUERY_DRAIN => QueryView::Drain(Drain(self)),
gst_sys::GST_QUERY_CONTEXT => QueryView::Context(Context(self)), gst_sys::GST_QUERY_CONTEXT => QueryView::Context(Context(self)),
gst_sys::GST_QUERY_BITRATE => QueryView::Bitrate(Bitrate(self)),
_ => QueryView::Other(Other(self)), _ => QueryView::Other(Other(self)),
} }
} }
@ -293,6 +300,7 @@ pub enum QueryView<T> {
Caps(Caps<T>), Caps(Caps<T>),
Drain(Drain<T>), Drain(Drain<T>),
Context(Context<T>), Context(Context<T>),
Bitrate(Bitrate<T>),
Other(Other<T>), Other(Other<T>),
__NonExhaustive, __NonExhaustive,
} }
@ -1218,6 +1226,27 @@ impl<T: AsMutPtr> Context<T> {
} }
} }
declare_concrete_query!(Bitrate, T);
impl<T: AsPtr> Bitrate<T> {
#[cfg(any(feature = "v1_16", feature = "dox"))]
pub fn get_bitrate(&self) -> u32 {
unsafe {
let mut bitrate = 0;
gst_sys::gst_query_parse_bitrate(self.0.as_ptr(), &mut bitrate);
bitrate
}
}
}
impl<T: AsMutPtr> Bitrate<T> {
#[cfg(any(feature = "v1_16", feature = "dox"))]
pub fn set_bitrate(&mut self, bitrate: u32) {
unsafe {
gst_sys::gst_query_set_bitrate(self.0.as_mut_ptr(), bitrate);
}
}
}
declare_concrete_query!(Other, T); declare_concrete_query!(Other, T);
#[cfg(test)] #[cfg(test)]

View file

@ -15,9 +15,9 @@ use glib;
use glib::translate::{from_glib_full, from_glib_none, mut_override, ToGlibPtr}; use glib::translate::{from_glib_full, from_glib_none, mut_override, ToGlibPtr};
use miniobject::*; use miniobject::*;
use Buffer; use BufferListRef;
use BufferList; use BufferRef;
use Caps; use CapsRef;
use FormattedSegment; use FormattedSegment;
use FormattedValue; use FormattedValue;
use Segment; use Segment;
@ -30,8 +30,8 @@ gst_define_mini_object_wrapper!(Sample, SampleRef, gst_sys::GstSample, [Debug,],
impl Sample { impl Sample {
pub fn new<F: FormattedValue>( pub fn new<F: FormattedValue>(
buffer: Option<&Buffer>, buffer: Option<&BufferRef>,
caps: Option<&Caps>, caps: Option<&CapsRef>,
segment: Option<&FormattedSegment<F>>, segment: Option<&FormattedSegment<F>>,
info: Option<Structure>, info: Option<Structure>,
) -> Self { ) -> Self {
@ -40,8 +40,11 @@ impl Sample {
let info = info.map(|i| i.into_ptr()).unwrap_or(ptr::null_mut()); let info = info.map(|i| i.into_ptr()).unwrap_or(ptr::null_mut());
from_glib_full(gst_sys::gst_sample_new( from_glib_full(gst_sys::gst_sample_new(
buffer.to_glib_none().0, buffer
caps.to_glib_none().0, .map(|buffer| buffer.as_mut_ptr())
.unwrap_or(ptr::null_mut()),
caps.map(|caps| caps.as_mut_ptr())
.unwrap_or(ptr::null_mut()),
segment.to_glib_none().0, segment.to_glib_none().0,
mut_override(info), mut_override(info),
)) ))
@ -49,8 +52,8 @@ impl Sample {
} }
pub fn with_buffer_list<F: FormattedValue>( pub fn with_buffer_list<F: FormattedValue>(
buffer_list: Option<&BufferList>, buffer_list: Option<&BufferListRef>,
caps: Option<&Caps>, caps: Option<&CapsRef>,
segment: Option<&FormattedSegment<F>>, segment: Option<&FormattedSegment<F>>,
info: Option<Structure>, info: Option<Structure>,
) -> Self { ) -> Self {
@ -59,7 +62,9 @@ impl Sample {
unsafe { unsafe {
gst_sys::gst_sample_set_buffer_list( gst_sys::gst_sample_set_buffer_list(
sample.to_glib_none().0, sample.to_glib_none().0,
buffer_list.to_glib_none().0, buffer_list
.map(|buffer_list| buffer_list.as_mut_ptr())
.unwrap_or(ptr::null_mut()),
); );
} }
sample sample
@ -67,16 +72,37 @@ impl Sample {
} }
impl SampleRef { impl SampleRef {
pub fn get_buffer(&self) -> Option<Buffer> { pub fn get_buffer(&self) -> Option<&BufferRef> {
unsafe { from_glib_none(gst_sys::gst_sample_get_buffer(self.as_mut_ptr())) } unsafe {
let ptr = gst_sys::gst_sample_get_buffer(self.as_mut_ptr());
if ptr.is_null() {
None
} else {
Some(BufferRef::from_ptr(ptr))
}
}
} }
pub fn get_buffer_list(&self) -> Option<BufferList> { pub fn get_buffer_list(&self) -> Option<&BufferListRef> {
unsafe { from_glib_none(gst_sys::gst_sample_get_buffer_list(self.as_mut_ptr())) } unsafe {
let ptr = gst_sys::gst_sample_get_buffer_list(self.as_mut_ptr());
if ptr.is_null() {
None
} else {
Some(BufferListRef::from_ptr(ptr))
}
}
} }
pub fn get_caps(&self) -> Option<Caps> { pub fn get_caps(&self) -> Option<&CapsRef> {
unsafe { from_glib_none(gst_sys::gst_sample_get_caps(self.as_mut_ptr())) } unsafe {
let ptr = gst_sys::gst_sample_get_caps(self.as_mut_ptr());
if ptr.is_null() {
None
} else {
Some(CapsRef::from_ptr(ptr))
}
}
} }
pub fn get_segment(&self) -> Option<Segment> { pub fn get_segment(&self) -> Option<Segment> {
@ -93,6 +119,56 @@ impl SampleRef {
} }
} }
} }
#[cfg(any(feature = "v1_16", feature = "dox"))]
pub fn set_buffer(&mut self, buffer: Option<&BufferRef>) {
unsafe {
gst_sys::gst_sample_set_buffer(
self.as_mut_ptr(),
buffer
.map(|buffer| buffer.as_mut_ptr())
.unwrap_or(ptr::null_mut()),
)
}
}
#[cfg(any(feature = "v1_16", feature = "dox"))]
pub fn set_buffer_list(&mut self, buffer_list: Option<&BufferListRef>) {
unsafe {
gst_sys::gst_sample_set_buffer_list(
self.as_mut_ptr(),
buffer_list
.map(|buffer_list| buffer_list.as_mut_ptr())
.unwrap_or(ptr::null_mut()),
)
}
}
#[cfg(any(feature = "v1_16", feature = "dox"))]
pub fn set_caps(&mut self, caps: Option<&CapsRef>) {
unsafe {
gst_sys::gst_sample_set_caps(
self.as_mut_ptr(),
caps.map(|caps| caps.as_mut_ptr())
.unwrap_or(ptr::null_mut()),
)
}
}
#[cfg(any(feature = "v1_16", feature = "dox"))]
pub fn set_segment(&mut self, segment: &Option<&Segment>) {
unsafe { gst_sys::gst_sample_set_segment(self.as_mut_ptr(), segment.to_glib_none().0) }
}
#[cfg(any(feature = "v1_16", feature = "dox"))]
pub fn set_info(&mut self, info: Option<Structure>) {
unsafe {
gst_sys::gst_sample_set_info(
self.as_mut_ptr(),
info.map(|i| i.into_ptr()).unwrap_or(ptr::null_mut()),
);
}
}
} }
impl fmt::Debug for SampleRef { impl fmt::Debug for SampleRef {

View file

@ -49,15 +49,18 @@ impl From<SampleDe> for Sample {
fn from(mut buf_de: SampleDe) -> Self { fn from(mut buf_de: SampleDe) -> Self {
if buf_de.buffer.is_some() { if buf_de.buffer.is_some() {
Sample::new::<GenericFormattedValue>( Sample::new::<GenericFormattedValue>(
buf_de.buffer.as_ref(), buf_de.buffer.as_ref().map(|buffer| buffer.as_ref()),
buf_de.caps.as_ref(), buf_de.caps.as_ref().map(|caps| caps.as_ref()),
buf_de.segment.as_ref(), buf_de.segment.as_ref(),
buf_de.info.take(), buf_de.info.take(),
) )
} else { } else {
Sample::with_buffer_list::<GenericFormattedValue>( Sample::with_buffer_list::<GenericFormattedValue>(
buf_de.buffer_list.as_ref(), buf_de
buf_de.caps.as_ref(), .buffer_list
.as_ref()
.map(|buffer_list| buffer_list.as_ref()),
buf_de.caps.as_ref().map(|caps| caps.as_ref()),
buf_de.segment.as_ref(), buf_de.segment.as_ref(),
buf_de.info.take(), buf_de.info.take(),
) )