examples: Improve custom-meta example to pass initialization into the init function via the params parameter

This commit is contained in:
Sebastian Dröge 2021-02-24 16:19:43 +02:00 committed by Sebastian Dröge
parent efb249f7b9
commit cc6a51e73d

View file

@ -12,7 +12,7 @@ mod examples_common;
mod custom_meta { mod custom_meta {
use gst::prelude::*; use gst::prelude::*;
use std::fmt; use std::fmt;
use std::ptr; use std::mem;
// Public Rust type for the custom meta. // Public Rust type for the custom meta.
#[repr(transparent)] #[repr(transparent)]
@ -29,19 +29,17 @@ mod custom_meta {
label: String, label: String,
) -> gst::MetaRefMut<Self, gst::meta::Standalone> { ) -> gst::MetaRefMut<Self, gst::meta::Standalone> {
unsafe { unsafe {
// First add it: this will store an empty label via custom_meta_init(). // Manually dropping because gst_buffer_add_meta() takes ownership of the
// content of the struct.
let mut params = mem::ManuallyDrop::new(imp::CustomMetaParams { label });
// The label is passed through via the params to custom_meta_init().
let meta = gst::ffi::gst_buffer_add_meta( let meta = gst::ffi::gst_buffer_add_meta(
buffer.as_mut_ptr(), buffer.as_mut_ptr(),
imp::custom_meta_get_info(), imp::custom_meta_get_info(),
ptr::null_mut(), &mut *params as *mut imp::CustomMetaParams as glib::ffi::gpointer,
) as *mut imp::CustomMeta; ) as *mut imp::CustomMeta;
// Then actually set the label.
{
let meta = &mut *meta;
meta.label = label;
}
Self::from_mut_ptr(buffer, meta) Self::from_mut_ptr(buffer, meta)
} }
} }
@ -76,6 +74,10 @@ mod custom_meta {
use std::mem; use std::mem;
use std::ptr; use std::ptr;
pub(super) struct CustomMetaParams {
pub label: String,
}
// This is the C type that is actually stored as meta inside the buffers. // This is the C type that is actually stored as meta inside the buffers.
#[repr(C)] #[repr(C)]
pub struct CustomMeta { pub struct CustomMeta {
@ -89,7 +91,7 @@ mod custom_meta {
let t = from_glib(gst::ffi::gst_meta_api_type_register( let t = from_glib(gst::ffi::gst_meta_api_type_register(
b"MyCustomMetaAPI\0".as_ptr() as *const _, b"MyCustomMetaAPI\0".as_ptr() as *const _,
// We provide no tags here as our meta is just a label and does // We provide no tags here as our meta is just a label and does
// not refer to any specific aspect of the buffer // not refer to any specific aspect of the buffer.
[ptr::null::<std::os::raw::c_char>()].as_ptr() as *mut *const _, [ptr::null::<std::os::raw::c_char>()].as_ptr() as *mut *const _,
)); ));
@ -105,13 +107,16 @@ mod custom_meta {
// initialized. They will contain random memory before. // initialized. They will contain random memory before.
unsafe extern "C" fn custom_meta_init( unsafe extern "C" fn custom_meta_init(
meta: *mut gst::ffi::GstMeta, meta: *mut gst::ffi::GstMeta,
_params: glib::ffi::gpointer, params: glib::ffi::gpointer,
_buffer: *mut gst::ffi::GstBuffer, _buffer: *mut gst::ffi::GstBuffer,
) -> glib::ffi::gboolean { ) -> glib::ffi::gboolean {
let meta = &mut *(meta as *mut CustomMeta); assert!(!params.is_null());
// Need to initialize all our fields correctly here let meta = &mut *(meta as *mut CustomMeta);
ptr::write(&mut meta.label, String::new()); let params = ptr::read(params as *const CustomMetaParams);
// Need to initialize all our fields correctly here.
ptr::write(&mut meta.label, params.label);
true.to_glib() true.to_glib()
} }
@ -137,7 +142,7 @@ mod custom_meta {
_type_: glib::ffi::GQuark, _type_: glib::ffi::GQuark,
_data: glib::ffi::gpointer, _data: glib::ffi::gpointer,
) -> glib::ffi::gboolean { ) -> glib::ffi::gboolean {
let meta = &mut *(meta as *mut CustomMeta); let meta = &*(meta as *mut CustomMeta);
// We simply copy over our meta here. Other metas might have to look at the type // We simply copy over our meta here. Other metas might have to look at the type
// and do things conditional on that, or even just drop the meta. // and do things conditional on that, or even just drop the meta.