mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer-rs.git
synced 2024-11-22 01:21:05 +00:00
analytics: Add bindings for apps/plugins
The whole API to use the Analytics meta is implemented. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/merge_requests/1358>
This commit is contained in:
parent
36792404a9
commit
7ec3c8713a
82 changed files with 2541 additions and 51 deletions
23
Cargo.lock
generated
23
Cargo.lock
generated
|
@ -881,6 +881,29 @@ dependencies = [
|
|||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gstreamer-analytics"
|
||||
version = "0.22.0"
|
||||
dependencies = [
|
||||
"gir-format-check",
|
||||
"glib",
|
||||
"gstreamer",
|
||||
"gstreamer-analytics-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gstreamer-analytics-sys"
|
||||
version = "0.22.0"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"gstreamer-sys",
|
||||
"libc",
|
||||
"shell-words",
|
||||
"system-deps",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gstreamer-app"
|
||||
version = "0.22.0"
|
||||
|
|
|
@ -3,6 +3,7 @@ resolver = "2"
|
|||
|
||||
default-members = [
|
||||
"gstreamer/sys",
|
||||
"gstreamer-analytics/sys",
|
||||
"gstreamer-app/sys",
|
||||
"gstreamer-audio/sys",
|
||||
"gstreamer-base/sys",
|
||||
|
@ -22,6 +23,7 @@ default-members = [
|
|||
"gstreamer-video/sys",
|
||||
"gstreamer-webrtc/sys",
|
||||
"gstreamer",
|
||||
"gstreamer-analytics",
|
||||
"gstreamer-app",
|
||||
"gstreamer-audio",
|
||||
"gstreamer-base",
|
||||
|
@ -47,6 +49,7 @@ default-members = [
|
|||
|
||||
members = [
|
||||
"gstreamer/sys",
|
||||
"gstreamer-analytics/sys",
|
||||
"gstreamer-app/sys",
|
||||
"gstreamer-audio/sys",
|
||||
"gstreamer-base/sys",
|
||||
|
@ -71,6 +74,7 @@ members = [
|
|||
"gstreamer-webrtc/sys",
|
||||
"gstreamer-allocators/sys",
|
||||
"gstreamer",
|
||||
"gstreamer-analytics",
|
||||
"gstreamer-app",
|
||||
"gstreamer-audio",
|
||||
"gstreamer-base",
|
||||
|
|
|
@ -13,7 +13,7 @@ get_features() {
|
|||
gstreamer-audio|gstreamer-editing-services|gstreamer-gl|gstreamer-pbutils|gstreamer-rtp|gstreamer-rtsp|gstreamer-video|gstreamer)
|
||||
echo "--features=serde,v1_24"
|
||||
;;
|
||||
gstreamer-validate)
|
||||
gstreamer-analytics)
|
||||
echo ""
|
||||
;;
|
||||
*)
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 3f9f549accb70d139a2ae049d36f32c059398060
|
||||
Subproject commit 63e90a30193bf8d228057c4570a50a0a2b40f2bd
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
1
gstreamer-analytics/CHANGELOG.md
Symbolic link
1
gstreamer-analytics/CHANGELOG.md
Symbolic link
|
@ -0,0 +1 @@
|
|||
../gstreamer/CHANGELOG.md
|
1
gstreamer-analytics/COPYRIGHT
Symbolic link
1
gstreamer-analytics/COPYRIGHT
Symbolic link
|
@ -0,0 +1 @@
|
|||
../COPYRIGHT
|
31
gstreamer-analytics/Cargo.toml
Normal file
31
gstreamer-analytics/Cargo.toml
Normal file
|
@ -0,0 +1,31 @@
|
|||
[package]
|
||||
name = "gstreamer-analytics"
|
||||
authors = ["Olivier Crête <olivier.crete@collabora.com>"]
|
||||
description = "Rust bindings for GStreamer Analytics library"
|
||||
license = "MIT OR Apache-2.0"
|
||||
readme = "README.md"
|
||||
documentation = "https://gstreamer.pages.freedesktop.org/gstreamer-rs/stable/latest/docs/gstreamer_analytics/"
|
||||
keywords = ["gstreamer", "multimedia", "audio", "video", "gnome"]
|
||||
version.workspace = true
|
||||
categories.workspace = true
|
||||
repository.workspace = true
|
||||
homepage.workspace = true
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
libc = "0.2"
|
||||
ffi = { package = "gstreamer-analytics-sys", path = "sys" }
|
||||
glib.workspace = true
|
||||
gst.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
gir-format-check = "0.1"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustc-args = ["--cfg", "docsrs"]
|
||||
rustdoc-args = ["--cfg", "docsrs", "--generate-link-to-definition"]
|
34
gstreamer-analytics/Gir.toml
Normal file
34
gstreamer-analytics/Gir.toml
Normal file
|
@ -0,0 +1,34 @@
|
|||
[options]
|
||||
girs_directories = ["../gir-files", "../gst-gir-files"]
|
||||
library = "GstAnalytics"
|
||||
version = "1.0"
|
||||
min_cfg_version = "1.24"
|
||||
work_mode = "normal"
|
||||
concurrency = "send+sync"
|
||||
generate_safety_asserts = true
|
||||
single_version_file = true
|
||||
generate_display_trait = false
|
||||
trust_return_value_nullability = true
|
||||
|
||||
external_libraries = [
|
||||
"GLib",
|
||||
"GObject",
|
||||
"Gst",
|
||||
]
|
||||
|
||||
generate = [
|
||||
"GstAnalytics.RelTypes"
|
||||
]
|
||||
|
||||
manual = [
|
||||
"GObject.Object",
|
||||
"Gst.Element",
|
||||
"Gst.MiniObject",
|
||||
"Gst.Object"
|
||||
]
|
||||
|
||||
|
||||
[[object]]
|
||||
name = "Gst.Buffer"
|
||||
status = "manual"
|
||||
ref_mode = "ref"
|
1
gstreamer-analytics/LICENSE-APACHE
Symbolic link
1
gstreamer-analytics/LICENSE-APACHE
Symbolic link
|
@ -0,0 +1 @@
|
|||
../LICENSE-APACHE
|
1
gstreamer-analytics/LICENSE-MIT
Symbolic link
1
gstreamer-analytics/LICENSE-MIT
Symbolic link
|
@ -0,0 +1 @@
|
|||
../LICENSE-MIT
|
214
gstreamer-analytics/README.md
Normal file
214
gstreamer-analytics/README.md
Normal file
|
@ -0,0 +1,214 @@
|
|||
# gstreamer-rs [![crates.io](https://img.shields.io/crates/v/gstreamer-app.svg)](https://crates.io/crates/gstreamer-app) [![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/) (App library) bindings for Rust.
|
||||
Documentation can be found [here](https://gstreamer.pages.freedesktop.org/gstreamer-rs/stable/latest/docs/gstreamer_app/).
|
||||
|
||||
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.14 and gst-plugins-base 1.14 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.14. 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. See the `Cargo.toml`
|
||||
files for the full details,
|
||||
|
||||
```console
|
||||
$ 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.
|
||||
|
||||
We recommend using the official GStreamer binaries over Homebrew, especially
|
||||
as GStreamer in Homebrew is [currently broken](https://github.com/orgs/Homebrew/discussions/3740#discussioncomment-3804964).
|
||||
|
||||
#### GStreamer Binaries
|
||||
|
||||
You need to download the *two* `.pkg` files from the GStreamer website and
|
||||
install them, e.g. `gstreamer-1.0-1.20.4-universal.pkg` and
|
||||
`gstreamer-1.0-devel-1.20.4-universal.pkg`.
|
||||
|
||||
After installation, you also need to set the `PATH` environment variable as
|
||||
follows
|
||||
|
||||
```console
|
||||
$ export PATH="/Library/Frameworks/GStreamer.framework/Versions/1.0/bin${PATH:+:$PATH}"
|
||||
```
|
||||
|
||||
Also note that the `pkg-config` from GStreamer should be the first one in
|
||||
the `PATH` as other versions have all kinds of quirks that will cause
|
||||
problems.
|
||||
|
||||
#### 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
|
||||
```
|
||||
|
||||
Make sure the version of these libraries is >= 1.14.
|
||||
|
||||
<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.
|
||||
|
||||
We recommend using the official GStreamer binaries over MSYS2.
|
||||
|
||||
#### 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.20.4.msi` and
|
||||
`gstreamer-1.0-devel-x86_64-1.20.4.msi`. Make sure to select the version that
|
||||
matches your Rust toolchain, i.e. MinGW or MSVC.
|
||||
|
||||
After installation set the ``PATH` environment variable as follows:
|
||||
|
||||
```console
|
||||
# For a UNIX-style shell:
|
||||
$ export PATH="c:/gstreamer/1.0/msvc_x86_64/bin${PATH:+:$PATH}"
|
||||
|
||||
# For cmd.exe:
|
||||
$ set PATH=C:\gstreamer\1.0\msvc_x86_64\bin;%PATH%
|
||||
```
|
||||
|
||||
Make sure to update the path to where you have actually installed GStreamer
|
||||
and for the corresponding toolchain.
|
||||
|
||||
Also note that the `pkg-config.exe` from GStreamer should be the first one in
|
||||
the `PATH` as other versions have all kinds of quirks that will cause
|
||||
problems.
|
||||
|
||||
#### 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
|
||||
```
|
||||
|
||||
Make sure the version of these libraries is >= 1.14.
|
||||
|
||||
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/).
|
||||
|
||||
<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.
|
44
gstreamer-analytics/src/auto/flags.rs
Normal file
44
gstreamer-analytics/src/auto/flags.rs
Normal 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
|
||||
|
||||
use glib::{bitflags::bitflags, translate::*};
|
||||
|
||||
bitflags! {
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
#[doc(alias = "GstAnalyticsRelTypes")]
|
||||
pub struct RelTypes: u32 {
|
||||
#[doc(alias = "GST_ANALYTICS_REL_TYPE_NONE")]
|
||||
const NONE = ffi::GST_ANALYTICS_REL_TYPE_NONE as _;
|
||||
#[doc(alias = "GST_ANALYTICS_REL_TYPE_IS_PART_OF")]
|
||||
const IS_PART_OF = ffi::GST_ANALYTICS_REL_TYPE_IS_PART_OF as _;
|
||||
#[doc(alias = "GST_ANALYTICS_REL_TYPE_CONTAIN")]
|
||||
const CONTAIN = ffi::GST_ANALYTICS_REL_TYPE_CONTAIN as _;
|
||||
#[doc(alias = "GST_ANALYTICS_REL_TYPE_RELATE_TO")]
|
||||
const RELATE_TO = ffi::GST_ANALYTICS_REL_TYPE_RELATE_TO as _;
|
||||
#[doc(alias = "GST_ANALYTICS_REL_TYPE_LAST")]
|
||||
const LAST = ffi::GST_ANALYTICS_REL_TYPE_LAST as _;
|
||||
#[doc(alias = "GST_ANALYTICS_REL_TYPE_ANY")]
|
||||
const ANY = ffi::GST_ANALYTICS_REL_TYPE_ANY as _;
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
impl IntoGlib for RelTypes {
|
||||
type GlibType = ffi::GstAnalyticsRelTypes;
|
||||
|
||||
#[inline]
|
||||
fn into_glib(self) -> ffi::GstAnalyticsRelTypes {
|
||||
self.bits()
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
impl FromGlib<ffi::GstAnalyticsRelTypes> for RelTypes {
|
||||
#[inline]
|
||||
unsafe fn from_glib(value: ffi::GstAnalyticsRelTypes) -> Self {
|
||||
skip_assert_initialized!();
|
||||
Self::from_bits_truncate(value)
|
||||
}
|
||||
}
|
7
gstreamer-analytics/src/auto/mod.rs
Normal file
7
gstreamer-analytics/src/auto/mod.rs
Normal file
|
@ -0,0 +1,7 @@
|
|||
// 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
|
||||
|
||||
mod flags;
|
||||
pub use self::flags::RelTypes;
|
3
gstreamer-analytics/src/auto/versions.txt
Normal file
3
gstreamer-analytics/src/auto/versions.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
212
gstreamer-analytics/src/classification.rs
Normal file
212
gstreamer-analytics/src/classification.rs
Normal file
|
@ -0,0 +1,212 @@
|
|||
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||
|
||||
use glib::translate::*;
|
||||
|
||||
use crate::relation_meta::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum AnalyticsClassificationMtd {}
|
||||
|
||||
mod sealed {
|
||||
pub trait Sealed {}
|
||||
impl<T: super::AnalyticsRelationMetaClassificationExt> Sealed for T {}
|
||||
}
|
||||
|
||||
pub trait AnalyticsRelationMetaClassificationExt: sealed::Sealed {
|
||||
fn add_one_cls_mtd(
|
||||
&mut self,
|
||||
confidence_level: f32,
|
||||
class_quark: glib::Quark,
|
||||
) -> Result<AnalyticsMtdRef<AnalyticsClassificationMtd>, glib::BoolError>;
|
||||
|
||||
fn add_cls_mtd(
|
||||
&mut self,
|
||||
confidence_levels: &[f32],
|
||||
class_quarks: &[glib::Quark],
|
||||
) -> Result<AnalyticsMtdRef<AnalyticsClassificationMtd>, glib::BoolError>;
|
||||
}
|
||||
|
||||
impl<'a> AnalyticsRelationMetaClassificationExt
|
||||
for gst::MetaRefMut<'a, AnalyticsRelationMeta, gst::meta::Standalone>
|
||||
{
|
||||
#[doc(alias = "gst_analytics_relation_meta_add_one_cls_mtd")]
|
||||
fn add_one_cls_mtd(
|
||||
&mut self,
|
||||
confidence_level: f32,
|
||||
class_quark: glib::Quark,
|
||||
) -> Result<AnalyticsMtdRef<'a, AnalyticsClassificationMtd>, glib::BoolError> {
|
||||
unsafe {
|
||||
let mut mtd = std::mem::MaybeUninit::uninit();
|
||||
let ret = from_glib(ffi::gst_analytics_relation_meta_add_one_cls_mtd(
|
||||
self.as_mut_ptr(),
|
||||
confidence_level,
|
||||
class_quark.into_glib(),
|
||||
mtd.as_mut_ptr(),
|
||||
));
|
||||
let id = mtd.assume_init().id;
|
||||
|
||||
if ret {
|
||||
Ok(AnalyticsMtdRef::from_meta(self.as_ref(), id))
|
||||
} else {
|
||||
Err(glib::bool_error!("Couldn't add more data"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_analytics_relation_meta_add_cls_mtd")]
|
||||
fn add_cls_mtd(
|
||||
&mut self,
|
||||
confidence_levels: &[f32],
|
||||
class_quarks: &[glib::Quark],
|
||||
) -> Result<AnalyticsMtdRef<'a, AnalyticsClassificationMtd>, glib::BoolError> {
|
||||
let length = std::cmp::min(confidence_levels.len(), class_quarks.len());
|
||||
unsafe {
|
||||
let mut mtd = std::mem::MaybeUninit::uninit();
|
||||
let ret = from_glib(ffi::gst_analytics_relation_meta_add_cls_mtd(
|
||||
self.as_mut_ptr(),
|
||||
length,
|
||||
mut_override(confidence_levels.as_ptr()),
|
||||
class_quarks.as_ptr() as *mut _,
|
||||
mtd.as_mut_ptr(),
|
||||
));
|
||||
let id = mtd.assume_init().id;
|
||||
|
||||
if ret {
|
||||
Ok(AnalyticsMtdRef::from_meta(self.as_ref(), id))
|
||||
} else {
|
||||
Err(glib::bool_error!("Couldn't add more data"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl AnalyticsMtd for AnalyticsClassificationMtd {
|
||||
#[doc(alias = "gst_analytics_cls_mtd_get_mtd_type")]
|
||||
fn mtd_type() -> ffi::GstAnalyticsMtdType {
|
||||
unsafe { ffi::gst_analytics_cls_mtd_get_mtd_type() }
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn from(t: ffi::GstAnalyticsMtd) -> ffi::GstAnalyticsClsMtd {
|
||||
std::mem::transmute(t)
|
||||
}
|
||||
|
||||
impl<'a> AnalyticsMtdRef<'a, AnalyticsClassificationMtd> {
|
||||
#[doc(alias = "gst_analytics_cls_mtd_get_length")]
|
||||
pub fn len(&self) -> usize {
|
||||
unsafe {
|
||||
let mut mtd = from(ffi::GstAnalyticsMtd::unsafe_from(self));
|
||||
ffi::gst_analytics_cls_mtd_get_length(&mut mtd)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_analytics_cls_mtd_get_level")]
|
||||
pub fn level(&self, index: usize) -> f32 {
|
||||
assert!(index < self.len());
|
||||
|
||||
unsafe {
|
||||
let mut mtd = from(ffi::GstAnalyticsMtd::unsafe_from(self));
|
||||
ffi::gst_analytics_cls_mtd_get_level(&mut mtd, index)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_analytics_cls_mtd_get_quark")]
|
||||
pub fn quark(&self, index: usize) -> glib::Quark {
|
||||
assert!(index < self.len());
|
||||
|
||||
unsafe {
|
||||
let mut mtd = from(ffi::GstAnalyticsMtd::unsafe_from(self));
|
||||
from_glib(ffi::gst_analytics_cls_mtd_get_quark(&mut mtd, index))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn iterate(&self) -> AnalyticsClassificationIterator {
|
||||
AnalyticsClassificationIterator {
|
||||
mtd: self,
|
||||
index: 0,
|
||||
length: self.len(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AnalyticsClassificationIterator<'a> {
|
||||
mtd: &'a AnalyticsMtdRef<'a, AnalyticsClassificationMtd>,
|
||||
index: usize,
|
||||
length: usize,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for AnalyticsClassificationIterator<'a> {
|
||||
type Item = (glib::Quark, f32);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.index == self.length {
|
||||
None
|
||||
} else {
|
||||
let ret = Some((self.mtd.quark(self.index), self.mtd.level(self.index)));
|
||||
self.index += 1;
|
||||
ret
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::*;
|
||||
|
||||
#[test]
|
||||
fn one_class() {
|
||||
gst::init().unwrap();
|
||||
|
||||
assert_eq!(AnalyticsClassificationMtd::type_name(), "classification");
|
||||
|
||||
let mut buf = gst::Buffer::new();
|
||||
let mut meta = AnalyticsRelationMeta::add(buf.make_mut());
|
||||
|
||||
assert!(meta.is_empty());
|
||||
|
||||
let cls = meta
|
||||
.add_one_cls_mtd(0.7, glib::Quark::from_str("class1"))
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(cls.len(), 1);
|
||||
assert_eq!(cls.level(0), 0.7);
|
||||
assert_eq!(cls.quark(0), glib::Quark::from_str("class1"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn many_classes() {
|
||||
gst::init().unwrap();
|
||||
|
||||
assert_eq!(AnalyticsClassificationMtd::type_name(), "classification");
|
||||
|
||||
let mut buf = gst::Buffer::new();
|
||||
let mut meta = AnalyticsRelationMeta::add(buf.make_mut());
|
||||
|
||||
assert!(meta.is_empty());
|
||||
|
||||
let classes = [
|
||||
glib::Quark::from_str("a"),
|
||||
glib::Quark::from_str("b"),
|
||||
glib::Quark::from_str("c"),
|
||||
glib::Quark::from_str("d"),
|
||||
];
|
||||
let levels = [0.1, 0.2, 0.3, 0.4];
|
||||
|
||||
let cls = meta.add_cls_mtd(&levels, &classes).unwrap();
|
||||
|
||||
assert_eq!(cls.len(), 4);
|
||||
for i in 0..4usize {
|
||||
assert_eq!(cls.level(i), levels[i]);
|
||||
assert_eq!(cls.quark(i), classes[i]);
|
||||
}
|
||||
|
||||
for (i, (q, l)) in cls.iterate().enumerate() {
|
||||
assert_eq!(l, levels[i]);
|
||||
assert_eq!(q, classes[i]);
|
||||
}
|
||||
}
|
||||
}
|
36
gstreamer-analytics/src/lib.rs
Normal file
36
gstreamer-analytics/src/lib.rs
Normal file
|
@ -0,0 +1,36 @@
|
|||
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||
|
||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||
#![allow(clippy::missing_safety_doc)]
|
||||
#![doc = include_str!("../README.md")]
|
||||
|
||||
pub use ffi;
|
||||
pub use glib;
|
||||
pub use gst;
|
||||
|
||||
macro_rules! skip_assert_initialized {
|
||||
() => {};
|
||||
}
|
||||
|
||||
mod auto;
|
||||
pub use crate::auto::*;
|
||||
|
||||
mod relation_meta;
|
||||
pub use crate::relation_meta::*;
|
||||
|
||||
mod object_detection;
|
||||
pub use crate::object_detection::*;
|
||||
|
||||
mod tracking;
|
||||
pub use crate::tracking::*;
|
||||
|
||||
mod classification;
|
||||
pub use crate::classification::*;
|
||||
|
||||
// Re-export all the traits in a prelude module, so that applications
|
||||
// can always "use gst_app::prelude::*" without getting conflicts
|
||||
pub mod prelude {
|
||||
pub use crate::classification::AnalyticsRelationMetaClassificationExt;
|
||||
pub use crate::object_detection::AnalyticsRelationMetaODExt;
|
||||
pub use crate::tracking::AnalyticsRelationMetaTrackingExt;
|
||||
}
|
171
gstreamer-analytics/src/object_detection.rs
Normal file
171
gstreamer-analytics/src/object_detection.rs
Normal file
|
@ -0,0 +1,171 @@
|
|||
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||
|
||||
use glib::translate::*;
|
||||
|
||||
use crate::relation_meta::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum AnalyticsODMtd {}
|
||||
|
||||
mod sealed {
|
||||
pub trait Sealed {}
|
||||
impl<T: super::AnalyticsRelationMetaODExt> Sealed for T {}
|
||||
}
|
||||
|
||||
pub trait AnalyticsRelationMetaODExt: sealed::Sealed {
|
||||
fn add_od_mtd(
|
||||
&mut self,
|
||||
type_: glib::Quark,
|
||||
x: i32,
|
||||
y: i32,
|
||||
w: i32,
|
||||
h: i32,
|
||||
loc_conf_lvl: f32,
|
||||
) -> Result<AnalyticsMtdRef<AnalyticsODMtd>, glib::BoolError>;
|
||||
}
|
||||
|
||||
impl<'a> AnalyticsRelationMetaODExt
|
||||
for gst::MetaRefMut<'a, AnalyticsRelationMeta, gst::meta::Standalone>
|
||||
{
|
||||
#[doc(alias = "gst_analytics_relation_meta_add_od_mtd")]
|
||||
fn add_od_mtd(
|
||||
&mut self,
|
||||
type_: glib::Quark,
|
||||
x: i32,
|
||||
y: i32,
|
||||
w: i32,
|
||||
h: i32,
|
||||
loc_conf_lvl: f32,
|
||||
) -> Result<AnalyticsMtdRef<AnalyticsODMtd>, glib::BoolError> {
|
||||
unsafe {
|
||||
let mut mtd = std::mem::MaybeUninit::uninit();
|
||||
let ret = from_glib(ffi::gst_analytics_relation_meta_add_od_mtd(
|
||||
self.as_mut_ptr(),
|
||||
type_.into_glib(),
|
||||
x,
|
||||
y,
|
||||
w,
|
||||
h,
|
||||
loc_conf_lvl,
|
||||
mtd.as_mut_ptr(),
|
||||
));
|
||||
let id = mtd.assume_init().id;
|
||||
|
||||
if ret {
|
||||
Ok(AnalyticsMtdRef::from_meta(self.as_ref(), id))
|
||||
} else {
|
||||
Err(glib::bool_error!("Couldn't add more data"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
pub struct AnalyticsODLocation {
|
||||
x: i32,
|
||||
y: i32,
|
||||
w: i32,
|
||||
h: i32,
|
||||
loc_conf_lvl: f32,
|
||||
}
|
||||
|
||||
unsafe impl AnalyticsMtd for AnalyticsODMtd {
|
||||
#[doc(alias = "gst_analytics_od_mtd_get_mtd_type")]
|
||||
fn mtd_type() -> ffi::GstAnalyticsMtdType {
|
||||
unsafe { ffi::gst_analytics_od_mtd_get_mtd_type() }
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn from(t: ffi::GstAnalyticsMtd) -> ffi::GstAnalyticsODMtd {
|
||||
std::mem::transmute(t)
|
||||
}
|
||||
|
||||
impl<'a> AnalyticsMtdRef<'a, AnalyticsODMtd> {
|
||||
#[doc(alias = "gst_analytics_od_mtd_get_obj_type")]
|
||||
pub fn obj_type(&self) -> glib::Quark {
|
||||
unsafe {
|
||||
let mut mtd = from(ffi::GstAnalyticsMtd::unsafe_from(self));
|
||||
let type_ = ffi::gst_analytics_od_mtd_get_obj_type(&mut mtd);
|
||||
glib::Quark::from_glib(type_)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_analytics_od_mtd_get_location")]
|
||||
pub fn location(&self) -> Result<AnalyticsODLocation, glib::BoolError> {
|
||||
let mut loc = AnalyticsODLocation::default();
|
||||
|
||||
let success = unsafe {
|
||||
let mut mtd = from(ffi::GstAnalyticsMtd::unsafe_from(self));
|
||||
ffi::gst_analytics_od_mtd_get_location(
|
||||
&mut mtd,
|
||||
&mut loc.x,
|
||||
&mut loc.y,
|
||||
&mut loc.w,
|
||||
&mut loc.h,
|
||||
&mut loc.loc_conf_lvl,
|
||||
)
|
||||
};
|
||||
|
||||
if success != 0 {
|
||||
Ok(loc)
|
||||
} else {
|
||||
Err(glib::bool_error!("Could retrieve location"))
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_analytics_od_mtd_get_confidence_lvl")]
|
||||
pub fn confidence_level(&self) -> f32 {
|
||||
unsafe {
|
||||
let mut mtd = from(ffi::GstAnalyticsMtd::unsafe_from(self));
|
||||
let mut lvl: f32 = 0.0;
|
||||
ffi::gst_analytics_od_mtd_get_confidence_lvl(&mut mtd, &mut lvl);
|
||||
lvl
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::*;
|
||||
|
||||
#[test]
|
||||
fn object_detection() {
|
||||
gst::init().unwrap();
|
||||
|
||||
assert_eq!(AnalyticsODMtd::type_name(), "object-detection");
|
||||
|
||||
let mut buf = gst::Buffer::new();
|
||||
let mut meta = AnalyticsRelationMeta::add(buf.make_mut());
|
||||
|
||||
assert!(meta.is_empty());
|
||||
|
||||
let od = meta
|
||||
.add_od_mtd(glib::Quark::from_str("blb"), 0, 1, 10, 20, 0.8)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(od.obj_type(), glib::Quark::from_str("blb"));
|
||||
|
||||
let loc = od.location().unwrap();
|
||||
|
||||
assert_eq!(loc.x, 0);
|
||||
assert_eq!(loc.y, 1);
|
||||
assert_eq!(loc.w, 10);
|
||||
assert_eq!(loc.h, 20);
|
||||
assert_eq!(loc.loc_conf_lvl, 0.8);
|
||||
let meta = buf.meta::<AnalyticsRelationMeta>().unwrap();
|
||||
|
||||
assert!(meta.mtd::<AnalyticsODMtd>(1).is_none());
|
||||
|
||||
let meta2 = buf.meta::<AnalyticsRelationMeta>().unwrap();
|
||||
let od2 = meta2.mtd::<AnalyticsODMtd>(0).unwrap();
|
||||
|
||||
assert_eq!(od2.obj_type(), glib::Quark::from_str("blb"));
|
||||
let loc = od2.location().unwrap();
|
||||
|
||||
assert_eq!(loc.x, 0);
|
||||
assert_eq!(loc.y, 1);
|
||||
assert_eq!(loc.w, 10);
|
||||
assert_eq!(loc.h, 20);
|
||||
assert_eq!(loc.loc_conf_lvl, 0.8);
|
||||
}
|
||||
}
|
706
gstreamer-analytics/src/relation_meta.rs
Normal file
706
gstreamer-analytics/src/relation_meta.rs
Normal file
|
@ -0,0 +1,706 @@
|
|||
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||
|
||||
use glib::translate::*;
|
||||
use gst::prelude::*;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use crate::RelTypes;
|
||||
|
||||
#[repr(transparent)]
|
||||
#[doc(alias = "GstAnalyticsRelationMeta")]
|
||||
pub struct AnalyticsRelationMeta(ffi::GstAnalyticsRelationMeta);
|
||||
|
||||
unsafe impl Send for AnalyticsRelationMeta {}
|
||||
unsafe impl Sync for AnalyticsRelationMeta {}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[doc(alias = "GstAnalyticsRelationMetaInitParams")]
|
||||
pub struct AnalyticsRelationMetaInitParams(ffi::GstAnalyticsRelationMetaInitParams);
|
||||
|
||||
impl Default for AnalyticsRelationMetaInitParams {
|
||||
fn default() -> Self {
|
||||
Self(ffi::GstAnalyticsRelationMetaInitParams {
|
||||
initial_relation_order: 0,
|
||||
initial_buf_size: 0,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl AnalyticsRelationMetaInitParams {
|
||||
pub fn new(initial_relation_order: usize, initial_buf_size: usize) -> Self {
|
||||
skip_assert_initialized!();
|
||||
Self(ffi::GstAnalyticsRelationMetaInitParams {
|
||||
initial_relation_order,
|
||||
initial_buf_size,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AnalyticsMtdRef<'a, T: AnalyticsMtd> {
|
||||
id: u32,
|
||||
meta: gst::MetaRef<'a, AnalyticsRelationMeta>,
|
||||
mtd_type: PhantomData<&'a T>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct AnalyticsMtdRefMut<'a, T: AnalyticsMtd> {
|
||||
id: u32,
|
||||
meta: &'a mut gst::MetaRefMut<'a, AnalyticsRelationMeta, gst::meta::Standalone>,
|
||||
mtd_type: PhantomData<&'a T>,
|
||||
}
|
||||
|
||||
pub struct AnalyticsRelationPath {
|
||||
garray: *mut glib::ffi::GArray,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for AnalyticsRelationMeta {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||
f.debug_struct("AnalyticsRelationMeta")
|
||||
.field("len", &self.len())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl AnalyticsRelationMeta {
|
||||
#[doc(alias = "gst_buffer_add_analytics_relation_meta")]
|
||||
pub fn add(buffer: &mut gst::BufferRef) -> gst::MetaRefMut<Self, gst::meta::Standalone> {
|
||||
skip_assert_initialized!();
|
||||
|
||||
unsafe {
|
||||
let meta_ptr = ffi::gst_buffer_add_analytics_relation_meta(buffer.as_mut_ptr());
|
||||
Self::from_mut_ptr(buffer, meta_ptr)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_buffer_add_analytics_relation_meta_full")]
|
||||
pub fn add_full<'a>(
|
||||
buffer: &'a mut gst::BufferRef,
|
||||
init_params: &AnalyticsRelationMetaInitParams,
|
||||
) -> gst::MetaRefMut<'a, Self, gst::meta::Standalone> {
|
||||
skip_assert_initialized!();
|
||||
|
||||
unsafe {
|
||||
let meta_ptr = ffi::gst_buffer_add_analytics_relation_meta_full(
|
||||
buffer.as_mut_ptr(),
|
||||
mut_override(&init_params.0),
|
||||
);
|
||||
Self::from_mut_ptr(buffer, meta_ptr)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_analytics_relation_get_length")]
|
||||
pub fn len(&self) -> usize {
|
||||
unsafe { ffi::gst_analytics_relation_get_length(self.as_mut_ptr()) }
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_analytics_relation_meta_set_relation")]
|
||||
pub fn set_relation(
|
||||
&mut self,
|
||||
type_: crate::RelTypes,
|
||||
an_meta_first_id: u32,
|
||||
an_meta_second_id: u32,
|
||||
) -> Result<(), glib::BoolError> {
|
||||
let ret = unsafe {
|
||||
from_glib(ffi::gst_analytics_relation_meta_set_relation(
|
||||
self.as_mut_ptr(),
|
||||
type_.into_glib(),
|
||||
an_meta_first_id,
|
||||
an_meta_second_id,
|
||||
))
|
||||
};
|
||||
|
||||
if ret {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(glib::bool_error!(
|
||||
"Could not set relation {:}->{:} of type {:?}",
|
||||
an_meta_first_id,
|
||||
an_meta_second_id,
|
||||
type_
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_analytics_relation_meta_get_relation")]
|
||||
pub fn relation(&self, an_meta_first_id: u32, an_meta_second_id: u32) -> crate::RelTypes {
|
||||
unsafe {
|
||||
from_glib(ffi::gst_analytics_relation_meta_get_relation(
|
||||
self.as_mut_ptr(),
|
||||
an_meta_first_id,
|
||||
an_meta_second_id,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_analytics_relation_meta_exist")]
|
||||
pub fn exist(
|
||||
&self,
|
||||
an_meta_first_id: u32,
|
||||
an_meta_second_id: u32,
|
||||
relation_span: i32,
|
||||
cond_types: crate::RelTypes,
|
||||
) -> bool {
|
||||
unsafe {
|
||||
from_glib(ffi::gst_analytics_relation_meta_exist(
|
||||
self.as_mut_ptr(),
|
||||
an_meta_first_id,
|
||||
an_meta_second_id,
|
||||
relation_span,
|
||||
cond_types.into_glib(),
|
||||
std::ptr::null_mut(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_analytics_relation_meta_exist")]
|
||||
pub fn exist_path(
|
||||
&self,
|
||||
an_meta_first_id: u32,
|
||||
an_meta_second_id: u32,
|
||||
relation_span: i32,
|
||||
cond_types: crate::RelTypes,
|
||||
) -> Result<AnalyticsRelationPath, glib::BoolError> {
|
||||
let mut array = std::ptr::null_mut::<glib::ffi::GArray>();
|
||||
let ret = unsafe {
|
||||
from_glib(ffi::gst_analytics_relation_meta_exist(
|
||||
self.as_mut_ptr(),
|
||||
an_meta_first_id,
|
||||
an_meta_second_id,
|
||||
relation_span,
|
||||
cond_types.into_glib(),
|
||||
&mut array,
|
||||
))
|
||||
};
|
||||
|
||||
if ret {
|
||||
Ok(AnalyticsRelationPath { garray: array })
|
||||
} else {
|
||||
Err(glib::bool_error!("Such relation doesn't exist"))
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn as_mut_ptr(&self) -> *mut ffi::GstAnalyticsRelationMeta {
|
||||
mut_override(&self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl UnsafeFrom<&AnalyticsRelationMeta> for ffi::GstAnalyticsMtd {
|
||||
unsafe fn unsafe_from(t: &AnalyticsRelationMeta) -> Self {
|
||||
ffi::GstAnalyticsMtd {
|
||||
id: 0,
|
||||
meta: t.as_mut_ptr(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AnalyticsRelationPath {
|
||||
pub fn as_slice(&self) -> &[u32] {
|
||||
unsafe {
|
||||
std::slice::from_raw_parts(
|
||||
(*self.garray).data as *const u32,
|
||||
(*self.garray).len as usize,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for AnalyticsRelationPath {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
glib::ffi::g_array_free(self.garray, glib::ffi::GTRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod sealed {
|
||||
pub trait Sealed {}
|
||||
impl<T> Sealed for T {}
|
||||
}
|
||||
|
||||
pub trait AnalyticsMetaRefExt<'a>: sealed::Sealed {
|
||||
#[doc(alias = "gst_analytics_relation_meta_get_mtd")]
|
||||
fn mtd<T: AnalyticsMtd>(&self, an_meta_id: u32) -> Option<AnalyticsMtdRef<'a, T>>;
|
||||
fn iter<T: AnalyticsMtd>(&'a self) -> AnalyticsMtdIter<T>;
|
||||
fn iter_direct_related<T: AnalyticsMtd>(
|
||||
&'a self,
|
||||
an_meta_id: u32,
|
||||
rel_type: RelTypes,
|
||||
) -> AnalyticsMtdIter<T>;
|
||||
}
|
||||
|
||||
impl<'a> AnalyticsMetaRefExt<'a> for gst::MetaRef<'a, AnalyticsRelationMeta> {
|
||||
fn mtd<T: AnalyticsMtd>(&self, an_meta_id: u32) -> Option<AnalyticsMtdRef<'a, T>> {
|
||||
unsafe {
|
||||
let mut mtd = std::mem::MaybeUninit::uninit();
|
||||
let ret = from_glib(ffi::gst_analytics_relation_meta_get_mtd(
|
||||
self.as_mut_ptr(),
|
||||
an_meta_id,
|
||||
T::mtd_type(),
|
||||
mtd.as_mut_ptr(),
|
||||
));
|
||||
let id = mtd.assume_init().id;
|
||||
|
||||
if ret {
|
||||
Some(AnalyticsMtdRef::from_meta(self, id))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn iter<T: AnalyticsMtd>(&'a self) -> AnalyticsMtdIter<'a, T> {
|
||||
AnalyticsMtdIter::new(self)
|
||||
}
|
||||
fn iter_direct_related<T: AnalyticsMtd>(
|
||||
&'a self,
|
||||
an_meta_id: u32,
|
||||
rel_type: RelTypes,
|
||||
) -> AnalyticsMtdIter<T> {
|
||||
AnalyticsMtdIter::new_direct_related(self, an_meta_id, rel_type.into_glib())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: AnalyticsMtd> AnalyticsMtdRef<'a, T> {
|
||||
pub fn id(&self) -> u32 {
|
||||
self.id
|
||||
}
|
||||
|
||||
pub unsafe fn from_meta(meta: &gst::MetaRef<'a, AnalyticsRelationMeta>, id: u32) -> Self {
|
||||
skip_assert_initialized!();
|
||||
AnalyticsMtdRef {
|
||||
meta: meta.clone(),
|
||||
id,
|
||||
mtd_type: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_analytics_mtd_get_mtd_type")]
|
||||
pub fn mtd_type(&self) -> ffi::GstAnalyticsMtdType {
|
||||
unsafe {
|
||||
let mut mtd = ffi::GstAnalyticsMtd::unsafe_from(self);
|
||||
ffi::gst_analytics_mtd_get_mtd_type(&mut mtd)
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'a> AnalyticsMtdRef<'a, AnalyticsAnyMtd> {
|
||||
pub fn downcast<T: AnalyticsMtd>(
|
||||
self,
|
||||
) -> Result<AnalyticsMtdRef<'a, T>, AnalyticsMtdRef<'a, AnalyticsAnyMtd>> {
|
||||
if self.mtd_type() == T::mtd_type() {
|
||||
Ok(AnalyticsMtdRef {
|
||||
id: self.id,
|
||||
meta: self.meta,
|
||||
mtd_type: PhantomData,
|
||||
})
|
||||
} else {
|
||||
Err(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn downcast_ref<T: AnalyticsMtd>(&self) -> Option<&AnalyticsMtdRef<'a, T>> {
|
||||
unsafe {
|
||||
if self.mtd_type() == T::mtd_type() {
|
||||
Some(&*(self as *const _ as *const _))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> AnalyticsMtdRefMut<'a, AnalyticsAnyMtd> {
|
||||
pub fn downcast_mut<T: AnalyticsMtd>(&mut self) -> Option<&mut AnalyticsMtdRefMut<'a, T>> {
|
||||
unsafe {
|
||||
if self.as_ref().mtd_type() == T::mtd_type() {
|
||||
Some(&mut *(self as *mut _ as *mut _))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: AnalyticsMtd> UnsafeFrom<&AnalyticsMtdRef<'a, T>> for ffi::GstAnalyticsMtd {
|
||||
unsafe fn unsafe_from(t: &AnalyticsMtdRef<'a, T>) -> Self {
|
||||
ffi::GstAnalyticsMtd {
|
||||
id: t.id,
|
||||
meta: t.meta.as_mut_ptr(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait AnalyticsMetaRefMutExt<'a>: sealed::Sealed {
|
||||
#[doc(alias = "gst_analytics_relation_meta_get_mtd")]
|
||||
fn mtd_mut<T: AnalyticsMtd>(&'a mut self, an_meta_id: u32)
|
||||
-> Option<AnalyticsMtdRefMut<'a, T>>;
|
||||
|
||||
fn iter_mut<T: AnalyticsMtd>(&'a mut self) -> AnalyticsMtdIterMut<T>;
|
||||
fn iter_direct_related_mut<T: AnalyticsMtd>(
|
||||
&'a mut self,
|
||||
an_meta_id: u32,
|
||||
rel_type: RelTypes,
|
||||
) -> AnalyticsMtdIterMut<T>;
|
||||
}
|
||||
|
||||
impl<'a> AnalyticsMetaRefMutExt<'a>
|
||||
for gst::MetaRefMut<'a, AnalyticsRelationMeta, gst::meta::Standalone>
|
||||
{
|
||||
fn mtd_mut<T: AnalyticsMtd>(
|
||||
&'a mut self,
|
||||
an_meta_id: u32,
|
||||
) -> Option<AnalyticsMtdRefMut<'a, T>> {
|
||||
unsafe {
|
||||
let mut mtd = std::mem::MaybeUninit::uninit();
|
||||
let ret = from_glib(ffi::gst_analytics_relation_meta_get_mtd(
|
||||
self.as_mut_ptr(),
|
||||
an_meta_id,
|
||||
T::mtd_type(),
|
||||
mtd.as_mut_ptr(),
|
||||
));
|
||||
let id = mtd.assume_init().id;
|
||||
|
||||
if ret {
|
||||
Some(AnalyticsMtdRefMut::from_meta(self, id))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn iter_mut<T: AnalyticsMtd>(&'a mut self) -> AnalyticsMtdIterMut<T> {
|
||||
AnalyticsMtdIterMut::new(self)
|
||||
}
|
||||
fn iter_direct_related_mut<T: AnalyticsMtd>(
|
||||
&'a mut self,
|
||||
an_meta_id: u32,
|
||||
rel_type: RelTypes,
|
||||
) -> AnalyticsMtdIterMut<T> {
|
||||
AnalyticsMtdIterMut::new_direct_related(self, an_meta_id, rel_type.into_glib())
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl MetaAPI for AnalyticsRelationMeta {
|
||||
type GstType = ffi::GstAnalyticsRelationMeta;
|
||||
|
||||
#[doc(alias = "gst_analytics_relation_meta_api_get_type")]
|
||||
#[inline]
|
||||
fn meta_api() -> glib::Type {
|
||||
unsafe { from_glib(ffi::gst_analytics_relation_meta_api_get_type()) }
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe trait AnalyticsMtd {
|
||||
fn mtd_type() -> ffi::GstAnalyticsMtdType;
|
||||
}
|
||||
|
||||
pub trait AnalyticsMtdExt: AnalyticsMtd {
|
||||
#[doc(alias = "gst_analytics_mtd_type_get_name")]
|
||||
fn type_name() -> &'static str {
|
||||
unsafe {
|
||||
let ptr = ffi::gst_analytics_mtd_type_get_name(Self::mtd_type());
|
||||
std::ffi::CStr::from_ptr(ptr).to_str().unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: AnalyticsMtd> AnalyticsMtdExt for T {}
|
||||
|
||||
impl<'a, T: AnalyticsMtd> AnalyticsMtdRefMut<'a, T> {
|
||||
pub fn id(&self) -> u32 {
|
||||
self.id
|
||||
}
|
||||
|
||||
pub unsafe fn from_meta(
|
||||
meta: &'a mut gst::MetaRefMut<'a, AnalyticsRelationMeta, gst::meta::Standalone>,
|
||||
id: u32,
|
||||
) -> Self {
|
||||
skip_assert_initialized!();
|
||||
AnalyticsMtdRefMut {
|
||||
meta,
|
||||
id,
|
||||
mtd_type: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: AnalyticsMtd> UnsafeFrom<&mut AnalyticsMtdRefMut<'a, T>> for ffi::GstAnalyticsMtd {
|
||||
unsafe fn unsafe_from(t: &mut AnalyticsMtdRefMut<'a, T>) -> Self {
|
||||
ffi::GstAnalyticsMtd {
|
||||
id: t.id,
|
||||
meta: t.meta.as_mut_ptr(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: AnalyticsMtd> From<AnalyticsMtdRefMut<'a, T>> for AnalyticsMtdRef<'a, T> {
|
||||
fn from(value: AnalyticsMtdRefMut<'a, T>) -> Self {
|
||||
skip_assert_initialized!();
|
||||
AnalyticsMtdRef {
|
||||
meta: value.meta.as_ref().clone(),
|
||||
id: value.id,
|
||||
mtd_type: value.mtd_type,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: AnalyticsMtd> From<&mut AnalyticsMtdRefMut<'a, T>> for AnalyticsMtdRef<'a, T> {
|
||||
fn from(value: &mut AnalyticsMtdRefMut<'a, T>) -> Self {
|
||||
skip_assert_initialized!();
|
||||
AnalyticsMtdRef {
|
||||
meta: value.meta.as_ref().clone(),
|
||||
id: value.id,
|
||||
mtd_type: value.mtd_type,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: AnalyticsMtd> AsRef<AnalyticsMtdRef<'a, T>> for AnalyticsMtdRefMut<'a, T> {
|
||||
#[inline]
|
||||
fn as_ref(&self) -> &AnalyticsMtdRef<'a, T> {
|
||||
unsafe { &*(self as *const AnalyticsMtdRefMut<'a, T> as *const AnalyticsMtdRef<'a, T>) }
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! define_mtd_iter {
|
||||
($name:ident, $metaref:ty, $itemref:ty, $copy_meta:expr) => {
|
||||
pub struct $name<'a, T: AnalyticsMtd> {
|
||||
meta: $metaref,
|
||||
state: glib::ffi::gpointer,
|
||||
mtd_type: ffi::GstAnalyticsMtdType,
|
||||
an_meta_id: u32,
|
||||
rel_type: ffi::GstAnalyticsRelTypes,
|
||||
phantom: std::marker::PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<'a, T: AnalyticsMtd> $name<'a, T> {
|
||||
fn new(meta: $metaref) -> Self {
|
||||
skip_assert_initialized!();
|
||||
$name {
|
||||
meta,
|
||||
state: std::ptr::null_mut(),
|
||||
mtd_type: T::mtd_type(),
|
||||
an_meta_id: std::u32::MAX,
|
||||
rel_type: RelTypes::ANY.into_glib(),
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
fn new_direct_related(
|
||||
meta: $metaref,
|
||||
an_meta_id: u32,
|
||||
rel_type: ffi::GstAnalyticsRelTypes,
|
||||
) -> Self {
|
||||
skip_assert_initialized!();
|
||||
$name {
|
||||
meta,
|
||||
state: std::ptr::null_mut(),
|
||||
mtd_type: T::mtd_type(),
|
||||
an_meta_id,
|
||||
rel_type,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: AnalyticsMtd + 'a> Iterator for $name<'a, T> {
|
||||
type Item = $itemref;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
unsafe {
|
||||
let mut mtd = ffi::GstAnalyticsMtd::unsafe_from(&**self.meta);
|
||||
let ret = {
|
||||
if self.an_meta_id == std::u32::MAX {
|
||||
ffi::gst_analytics_relation_meta_iterate(
|
||||
self.meta.as_mut_ptr(),
|
||||
&mut self.state,
|
||||
self.mtd_type,
|
||||
&mut mtd,
|
||||
)
|
||||
} else {
|
||||
ffi::gst_analytics_relation_meta_get_direct_related(
|
||||
self.meta.as_mut_ptr(),
|
||||
self.an_meta_id,
|
||||
self.rel_type,
|
||||
self.mtd_type,
|
||||
&mut self.state,
|
||||
&mut mtd,
|
||||
)
|
||||
}
|
||||
};
|
||||
if from_glib(ret) {
|
||||
// This is a known clippy limitation
|
||||
// https://github.com/rust-lang/rust-clippy/issues/1553
|
||||
#[allow(clippy::redundant_closure_call)]
|
||||
Some(Self::Item::from_meta($copy_meta(self.meta), mtd.id))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
define_mtd_iter!(
|
||||
AnalyticsMtdIter,
|
||||
&'a gst::MetaRef<'a, AnalyticsRelationMeta>,
|
||||
AnalyticsMtdRef<'a, T>,
|
||||
|meta| meta
|
||||
);
|
||||
|
||||
define_mtd_iter!(
|
||||
AnalyticsMtdIterMut,
|
||||
&'a mut gst::MetaRefMut<'a, AnalyticsRelationMeta, gst::meta::Standalone>,
|
||||
AnalyticsMtdRefMut<'a, T>,
|
||||
|meta: &mut _| &mut *(meta as *mut gst::MetaRefMut<
|
||||
'a,
|
||||
AnalyticsRelationMeta,
|
||||
gst::meta::Standalone,
|
||||
>)
|
||||
);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum AnalyticsAnyMtd {}
|
||||
|
||||
unsafe impl AnalyticsMtd for AnalyticsAnyMtd {
|
||||
fn mtd_type() -> ffi::GstAnalyticsMtdType {
|
||||
ffi::GST_ANALYTICS_MTD_TYPE_ANY as ffi::GstAnalyticsMtdType
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::*;
|
||||
|
||||
#[test]
|
||||
fn build_relation_meta() {
|
||||
gst::init().unwrap();
|
||||
|
||||
let mut buf = gst::Buffer::new();
|
||||
|
||||
let meta = AnalyticsRelationMeta::add(buf.make_mut());
|
||||
|
||||
assert!(meta.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn build_relation_meta_full() {
|
||||
gst::init().unwrap();
|
||||
|
||||
let mut buf = gst::Buffer::new();
|
||||
|
||||
let params = AnalyticsRelationMetaInitParams::new(10, 10);
|
||||
let meta = AnalyticsRelationMeta::add_full(buf.make_mut(), ¶ms);
|
||||
|
||||
assert!(meta.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn relations() {
|
||||
gst::init().unwrap();
|
||||
|
||||
let mut buf = gst::Buffer::new();
|
||||
let _ = AnalyticsRelationMeta::add(buf.make_mut());
|
||||
|
||||
let mut meta = buf.make_mut().meta_mut::<AnalyticsRelationMeta>().unwrap();
|
||||
let od = meta
|
||||
.add_od_mtd(glib::Quark::from_str("blb"), 0, 1, 10, 20, 0.8)
|
||||
.unwrap();
|
||||
let od1_id = od.id();
|
||||
|
||||
let od = meta
|
||||
.add_od_mtd(glib::Quark::from_str("blb"), 0, 1, 10, 20, 0.8)
|
||||
.unwrap();
|
||||
let od2_id = od.id();
|
||||
|
||||
let od: AnalyticsMtdRef<'_, AnalyticsODMtd> = meta
|
||||
.add_od_mtd(glib::Quark::from_str("blb"), 0, 1, 10, 20, 0.8)
|
||||
.unwrap();
|
||||
let od3_id = od.id();
|
||||
|
||||
meta.set_relation(RelTypes::IS_PART_OF, od1_id, od2_id)
|
||||
.unwrap();
|
||||
meta.set_relation(RelTypes::IS_PART_OF, od2_id, od3_id)
|
||||
.unwrap();
|
||||
|
||||
meta.set_relation(RelTypes::IS_PART_OF, 8888, 9999)
|
||||
.expect_err("Invalid id");
|
||||
|
||||
let meta = buf.meta::<AnalyticsRelationMeta>().unwrap();
|
||||
assert!(meta.relation(od1_id, od2_id) == crate::RelTypes::IS_PART_OF);
|
||||
assert!(meta.relation(od2_id, od3_id) == crate::RelTypes::IS_PART_OF);
|
||||
|
||||
assert!(meta.exist(od1_id, od2_id, 1, crate::RelTypes::IS_PART_OF));
|
||||
assert!(meta.exist(od1_id, od3_id, 2, crate::RelTypes::IS_PART_OF));
|
||||
assert!(!meta.exist(od2_id, od1_id, 1, crate::RelTypes::IS_PART_OF));
|
||||
assert!(!meta.exist(od1_id, od3_id, 1, crate::RelTypes::IS_PART_OF));
|
||||
assert!(!meta.exist(od1_id, od2_id, 1, crate::RelTypes::CONTAIN));
|
||||
|
||||
let path = meta
|
||||
.exist_path(od1_id, od3_id, 3, crate::RelTypes::ANY)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(path.as_slice().len(), 3);
|
||||
assert_eq!(path.as_slice()[0], od1_id);
|
||||
assert_eq!(path.as_slice()[1], od2_id);
|
||||
assert_eq!(path.as_slice()[2], od3_id);
|
||||
|
||||
assert_eq!(meta.len(), meta.iter::<AnalyticsAnyMtd>().count());
|
||||
assert_eq!(meta.len(), meta.iter::<AnalyticsODMtd>().count());
|
||||
for mtd in meta.iter::<AnalyticsODMtd>() {
|
||||
assert_eq!(mtd.obj_type(), glib::Quark::from_str("blb"))
|
||||
}
|
||||
|
||||
assert_eq!(meta.len(), meta.iter::<AnalyticsAnyMtd>().count());
|
||||
for mtd in meta.iter::<AnalyticsAnyMtd>() {
|
||||
if let Ok(mtd) = mtd.downcast::<AnalyticsODMtd>() {
|
||||
assert_eq!(mtd.obj_type(), glib::Quark::from_str("blb"))
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
meta.iter_direct_related::<AnalyticsODMtd>(od1_id, crate::RelTypes::IS_PART_OF)
|
||||
.count(),
|
||||
1
|
||||
);
|
||||
assert_eq!(
|
||||
meta.iter_direct_related::<AnalyticsODMtd>(od2_id, crate::RelTypes::IS_PART_OF)
|
||||
.count(),
|
||||
1
|
||||
);
|
||||
assert_eq!(
|
||||
meta.iter_direct_related::<AnalyticsODMtd>(od3_id, crate::RelTypes::IS_PART_OF)
|
||||
.count(),
|
||||
0
|
||||
);
|
||||
assert_eq!(
|
||||
meta.iter_direct_related::<AnalyticsODMtd>(od1_id, crate::RelTypes::CONTAIN)
|
||||
.count(),
|
||||
0
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
meta.iter_direct_related::<AnalyticsAnyMtd>(od1_id, crate::RelTypes::CONTAIN)
|
||||
.count(),
|
||||
0
|
||||
);
|
||||
for mtd in meta.iter_direct_related::<AnalyticsODMtd>(od1_id, crate::RelTypes::IS_PART_OF) {
|
||||
assert_eq!(mtd.obj_type(), glib::Quark::from_str("blb"))
|
||||
}
|
||||
|
||||
let mut meta = buf.make_mut().meta_mut::<AnalyticsRelationMeta>().unwrap();
|
||||
assert_eq!(meta.len(), meta.iter_mut::<AnalyticsAnyMtd>().count());
|
||||
|
||||
let mut meta = buf.make_mut().meta_mut::<AnalyticsRelationMeta>().unwrap();
|
||||
let _ = meta.add_tracking_mtd(10, gst::ClockTime::from_seconds(10));
|
||||
let _ = meta.add_tracking_mtd(10, gst::ClockTime::from_seconds(10));
|
||||
|
||||
for mut item in meta.iter_mut::<AnalyticsTrackingMtd>() {
|
||||
item.set_lost().unwrap();
|
||||
}
|
||||
}
|
||||
}
|
158
gstreamer-analytics/src/tracking.rs
Normal file
158
gstreamer-analytics/src/tracking.rs
Normal file
|
@ -0,0 +1,158 @@
|
|||
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||
|
||||
use glib::translate::*;
|
||||
|
||||
use crate::relation_meta::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum AnalyticsTrackingMtd {}
|
||||
|
||||
mod sealed {
|
||||
pub trait Sealed {}
|
||||
impl<T: super::AnalyticsRelationMetaTrackingExt> Sealed for T {}
|
||||
}
|
||||
|
||||
pub trait AnalyticsRelationMetaTrackingExt: sealed::Sealed {
|
||||
fn add_tracking_mtd(
|
||||
&mut self,
|
||||
tracking_id: u64,
|
||||
tracking_first_seen: gst::ClockTime,
|
||||
) -> Result<AnalyticsMtdRef<AnalyticsTrackingMtd>, glib::BoolError>;
|
||||
}
|
||||
|
||||
impl<'a> AnalyticsRelationMetaTrackingExt
|
||||
for gst::MetaRefMut<'a, AnalyticsRelationMeta, gst::meta::Standalone>
|
||||
{
|
||||
#[doc(alias = "gst_analytics_relation_meta_add_tracking_mtd")]
|
||||
fn add_tracking_mtd(
|
||||
&mut self,
|
||||
tracking_id: u64,
|
||||
tracking_first_seen: gst::ClockTime,
|
||||
) -> Result<AnalyticsMtdRef<AnalyticsTrackingMtd>, glib::BoolError> {
|
||||
unsafe {
|
||||
let mut mtd = std::mem::MaybeUninit::uninit();
|
||||
let ret = from_glib(ffi::gst_analytics_relation_meta_add_tracking_mtd(
|
||||
self.as_mut_ptr(),
|
||||
tracking_id,
|
||||
tracking_first_seen.into_glib(),
|
||||
mtd.as_mut_ptr(),
|
||||
));
|
||||
let id = mtd.assume_init().id;
|
||||
|
||||
if ret {
|
||||
Ok(AnalyticsMtdRef::from_meta(self.as_ref(), id))
|
||||
} else {
|
||||
Err(glib::bool_error!("Couldn't add more data"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl AnalyticsMtd for AnalyticsTrackingMtd {
|
||||
#[doc(alias = "gst_analytics_tracking_mtd_get_mtd_type")]
|
||||
fn mtd_type() -> ffi::GstAnalyticsMtdType {
|
||||
unsafe { ffi::gst_analytics_tracking_mtd_get_mtd_type() }
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn from(t: ffi::GstAnalyticsMtd) -> ffi::GstAnalyticsTrackingMtd {
|
||||
std::mem::transmute(t)
|
||||
}
|
||||
|
||||
impl<'a> AnalyticsMtdRef<'a, AnalyticsTrackingMtd> {
|
||||
#[doc(alias = "gst_analytics_tracking_mtd_get_info")]
|
||||
pub fn info(&self) -> (u64, gst::ClockTime, gst::ClockTime, bool) {
|
||||
let mut tracking_id: u64 = 0;
|
||||
let mut tracking_first_seen: u64 = 0;
|
||||
let mut tracking_last_seen: u64 = 0;
|
||||
let mut tracking_lost: i32 = 0;
|
||||
|
||||
unsafe {
|
||||
let mut mtd = from(ffi::GstAnalyticsMtd::unsafe_from(self));
|
||||
ffi::gst_analytics_tracking_mtd_get_info(
|
||||
&mut mtd,
|
||||
&mut tracking_id,
|
||||
&mut tracking_first_seen,
|
||||
&mut tracking_last_seen,
|
||||
&mut tracking_lost,
|
||||
);
|
||||
};
|
||||
|
||||
(
|
||||
tracking_id,
|
||||
gst::ClockTime::from_nseconds(tracking_first_seen),
|
||||
gst::ClockTime::from_nseconds(tracking_last_seen),
|
||||
tracking_lost != 0,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> AnalyticsMtdRefMut<'a, AnalyticsTrackingMtd> {
|
||||
#[doc(alias = "gst_analytics_tracking_mtd_update_last_seen")]
|
||||
pub fn update_last_seen(&mut self, last_seen: gst::ClockTime) -> Result<(), glib::BoolError> {
|
||||
let ret: bool = unsafe {
|
||||
let mut mtd = from(ffi::GstAnalyticsMtd::unsafe_from(self));
|
||||
from_glib(ffi::gst_analytics_tracking_mtd_update_last_seen(
|
||||
&mut mtd,
|
||||
last_seen.into_glib(),
|
||||
))
|
||||
};
|
||||
assert!(ret);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_analytics_tracking_mtd_set_lost")]
|
||||
pub fn set_lost(&mut self) -> Result<(), glib::BoolError> {
|
||||
let ret: bool = unsafe {
|
||||
let mut mtd = from(ffi::GstAnalyticsMtd::unsafe_from(self));
|
||||
from_glib(ffi::gst_analytics_tracking_mtd_set_lost(&mut mtd))
|
||||
};
|
||||
assert!(ret);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::*;
|
||||
|
||||
#[test]
|
||||
fn tracking() {
|
||||
gst::init().unwrap();
|
||||
|
||||
assert_eq!(AnalyticsTrackingMtd::type_name(), "object-tracking");
|
||||
|
||||
let mut buf = gst::Buffer::new();
|
||||
let mut meta = AnalyticsRelationMeta::add(buf.make_mut());
|
||||
|
||||
assert!(meta.is_empty());
|
||||
|
||||
let track = meta
|
||||
.add_tracking_mtd(10, gst::ClockTime::from_seconds(10))
|
||||
.unwrap();
|
||||
|
||||
let (tracking_id, tracking_first_seen, tracking_last_seen, tracking_lost) = track.info();
|
||||
|
||||
assert_eq!(tracking_id, 10);
|
||||
assert_eq!(tracking_first_seen, gst::ClockTime::from_seconds(10));
|
||||
assert_eq!(tracking_last_seen, gst::ClockTime::from_seconds(10));
|
||||
assert!(!tracking_lost);
|
||||
|
||||
let track_id = track.id();
|
||||
|
||||
let mut tracking_mut = meta.mtd_mut::<AnalyticsTrackingMtd>(track_id).unwrap();
|
||||
|
||||
tracking_mut
|
||||
.update_last_seen(gst::ClockTime::from_seconds(20))
|
||||
.unwrap();
|
||||
tracking_mut.set_lost().unwrap();
|
||||
|
||||
let tracking: AnalyticsMtdRef<_> = tracking_mut.into();
|
||||
let (tracking_id, tracking_first_seen, tracking_last_seen, tracking_lost) = tracking.info();
|
||||
|
||||
assert_eq!(tracking_id, 10);
|
||||
assert_eq!(tracking_first_seen, gst::ClockTime::from_seconds(10));
|
||||
assert_eq!(tracking_last_seen, gst::ClockTime::from_seconds(20));
|
||||
assert!(tracking_lost);
|
||||
}
|
||||
}
|
1
gstreamer-analytics/sys/CHANGELOG.md
Symbolic link
1
gstreamer-analytics/sys/CHANGELOG.md
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../gstreamer/CHANGELOG.md
|
1
gstreamer-analytics/sys/COPYRIGHT
Symbolic link
1
gstreamer-analytics/sys/COPYRIGHT
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../COPYRIGHT
|
57
gstreamer-analytics/sys/Cargo.toml
Normal file
57
gstreamer-analytics/sys/Cargo.toml
Normal file
|
@ -0,0 +1,57 @@
|
|||
[build-dependencies]
|
||||
system-deps = "6"
|
||||
|
||||
[dependencies]
|
||||
libc = "0.2"
|
||||
|
||||
[dependencies.glib-sys]
|
||||
workspace = true
|
||||
|
||||
[dependencies.gstreamer-sys]
|
||||
workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
shell-words = "1.0.0"
|
||||
tempfile = "3"
|
||||
|
||||
[lib]
|
||||
name = "gstreamer_analytics_sys"
|
||||
|
||||
[package]
|
||||
authors = ["Olivier Crête <olivier.crete@collabora.com"]
|
||||
build = "build.rs"
|
||||
description = "FFI bindings to libgstanalytics-1.0"
|
||||
documentation = "https://gstreamer.pages.freedesktop.org/gstreamer-rs/stable/latest/docs/gstreamer_analytics_sys/"
|
||||
keywords = ["ffi", "gstreamer", "gnome", "multimedia"]
|
||||
license = "MIT"
|
||||
name = "gstreamer-analytics-sys"
|
||||
readme = "README.md"
|
||||
|
||||
[package.version]
|
||||
workspace = true
|
||||
|
||||
[package.categories]
|
||||
workspace = true
|
||||
|
||||
[package.repository]
|
||||
workspace = true
|
||||
|
||||
[package.homepage]
|
||||
workspace = true
|
||||
|
||||
[package.edition]
|
||||
workspace = true
|
||||
|
||||
[package.rust-version]
|
||||
workspace = true
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustc-args = ["--cfg", "docsrs"]
|
||||
rustdoc-args = ["--cfg", "docsrs", "--generate-link-to-definition"]
|
||||
|
||||
[package.metadata.system-deps.gstreamer_analytics_1_0]
|
||||
name = "gstreamer-analytics-1.0"
|
||||
version = "1.23"
|
||||
|
||||
[features]
|
48
gstreamer-analytics/sys/Gir.toml
Normal file
48
gstreamer-analytics/sys/Gir.toml
Normal file
|
@ -0,0 +1,48 @@
|
|||
[options]
|
||||
girs_directories = ["../../gir-files", "../../gst-gir-files"]
|
||||
library = "GstAnalytics"
|
||||
version = "1.0"
|
||||
min_cfg_version = "1.24"
|
||||
work_mode = "sys"
|
||||
single_version_file = true
|
||||
|
||||
external_libraries = [
|
||||
"GLib",
|
||||
]
|
||||
|
||||
manual = [
|
||||
"GObject.Object",
|
||||
"Gst.Element",
|
||||
"Gst.MiniObject",
|
||||
"Gst.Object",
|
||||
]
|
||||
|
||||
[external_libraries]
|
||||
gstreamer="Gst"
|
||||
|
||||
[[object]]
|
||||
name = "GstAnalytics.RelationMeta"
|
||||
status = "generate"
|
||||
[[object.function]]
|
||||
name = "relation_meta_api_get_type"
|
||||
version = "1.24"
|
||||
|
||||
[[object]]
|
||||
name = "GstAnalytics.ClsMtd"
|
||||
status = "generate"
|
||||
boxed_inline = true
|
||||
|
||||
[[object]]
|
||||
name = "GstAnalytics.TrackingMtd"
|
||||
status = "generate"
|
||||
boxed_inline = true
|
||||
|
||||
[[object]]
|
||||
name = "GstAnalytics.ODMtd"
|
||||
status = "generate"
|
||||
boxed_inline = true
|
||||
|
||||
[[object]]
|
||||
name = "GstAnalytics.Mtd"
|
||||
status = "generate"
|
||||
boxed_inline = true
|
1
gstreamer-analytics/sys/LICENSE
Symbolic link
1
gstreamer-analytics/sys/LICENSE
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../LICENSE-MIT
|
31
gstreamer-analytics/sys/README.md
Normal file
31
gstreamer-analytics/sys/README.md
Normal file
|
@ -0,0 +1,31 @@
|
|||
# gstreamer-sys [![crates.io](https://img.shields.io/crates/v/gstreamer-app-sys.svg)](https://crates.io/crates/gstreamer-app-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/) (App 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.
|
18
gstreamer-analytics/sys/build.rs
Normal file
18
gstreamer-analytics/sys/build.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
// 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(not(docsrs))]
|
||||
use std::process;
|
||||
|
||||
#[cfg(docsrs)]
|
||||
fn main() {} // prevent linking libraries to avoid documentation failure
|
||||
|
||||
#[cfg(not(docsrs))]
|
||||
fn main() {
|
||||
if let Err(s) = system_deps::Config::new().probe() {
|
||||
println!("cargo:warning={s}");
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
3
gstreamer-analytics/sys/src/auto/versions.txt
Normal file
3
gstreamer-analytics/sys/src/auto/versions.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
337
gstreamer-analytics/sys/src/lib.rs
Normal file
337
gstreamer-analytics/sys/src/lib.rs
Normal file
|
@ -0,0 +1,337 @@
|
|||
// 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
|
||||
|
||||
#![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(docsrs, feature(doc_cfg))]
|
||||
|
||||
use glib_sys as glib;
|
||||
use gstreamer_sys as gst;
|
||||
|
||||
#[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};
|
||||
|
||||
// Aliases
|
||||
pub type GstAnalyticsMtdType = uintptr_t;
|
||||
|
||||
// Constants
|
||||
pub const GST_AN_RELATION_META_TAG: &[u8] = b"GST-ANALYSIS-RELATION-META-TAG\0";
|
||||
pub const GST_INF_RELATION_SPAN: c_int = -1;
|
||||
pub const GST_ANALYTICS_MTD_TYPE_ANY: c_int = 0;
|
||||
|
||||
// Flags
|
||||
pub type GstAnalyticsRelTypes = c_uint;
|
||||
pub const GST_ANALYTICS_REL_TYPE_NONE: GstAnalyticsRelTypes = 0;
|
||||
pub const GST_ANALYTICS_REL_TYPE_IS_PART_OF: GstAnalyticsRelTypes = 2;
|
||||
pub const GST_ANALYTICS_REL_TYPE_CONTAIN: GstAnalyticsRelTypes = 4;
|
||||
pub const GST_ANALYTICS_REL_TYPE_RELATE_TO: GstAnalyticsRelTypes = 8;
|
||||
pub const GST_ANALYTICS_REL_TYPE_LAST: GstAnalyticsRelTypes = 16;
|
||||
pub const GST_ANALYTICS_REL_TYPE_ANY: GstAnalyticsRelTypes = 2147483647;
|
||||
|
||||
// Records
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(C)]
|
||||
pub struct GstAnalyticsClsMtd {
|
||||
pub id: c_uint,
|
||||
pub meta: *mut GstAnalyticsRelationMeta,
|
||||
}
|
||||
|
||||
impl ::std::fmt::Debug for GstAnalyticsClsMtd {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
f.debug_struct(&format!("GstAnalyticsClsMtd @ {self:p}"))
|
||||
.field("id", &self.id)
|
||||
.field("meta", &self.meta)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(C)]
|
||||
pub struct GstAnalyticsMtd {
|
||||
pub id: c_uint,
|
||||
pub meta: *mut GstAnalyticsRelationMeta,
|
||||
}
|
||||
|
||||
impl ::std::fmt::Debug for GstAnalyticsMtd {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
f.debug_struct(&format!("GstAnalyticsMtd @ {self:p}"))
|
||||
.field("id", &self.id)
|
||||
.field("meta", &self.meta)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(C)]
|
||||
pub struct GstAnalyticsMtdImpl {
|
||||
pub name: *const c_char,
|
||||
pub mtd_meta_transform: Option<
|
||||
unsafe extern "C" fn(
|
||||
*mut gst::GstBuffer,
|
||||
*mut GstAnalyticsMtd,
|
||||
*mut gst::GstBuffer,
|
||||
glib::GQuark,
|
||||
gpointer,
|
||||
) -> gboolean,
|
||||
>,
|
||||
pub _reserved: [gpointer; 20],
|
||||
}
|
||||
|
||||
impl ::std::fmt::Debug for GstAnalyticsMtdImpl {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
f.debug_struct(&format!("GstAnalyticsMtdImpl @ {self:p}"))
|
||||
.field("name", &self.name)
|
||||
.field("mtd_meta_transform", &self.mtd_meta_transform)
|
||||
.field("_reserved", &self._reserved)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(C)]
|
||||
pub struct GstAnalyticsODMtd {
|
||||
pub id: c_uint,
|
||||
pub meta: *mut GstAnalyticsRelationMeta,
|
||||
}
|
||||
|
||||
impl ::std::fmt::Debug for GstAnalyticsODMtd {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
f.debug_struct(&format!("GstAnalyticsODMtd @ {self:p}"))
|
||||
.field("id", &self.id)
|
||||
.field("meta", &self.meta)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct _GstAnalyticsRelationMeta {
|
||||
_data: [u8; 0],
|
||||
_marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>,
|
||||
}
|
||||
|
||||
pub type GstAnalyticsRelationMeta = _GstAnalyticsRelationMeta;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(C)]
|
||||
pub struct GstAnalyticsRelationMetaInitParams {
|
||||
pub initial_relation_order: size_t,
|
||||
pub initial_buf_size: size_t,
|
||||
}
|
||||
|
||||
impl ::std::fmt::Debug for GstAnalyticsRelationMetaInitParams {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
f.debug_struct(&format!("GstAnalyticsRelationMetaInitParams @ {self:p}"))
|
||||
.field("initial_relation_order", &self.initial_relation_order)
|
||||
.field("initial_buf_size", &self.initial_buf_size)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(C)]
|
||||
pub struct GstAnalyticsTrackingMtd {
|
||||
pub id: c_uint,
|
||||
pub meta: *mut GstAnalyticsRelationMeta,
|
||||
}
|
||||
|
||||
impl ::std::fmt::Debug for GstAnalyticsTrackingMtd {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
f.debug_struct(&format!("GstAnalyticsTrackingMtd @ {self:p}"))
|
||||
.field("id", &self.id)
|
||||
.field("meta", &self.meta)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[link(name = "gstanalytics-1.0")]
|
||||
extern "C" {
|
||||
|
||||
//=========================================================================
|
||||
// GstAnalyticsClsMtd
|
||||
//=========================================================================
|
||||
pub fn gst_analytics_cls_mtd_get_index_by_quark(
|
||||
handle: *mut GstAnalyticsClsMtd,
|
||||
quark: glib::GQuark,
|
||||
) -> c_int;
|
||||
pub fn gst_analytics_cls_mtd_get_length(handle: *mut GstAnalyticsClsMtd) -> size_t;
|
||||
pub fn gst_analytics_cls_mtd_get_level(
|
||||
handle: *mut GstAnalyticsClsMtd,
|
||||
index: size_t,
|
||||
) -> c_float;
|
||||
pub fn gst_analytics_cls_mtd_get_quark(
|
||||
handle: *mut GstAnalyticsClsMtd,
|
||||
index: size_t,
|
||||
) -> glib::GQuark;
|
||||
pub fn gst_analytics_cls_mtd_get_mtd_type() -> GstAnalyticsMtdType;
|
||||
|
||||
//=========================================================================
|
||||
// GstAnalyticsMtd
|
||||
//=========================================================================
|
||||
pub fn gst_analytics_mtd_get_id(instance: *mut GstAnalyticsMtd) -> c_uint;
|
||||
pub fn gst_analytics_mtd_get_mtd_type(instance: *mut GstAnalyticsMtd) -> GstAnalyticsMtdType;
|
||||
pub fn gst_analytics_mtd_get_size(instance: *mut GstAnalyticsMtd) -> size_t;
|
||||
pub fn gst_analytics_mtd_type_get_name(type_: GstAnalyticsMtdType) -> *const c_char;
|
||||
|
||||
//=========================================================================
|
||||
// GstAnalyticsODMtd
|
||||
//=========================================================================
|
||||
pub fn gst_analytics_od_mtd_get_confidence_lvl(
|
||||
instance: *mut GstAnalyticsODMtd,
|
||||
loc_conf_lvl: *mut c_float,
|
||||
) -> gboolean;
|
||||
pub fn gst_analytics_od_mtd_get_location(
|
||||
instance: *mut GstAnalyticsODMtd,
|
||||
x: *mut c_int,
|
||||
y: *mut c_int,
|
||||
w: *mut c_int,
|
||||
h: *mut c_int,
|
||||
loc_conf_lvl: *mut c_float,
|
||||
) -> gboolean;
|
||||
pub fn gst_analytics_od_mtd_get_obj_type(handle: *mut GstAnalyticsODMtd) -> glib::GQuark;
|
||||
pub fn gst_analytics_od_mtd_get_mtd_type() -> GstAnalyticsMtdType;
|
||||
|
||||
//=========================================================================
|
||||
// GstAnalyticsRelationMeta
|
||||
//=========================================================================
|
||||
pub fn gst_analytics_relation_meta_add_cls_mtd(
|
||||
instance: *mut GstAnalyticsRelationMeta,
|
||||
length: size_t,
|
||||
confidence_levels: *mut c_float,
|
||||
class_quarks: *mut glib::GQuark,
|
||||
cls_mtd: *mut GstAnalyticsClsMtd,
|
||||
) -> gboolean;
|
||||
pub fn gst_analytics_relation_meta_add_mtd(
|
||||
meta: *mut GstAnalyticsRelationMeta,
|
||||
impl_: *const GstAnalyticsMtdImpl,
|
||||
size: size_t,
|
||||
rlt_mtd: *mut GstAnalyticsMtd,
|
||||
) -> gpointer;
|
||||
pub fn gst_analytics_relation_meta_add_od_mtd(
|
||||
instance: *mut GstAnalyticsRelationMeta,
|
||||
type_: glib::GQuark,
|
||||
x: c_int,
|
||||
y: c_int,
|
||||
w: c_int,
|
||||
h: c_int,
|
||||
loc_conf_lvl: c_float,
|
||||
od_mtd: *mut GstAnalyticsODMtd,
|
||||
) -> gboolean;
|
||||
pub fn gst_analytics_relation_meta_add_one_cls_mtd(
|
||||
instance: *mut GstAnalyticsRelationMeta,
|
||||
confidence_level: c_float,
|
||||
class_quark: glib::GQuark,
|
||||
cls_mtd: *mut GstAnalyticsClsMtd,
|
||||
) -> gboolean;
|
||||
pub fn gst_analytics_relation_meta_add_tracking_mtd(
|
||||
instance: *mut GstAnalyticsRelationMeta,
|
||||
tracking_id: u64,
|
||||
tracking_first_seen: gst::GstClockTime,
|
||||
trk_mtd: *mut GstAnalyticsTrackingMtd,
|
||||
) -> gboolean;
|
||||
pub fn gst_analytics_relation_meta_exist(
|
||||
rmeta: *mut GstAnalyticsRelationMeta,
|
||||
an_meta_first_id: c_uint,
|
||||
an_meta_second_id: c_uint,
|
||||
max_relation_span: c_int,
|
||||
cond_types: GstAnalyticsRelTypes,
|
||||
relations_path: *mut *mut glib::GArray,
|
||||
) -> gboolean;
|
||||
pub fn gst_analytics_relation_meta_get_cls_mtd(
|
||||
meta: *mut GstAnalyticsRelationMeta,
|
||||
an_meta_id: c_uint,
|
||||
rlt: *mut GstAnalyticsClsMtd,
|
||||
) -> gboolean;
|
||||
pub fn gst_analytics_relation_meta_get_direct_related(
|
||||
meta: *mut GstAnalyticsRelationMeta,
|
||||
an_meta_id: c_uint,
|
||||
relation_type: GstAnalyticsRelTypes,
|
||||
type_: GstAnalyticsMtdType,
|
||||
state: *mut gpointer,
|
||||
rlt_mtd: *mut GstAnalyticsMtd,
|
||||
) -> gboolean;
|
||||
pub fn gst_analytics_relation_meta_get_mtd(
|
||||
meta: *mut GstAnalyticsRelationMeta,
|
||||
an_meta_id: c_uint,
|
||||
type_: GstAnalyticsMtdType,
|
||||
rlt: *mut GstAnalyticsMtd,
|
||||
) -> gboolean;
|
||||
pub fn gst_analytics_relation_meta_get_mtd_data(
|
||||
meta: *mut GstAnalyticsRelationMeta,
|
||||
an_meta_id: c_uint,
|
||||
) -> gpointer;
|
||||
pub fn gst_analytics_relation_meta_get_od_mtd(
|
||||
meta: *mut GstAnalyticsRelationMeta,
|
||||
an_meta_id: c_uint,
|
||||
rlt: *mut GstAnalyticsODMtd,
|
||||
) -> gboolean;
|
||||
pub fn gst_analytics_relation_meta_get_relation(
|
||||
meta: *mut GstAnalyticsRelationMeta,
|
||||
an_meta_first_id: c_uint,
|
||||
an_meta_second_id: c_uint,
|
||||
) -> GstAnalyticsRelTypes;
|
||||
pub fn gst_analytics_relation_meta_get_tracking_mtd(
|
||||
meta: *mut GstAnalyticsRelationMeta,
|
||||
an_meta_id: c_uint,
|
||||
rlt: *mut GstAnalyticsTrackingMtd,
|
||||
) -> gboolean;
|
||||
pub fn gst_analytics_relation_meta_iterate(
|
||||
meta: *mut GstAnalyticsRelationMeta,
|
||||
state: *mut gpointer,
|
||||
type_: GstAnalyticsMtdType,
|
||||
rlt_mtd: *mut GstAnalyticsMtd,
|
||||
) -> gboolean;
|
||||
pub fn gst_analytics_relation_meta_set_relation(
|
||||
meta: *mut GstAnalyticsRelationMeta,
|
||||
type_: GstAnalyticsRelTypes,
|
||||
an_meta_first_id: c_uint,
|
||||
an_meta_second_id: c_uint,
|
||||
) -> gboolean;
|
||||
pub fn gst_analytics_relation_meta_get_info() -> *const gst::GstMetaInfo;
|
||||
|
||||
//=========================================================================
|
||||
// GstAnalyticsTrackingMtd
|
||||
//=========================================================================
|
||||
pub fn gst_analytics_tracking_mtd_get_info(
|
||||
instance: *mut GstAnalyticsTrackingMtd,
|
||||
tracking_id: *mut u64,
|
||||
tracking_first_seen: *mut gst::GstClockTime,
|
||||
tracking_last_seen: *mut gst::GstClockTime,
|
||||
tracking_lost: *mut gboolean,
|
||||
) -> gboolean;
|
||||
pub fn gst_analytics_tracking_mtd_set_lost(instance: *mut GstAnalyticsTrackingMtd) -> gboolean;
|
||||
pub fn gst_analytics_tracking_mtd_update_last_seen(
|
||||
instance: *mut GstAnalyticsTrackingMtd,
|
||||
last_seen: gst::GstClockTime,
|
||||
) -> gboolean;
|
||||
pub fn gst_analytics_tracking_mtd_get_mtd_type() -> GstAnalyticsMtdType;
|
||||
|
||||
//=========================================================================
|
||||
// Other functions
|
||||
//=========================================================================
|
||||
pub fn gst_buffer_add_analytics_relation_meta(
|
||||
buffer: *mut gst::GstBuffer,
|
||||
) -> *mut GstAnalyticsRelationMeta;
|
||||
pub fn gst_buffer_add_analytics_relation_meta_full(
|
||||
buffer: *mut gst::GstBuffer,
|
||||
init_params: *mut GstAnalyticsRelationMetaInitParams,
|
||||
) -> *mut GstAnalyticsRelationMeta;
|
||||
pub fn gst_buffer_get_analytics_relation_meta(
|
||||
buffer: *mut gst::GstBuffer,
|
||||
) -> *mut GstAnalyticsRelationMeta;
|
||||
pub fn gst_analytics_relation_get_length(instance: *mut GstAnalyticsRelationMeta) -> size_t;
|
||||
pub fn gst_analytics_relation_meta_api_get_type() -> GType;
|
||||
|
||||
}
|
273
gstreamer-analytics/sys/tests/abi.rs
Normal file
273
gstreamer-analytics/sys/tests/abi.rs
Normal file
|
@ -0,0 +1,273 @@
|
|||
// 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(unix)]
|
||||
|
||||
use gstreamer_analytics_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, Stdio};
|
||||
use std::str;
|
||||
use tempfile::Builder;
|
||||
|
||||
static PACKAGES: &[&str] = &["gstreamer-analytics-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 {cmd:?} failed, {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);
|
||||
cmd.stderr(Stdio::inherit());
|
||||
let out = cmd.output()?;
|
||||
if !out.status.success() {
|
||||
let (status, stdout) = (out.status, String::from_utf8_lossy(&out.stdout));
|
||||
return Err(format!("command {cmd:?} failed, {status:?}\nstdout: {stdout}").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]
|
||||
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 (name, value) = l.split_once(';').expect("Missing ';' separator");
|
||||
c_constants.push((name.to_owned(), value.to_owned()));
|
||||
}
|
||||
|
||||
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: {rust_name:?}\nC: {c_name:?}");
|
||||
continue;
|
||||
}
|
||||
|
||||
if rust_value != c_value {
|
||||
results.record_failed();
|
||||
eprintln!(
|
||||
"Constant value mismatch for {rust_name}\nRust: {rust_value:?}\nC: {c_value:?}",
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
results.record_passed();
|
||||
}
|
||||
|
||||
results.expect_total_success();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cross_validate_layout_with_c() {
|
||||
let mut c_layouts = Vec::new();
|
||||
|
||||
for l in get_c_output("layout").unwrap().lines() {
|
||||
let (name, value) = l.split_once(';').expect("Missing first ';' separator");
|
||||
let (size, alignment) = value.split_once(';').expect("Missing second ';' separator");
|
||||
let size = size.parse().expect("Failed to parse size");
|
||||
let alignment = alignment.parse().expect("Failed to parse alignment");
|
||||
c_layouts.push((name.to_owned(), 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: {rust_name:?}\nC: {c_name:?}");
|
||||
continue;
|
||||
}
|
||||
|
||||
if rust_layout != c_layout {
|
||||
results.record_failed();
|
||||
eprintln!("Layout mismatch for {rust_name}\nRust: {rust_layout:?}\nC: {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 cmd = Command::new(exe);
|
||||
cmd.stderr(Stdio::inherit());
|
||||
let out = cmd.output()?;
|
||||
if !out.status.success() {
|
||||
let (status, stdout) = (out.status, String::from_utf8_lossy(&out.stdout));
|
||||
return Err(format!("command {cmd:?} failed, {status:?}\nstdout: {stdout}").into());
|
||||
}
|
||||
|
||||
Ok(String::from_utf8(out.stdout)?)
|
||||
}
|
||||
|
||||
const RUST_LAYOUTS: &[(&str, Layout)] = &[
|
||||
(
|
||||
"GstAnalyticsClsMtd",
|
||||
Layout {
|
||||
size: size_of::<GstAnalyticsClsMtd>(),
|
||||
alignment: align_of::<GstAnalyticsClsMtd>(),
|
||||
},
|
||||
),
|
||||
(
|
||||
"GstAnalyticsMtd",
|
||||
Layout {
|
||||
size: size_of::<GstAnalyticsMtd>(),
|
||||
alignment: align_of::<GstAnalyticsMtd>(),
|
||||
},
|
||||
),
|
||||
(
|
||||
"GstAnalyticsMtdImpl",
|
||||
Layout {
|
||||
size: size_of::<GstAnalyticsMtdImpl>(),
|
||||
alignment: align_of::<GstAnalyticsMtdImpl>(),
|
||||
},
|
||||
),
|
||||
(
|
||||
"GstAnalyticsMtdType",
|
||||
Layout {
|
||||
size: size_of::<GstAnalyticsMtdType>(),
|
||||
alignment: align_of::<GstAnalyticsMtdType>(),
|
||||
},
|
||||
),
|
||||
(
|
||||
"GstAnalyticsODMtd",
|
||||
Layout {
|
||||
size: size_of::<GstAnalyticsODMtd>(),
|
||||
alignment: align_of::<GstAnalyticsODMtd>(),
|
||||
},
|
||||
),
|
||||
(
|
||||
"GstAnalyticsRelTypes",
|
||||
Layout {
|
||||
size: size_of::<GstAnalyticsRelTypes>(),
|
||||
alignment: align_of::<GstAnalyticsRelTypes>(),
|
||||
},
|
||||
),
|
||||
(
|
||||
"GstAnalyticsRelationMetaInitParams",
|
||||
Layout {
|
||||
size: size_of::<GstAnalyticsRelationMetaInitParams>(),
|
||||
alignment: align_of::<GstAnalyticsRelationMetaInitParams>(),
|
||||
},
|
||||
),
|
||||
(
|
||||
"GstAnalyticsTrackingMtd",
|
||||
Layout {
|
||||
size: size_of::<GstAnalyticsTrackingMtd>(),
|
||||
alignment: align_of::<GstAnalyticsTrackingMtd>(),
|
||||
},
|
||||
),
|
||||
];
|
||||
|
||||
const RUST_CONSTANTS: &[(&str, &str)] = &[
|
||||
("GST_ANALYTICS_MTD_TYPE_ANY", "0"),
|
||||
("(guint) GST_ANALYTICS_REL_TYPE_ANY", "2147483647"),
|
||||
("(guint) GST_ANALYTICS_REL_TYPE_CONTAIN", "4"),
|
||||
("(guint) GST_ANALYTICS_REL_TYPE_IS_PART_OF", "2"),
|
||||
("(guint) GST_ANALYTICS_REL_TYPE_LAST", "16"),
|
||||
("(guint) GST_ANALYTICS_REL_TYPE_NONE", "0"),
|
||||
("(guint) GST_ANALYTICS_REL_TYPE_RELATE_TO", "8"),
|
||||
("GST_AN_RELATION_META_TAG", "GST-ANALYSIS-RELATION-META-TAG"),
|
||||
("GST_INF_RELATION_SPAN", "-1"),
|
||||
];
|
42
gstreamer-analytics/sys/tests/constant.c
Normal file
42
gstreamer-analytics/sys/tests/constant.c
Normal file
|
@ -0,0 +1,42 @@
|
|||
// 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
|
||||
|
||||
#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_ANALYTICS_MTD_TYPE_ANY);
|
||||
PRINT_CONSTANT((guint) GST_ANALYTICS_REL_TYPE_ANY);
|
||||
PRINT_CONSTANT((guint) GST_ANALYTICS_REL_TYPE_CONTAIN);
|
||||
PRINT_CONSTANT((guint) GST_ANALYTICS_REL_TYPE_IS_PART_OF);
|
||||
PRINT_CONSTANT((guint) GST_ANALYTICS_REL_TYPE_LAST);
|
||||
PRINT_CONSTANT((guint) GST_ANALYTICS_REL_TYPE_NONE);
|
||||
PRINT_CONSTANT((guint) GST_ANALYTICS_REL_TYPE_RELATE_TO);
|
||||
PRINT_CONSTANT(GST_AN_RELATION_META_TAG);
|
||||
PRINT_CONSTANT(GST_INF_RELATION_SPAN);
|
||||
return 0;
|
||||
}
|
20
gstreamer-analytics/sys/tests/layout.c
Normal file
20
gstreamer-analytics/sys/tests/layout.c
Normal file
|
@ -0,0 +1,20 @@
|
|||
// 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
|
||||
|
||||
#include "manual.h"
|
||||
#include <stdalign.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
printf("%s;%zu;%zu\n", "GstAnalyticsClsMtd", sizeof(GstAnalyticsClsMtd), alignof(GstAnalyticsClsMtd));
|
||||
printf("%s;%zu;%zu\n", "GstAnalyticsMtd", sizeof(GstAnalyticsMtd), alignof(GstAnalyticsMtd));
|
||||
printf("%s;%zu;%zu\n", "GstAnalyticsMtdImpl", sizeof(GstAnalyticsMtdImpl), alignof(GstAnalyticsMtdImpl));
|
||||
printf("%s;%zu;%zu\n", "GstAnalyticsMtdType", sizeof(GstAnalyticsMtdType), alignof(GstAnalyticsMtdType));
|
||||
printf("%s;%zu;%zu\n", "GstAnalyticsODMtd", sizeof(GstAnalyticsODMtd), alignof(GstAnalyticsODMtd));
|
||||
printf("%s;%zu;%zu\n", "GstAnalyticsRelTypes", sizeof(GstAnalyticsRelTypes), alignof(GstAnalyticsRelTypes));
|
||||
printf("%s;%zu;%zu\n", "GstAnalyticsRelationMetaInitParams", sizeof(GstAnalyticsRelationMetaInitParams), alignof(GstAnalyticsRelationMetaInitParams));
|
||||
printf("%s;%zu;%zu\n", "GstAnalyticsTrackingMtd", sizeof(GstAnalyticsTrackingMtd), alignof(GstAnalyticsTrackingMtd));
|
||||
return 0;
|
||||
}
|
3
gstreamer-analytics/sys/tests/manual.h
Normal file
3
gstreamer-analytics/sys/tests/manual.h
Normal file
|
@ -0,0 +1,3 @@
|
|||
// Feel free to edit this file, it won't be regenerated by gir generator unless removed.
|
||||
|
||||
#include <gst/analytics/analytics.h>
|
8
gstreamer-analytics/tests/check_gir.rs
Normal file
8
gstreamer-analytics/tests/check_gir.rs
Normal 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);
|
||||
}
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 5975266da3b0)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ fe8258109e60)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 3f9f549accb7)
|
||||
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 63e90a30193b)
|
||||
|
|
Loading…
Reference in a new issue