Add crates for gstreamer-allocators

This commit is contained in:
Christian Meissl 2022-02-26 16:16:35 +01:00 committed by Sebastian Dröge
parent 44d39f8824
commit a8dc789ef8
34 changed files with 1457 additions and 0 deletions

View file

@ -23,6 +23,7 @@ members = [
"gstreamer-tag/sys", "gstreamer-tag/sys",
"gstreamer-video/sys", "gstreamer-video/sys",
"gstreamer-webrtc/sys", "gstreamer-webrtc/sys",
"gstreamer-allocators/sys",
"gstreamer", "gstreamer",
"gstreamer-app", "gstreamer-app",
"gstreamer-audio", "gstreamer-audio",
@ -43,6 +44,7 @@ members = [
"gstreamer-sdp", "gstreamer-sdp",
"gstreamer-video", "gstreamer-video",
"gstreamer-webrtc", "gstreamer-webrtc",
"gstreamer-allocators",
"examples", "examples",
"tutorials", "tutorials",
] ]

View file

@ -0,0 +1 @@
../gstreamer/CHANGELOG.md

View file

@ -0,0 +1 @@
../COPYRIGHT

View file

@ -0,0 +1,38 @@
[package]
name = "gstreamer-allocators"
version = "0.19.0"
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
categories = ["api-bindings", "multimedia"]
description = "Rust bindings for GStreamer Allocators library"
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
license = "MIT/Apache-2.0"
readme = "README.md"
homepage = "https://gstreamer.freedesktop.org"
documentation = "https://gstreamer.pages.freedesktop.org/gstreamer-rs/stable/latest/docs/gstreamer_allocators/"
keywords = ["gstreamer", "multimedia", "audio", "video", "gnome"]
edition = "2021"
rust-version = "1.56"
[dependencies]
libc = "0.2"
bitflags = "1.0"
ffi = { package = "gstreamer-allocators-sys", path = "sys" }
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
gst = { package = "gstreamer", path = "../gstreamer" }
once_cell = "1.0"
[dev-dependencies]
gir-format-check = "0.1"
[features]
default = []
v1_10 = ["gst/v1_10", "ffi/v1_10"]
v1_12 = ["gst/v1_12", "ffi/v1_12", "v1_10"]
v1_14 = ["gst/v1_14", "ffi/v1_14", "v1_12"]
v1_16 = ["gst/v1_16", "ffi/v1_16", "v1_14"]
v1_18 = ["gst/v1_18", "ffi/v1_18", "v1_16"]
v1_20 = ["gst/v1_20", "ffi/v1_20", "v1_18"]
dox = ["v1_20", "ffi/dox", "glib/dox", "gst/dox"]
[package.metadata.docs.rs]
features = ["dox"]

View file

@ -0,0 +1,72 @@
[options]
concurrency = "send+sync"
generate_display_trait = false
generate_safety_asserts = true
girs_directories = ["../gir-files", "../gst-gir-files"]
library = "GstAllocators"
min_cfg_version = "1.8"
single_version_file = true
trust_return_value_nullability = true
version = "1.0"
work_mode = "normal"
external_libraries = [
"GLib",
"GObject",
"Gst",
]
generate = [
"GstAllocators.FdMemoryFlags",
"GstAllocators.PhysMemoryAllocator",
]
manual = [
"Gst.Allocator",
"Gst.Memory",
]
[[object]]
name = "Gst.Buffer"
ref_mode = "ref"
status = "manual"
[[object]]
name = "GstAllocators.*"
status = "generate"
[[object.function]]
name = "dmabuf_memory_get_fd"
manual = true
[[object.function]]
name = "fd_memory_get_fd"
manual = true
[[object.function]]
name = "is_dmabuf_memory"
manual = true
[[object.function]]
name = "is_fd_memory"
manual = true
[[object.function]]
name = "is_phys_memory"
manual = true
[[object.function]]
name = "phys_memory_get_phys_addr"
manual = true
[[object]]
name = "GstAllocators.DmaBufAllocator"
status = "generate"
cfg_condition = "target_os = \"linux\""
[[object.function]]
name = "alloc"
manual = true
[[object.function]]
name = "alloc_with_flags"
manual = true
[[object]]
name = "GstAllocators.FdAllocator"
status = "generate"
[[object.function]]
name = "alloc"
manual = true

View file

@ -0,0 +1 @@
../LICENSE-APACHE

View file

@ -0,0 +1 @@
../LICENSE-MIT

View file

@ -0,0 +1,202 @@
# gstreamer-rs [![crates.io](https://img.shields.io/crates/v/gstreamer-allocators.svg)](https://crates.io/crates/gstreamer-allocators) [![pipeline status](https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/badges/main/pipeline.svg)](https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/commits/main)
[GStreamer](https://gstreamer.freedesktop.org/) (Allocators library) bindings for Rust.
Documentation can be found [here](https://gstreamer.pages.freedesktop.org/gstreamer-rs/stable/latest/docs/gstreamer_allocators/).
These bindings are providing a safe API that can be used to interface with
GStreamer, e.g. for writing GStreamer-based applications and GStreamer plugins.
The bindings are mostly autogenerated with [gir](https://github.com/gtk-rs/gir/)
based on the [GObject-Introspection](https://wiki.gnome.org/Projects/GObjectIntrospection/)
API metadata provided by the GStreamer project.
## Table of Contents
1. [Installation](#installation)
1. [Linux/BSDs](#installation-linux)
1. [macOS](#installation-macos)
1. [Windows](#installation-windows)
1. [Getting Started](#getting-started)
1. [License](#license)
1. [Contribution](#contribution)
<a name="installation"/>
## Installation
To build the GStreamer bindings or anything depending on them, you need to
have at least GStreamer 1.8 and gst-plugins-base 1.8 installed. In addition,
some of the examples/tutorials require various GStreamer plugins to be
available, which can be found in gst-plugins-base, gst-plugins-good,
gst-plugins-bad, gst-plugins-ugly and/or gst-libav.
<a name="installation-linux"/>
### Linux/BSDs
You need to install the above mentioned packages with your distributions
package manager, or build them from source.
On Debian/Ubuntu they can be installed with
```console
$ apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev \
gstreamer1.0-plugins-base gstreamer1.0-plugins-good \
gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly \
gstreamer1.0-libav libgstrtspserver-1.0-dev libges-1.0-dev
```
The minimum required version of the above libraries is >= 1.8. If you
build the gstreamer-player sub-crate, or any of the examples that
depend on gstreamer-player, you must ensure that in addition to the
above packages, `libgstreamer-plugins-bad1.0-dev` is installed and
that the version is >= 1.12. See the `Cargo.toml` files for the full
details,
```console
$ # Only if you wish to install gstreamer-player, make sure the version
$ # of this package is >= 1.12.
$ apt-get install libgstreamer-plugins-bad1.0-dev
```
Package names on other distributions should be similar.
Please submit a pull request with instructions for yours.
<a name="installation-macos"/>
### macOS
You can install GStreamer and the plugins via [Homebrew](https://brew.sh/) or
by installing the [binaries](https://gstreamer.freedesktop.org/data/pkg/osx/)
provided by the GStreamer project.
#### Homebrew
Homebrew only installs various plugins if explicitly enabled, so some extra
`--with-*` flags may be required.
```console
$ brew install gstreamer gst-plugins-base gst-plugins-good \
gst-plugins-bad gst-plugins-ugly gst-libav gst-rtsp-server \
gst-editing-services --with-orc --with-libogg --with-opus \
--with-pango --with-theora --with-libvorbis --with-libvpx \
--enable-gtk3
```
If you wish to install the gstreamer-player sub-crate, make sure the
version of these libraries is >= 1.12. Otherwise, a version >= 1.8 is
sufficient.
#### GStreamer Binaries
You need to download the *two* `.pkg` files from the GStreamer website and
install them, e.g. `gstreamer-1.0-1.12.3-x86_64.pkg` and
`gstreamer-1.0-devel-1.12.3-x86_64.pkg`.
After installation, you also need to install `pkg-config` (e.g. via Homebrew)
and set the `PKG_CONFIG_PATH` environment variable
```console
$ export PKG_CONFIG_PATH="/Library/Frameworks/GStreamer.framework/Versions/Current/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}"
```
<a name="installation-windows"/>
### Windows
You can install GStreamer and the plugins via [MSYS2](http://www.msys2.org/)
with `pacman` or by installing the
[binaries](https://gstreamer.freedesktop.org/data/pkg/windows/) provided by
the GStreamer project.
#### MSYS2 / pacman
```console
$ pacman -S glib2-devel pkg-config \
mingw-w64-x86_64-gstreamer mingw-w64-x86_64-gst-plugins-base \
mingw-w64-x86_64-gst-plugins-good mingw-w64-x86_64-gst-plugins-bad \
mingw-w64-x86_64-gst-plugins-ugly mingw-w64-x86_64-gst-libav \
mingw-w64-x86_64-gst-rtsp-server
```
If you wish to install the gstreamer-player sub-crate, make sure the
version of these libraries is >= 1.12. Otherwise, a version >= 1.8 is
sufficient.
Note that the version of `pkg-config` included in `MSYS2` is
[known to have problems](https://github.com/rust-lang/pkg-config-rs/issues/51#issuecomment-346300858)
compiling GStreamer, so you may need to install another version. One option
would be [`pkg-config-lite`](https://sourceforge.net/projects/pkgconfiglite/).
#### GStreamer Binaries
You need to download the *two* `.msi` files for your platform from the
GStreamer website and install them, e.g. `gstreamer-1.0-x86_64-1.12.3.msi` and
`gstreamer-1.0-devel-x86_64-1.12.3.msi`.
After installation, you also need to install `pkg-config` (e.g. via MSYS2 or
from [here](https://sourceforge.net/projects/pkgconfiglite/))
and set the `PKG_CONFIG_PATH` environment variable
```console
$ export PKG_CONFIG_PATH="c:\\gstreamer\\1.0\\x86_64\\lib\\pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}"
```
<a name="getting-started"/>
## Getting Started
The API reference can be found
[here](https://gstreamer.pages.freedesktop.org/gstreamer-rs/stable/latest/docs/gstreamer/), however it is
only the Rust API reference and does not explain any of the concepts.
For getting started with GStreamer development, the best would be to follow
the [documentation](https://gstreamer.freedesktop.org/documentation/) on the
GStreamer website, especially the [Application Development
Manual](https://gstreamer.freedesktop.org/documentation/application-development/).
While being C-centric, it explains all the fundamental concepts of GStreamer
and the code examples should be relatively easily translatable to Rust. The
API is basically the same, function/struct names are the same and everything
is only more convenient (hopefully) and safer.
In addition there are
[tutorials](https://gstreamer.freedesktop.org/documentation/tutorials/) on the
GStreamer website. Many of them were ported to Rust already and the code can
be found in the
[tutorials](https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/tree/main/tutorials)
directory.
Some further examples for various aspects of GStreamer and how to use it from
Rust can be found in the
[examples](https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/tree/main/examples)
directory.
Various GStreamer plugins written in Rust can be found in the
[gst-plugins-rs](https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs)
repository.
<a name="license"/>
## LICENSE
gstreamer-rs and all crates contained in here are licensed under either of
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
http://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT](LICENSE-MIT) or
http://opensource.org/licenses/MIT)
at your option.
GStreamer itself is licensed under the Lesser General Public License version
2.1 or (at your option) any later version:
https://www.gnu.org/licenses/lgpl-2.1.html
<a name="contribution"/>
## Contribution
Any kinds of contributions are welcome as a pull request.
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in gstreamer-rs by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions.

View file

@ -0,0 +1,26 @@
// This file was generated by gir (https://github.com/gtk-rs/gir)
// from gir-files (https://github.com/gtk-rs/gir-files)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git)
// DO NOT EDIT
use std::ffi::CStr;
#[doc(alias = "GST_ALLOCATOR_DMABUF")]
pub static ALLOCATOR_DMABUF: once_cell::sync::Lazy<&'static str> =
once_cell::sync::Lazy::new(|| unsafe {
CStr::from_ptr(ffi::GST_ALLOCATOR_DMABUF).to_str().unwrap()
});
#[doc(alias = "GST_ALLOCATOR_FD")]
pub static ALLOCATOR_FD: once_cell::sync::Lazy<&'static str> =
once_cell::sync::Lazy::new(|| unsafe {
CStr::from_ptr(ffi::GST_ALLOCATOR_FD).to_str().unwrap()
});
#[cfg(any(feature = "v1_12", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_12")))]
#[doc(alias = "GST_CAPS_FEATURE_MEMORY_DMABUF")]
pub static CAPS_FEATURE_MEMORY_DMABUF: once_cell::sync::Lazy<&'static str> =
once_cell::sync::Lazy::new(|| unsafe {
CStr::from_ptr(ffi::GST_CAPS_FEATURE_MEMORY_DMABUF)
.to_str()
.unwrap()
});

View file

@ -0,0 +1,36 @@
// This file was generated by gir (https://github.com/gtk-rs/gir)
// from gir-files (https://github.com/gtk-rs/gir-files)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git)
// DO NOT EDIT
use crate::FdAllocator;
use glib::object::Cast;
use glib::translate::*;
glib::wrapper! {
#[doc(alias = "GstDmaBufAllocator")]
pub struct DmaBufAllocator(Object<ffi::GstDmaBufAllocator, ffi::GstDmaBufAllocatorClass>) @extends FdAllocator, gst::Allocator;
match fn {
type_ => || ffi::gst_dmabuf_allocator_get_type(),
}
}
impl DmaBufAllocator {
pub const NONE: Option<&'static DmaBufAllocator> = None;
#[doc(alias = "gst_dmabuf_allocator_new")]
pub fn new() -> DmaBufAllocator {
assert_initialized_main_thread!();
unsafe { gst::Allocator::from_glib_full(ffi::gst_dmabuf_allocator_new()).unsafe_cast() }
}
}
impl Default for DmaBufAllocator {
fn default() -> Self {
Self::new()
}
}
unsafe impl Send for DmaBufAllocator {}
unsafe impl Sync for DmaBufAllocator {}

View file

@ -0,0 +1,35 @@
// This file was generated by gir (https://github.com/gtk-rs/gir)
// from gir-files (https://github.com/gtk-rs/gir-files)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git)
// DO NOT EDIT
use glib::object::Cast;
use glib::translate::*;
glib::wrapper! {
#[doc(alias = "GstFdAllocator")]
pub struct FdAllocator(Object<ffi::GstFdAllocator, ffi::GstFdAllocatorClass>) @extends gst::Allocator;
match fn {
type_ => || ffi::gst_fd_allocator_get_type(),
}
}
impl FdAllocator {
pub const NONE: Option<&'static FdAllocator> = None;
#[doc(alias = "gst_fd_allocator_new")]
pub fn new() -> FdAllocator {
assert_initialized_main_thread!();
unsafe { gst::Allocator::from_glib_full(ffi::gst_fd_allocator_new()).unsafe_cast() }
}
}
impl Default for FdAllocator {
fn default() -> Self {
Self::new()
}
}
unsafe impl Send for FdAllocator {}
unsafe impl Sync for FdAllocator {}

View file

@ -0,0 +1,38 @@
// This file was generated by gir (https://github.com/gtk-rs/gir)
// from gir-files (https://github.com/gtk-rs/gir-files)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git)
// DO NOT EDIT
use bitflags::bitflags;
use glib::translate::*;
bitflags! {
#[doc(alias = "GstFdMemoryFlags")]
pub struct FdMemoryFlags: u32 {
#[doc(alias = "GST_FD_MEMORY_FLAG_NONE")]
const NONE = ffi::GST_FD_MEMORY_FLAG_NONE as u32;
#[doc(alias = "GST_FD_MEMORY_FLAG_KEEP_MAPPED")]
const KEEP_MAPPED = ffi::GST_FD_MEMORY_FLAG_KEEP_MAPPED as u32;
#[doc(alias = "GST_FD_MEMORY_FLAG_MAP_PRIVATE")]
const MAP_PRIVATE = ffi::GST_FD_MEMORY_FLAG_MAP_PRIVATE as u32;
#[doc(alias = "GST_FD_MEMORY_FLAG_DONT_CLOSE")]
const DONT_CLOSE = ffi::GST_FD_MEMORY_FLAG_DONT_CLOSE as u32;
}
}
#[doc(hidden)]
impl IntoGlib for FdMemoryFlags {
type GlibType = ffi::GstFdMemoryFlags;
fn into_glib(self) -> ffi::GstFdMemoryFlags {
self.bits()
}
}
#[doc(hidden)]
impl FromGlib<ffi::GstFdMemoryFlags> for FdMemoryFlags {
unsafe fn from_glib(value: ffi::GstFdMemoryFlags) -> Self {
skip_assert_initialized!();
Self::from_bits_truncate(value)
}
}

View file

@ -0,0 +1,6 @@
// This file was generated by gir (https://github.com/gtk-rs/gir)
// from gir-files (https://github.com/gtk-rs/gir-files)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git)
// DO NOT EDIT
use glib::translate::*;

View file

@ -0,0 +1,44 @@
// This file was generated by gir (https://github.com/gtk-rs/gir)
// from gir-files (https://github.com/gtk-rs/gir-files)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git)
// DO NOT EDIT
#[cfg(any(target_os = "linux", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(target_os = "linux")))]
#[cfg(any(feature = "v1_12", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_12")))]
mod dma_buf_allocator;
#[cfg(any(target_os = "linux", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(target_os = "linux")))]
#[cfg(any(feature = "v1_12", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_12")))]
pub use self::dma_buf_allocator::DmaBufAllocator;
mod fd_allocator;
pub use self::fd_allocator::FdAllocator;
#[cfg(any(feature = "v1_14", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
mod phys_memory_allocator;
#[cfg(any(feature = "v1_14", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
pub use self::phys_memory_allocator::PhysMemoryAllocator;
mod flags;
pub use self::flags::FdMemoryFlags;
pub mod functions;
mod constants;
pub use self::constants::ALLOCATOR_DMABUF;
pub use self::constants::ALLOCATOR_FD;
#[cfg(any(feature = "v1_12", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_12")))]
pub use self::constants::CAPS_FEATURE_MEMORY_DMABUF;
#[doc(hidden)]
pub mod traits {
#[cfg(any(feature = "v1_14", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
pub use super::phys_memory_allocator::PhysMemoryAllocatorExt;
}

View file

@ -0,0 +1,26 @@
// This file was generated by gir (https://github.com/gtk-rs/gir)
// from gir-files (https://github.com/gtk-rs/gir-files)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git)
// DO NOT EDIT
use glib::object::IsA;
glib::wrapper! {
#[doc(alias = "GstPhysMemoryAllocator")]
pub struct PhysMemoryAllocator(Interface<ffi::GstPhysMemoryAllocator, ffi::GstPhysMemoryAllocatorInterface>) @requires gst::Allocator;
match fn {
type_ => || ffi::gst_phys_memory_allocator_get_type(),
}
}
impl PhysMemoryAllocator {
pub const NONE: Option<&'static PhysMemoryAllocator> = None;
}
unsafe impl Send for PhysMemoryAllocator {}
unsafe impl Sync for PhysMemoryAllocator {}
pub trait PhysMemoryAllocatorExt: 'static {}
impl<O: IsA<PhysMemoryAllocator>> PhysMemoryAllocatorExt for O {}

View file

@ -0,0 +1,3 @@
Generated by gir (https://github.com/gtk-rs/gir @ e0d8d8d645b1)
from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)

View file

@ -0,0 +1,8 @@
// Take a look at the license at the top of the repository in the LICENSE file.
use gst::CapsFeatures;
use once_cell::sync::Lazy;
pub static CAPS_FEATURES_MEMORY_DMABUF: Lazy<CapsFeatures> =
Lazy::new(|| CapsFeatures::new(&[*crate::CAPS_FEATURE_MEMORY_DMABUF]));

View file

@ -0,0 +1,74 @@
use std::{
fmt,
os::unix::prelude::{IntoRawFd, RawFd},
};
use glib::{translate::*, Cast};
use gst::{Memory, MemoryRef};
#[cfg(any(feature = "v1_16", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_16")))]
use crate::FdMemoryFlags;
use crate::{DmaBufAllocator, FdMemory, FdMemoryRef};
gst::memory_object_wrapper!(
DmaBufMemory,
DmaBufMemoryRef,
gst::ffi::GstMemory,
|mem: &gst::MemoryRef| { unsafe { from_glib(ffi::gst_is_dmabuf_memory(mem.as_mut_ptr())) } },
FdMemory,
FdMemoryRef,
Memory,
MemoryRef
);
impl fmt::Debug for DmaBufMemory {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
DmaBufMemoryRef::fmt(self, f)
}
}
impl fmt::Debug for DmaBufMemoryRef {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
MemoryRef::fmt(self, f)
}
}
impl DmaBufMemoryRef {
#[doc(alias = "gst_dmabuf_memory_get_fd")]
pub fn fd(&self) -> RawFd {
assert_initialized_main_thread!();
unsafe { ffi::gst_dmabuf_memory_get_fd(self.as_mut_ptr()) }
}
}
impl DmaBufAllocator {
#[doc(alias = "gst_dmabuf_allocator_alloc")]
pub unsafe fn alloc<A: IntoRawFd>(&self, fd: A, size: usize) -> gst::Memory {
assert_initialized_main_thread_unsafe!();
from_glib_full(ffi::gst_dmabuf_allocator_alloc(
self.unsafe_cast_ref::<gst::Allocator>().to_glib_none().0,
fd.into_raw_fd(),
size,
))
}
#[cfg(any(feature = "v1_16", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_16")))]
#[doc(alias = "gst_dmabuf_allocator_alloc_with_flags")]
pub unsafe fn alloc_with_flags(
&self,
fd: RawFd,
size: usize,
flags: FdMemoryFlags,
) -> gst::Memory {
assert_initialized_main_thread_unsafe!();
from_glib_full(ffi::gst_dmabuf_allocator_alloc_with_flags(
self.unsafe_cast_ref::<gst::Allocator>().to_glib_none().0,
fd,
size,
flags.into_glib(),
))
}
}

View file

@ -0,0 +1,59 @@
use std::{fmt, os::unix::prelude::RawFd};
use glib::{translate::*, Cast};
use gst::{Memory, MemoryRef};
use crate::{FdAllocator, FdMemoryFlags};
gst::memory_object_wrapper!(
FdMemory,
FdMemoryRef,
gst::ffi::GstMemory,
|mem: &gst::MemoryRef| { unsafe { from_glib(ffi::gst_is_fd_memory(mem.as_mut_ptr())) } },
Memory,
MemoryRef,
);
impl fmt::Debug for FdMemory {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
FdMemoryRef::fmt(self, f)
}
}
impl fmt::Debug for FdMemoryRef {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("FdMemory")
.field("ptr", unsafe { &self.as_ptr() })
.field("allocator", &self.allocator())
.field("parent", &self.parent())
.field("maxsize", &self.maxsize())
.field("align", &self.align())
.field("offset", &self.offset())
.field("size", &self.size())
.field("flags", &self.flags())
.field("fd", &self.fd())
.finish()
}
}
impl FdMemoryRef {
#[doc(alias = "gst_fd_memory_get_fd")]
pub fn fd(&self) -> RawFd {
assert_initialized_main_thread!();
unsafe { ffi::gst_fd_memory_get_fd(self.as_mut_ptr()) }
}
}
impl FdAllocator {
#[doc(alias = "gst_fd_allocator_alloc")]
pub unsafe fn alloc(&self, fd: RawFd, size: usize, flags: FdMemoryFlags) -> gst::Memory {
assert_initialized_main_thread_unsafe!();
from_glib_full(ffi::gst_fd_allocator_alloc(
self.unsafe_cast_ref::<gst::Allocator>().to_glib_none().0,
fd,
size,
flags.into_glib(),
))
}
}

View file

@ -0,0 +1,74 @@
// Take a look at the license at the top of the repository in the LICENSE file.
#![cfg_attr(feature = "dox", feature(doc_cfg))]
#![allow(clippy::missing_safety_doc)]
#![allow(clippy::non_send_fields_in_send_ty)]
#![doc = include_str!("../README.md")]
pub use ffi;
pub use glib;
pub use gst;
macro_rules! assert_initialized_main_thread {
() => {
if unsafe { gst::ffi::gst_is_initialized() } != glib::ffi::GTRUE {
panic!("GStreamer has not been initialized. Call `gst::init` first.");
}
};
}
macro_rules! assert_initialized_main_thread_unsafe {
() => {
if gst::ffi::gst_is_initialized() != glib::ffi::GTRUE {
panic!("GStreamer has not been initialized. Call `gst::init` first.");
}
};
}
macro_rules! skip_assert_initialized {
() => {};
}
#[allow(clippy::unreadable_literal)]
#[allow(clippy::too_many_arguments)]
#[allow(clippy::match_same_arms)]
#[allow(clippy::type_complexity)]
#[allow(clippy::use_self)]
#[allow(unused_imports)]
mod auto;
pub use crate::auto::*;
#[cfg(any(feature = "v1_12", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_12")))]
mod caps_features;
#[cfg(any(feature = "v1_12", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_12")))]
pub use crate::caps_features::CAPS_FEATURES_MEMORY_DMABUF;
mod fd_allocator;
pub use fd_allocator::*;
#[cfg(any(target_os = "linux", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(target_os = "linux")))]
#[cfg(any(feature = "v1_12", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_12")))]
mod dma_buf_allocator;
#[cfg(any(target_os = "linux", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(target_os = "linux")))]
#[cfg(any(feature = "v1_12", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_12")))]
pub use dma_buf_allocator::*;
#[cfg(any(feature = "v1_14", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
mod phys_memory;
#[cfg(any(feature = "v1_14", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
pub use phys_memory::*;
// Re-export all the traits in a prelude module, so that applications
// can always "use gst_base::prelude::*" without getting conflicts
pub mod prelude {
#[doc(hidden)]
pub use gst::prelude::*;
}

View file

@ -0,0 +1,44 @@
use std::fmt;
use glib::translate::*;
use gst::{Memory, MemoryRef};
gst::memory_object_wrapper!(
PhysMemory,
PhysMemoryRef,
gst::ffi::GstMemory,
|mem: &gst::MemoryRef| { unsafe { from_glib(ffi::gst_is_phys_memory(mem.as_mut_ptr())) } },
Memory,
MemoryRef,
);
impl fmt::Debug for PhysMemory {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
PhysMemoryRef::fmt(self, f)
}
}
impl fmt::Debug for PhysMemoryRef {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("FdMemory")
.field("ptr", unsafe { &self.as_ptr() })
.field("allocator", &self.allocator())
.field("parent", &self.parent())
.field("maxsize", &self.maxsize())
.field("align", &self.align())
.field("offset", &self.offset())
.field("size", &self.size())
.field("flags", &self.flags())
.field("phys_addr", &format!("{:x}", self.phys_addr()))
.finish()
}
}
impl PhysMemoryRef {
#[doc(alias = "gst_phys_memory_get_phys_addr")]
pub fn phys_addr(&self) -> libc::uintptr_t {
assert_initialized_main_thread!();
unsafe { ffi::gst_phys_memory_get_phys_addr(self.as_mut_ptr()) }
}
}

View file

@ -0,0 +1 @@
../../gstreamer/CHANGELOG.md

View file

@ -0,0 +1 @@
../../COPYRIGHT

View file

@ -0,0 +1,71 @@
[build-dependencies]
system-deps = "6"
[dependencies]
libc = "0.2"
[dependencies.glib]
git = "https://github.com/gtk-rs/gtk-rs-core"
package = "glib-sys"
[dependencies.gobject]
git = "https://github.com/gtk-rs/gtk-rs-core"
package = "gobject-sys"
[dependencies.gst]
package = "gstreamer-sys"
path = "../../gstreamer/sys"
[dev-dependencies]
shell-words = "1.0.0"
tempfile = "3"
[features]
dox = []
v1_10 = []
v1_12 = ["v1_10"]
v1_14 = ["v1_12"]
v1_16 = ["v1_14"]
v1_18 = ["v1_16"]
v1_20 = ["v1_18"]
[lib]
name = "gstreamer_allocators_sys"
[package]
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
build = "build.rs"
description = "FFI bindings to libgstallocators-1.0"
documentation = "https://gstreamer.pages.freedesktop.org/gstreamer-rs/stable/latest/docs/gstreamer_allocators_sys/"
edition = "2021"
homepage = "https://gstreamer.freedesktop.org"
keywords = ["ffi", "gstreamer", "gnome", "multimedia"]
license = "MIT"
name = "gstreamer-allocators-sys"
readme = "README.md"
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
rust-version = "1.56"
version = "0.19.0"
[package.metadata.docs.rs]
features = ["dox"]
[package.metadata.system-deps.gstreamer_allocators_1_0]
name = "gstreamer-allocators-1.0"
version = "1.8"
[package.metadata.system-deps.gstreamer_allocators_1_0.v1_10]
version = "1.10"
[package.metadata.system-deps.gstreamer_allocators_1_0.v1_12]
version = "1.12"
[package.metadata.system-deps.gstreamer_allocators_1_0.v1_14]
version = "1.14"
[package.metadata.system-deps.gstreamer_allocators_1_0.v1_16]
version = "1.16"
[package.metadata.system-deps.gstreamer_allocators_1_0.v1_18]
version = "1.18"
[package.metadata.system-deps.gstreamer_allocators_1_0.v1_20]
version = "1.20"

View file

@ -0,0 +1,23 @@
[options]
girs_directories = ["../../gir-files", "../../gst-gir-files"]
library = "GstAllocators"
version = "1.0"
min_cfg_version = "1.8"
work_mode = "sys"
extra_versions = [
"1.20",
"1.18",
"1.16",
"1.14",
"1.12",
"1.10",
]
external_libraries = [
"GLib",
"GObject",
]
[external_libraries]
gstreamer="Gst"

View file

@ -0,0 +1 @@
../../LICENSE-MIT

View file

@ -0,0 +1,31 @@
# gstreamer-sys [![crates.io](https://img.shields.io/crates/v/gstreamer-allocators-sys.svg)](https://crates.io/crates/gstreamer-allocators-sys) [![pipeline status](https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/badges/main/pipeline.svg)](https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/commits/main)
[GStreamer](https://gstreamer.freedesktop.org/) (Allocators library) FFI bindings for Rust.
These bindings are providing unsafe FFI API that can be used to interface with
GStreamer. Generally they are meant to be used as the building block for
higher-level abstractions like:
* Bindings for GStreamer applications and plugins: https://gitlab.freedesktop.org/gstreamer/gstreamer-rs
* Various GStreamer plugins written in Rust: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs
The bindings are autogenerated with [gir](https://github.com/gtk-rs/gir/)
based on the [GObject-Introspection](https://wiki.gnome.org/Projects/GObjectIntrospection/)
API metadata provided by the GStreamer project.
## LICENSE
gstreamer-sys and all crates contained here are licensed under the MIT
license ([LICENSE](LICENSE) or http://opensource.org/licenses/MIT).
GStreamer itself is licensed under the Lesser General Public License version
2.1 or (at your option) any later version:
https://www.gnu.org/licenses/lgpl-2.1.html
## Contribution
Any kinds of contributions are welcome as a pull request.
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in gstreamer-rs by you shall be licensed under the MIT license as above,
without any additional terms or conditions.

View file

@ -0,0 +1,18 @@
// Generated by gir (https://github.com/gtk-rs/gir @ e0d8d8d645b1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
#[cfg(not(feature = "dox"))]
use std::process;
#[cfg(feature = "dox")]
fn main() {} // prevent linking libraries to avoid documentation failure
#[cfg(not(feature = "dox"))]
fn main() {
if let Err(s) = system_deps::Config::new().probe() {
println!("cargo:warning={}", s);
process::exit(1);
}
}

View file

@ -0,0 +1,183 @@
// Generated by gir (https://github.com/gtk-rs/gir @ e0d8d8d645b1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
#![allow(non_camel_case_types, non_upper_case_globals, non_snake_case)]
#![allow(
clippy::approx_constant,
clippy::type_complexity,
clippy::unreadable_literal,
clippy::upper_case_acronyms
)]
#![cfg_attr(feature = "dox", feature(doc_cfg))]
#[allow(unused_imports)]
use libc::{
c_char, c_double, c_float, c_int, c_long, c_short, c_uchar, c_uint, c_ulong, c_ushort, c_void,
intptr_t, size_t, ssize_t, uintptr_t, FILE,
};
#[allow(unused_imports)]
use glib::{gboolean, gconstpointer, gpointer, GType};
// Constants
pub const GST_ALLOCATOR_DMABUF: *const c_char = b"dmabuf\0" as *const u8 as *const c_char;
pub const GST_ALLOCATOR_FD: *const c_char = b"fd\0" as *const u8 as *const c_char;
pub const GST_CAPS_FEATURE_MEMORY_DMABUF: *const c_char =
b"memory:DMABuf\0" as *const u8 as *const c_char;
// Flags
pub type GstFdMemoryFlags = c_uint;
pub const GST_FD_MEMORY_FLAG_NONE: GstFdMemoryFlags = 0;
pub const GST_FD_MEMORY_FLAG_KEEP_MAPPED: GstFdMemoryFlags = 1;
pub const GST_FD_MEMORY_FLAG_MAP_PRIVATE: GstFdMemoryFlags = 2;
pub const GST_FD_MEMORY_FLAG_DONT_CLOSE: GstFdMemoryFlags = 4;
// Records
#[derive(Copy, Clone)]
#[repr(C)]
pub struct GstDmaBufAllocatorClass {
pub parent_class: GstFdAllocatorClass,
pub _gst_reserved: [gpointer; 4],
}
impl ::std::fmt::Debug for GstDmaBufAllocatorClass {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
f.debug_struct(&format!("GstDmaBufAllocatorClass @ {:p}", self))
.field("parent_class", &self.parent_class)
.finish()
}
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct GstFdAllocatorClass {
pub parent_class: gst::GstAllocatorClass,
}
impl ::std::fmt::Debug for GstFdAllocatorClass {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
f.debug_struct(&format!("GstFdAllocatorClass @ {:p}", self))
.field("parent_class", &self.parent_class)
.finish()
}
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct GstPhysMemoryAllocatorInterface {
pub parent_iface: gobject::GTypeInterface,
pub get_phys_addr:
Option<unsafe extern "C" fn(*mut GstPhysMemoryAllocator, *mut gst::GstMemory) -> uintptr_t>,
}
impl ::std::fmt::Debug for GstPhysMemoryAllocatorInterface {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
f.debug_struct(&format!("GstPhysMemoryAllocatorInterface @ {:p}", self))
.field("get_phys_addr", &self.get_phys_addr)
.finish()
}
}
// Classes
#[derive(Copy, Clone)]
#[repr(C)]
pub struct GstDmaBufAllocator {
pub parent: GstFdAllocator,
pub _gst_reserved: [gpointer; 4],
}
impl ::std::fmt::Debug for GstDmaBufAllocator {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
f.debug_struct(&format!("GstDmaBufAllocator @ {:p}", self))
.field("parent", &self.parent)
.finish()
}
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct GstFdAllocator {
pub parent: gst::GstAllocator,
}
impl ::std::fmt::Debug for GstFdAllocator {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
f.debug_struct(&format!("GstFdAllocator @ {:p}", self))
.field("parent", &self.parent)
.finish()
}
}
// Interfaces
#[repr(C)]
pub struct GstPhysMemoryAllocator {
_data: [u8; 0],
_marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>,
}
impl ::std::fmt::Debug for GstPhysMemoryAllocator {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(f, "GstPhysMemoryAllocator @ {:p}", self)
}
}
#[link(name = "gstallocators-1.0")]
extern "C" {
//=========================================================================
// GstDmaBufAllocator
//=========================================================================
#[cfg(any(feature = "v1_12", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_12")))]
pub fn gst_dmabuf_allocator_get_type() -> GType;
pub fn gst_dmabuf_allocator_new() -> *mut gst::GstAllocator;
pub fn gst_dmabuf_allocator_alloc(
allocator: *mut gst::GstAllocator,
fd: c_int,
size: size_t,
) -> *mut gst::GstMemory;
#[cfg(any(feature = "v1_16", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_16")))]
pub fn gst_dmabuf_allocator_alloc_with_flags(
allocator: *mut gst::GstAllocator,
fd: c_int,
size: size_t,
flags: GstFdMemoryFlags,
) -> *mut gst::GstMemory;
//=========================================================================
// GstFdAllocator
//=========================================================================
pub fn gst_fd_allocator_get_type() -> GType;
pub fn gst_fd_allocator_new() -> *mut gst::GstAllocator;
pub fn gst_fd_allocator_alloc(
allocator: *mut gst::GstAllocator,
fd: c_int,
size: size_t,
flags: GstFdMemoryFlags,
) -> *mut gst::GstMemory;
//=========================================================================
// GstPhysMemoryAllocator
//=========================================================================
#[cfg(any(feature = "v1_14", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
pub fn gst_phys_memory_allocator_get_type() -> GType;
//=========================================================================
// Other functions
//=========================================================================
pub fn gst_dmabuf_memory_get_fd(mem: *mut gst::GstMemory) -> c_int;
pub fn gst_fd_memory_get_fd(mem: *mut gst::GstMemory) -> c_int;
pub fn gst_is_dmabuf_memory(mem: *mut gst::GstMemory) -> gboolean;
pub fn gst_is_fd_memory(mem: *mut gst::GstMemory) -> gboolean;
#[cfg(any(feature = "v1_14", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
pub fn gst_is_phys_memory(mem: *mut gst::GstMemory) -> gboolean;
#[cfg(any(feature = "v1_14", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
pub fn gst_phys_memory_get_phys_addr(mem: *mut gst::GstMemory) -> uintptr_t;
}

View file

@ -0,0 +1,268 @@
// Generated by gir (https://github.com/gtk-rs/gir @ e0d8d8d645b1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
use gstreamer_allocators_sys::*;
use std::env;
use std::error::Error;
use std::ffi::OsString;
use std::mem::{align_of, size_of};
use std::path::Path;
use std::process::Command;
use std::str;
use tempfile::Builder;
static PACKAGES: &[&str] = &["gstreamer-allocators-1.0"];
#[derive(Clone, Debug)]
struct Compiler {
pub args: Vec<String>,
}
impl Compiler {
pub fn new() -> Result<Self, Box<dyn Error>> {
let mut args = get_var("CC", "cc")?;
args.push("-Wno-deprecated-declarations".to_owned());
// For _Generic
args.push("-std=c11".to_owned());
// For %z support in printf when using MinGW.
args.push("-D__USE_MINGW_ANSI_STDIO".to_owned());
args.extend(get_var("CFLAGS", "")?);
args.extend(get_var("CPPFLAGS", "")?);
args.extend(pkg_config_cflags(PACKAGES)?);
Ok(Self { args })
}
pub fn compile(&self, src: &Path, out: &Path) -> Result<(), Box<dyn Error>> {
let mut cmd = self.to_command();
cmd.arg(src);
cmd.arg("-o");
cmd.arg(out);
let status = cmd.spawn()?.wait()?;
if !status.success() {
return Err(format!("compilation command {:?} failed, {}", &cmd, status).into());
}
Ok(())
}
fn to_command(&self) -> Command {
let mut cmd = Command::new(&self.args[0]);
cmd.args(&self.args[1..]);
cmd
}
}
fn get_var(name: &str, default: &str) -> Result<Vec<String>, Box<dyn Error>> {
match env::var(name) {
Ok(value) => Ok(shell_words::split(&value)?),
Err(env::VarError::NotPresent) => Ok(shell_words::split(default)?),
Err(err) => Err(format!("{} {}", name, err).into()),
}
}
fn pkg_config_cflags(packages: &[&str]) -> Result<Vec<String>, Box<dyn Error>> {
if packages.is_empty() {
return Ok(Vec::new());
}
let pkg_config = env::var_os("PKG_CONFIG").unwrap_or_else(|| OsString::from("pkg-config"));
let mut cmd = Command::new(pkg_config);
cmd.arg("--cflags");
cmd.args(packages);
let out = cmd.output()?;
if !out.status.success() {
return Err(format!("command {:?} returned {}", &cmd, out.status).into());
}
let stdout = str::from_utf8(&out.stdout)?;
Ok(shell_words::split(stdout.trim())?)
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
struct Layout {
size: usize,
alignment: usize,
}
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
struct Results {
/// Number of successfully completed tests.
passed: usize,
/// Total number of failed tests (including those that failed to compile).
failed: usize,
}
impl Results {
fn record_passed(&mut self) {
self.passed += 1;
}
fn record_failed(&mut self) {
self.failed += 1;
}
fn summary(&self) -> String {
format!("{} passed; {} failed", self.passed, self.failed)
}
fn expect_total_success(&self) {
if self.failed == 0 {
println!("OK: {}", self.summary());
} else {
panic!("FAILED: {}", self.summary());
};
}
}
#[test]
#[cfg(target_os = "linux")]
fn cross_validate_constants_with_c() {
let mut c_constants: Vec<(String, String)> = Vec::new();
for l in get_c_output("constant").unwrap().lines() {
let mut words = l.trim().split(';');
let name = words.next().expect("Failed to parse name").to_owned();
let value = words
.next()
.and_then(|s| s.parse().ok())
.expect("Failed to parse value");
c_constants.push((name, value));
}
let mut results = Results::default();
for ((rust_name, rust_value), (c_name, c_value)) in
RUST_CONSTANTS.iter().zip(c_constants.iter())
{
if rust_name != c_name {
results.record_failed();
eprintln!("Name mismatch:\nRust: {:?}\nC: {:?}", rust_name, c_name,);
continue;
}
if rust_value != c_value {
results.record_failed();
eprintln!(
"Constant value mismatch for {}\nRust: {:?}\nC: {:?}",
rust_name, rust_value, &c_value
);
continue;
}
results.record_passed();
}
results.expect_total_success();
}
#[test]
#[cfg(target_os = "linux")]
fn cross_validate_layout_with_c() {
let mut c_layouts = Vec::new();
for l in get_c_output("layout").unwrap().lines() {
let mut words = l.trim().split(';');
let name = words.next().expect("Failed to parse name").to_owned();
let size = words
.next()
.and_then(|s| s.parse().ok())
.expect("Failed to parse size");
let alignment = words
.next()
.and_then(|s| s.parse().ok())
.expect("Failed to parse alignment");
c_layouts.push((name, Layout { size, alignment }));
}
let mut results = Results::default();
for ((rust_name, rust_layout), (c_name, c_layout)) in RUST_LAYOUTS.iter().zip(c_layouts.iter())
{
if rust_name != c_name {
results.record_failed();
eprintln!("Name mismatch:\nRust: {:?}\nC: {:?}", rust_name, c_name,);
continue;
}
if rust_layout != c_layout {
results.record_failed();
eprintln!(
"Layout mismatch for {}\nRust: {:?}\nC: {:?}",
rust_name, rust_layout, &c_layout
);
continue;
}
results.record_passed();
}
results.expect_total_success();
}
fn get_c_output(name: &str) -> Result<String, Box<dyn Error>> {
let tmpdir = Builder::new().prefix("abi").tempdir()?;
let exe = tmpdir.path().join(name);
let c_file = Path::new("tests").join(name).with_extension("c");
let cc = Compiler::new().expect("configured compiler");
cc.compile(&c_file, &exe)?;
let mut abi_cmd = Command::new(exe);
let output = abi_cmd.output()?;
if !output.status.success() {
return Err(format!("command {:?} failed, {:?}", &abi_cmd, &output).into());
}
Ok(String::from_utf8(output.stdout)?)
}
const RUST_LAYOUTS: &[(&str, Layout)] = &[
(
"GstDmaBufAllocator",
Layout {
size: size_of::<GstDmaBufAllocator>(),
alignment: align_of::<GstDmaBufAllocator>(),
},
),
(
"GstDmaBufAllocatorClass",
Layout {
size: size_of::<GstDmaBufAllocatorClass>(),
alignment: align_of::<GstDmaBufAllocatorClass>(),
},
),
(
"GstFdAllocator",
Layout {
size: size_of::<GstFdAllocator>(),
alignment: align_of::<GstFdAllocator>(),
},
),
(
"GstFdAllocatorClass",
Layout {
size: size_of::<GstFdAllocatorClass>(),
alignment: align_of::<GstFdAllocatorClass>(),
},
),
(
"GstFdMemoryFlags",
Layout {
size: size_of::<GstFdMemoryFlags>(),
alignment: align_of::<GstFdMemoryFlags>(),
},
),
(
"GstPhysMemoryAllocatorInterface",
Layout {
size: size_of::<GstPhysMemoryAllocatorInterface>(),
alignment: align_of::<GstPhysMemoryAllocatorInterface>(),
},
),
];
const RUST_CONSTANTS: &[(&str, &str)] = &[
("GST_ALLOCATOR_DMABUF", "dmabuf"),
("GST_ALLOCATOR_FD", "fd"),
("GST_CAPS_FEATURE_MEMORY_DMABUF", "memory:DMABuf"),
("(guint) GST_FD_MEMORY_FLAG_DONT_CLOSE", "4"),
("(guint) GST_FD_MEMORY_FLAG_KEEP_MAPPED", "1"),
("(guint) GST_FD_MEMORY_FLAG_MAP_PRIVATE", "2"),
("(guint) GST_FD_MEMORY_FLAG_NONE", "0"),
];

View file

@ -0,0 +1,40 @@
// Generated by gir (https://github.com/gtk-rs/gir @ e0d8d8d645b1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
#include "manual.h"
#include <stdio.h>
#define PRINT_CONSTANT(CONSTANT_NAME) \
printf("%s;", #CONSTANT_NAME); \
printf(_Generic((CONSTANT_NAME), \
char *: "%s", \
const char *: "%s", \
char: "%c", \
signed char: "%hhd", \
unsigned char: "%hhu", \
short int: "%hd", \
unsigned short int: "%hu", \
int: "%d", \
unsigned int: "%u", \
long: "%ld", \
unsigned long: "%lu", \
long long: "%lld", \
unsigned long long: "%llu", \
float: "%f", \
double: "%f", \
long double: "%ld"), \
CONSTANT_NAME); \
printf("\n");
int main() {
PRINT_CONSTANT(GST_ALLOCATOR_DMABUF);
PRINT_CONSTANT(GST_ALLOCATOR_FD);
PRINT_CONSTANT(GST_CAPS_FEATURE_MEMORY_DMABUF);
PRINT_CONSTANT((guint) GST_FD_MEMORY_FLAG_DONT_CLOSE);
PRINT_CONSTANT((guint) GST_FD_MEMORY_FLAG_KEEP_MAPPED);
PRINT_CONSTANT((guint) GST_FD_MEMORY_FLAG_MAP_PRIVATE);
PRINT_CONSTANT((guint) GST_FD_MEMORY_FLAG_NONE);
return 0;
}

View file

@ -0,0 +1,18 @@
// Generated by gir (https://github.com/gtk-rs/gir @ e0d8d8d645b1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
#include "manual.h"
#include <stdalign.h>
#include <stdio.h>
int main() {
printf("%s;%zu;%zu\n", "GstDmaBufAllocator", sizeof(GstDmaBufAllocator), alignof(GstDmaBufAllocator));
printf("%s;%zu;%zu\n", "GstDmaBufAllocatorClass", sizeof(GstDmaBufAllocatorClass), alignof(GstDmaBufAllocatorClass));
printf("%s;%zu;%zu\n", "GstFdAllocator", sizeof(GstFdAllocator), alignof(GstFdAllocator));
printf("%s;%zu;%zu\n", "GstFdAllocatorClass", sizeof(GstFdAllocatorClass), alignof(GstFdAllocatorClass));
printf("%s;%zu;%zu\n", "GstFdMemoryFlags", sizeof(GstFdMemoryFlags), alignof(GstFdMemoryFlags));
printf("%s;%zu;%zu\n", "GstPhysMemoryAllocatorInterface", sizeof(GstPhysMemoryAllocatorInterface), alignof(GstPhysMemoryAllocatorInterface));
return 0;
}

View file

@ -0,0 +1,3 @@
// Feel free to edit this file, it won't be regenerated by gir generator unless removed.
#include <gst/base/base.h>

View file

@ -0,0 +1,8 @@
// Take a look at the license at the top of the repository in the LICENSE file.
#[test]
fn check_gir_file() {
let res = gir_format_check::check_gir_file("Gir.toml");
println!("{}", res);
assert_eq!(res.nb_errors, 0);
}