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| {
let sample = appsink.pull_sample().ok_or(gst::FlowError::Eos)?;
let _buffer = sample.get_buffer().ok_or_else(|| {
gst_element_error!(
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(|| {
{
let _buffer = sample.get_buffer().ok_or_else(|| {
gst_element_error!(
appsink,
gst::ResourceError::Failed,
("Failed to get video info from sample")
("Failed to get buffer from appsink")
);
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
.lock()
.unwrap()
@ -638,7 +640,7 @@ fn main_loop(mut app: App) -> Result<(), Error> {
let buffer = sample.get_buffer().unwrap();
let info = sample
.get_caps()
.and_then(|caps| gst_video::VideoInfo::from_caps(caps.as_ref()))
.and_then(|caps| gst_video::VideoInfo::from_caps(caps))
.unwrap();
{
@ -650,11 +652,13 @@ fn main_loop(mut app: App) -> Result<(), Error> {
.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());
}
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));
}
}

View file

@ -165,7 +165,7 @@ mod tests {
let res = res.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 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 {
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);
@ -1329,6 +1343,8 @@ pub struct SeekBuilder<'a> {
start: GenericFormattedValue,
stop_type: ::SeekType,
stop: GenericFormattedValue,
#[allow(unused)]
trickmode_interval: Option<::ClockTime>,
}
impl<'a> SeekBuilder<'a> {
fn new(
@ -1348,18 +1364,30 @@ impl<'a> SeekBuilder<'a> {
start,
stop_type,
stop,
trickmode_interval: None,
}
}
event_builder_generic_impl!(|s: &Self| gst_sys::gst_event_new_seek(
s.rate,
s.start.get_format().to_glib(),
s.flags.to_glib(),
s.start_type.to_glib(),
s.start.get_value(),
s.stop_type.to_glib(),
s.stop.get_value(),
));
event_builder_generic_impl!(|s: &Self| {
let ev = gst_sys::gst_event_new_seek(
s.rate,
s.start.get_format().to_glib(),
s.flags.to_glib(),
s.start_type.to_glib(),
s.start.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> {

View file

@ -102,6 +102,7 @@ impl MessageRef {
gst_sys::GST_MESSAGE_STREAMS_SELECTED => {
MessageView::StreamsSelected(StreamsSelected(self))
}
gst_sys::GST_MESSAGE_DEVICE_CHANGED => MessageView::DeviceChanged(DeviceChanged(self)),
_ => MessageView::Other,
}
}
@ -340,6 +341,15 @@ impl Message {
assert_initialized_main_thread!();
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 {
@ -396,6 +406,7 @@ pub enum MessageView<'a> {
StreamCollection(StreamCollection<'a>),
StreamsSelected(StreamsSelected<'a>),
Redirect(Redirect<'a>),
DeviceChanged(DeviceChanged<'a>),
Other,
__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> {
src: Option<Object>,
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)]
mod tests {
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 {
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 {
self.meta as *const _ as *const <T as MetaAPI>::GstType
}

View file

@ -99,6 +99,26 @@ impl<T: MiniObject> GstRc<T> {
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> {
@ -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> {
fn clone(&self) -> GstRc<T> {
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 {
@ -213,6 +219,7 @@ impl QueryRef {
gst_sys::GST_QUERY_CAPS => QueryView::Caps(Caps(self)),
gst_sys::GST_QUERY_DRAIN => QueryView::Drain(Drain(self)),
gst_sys::GST_QUERY_CONTEXT => QueryView::Context(Context(self)),
gst_sys::GST_QUERY_BITRATE => QueryView::Bitrate(Bitrate(self)),
_ => QueryView::Other(Other(self)),
}
}
@ -293,6 +300,7 @@ pub enum QueryView<T> {
Caps(Caps<T>),
Drain(Drain<T>),
Context(Context<T>),
Bitrate(Bitrate<T>),
Other(Other<T>),
__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);
#[cfg(test)]

View file

@ -15,9 +15,9 @@ use glib;
use glib::translate::{from_glib_full, from_glib_none, mut_override, ToGlibPtr};
use miniobject::*;
use Buffer;
use BufferList;
use Caps;
use BufferListRef;
use BufferRef;
use CapsRef;
use FormattedSegment;
use FormattedValue;
use Segment;
@ -30,8 +30,8 @@ gst_define_mini_object_wrapper!(Sample, SampleRef, gst_sys::GstSample, [Debug,],
impl Sample {
pub fn new<F: FormattedValue>(
buffer: Option<&Buffer>,
caps: Option<&Caps>,
buffer: Option<&BufferRef>,
caps: Option<&CapsRef>,
segment: Option<&FormattedSegment<F>>,
info: Option<Structure>,
) -> Self {
@ -40,8 +40,11 @@ impl Sample {
let info = info.map(|i| i.into_ptr()).unwrap_or(ptr::null_mut());
from_glib_full(gst_sys::gst_sample_new(
buffer.to_glib_none().0,
caps.to_glib_none().0,
buffer
.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,
mut_override(info),
))
@ -49,8 +52,8 @@ impl Sample {
}
pub fn with_buffer_list<F: FormattedValue>(
buffer_list: Option<&BufferList>,
caps: Option<&Caps>,
buffer_list: Option<&BufferListRef>,
caps: Option<&CapsRef>,
segment: Option<&FormattedSegment<F>>,
info: Option<Structure>,
) -> Self {
@ -59,7 +62,9 @@ impl Sample {
unsafe {
gst_sys::gst_sample_set_buffer_list(
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
@ -67,16 +72,37 @@ impl Sample {
}
impl SampleRef {
pub fn get_buffer(&self) -> Option<Buffer> {
unsafe { from_glib_none(gst_sys::gst_sample_get_buffer(self.as_mut_ptr())) }
pub fn get_buffer(&self) -> Option<&BufferRef> {
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> {
unsafe { from_glib_none(gst_sys::gst_sample_get_buffer_list(self.as_mut_ptr())) }
pub fn get_buffer_list(&self) -> Option<&BufferListRef> {
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> {
unsafe { from_glib_none(gst_sys::gst_sample_get_caps(self.as_mut_ptr())) }
pub fn get_caps(&self) -> Option<&CapsRef> {
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> {
@ -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 {

View file

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