mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-11-21 19:11:02 +00:00
net/quinn: Add helper for adding stream id as meta to buffers
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1634>
This commit is contained in:
parent
9b5f4b48ca
commit
0e89a79727
4 changed files with 165 additions and 0 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -2846,6 +2846,7 @@ version = "0.14.0-alpha.1"
|
|||
dependencies = [
|
||||
"bytes",
|
||||
"futures",
|
||||
"glib",
|
||||
"gst-plugin-version-helper",
|
||||
"gstreamer",
|
||||
"gstreamer-base",
|
||||
|
|
|
@ -11,6 +11,7 @@ rust-version.workspace = true
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
glib.workspace = true
|
||||
gst.workspace = true
|
||||
gst-base.workspace = true
|
||||
tokio = { version = "1.36.0", default-features = false, features = ["time", "rt-multi-thread"] }
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
use gst::glib;
|
||||
use gst::prelude::*;
|
||||
mod common;
|
||||
pub mod quinnquicmeta;
|
||||
mod quinnquicsink;
|
||||
mod quinnquicsrc;
|
||||
mod utils;
|
||||
|
|
162
net/quinn/src/quinnquicmeta/mod.rs
Normal file
162
net/quinn/src/quinnquicmeta/mod.rs
Normal file
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* Taken from
|
||||
* https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/blob/main/examples/src/bin/custom_meta.rs
|
||||
*/
|
||||
use gst::prelude::*;
|
||||
use std::{fmt, mem};
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct QuinnQuicMeta(imp::QuinnQuicMeta);
|
||||
|
||||
unsafe impl Send for QuinnQuicMeta {}
|
||||
unsafe impl Sync for QuinnQuicMeta {}
|
||||
|
||||
impl QuinnQuicMeta {
|
||||
pub fn add(
|
||||
buffer: &mut gst::BufferRef,
|
||||
stream_id: u64,
|
||||
is_datagram: bool,
|
||||
) -> gst::MetaRefMut<Self, gst::meta::Standalone> {
|
||||
unsafe {
|
||||
let mut params = mem::ManuallyDrop::new(imp::QuinnQuicMetaParams {
|
||||
stream_id,
|
||||
is_datagram,
|
||||
});
|
||||
|
||||
let meta = gst::ffi::gst_buffer_add_meta(
|
||||
buffer.as_mut_ptr(),
|
||||
imp::custom_meta_get_info(),
|
||||
&mut *params as *mut imp::QuinnQuicMetaParams as glib::ffi::gpointer,
|
||||
) as *mut imp::QuinnQuicMeta;
|
||||
|
||||
Self::from_mut_ptr(buffer, meta)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn stream_id(&self) -> u64 {
|
||||
self.0.stream_id
|
||||
}
|
||||
|
||||
pub fn is_datagram(&self) -> bool {
|
||||
self.0.is_datagram
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl MetaAPI for QuinnQuicMeta {
|
||||
type GstType = imp::QuinnQuicMeta;
|
||||
|
||||
fn meta_api() -> glib::Type {
|
||||
imp::custom_meta_api_get_type()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for QuinnQuicMeta {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("QuinnQuicMeta")
|
||||
.field("stream_id", &self.0.stream_id)
|
||||
.field("is_datagram", &self.0.is_datagram)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
mod imp {
|
||||
use std::{mem, ptr};
|
||||
|
||||
use glib::translate::*;
|
||||
|
||||
pub(super) struct QuinnQuicMetaParams {
|
||||
pub stream_id: u64,
|
||||
pub is_datagram: bool,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct QuinnQuicMeta {
|
||||
parent: gst::ffi::GstMeta,
|
||||
pub(super) stream_id: u64,
|
||||
pub(super) is_datagram: bool,
|
||||
}
|
||||
|
||||
pub(super) fn custom_meta_api_get_type() -> glib::Type {
|
||||
static TYPE: std::sync::OnceLock<glib::Type> = std::sync::OnceLock::new();
|
||||
|
||||
*TYPE.get_or_init(|| unsafe {
|
||||
let t = glib::Type::from_glib(gst::ffi::gst_meta_api_type_register(
|
||||
b"QuinnQuicMetaAPI\0".as_ptr() as *const _,
|
||||
[ptr::null::<std::os::raw::c_int>()].as_ptr() as *mut *const _,
|
||||
));
|
||||
|
||||
assert_ne!(t, glib::Type::INVALID);
|
||||
|
||||
t
|
||||
})
|
||||
}
|
||||
|
||||
unsafe extern "C" fn custom_meta_init(
|
||||
meta: *mut gst::ffi::GstMeta,
|
||||
params: glib::ffi::gpointer,
|
||||
_buffer: *mut gst::ffi::GstBuffer,
|
||||
) -> glib::ffi::gboolean {
|
||||
assert!(!params.is_null());
|
||||
|
||||
let meta = &mut *(meta as *mut QuinnQuicMeta);
|
||||
let params = ptr::read(params as *const QuinnQuicMetaParams);
|
||||
|
||||
ptr::write(&mut meta.stream_id, params.stream_id);
|
||||
ptr::write(&mut meta.is_datagram, params.is_datagram);
|
||||
|
||||
true.into_glib()
|
||||
}
|
||||
|
||||
unsafe extern "C" fn custom_meta_free(
|
||||
meta: *mut gst::ffi::GstMeta,
|
||||
_buffer: *mut gst::ffi::GstBuffer,
|
||||
) {
|
||||
let meta = &mut *(meta as *mut QuinnQuicMeta);
|
||||
|
||||
// Need to free/drop all our fields here.
|
||||
ptr::drop_in_place(&mut meta.stream_id);
|
||||
}
|
||||
|
||||
unsafe extern "C" fn custom_meta_transform(
|
||||
dest: *mut gst::ffi::GstBuffer,
|
||||
meta: *mut gst::ffi::GstMeta,
|
||||
_buffer: *mut gst::ffi::GstBuffer,
|
||||
_type_: glib::ffi::GQuark,
|
||||
_data: glib::ffi::gpointer,
|
||||
) -> glib::ffi::gboolean {
|
||||
let meta = &*(meta as *mut QuinnQuicMeta);
|
||||
|
||||
super::QuinnQuicMeta::add(
|
||||
gst::BufferRef::from_mut_ptr(dest),
|
||||
meta.stream_id,
|
||||
meta.is_datagram,
|
||||
);
|
||||
|
||||
true.into_glib()
|
||||
}
|
||||
|
||||
pub(super) fn custom_meta_get_info() -> *const gst::ffi::GstMetaInfo {
|
||||
struct MetaInfo(ptr::NonNull<gst::ffi::GstMetaInfo>);
|
||||
unsafe impl Send for MetaInfo {}
|
||||
unsafe impl Sync for MetaInfo {}
|
||||
|
||||
static META_INFO: std::sync::OnceLock<MetaInfo> = std::sync::OnceLock::new();
|
||||
|
||||
META_INFO
|
||||
.get_or_init(|| unsafe {
|
||||
MetaInfo(
|
||||
ptr::NonNull::new(gst::ffi::gst_meta_register(
|
||||
custom_meta_api_get_type().into_glib(),
|
||||
b"QuinnQuicMeta\0".as_ptr() as *const _,
|
||||
mem::size_of::<QuinnQuicMeta>(),
|
||||
Some(custom_meta_init),
|
||||
Some(custom_meta_free),
|
||||
Some(custom_meta_transform),
|
||||
) as *mut gst::ffi::GstMetaInfo)
|
||||
.expect("Failed to register meta API"),
|
||||
)
|
||||
})
|
||||
.0
|
||||
.as_ptr()
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue