Compare commits

...

112 commits
main ... 0.18

Author SHA1 Message Date
Sebastian Dröge
20c66951db Update Cargo.lock 2022-06-24 11:12:47 +03:00
Sebastian Dröge
7873a426d4 base: Fix memory leak if BaseSrc/PushSrc parent class is not filling the provided buffer as it should 2022-06-24 11:12:38 +03:00
Sebastian Dröge
62a2ad8a1e gstreamer: Fix serde serialization tests
ron serialization is now writing `1.0` instead of just `1`.
2022-06-24 11:12:38 +03:00
Sebastian Dröge
4cefe838f1 base: Add support for returning buffer lists from BaseSrc/PushSrc subclasses 2022-06-24 11:12:38 +03:00
Sebastian Dröge
c8e8031b74 ci: Fix syntax for coverage reports to the new format 2022-06-07 20:34:21 +03:00
Stephan Seitz
a4ba8b87cd gstreamer: add PadProbeId::as_raw()
This allows to convert PadProbeId to numberic values without
taking them by value (like `into_glib`).

See https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/issues/382#note_1391236
2022-06-07 20:34:21 +03:00
Sebastian Dröge
c651d96c49 net: Add various static PTP clock API
This allows initializing the PTP clock infrastructure, deinitializing
it, checking the current status and adding statistics callbacks.
2022-06-07 20:34:21 +03:00
Mathieu Duponchelle
ba25d7ea90 base classes: expose accessors for static pads
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/merge_requests/1023>
2022-06-07 20:21:12 +03:00
Sebastian Dröge
08953dfe66 gstreamer: Implement FusedStream for the Bus stream 2022-06-07 20:20:01 +03:00
Sebastian Dröge
9ee22baa07 Update CHANGELOG.md for 0.18.8 2022-04-26 14:02:36 +03:00
Sebastian Dröge
370d49cefd Update Cargo.lock 2022-04-26 13:57:03 +03:00
Sebastian Dröge
d5aa2e9b5f Update versions to 0.18.8 2022-04-26 13:55:34 +03:00
Mathieu Duponchelle
ffd1f3e15f rtpbuffer: bind length calculation API
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/merge_requests/1014>
2022-04-23 10:03:56 +03:00
Sebastian Dröge
cfef08470b Update Cargo.lock 2022-04-22 17:44:05 +03:00
Sebastian Dröge
87f2d51a35 gstreamer: Update to pretty-hex 0.3 2022-04-22 17:36:16 +03:00
Mathieu Duponchelle
433fa3da5c rtp_buffer: bind buffer getters
* Expose the buffer field, useful to look up flags and meta

* Expose the payload_buffer API, useful to avoid copies, for instance
  when storing in an adapter

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/merge_requests/1008>
2022-04-22 17:36:03 +03:00
Mathieu Duponchelle
05e59747ab rtp: add bindings for RTPBaseDepayload
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/merge_requests/1008>
2022-04-22 17:35:40 +03:00
Mathieu Duponchelle
6c57d89e9c rtp: add bindings for RTPBasePayload
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/merge_requests/1008>
2022-04-22 17:35:31 +03:00
Jan Alexander Steffens (heftig)
52ae5e435b gstreamer: Export subclass::TaskPoolFunction
This must be accessible in order to subclass TaskPool.
2022-04-22 17:35:21 +03:00
Sebastian Dröge
5a334cdcd3 gstreamer: Complete the Task bindings 2022-04-22 17:33:23 +03:00
Sebastian Dröge
4f8f99e2bf Update Carg.lock 2022-04-04 16:49:54 +03:00
Sebastian Dröge
eb9a74bf99 Update versions to 0.18.7 2022-04-04 16:49:54 +03:00
Sebastian Dröge
9bf6f2b010 Update CHANGELOG.md for 0.18.7 2022-04-04 16:49:54 +03:00
Sebastian Dröge
e38cf2eb1e Update Cargo.lock 2022-04-04 16:27:00 +03:00
Sebastian Dröge
e3ee743740 Regenerate everything with latest gir 2022-04-04 16:27:00 +03:00
Sebastian Dröge
4eb9cead75 Update gir 2022-04-04 16:27:00 +03:00
Sebastian Dröge
434dff7ad0 video: Add various VideoFormatInfo/VideoInfo/VideoFrame helper API 2022-04-04 16:27:00 +03:00
Sebastian Dröge
b59f90e634 Don't use unnecessary RefCell wrappers for FnMut callbacks
They don't add any safety as this is via unsafe code anyway and are not
needed to get mutable references in this context anyway, while adding a
bit of runtime overhead.
2022-04-04 16:27:00 +03:00
Sebastian Dröge
ef387890fa video: Add subclassing bindings for VideoAggregatorConvertPad 2022-04-04 16:27:00 +03:00
Sebastian Dröge
33982ccf2c audio: Add subclassing bindings for audioaggregator 2022-04-04 16:27:00 +03:00
Sebastian Dröge
070c313f8a audio: Add audioaggregator bindings 2022-04-04 16:27:00 +03:00
Jan Alexander Steffens (heftig)
c447f6fd91 gstreamer: Add TaskPool bindings and subclassing
Fixes: https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/issues/14
2022-04-04 16:27:00 +03:00
Alejandro González
e30ad5d231 Fix macOS PKG_CONFIG_PATH in readme for GStreamer Binaries
I've just installed the latest 1.20.1 GStreamer .pkg on a macOS GitHub
Actions CI runner and it turns out that no
/Library/Frameworks/GStreamer.framework/Versions directory exists. A
/Library/Frameworks/GStreamer.framework/1.0 directory is installed
instead, which is more consistent with the GStreamer distributions for
other OSes, and works well enough to get pkg-config working.
2022-04-04 16:11:54 +03:00
Sebastian Dröge
4f186e0147 Don't unnecessarily borrow dereferenced values explicitly
warning: this expression borrows a value the compiler would automatically borrow
  --> gstreamer-rtsp-server/src/rtsp_session_pool.rs:16:5
   |
16 |     (&mut *func.borrow_mut())(&from_glib_borrow(pool)).into_glib()
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ help: change this to: `(*func.borrow_mut())`
   |
   = note: `#[warn(clippy::needless_borrow)]` on by default
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow
2022-04-04 16:11:28 +03:00
Sebastian Dröge
6a76e19e78 video: Add subclass bindings for VideoAggregator 2022-04-04 16:11:16 +03:00
Sebastian Dröge
dcab2553bf video: Add bindings for VideoAggregator 2022-04-04 16:11:09 +03:00
Sebastian Dröge
3c6a9cede5 video: Allow converting a VideoFrame into an FFI GstVideoFrame 2022-04-04 16:11:03 +03:00
Sebastian Dröge
917c50c36b Use SPDX license format in Cargo.toml 2022-04-04 16:10:08 +03:00
Sebastian Dröge
e202eff2d9 Update Cargo.lock 2022-03-08 19:41:00 +02:00
Sebastian Dröge
cc4aee02a5 Update Cargo.lock 2022-03-08 19:21:45 +02:00
Sebastian Dröge
d8169d7976 Update CHANGELOG.md for 0.18.6 2022-03-08 19:20:48 +02:00
Sebastian Dröge
883681bd4c Update versions to 0.18.6 2022-03-08 19:18:44 +02:00
Sebastian Dröge
5b24acb9c0 gstreamer: Require Send and not Sync for the values of an Array / List
`Sync` is more than required here: only sending of the values to another
thread is required.
2022-03-08 18:49:08 +02:00
Sebastian Dröge
24a2bb78a6 gstreamer: Simplify and speed up log message string construction
For pre-1.20 simply use `%s` as format string instead of escaping the
`%` inline while writing. This allows a simpler implementation and is
also faster, see https://github.com/gtk-rs/gtk-rs-core/pull/583.
2022-03-08 18:37:23 +02:00
Sebastian Dröge
019ff43b60 Update Cargo.lock 2022-03-08 14:54:45 +02:00
Sebastian Dröge
14e387ef23 Revert "rtsp-server: Add bindings for Onvif-specific client/media/media-factory/server"
This reverts commit e78b0bc53c.

This was applied twice.
2022-02-20 20:55:28 +02:00
Sebastian Dröge
e78b0bc53c rtsp-server: Add bindings for Onvif-specific client/media/media-factory/server
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/issues/373
2022-02-20 20:27:29 +02:00
Sebastian Dröge
902aa50063 Update Cargo.lock 2022-02-20 20:20:52 +02:00
Sebastian Dröge
cb885cb99e Update CHANGELOG.md for 0.18.5 2022-02-20 20:20:46 +02:00
Sebastian Dröge
a58efe2910 Update versions to 0.18.5 2022-02-20 20:17:18 +02:00
Sebastian Dröge
0fdfe4d148 Update Cargo.lock 2022-02-18 17:24:00 +02:00
Sebastian Dröge
1bd3ed058a rtsp-server: Add subclassing support for Onvif-specific client/media/media-factory/server 2022-02-18 17:01:48 +02:00
Sebastian Dröge
523abc7b3f rtsp-server: Add bindings for Onvif-specific client/media/media-factory/server
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/issues/373
2022-02-18 17:01:43 +02:00
Marijn Suijten
0873db2a41 gstreamer/plugin_1_14: Use minor version 20 instead of 19 for v1_20
Now that gstreamer 1.20 is out all v1_20 plugins will be linked against
the 1.20 stable release, not the unstable 1.19 development release.
2022-02-18 17:01:37 +02:00
Marijn Suijten
a838b2ec36 Revert "sys: Link all v1_20 sys crates against library 1.19" - use 1.20
This reverts commit 8226c94110.

Now that GStreamer 1.20 is out, the v1_20 feature can and should link
directly to the stable release instead of the unstable 1.19 development
release.
2022-02-18 17:01:30 +02:00
Marijn Suijten
57cf66e26b gstreamer/sys: Move v1_18_3 system-deps metadata above v1_20
Keep the versions sorted numerically.
2022-02-18 17:01:23 +02:00
Sebastian Dröge
e5e2b8e682 gstreamer: Fix downcast_ref() / downcast_mut() impls on MiniObjectRef
They have to return the `Ref` type and not the owned type.
2022-02-18 17:01:17 +02:00
Sebastian Dröge
849440403c gstreamer: Add Debug impl for MiniObject / MiniObjectRef 2022-02-18 17:01:11 +02:00
Sebastian Dröge
b1f1c7dd4e examples: Update to image 0.24 2022-02-18 17:01:04 +02:00
Christian Meissl
af28e036a5 support for subclassing buffer pool 2022-02-18 17:00:58 +02:00
Sebastian Dröge
67291b6d17 Handle empty slices correctly
Passing `NULL` to `slice::from_raw_parts` is invalid.
2022-02-18 17:00:31 +02:00
Sebastian Dröge
b43cbf216d Update Cargo.lock 2022-02-04 18:44:11 +02:00
Sebastian Dröge
5b2396405d Update versions to 0.18.4 2022-02-04 18:42:03 +02:00
Sebastian Dröge
86fd63585a Update README.md for 0.18.4 2022-02-04 18:40:47 +02:00
Christian Meissl
eb996c7125 fix readme doc links 2022-02-04 18:13:10 +02:00
Sebastian Dröge
bc9360968b Update Cargo.lock 2022-02-04 14:03:42 +02:00
Sebastian Dröge
55ed03c395 Regenerate with latest gir files 2022-02-04 14:02:45 +02:00
Sebastian Dröge
769dbe330d Update GStreamer gir files 2022-02-04 14:01:03 +02:00
Sebastian Dröge
c8ac0bd6b7 Update gir-files 2022-02-04 14:00:58 +02:00
Sebastian Dröge
973919fae7 ci: Update to get GStreamer 1.20.0 release 2022-02-04 14:00:51 +02:00
Sebastian Dröge
c37316fac1 video: Allow getting an owned reference to the input buffer from a video codec frame 2022-02-04 14:00:45 +02:00
Sebastian Dröge
5ee2ce9d10 deny: Remove heck override as all dependencies are up to date now 2022-02-04 14:00:32 +02:00
Sebastian Dröge
1c28671af4 Update Cargo.lock 2022-01-31 14:54:15 +02:00
Sebastian Dröge
d1b3313c09 Update versions to 0.18.3 2022-01-31 14:53:36 +02:00
Sebastian Dröge
5920807e0b Update CHANGELOG.md for 0.18.3 2022-01-31 14:53:36 +02:00
Sebastian Dröge
e0aa48ce1b ges: Depend on glib 0.15.3 for ThreadGuard API 2022-01-31 14:53:36 +02:00
Sebastian Dröge
d5bcc82dc5 Update Cargo.lock 2022-01-29 18:52:33 +02:00
Sebastian Dröge
414d640ed9 Regenerate with latest gir and GStreamer gir files 2022-01-29 18:26:28 +02:00
Sebastian Dröge
7bc8eb0444 ci: Update GStreamer version 2022-01-29 18:25:35 +02:00
Sebastian Dröge
2ebf11a5cd webrtc: Generate WebRTCError type 2022-01-29 18:25:27 +02:00
Sebastian Dröge
040ac36c57 rtp: Add subclass bindings for RTPHeaderExtension 2022-01-29 18:25:18 +02:00
Sebastian Dröge
cd4e191a00 rtp: Re-export standalone functions from crate root 2022-01-29 18:24:46 +02:00
Sebastian Dröge
4782066345 rtp: Add gst::Element as parent class for RTPHeaderExtension 2022-01-29 18:24:40 +02:00
Sebastian Dröge
4e3882f429 video: Add VideoOverlayComposition::add_rectangle() to add new rectangles after construction
Usually it is more convenient to provide them all via an iterator during
construction but in some cases this might be nicer.
2022-01-29 18:24:34 +02:00
Sebastian Dröge
a0e192edb9 video: Implement Default for VideoOverlayComposition in 1.20 2022-01-29 18:24:28 +02:00
Sebastian Dröge
245fe4452c ci: Update image to get newer GStreamer build 2022-01-29 18:24:18 +02:00
Sebastian Dröge
691fed0f31 Get rid of fragile dependency and use GLib API instead 2022-01-29 18:24:08 +02:00
Sebastian Dröge
582e26c6b0 Update GStreamer gir files 2022-01-29 18:23:25 +02:00
Sebastian Dröge
824aa32a79 Update gir 2022-01-29 18:23:20 +02:00
Sebastian Dröge
3c800faa07 Update CHANGELOG.md for 0.18.2 2022-01-24 16:45:55 +02:00
Sebastian Dröge
8c546e53ef Update Cargo.lock 2022-01-24 16:44:37 +02:00
Sebastian Dröge
f4aa0c09a9 Update versions to 0.18.2 2022-01-24 16:42:43 +02:00
Sebastian Dröge
42583595f2 examples: Make use of glib::closure! for the overlay-composition example 2022-01-24 16:03:53 +02:00
Sebastian Dröge
0d5132a7f0 gstreamer: Implement FromValue for mini object references 2022-01-24 16:03:49 +02:00
Sebastian Dröge
93a777e6c9 gstreamer: Minor cleanup 2022-01-24 16:03:42 +02:00
Sebastian Dröge
d2bc6d94f9 gstreamer: Add bindings for gst_debug_log_get_line() 2022-01-24 16:03:38 +02:00
Sebastian Dröge
294e73e670 Update Cargo.lock 2022-01-18 17:13:56 +02:00
Sebastian Dröge
89e0654f35 Update versions to 0.18.1 2022-01-18 16:52:43 +02:00
Sebastian Dröge
5f817b0443 Update CHANGELOG.md for 0.18.1 2022-01-18 16:51:35 +02:00
Sebastian Dröge
50c6f48728 message: Handle the Redirect message in Message::view() 2022-01-18 16:18:39 +02:00
Sebastian Dröge
656e815b23 gstreamer: Mark Structure and CapsFeatures as #[repr(transparent)] too 2022-01-18 15:47:21 +02:00
Jan Alexander Steffens (heftig)
5b8f4a8632 gstreamer: Split parsers for owned and borrowed views
When we have a view like `Caps<&EventRef>`, we can return a `CapsRef`
borrowing from the wrapped `EventRef`. This way, the `CapsRef` we return
can outlive the view itself.

This is in contrast to a `Caps<Event>` view which owns the `Event`.
Here, the `CapsRef` we return cannot outlive the view.

gstreamer-rs 0.18 consolidated code and treated everything like the
latter case. Fix this by duplicating the accessors for each case.

Fixes: https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/issues/367
2022-01-18 15:47:15 +02:00
Sebastian Dröge
7018e5641a video: Mark VideoTimeCode as #[repr(transparent)] 2022-01-18 15:47:09 +02:00
Sebastian Dröge
03087ddfb0 gstreamer: Mark miniobject wrapper types as #[repr(transparent)]
That way they're treated everywhere exactly like a raw pointer.
2022-01-18 15:47:04 +02:00
Sebastian Dröge
1fbb6a3a1c Replace Foo::from_instance(foo) with foo.imp() 2022-01-18 15:46:59 +02:00
Sebastian Dröge
d778be0e5d Update CHANGELOG.md for 0.18.0 2022-01-16 13:12:39 +02:00
Sebastian Dröge
1657d89812 Update CHANGELOG.md for 0.17.4 2022-01-16 12:17:26 +02:00
Sebastian Dröge
0b77d0c172 ci: Don't run cargo update 2022-01-15 21:38:56 +02:00
Sebastian Dröge
007df43b2f examples: overlay-composition: Use cairo's new ImageSurfaceDataOwned to get rid of unsafe code 2022-01-15 20:22:25 +02:00
Sebastian Dröge
fbe6471625 Include Cargo.lock in the repository 2022-01-15 17:39:14 +02:00
Sebastian Dröge
b7f04289ab Add 0.18 version requirement to the dependencies from this repository 2022-01-15 17:28:01 +02:00
Sebastian Dröge
5fa5f04e04 Switch to 0.15 branches of gtk-rs and provide a version 2022-01-15 17:19:45 +02:00
325 changed files with 12368 additions and 989 deletions

View file

@ -63,13 +63,6 @@ stages:
before_script:
- source ./ci/env.sh
- mkdir .cargo && echo -e "[net]\ngit-fetch-with-cli = true" > .cargo/config
# If cargo exists assume we probably will want to update
# the lockfile
- |
if command -v cargo; then
cargo generate-lockfile --color=always
cargo update --color=always
fi
.debian:11-base:
extends: .debian:11
@ -458,7 +451,9 @@ coverage:
paths:
- 'coverage'
reports:
cobertura: coverage.xml
coverage_report:
coverage_format: cobertura
path: coverage.xml
doc-stripping:
variables:

2831
Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -96,7 +96,7 @@ After installation, you also need to install `pkg-config` (e.g. via Homebrew)
and set the `PKG_CONFIG_PATH` environment variable
```console
$ export PKG_CONFIG_PATH="/Library/Frameworks/GStreamer.framework/Versions/Current/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}"
$ export PKG_CONFIG_PATH="/Library/Frameworks/GStreamer.framework/Versions/1.0/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}"
```
<a name="installation-windows"/>

View file

@ -1,4 +1,4 @@
variables:
GST_RS_IMG_TAG: '2022-01-13.0'
GST_RS_IMG_TAG: '2022-02-04.0'
GST_RS_STABLE: '1.58.0'
GST_RS_MSRV: '1.56.0'

View file

@ -33,8 +33,3 @@ unknown-git = "deny"
allow-git = [
"https://github.com/gtk-rs/gtk-rs-core",
]
# ignore duplicated heck dependency because various crates depend on an old version
[[bans.skip]]
name = "heck"
version = "0.3"

View file

@ -1,41 +1,41 @@
[package]
name = "examples"
version = "0.18.0"
version = "0.18.8"
license = "MIT"
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
edition = "2021"
rust-version = "1.56"
[dependencies]
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
gst = { package = "gstreamer", path = "../gstreamer" }
gst-gl = { package = "gstreamer-gl", path = "../gstreamer-gl", optional = true }
gst-gl-egl = { package = "gstreamer-gl-egl", path = "../gstreamer-gl/egl", optional = true }
gst-gl-wayland = { package = "gstreamer-gl-wayland", path = "../gstreamer-gl/wayland", optional = true }
gst-gl-x11 = { package = "gstreamer-gl-x11", path = "../gstreamer-gl/x11", optional = true }
gst-app = { package = "gstreamer-app", path = "../gstreamer-app" }
gst-audio = { package = "gstreamer-audio", path = "../gstreamer-audio" }
gst-base = { package = "gstreamer-base", path = "../gstreamer-base" }
gst-video = { package = "gstreamer-video", path = "../gstreamer-video" }
gst-pbutils = { package = "gstreamer-pbutils", path = "../gstreamer-pbutils" }
gst-player = { package = "gstreamer-player", path = "../gstreamer-player", optional = true }
ges = { package = "gstreamer-editing-services", path = "../gstreamer-editing-services", optional = true }
gst-sdp = { package = "gstreamer-sdp", path = "../gstreamer-sdp", optional = true }
gst-rtsp = { package = "gstreamer-rtsp", path = "../gstreamer-rtsp", optional = true }
gst-rtsp-server = { package = "gstreamer-rtsp-server", path = "../gstreamer-rtsp-server", optional = true }
gtk = { git = "https://github.com/gtk-rs/gtk3-rs", optional = true }
gdk = { git = "https://github.com/gtk-rs/gtk3-rs", optional = true }
gio = { git = "https://github.com/gtk-rs/gtk-rs-core" , optional = true }
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.15", version = "0.15" }
gst = { package = "gstreamer", version = "0.18", path = "../gstreamer" }
gst-gl = { package = "gstreamer-gl", version = "0.18", path = "../gstreamer-gl", optional = true }
gst-gl-egl = { package = "gstreamer-gl-egl", version = "0.18", path = "../gstreamer-gl/egl", optional = true }
gst-gl-wayland = { package = "gstreamer-gl-wayland", version = "0.18", path = "../gstreamer-gl/wayland", optional = true }
gst-gl-x11 = { package = "gstreamer-gl-x11", version = "0.18", path = "../gstreamer-gl/x11", optional = true }
gst-app = { package = "gstreamer-app", version = "0.18", path = "../gstreamer-app" }
gst-audio = { package = "gstreamer-audio", version = "0.18", path = "../gstreamer-audio" }
gst-base = { package = "gstreamer-base", version = "0.18", path = "../gstreamer-base" }
gst-video = { package = "gstreamer-video", version = "0.18", path = "../gstreamer-video" }
gst-pbutils = { package = "gstreamer-pbutils", version = "0.18", path = "../gstreamer-pbutils" }
gst-player = { package = "gstreamer-player", version = "0.18", path = "../gstreamer-player", optional = true }
ges = { package = "gstreamer-editing-services", version = "0.18", path = "../gstreamer-editing-services", optional = true }
gst-sdp = { package = "gstreamer-sdp", version = "0.18", path = "../gstreamer-sdp", optional = true }
gst-rtsp = { package = "gstreamer-rtsp", version = "0.18", path = "../gstreamer-rtsp", optional = true }
gst-rtsp-server = { package = "gstreamer-rtsp-server", version = "0.18", path = "../gstreamer-rtsp-server", optional = true }
gtk = { git = "https://github.com/gtk-rs/gtk3-rs", branch = "0.15", version = "0.15", optional = true }
gdk = { git = "https://github.com/gtk-rs/gtk3-rs", branch = "0.15", version = "0.15", optional = true }
gio = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.15", version = "0.15" , optional = true }
anyhow = "1.0"
derive_more = "0.99.5"
futures = "0.3"
byte-slice-cast = "1"
cairo-rs = { git = "https://github.com/gtk-rs/gtk-rs-core" , features=["use_glib"], optional = true }
pango = { git = "https://github.com/gtk-rs/gtk-rs-core" , optional = true }
pangocairo = { git = "https://github.com/gtk-rs/gtk-rs-core" , optional = true }
cairo-rs = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.15", version = "0.15" , features=["use_glib"], optional = true }
pango = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.15", version = "0.15" , optional = true }
pangocairo = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.15", version = "0.15" , optional = true }
glutin = { version = "0.28", optional = true }
once_cell = "1.0"
image = { version="0.23", optional = true }
image = { version="0.24", optional = true }
[target.'cfg(target_os = "macos")'.dependencies]
cocoa = "0.24"

View file

@ -7,10 +7,6 @@
// {videotestsrc} - {overlaycomposition} - {capsfilter} - {videoconvert} - {autovideosink}
// The capsfilter element allows us to dictate the video resolution we want for the
// videotestsrc and the overlaycomposition element.
//
// There is a small amount of unsafe code that demonstrates how to work around
// Cairo's internal refcounting of the target buffer surface
#![allow(clippy::non_send_fields_in_send_ty)]
use gst::prelude::*;
@ -120,7 +116,6 @@ fn create_pipeline() -> Result<gst::Pipeline, Error> {
info: None,
}));
let drawer_clone = drawer.clone();
// Connect to the overlaycomposition element's "draw" signal, which is emitted for
// each videoframe piped through the element. The signal handler needs to
// return a gst_video::VideoOverlayComposition to be drawn on the frame
@ -132,54 +127,31 @@ fn create_pipeline() -> Result<gst::Pipeline, Error> {
//
// In this case, the signal passes the gst::Element and a gst::Sample with
// the current buffer
overlay.connect("draw", false, move |args| {
use std::f64::consts::PI;
overlay.connect_closure(
"draw",
false,
glib::closure!(@strong drawer => move |_overlay: &gst::Element,
sample: &gst::Sample| {
use std::f64::consts::PI;
let drawer = &drawer_clone;
let drawer = drawer.lock().unwrap();
let drawer = drawer.lock().unwrap();
// Get the signal's arguments
let _overlay = args[0].get::<gst::Element>().unwrap();
let sample = args[1].get::<gst::Sample>().unwrap();
let buffer = sample.buffer().unwrap();
let timestamp = buffer.pts().unwrap();
let buffer = sample.buffer().unwrap();
let timestamp = buffer.pts().unwrap();
let info = drawer.info.as_ref().unwrap();
let layout = drawer.layout.borrow();
let info = drawer.info.as_ref().unwrap();
let layout = drawer.layout.borrow();
let angle = 2.0 * PI * (timestamp % (10 * gst::ClockTime::SECOND)).nseconds() as f64
/ (10.0 * gst::ClockTime::SECOND.nseconds() as f64);
let angle = 2.0 * PI * (timestamp % (10 * gst::ClockTime::SECOND)).nseconds() as f64
/ (10.0 * gst::ClockTime::SECOND.nseconds() as f64);
/* Create a gst::Buffer for Cairo to draw into */
let frame_width = info.width() as usize;
let frame_height = info.height() as usize;
let stride = 4 * frame_width;
let frame_size = stride * frame_height;
/* Create an RGBA buffer, and add a video meta that the videooverlaycomposition expects */
let mut buffer = gst::Buffer::with_size(frame_size).unwrap();
gst_video::VideoMeta::add(
buffer.get_mut().unwrap(),
gst_video::VideoFrameFlags::empty(),
gst_video::VideoFormat::Bgra,
frame_width as u32,
frame_height as u32,
)
.unwrap();
let buffer = buffer.into_mapped_buffer_writable().unwrap();
let buffer = {
let buffer_ptr = unsafe { buffer.buffer().as_ptr() };
let surface = cairo::ImageSurface::create_for_data(
buffer,
/* Create a Cairo image surface to draw into and the context around it. */
let surface = cairo::ImageSurface::create(
cairo::Format::ARgb32,
frame_width as i32,
frame_height as i32,
stride as i32,
info.width() as i32,
info.height() as i32,
)
.unwrap();
let cr = cairo::Context::new(&surface).expect("Failed to create cairo context");
cr.save().expect("Failed to save state");
@ -233,44 +205,46 @@ fn create_pipeline() -> Result<gst::Pipeline, Error> {
cr.restore().expect("Failed to restore state");
}
// Safety: The surface still owns a mutable reference to the buffer but our reference
// to the surface here is the last one. After dropping the surface the buffer would be
// freed, so we keep an additional strong reference here before dropping the surface,
// which is then returned. As such it's guaranteed that nothing is using the buffer
// anymore mutably.
/* Drop the Cairo context to release the additional reference to the data and
* then take ownership of the data. This only works if we have the one and only
* reference to the image surface */
drop(cr);
unsafe {
assert_eq!(
cairo::ffi::cairo_surface_get_reference_count(surface.to_raw_none()),
1
);
let buffer = glib::translate::from_glib_none(buffer_ptr);
drop(surface);
buffer
}
};
let stride = surface.stride();
let data = surface.take_data().unwrap();
/* Turn the buffer into a VideoOverlayRectangle, then place
* that into a VideoOverlayComposition and return it.
*
* A VideoOverlayComposition can take a Vec of such rectangles
* spaced around the video frame, but we're just outputting 1
* here */
let rect = gst_video::VideoOverlayRectangle::new_raw(
&buffer,
0,
0,
frame_width as u32,
frame_height as u32,
gst_video::VideoOverlayFormatFlags::PREMULTIPLIED_ALPHA,
);
/* Create an RGBA buffer, and add a video meta that the videooverlaycomposition expects */
let mut buffer = gst::Buffer::from_mut_slice(data);
gst_video::VideoMeta::add_full(
buffer.get_mut().unwrap(),
gst_video::VideoFrameFlags::empty(),
gst_video::VideoFormat::Bgra,
info.width(),
info.height(),
&[0],
&[stride],
)
.unwrap();
/* Turn the buffer into a VideoOverlayRectangle, then place
* that into a VideoOverlayComposition and return it.
*
* A VideoOverlayComposition can take a Vec of such rectangles
* spaced around the video frame, but we're just outputting 1
* here */
let rect = gst_video::VideoOverlayRectangle::new_raw(
&buffer,
0,
0,
info.width(),
info.height(),
gst_video::VideoOverlayFormatFlags::PREMULTIPLIED_ALPHA,
);
Some(
gst_video::VideoOverlayComposition::new(Some(&rect))
.unwrap()
.to_value(),
)
});
}),
);
// Add a signal handler to the overlay's "caps-changed" signal. This could e.g.
// be called when the sink that we render to does not support resizing the image
@ -279,15 +253,17 @@ fn create_pipeline() -> Result<gst::Pipeline, Error> {
// resize our canvas's size.
// Another possibility for when this might happen is, when our video is a network
// stream that dynamically changes resolution when enough bandwith is available.
overlay.connect("caps-changed", false, move |args| {
let _overlay = args[0].get::<gst::Element>().unwrap();
let caps = args[1].get::<gst::Caps>().unwrap();
let mut drawer = drawer.lock().unwrap();
drawer.info = Some(gst_video::VideoInfo::from_caps(&caps).unwrap());
None
});
overlay.connect_closure(
"caps-changed",
false,
glib::closure!(move |_overlay: &gst::Element,
caps: &gst::Caps,
_width: u32,
_height: u32| {
let mut drawer = drawer.lock().unwrap();
drawer.info = Some(gst_video::VideoInfo::from_caps(caps).unwrap());
}),
);
Ok(pipeline)
}

View file

@ -10,7 +10,6 @@
// {videotestsrc} - {cairooverlay} - {capsfilter} - {videoconvert} - {autovideosink}
// The capsfilter element allows us to dictate the video resolution we want for the
// videotestsrc and the cairooverlay element.
#![allow(clippy::non_send_fields_in_send_ty)]
use gst::prelude::*;

View file

@ -236,7 +236,7 @@ mod fir_filter {
// Sets the coefficients by getting access to the private
// struct and simply setting them
pub fn set_coeffs(&self, coeffs: Vec<f32>) {
let imp = imp::FirFilter::from_instance(self);
let imp = self.imp();
*imp.coeffs.lock().unwrap() = coeffs;
}
}

2
gir

@ -1 +1 @@
Subproject commit ee37253c10af159268f76cc9852d2d2a3c09ecc0
Subproject commit c063b4567de5dcab93d4091e3cd33428cd994636

@ -1 +1 @@
Subproject commit 5502d32880f5b02b8bd124b9df58826ecbd540d0
Subproject commit 7ebd4478b4a575ebe733bce9a39e0ded27eac7d3

@ -1 +1 @@
Subproject commit f05404723520e67ad2e0054b45ce245438c88473
Subproject commit 654191eba8d79896ecfbab2a2bc6d684674424cc

View file

@ -1,11 +1,11 @@
[package]
name = "gstreamer-app"
version = "0.18.0"
version = "0.18.8"
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
categories = ["api-bindings", "multimedia"]
description = "Rust bindings for GStreamer App library"
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
license = "MIT/Apache-2.0"
license = "MIT OR Apache-2.0"
readme = "README.md"
homepage = "https://gstreamer.freedesktop.org"
documentation = "https://gstreamer.pages.freedesktop.org/gstreamer-rs/stable/latest/docs/gstreamer_app/"
@ -18,10 +18,10 @@ futures-core = "0.3"
futures-sink = "0.3"
bitflags = "1.0"
libc = "0.2"
ffi = { package = "gstreamer-app-sys", path = "sys", features = ["v1_8"] }
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
gst = { package = "gstreamer", path = "../gstreamer" }
gst-base = { package = "gstreamer-base", path = "../gstreamer-base" }
ffi = { package = "gstreamer-app-sys", version = "0.18", path = "sys", features = ["v1_8"] }
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.15", version = "0.15" }
gst = { package = "gstreamer", version = "0.18", path = "../gstreamer" }
gst-base = { package = "gstreamer-base", version = "0.18", path = "../gstreamer-base" }
once_cell = "1.0"
[dev-dependencies]

View file

@ -1,7 +1,7 @@
# 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/master/pipeline.svg)](https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/commits/master)
[GStreamer](https://gstreamer.freedesktop.org/) (App library) bindings for Rust.
Documentation can be found [here](https://slomo.pages.freedesktop.org/rustdocs/gstreamer/gstreamer_app/).
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.

View file

@ -4,7 +4,6 @@ use crate::AppSink;
use glib::ffi::gpointer;
use glib::prelude::*;
use glib::translate::*;
use std::cell::RefCell;
use std::mem;
use std::panic;
use std::ptr;
@ -22,18 +21,14 @@ use {
#[allow(clippy::type_complexity)]
pub struct AppSinkCallbacks {
eos: Option<RefCell<Box<dyn FnMut(&AppSink) + Send + 'static>>>,
eos: Option<Box<dyn FnMut(&AppSink) + Send + 'static>>,
new_preroll: Option<
RefCell<
Box<dyn FnMut(&AppSink) -> Result<gst::FlowSuccess, gst::FlowError> + Send + 'static>,
>,
Box<dyn FnMut(&AppSink) -> Result<gst::FlowSuccess, gst::FlowError> + Send + 'static>,
>,
new_sample: Option<
RefCell<
Box<dyn FnMut(&AppSink) -> Result<gst::FlowSuccess, gst::FlowError> + Send + 'static>,
>,
Box<dyn FnMut(&AppSink) -> Result<gst::FlowSuccess, gst::FlowError> + Send + 'static>,
>,
new_event: Option<RefCell<Box<dyn FnMut(&AppSink) -> bool + Send + 'static>>>,
new_event: Option<Box<dyn FnMut(&AppSink) -> bool + Send + 'static>>,
panicked: AtomicBool,
callbacks: ffi::GstAppSinkCallbacks,
}
@ -56,24 +51,20 @@ impl AppSinkCallbacks {
#[allow(clippy::type_complexity)]
#[must_use = "The builder must be built to be used"]
pub struct AppSinkCallbacksBuilder {
eos: Option<RefCell<Box<dyn FnMut(&AppSink) + Send + 'static>>>,
eos: Option<Box<dyn FnMut(&AppSink) + Send + 'static>>,
new_preroll: Option<
RefCell<
Box<dyn FnMut(&AppSink) -> Result<gst::FlowSuccess, gst::FlowError> + Send + 'static>,
>,
Box<dyn FnMut(&AppSink) -> Result<gst::FlowSuccess, gst::FlowError> + Send + 'static>,
>,
new_sample: Option<
RefCell<
Box<dyn FnMut(&AppSink) -> Result<gst::FlowSuccess, gst::FlowError> + Send + 'static>,
>,
Box<dyn FnMut(&AppSink) -> Result<gst::FlowSuccess, gst::FlowError> + Send + 'static>,
>,
new_event: Option<RefCell<Box<dyn FnMut(&AppSink) -> bool + Send + 'static>>>,
new_event: Option<Box<dyn FnMut(&AppSink) -> bool + Send + 'static>>,
}
impl AppSinkCallbacksBuilder {
pub fn eos<F: FnMut(&AppSink) + Send + 'static>(self, eos: F) -> Self {
Self {
eos: Some(RefCell::new(Box::new(eos))),
eos: Some(Box::new(eos)),
..self
}
}
@ -85,7 +76,7 @@ impl AppSinkCallbacksBuilder {
new_preroll: F,
) -> Self {
Self {
new_preroll: Some(RefCell::new(Box::new(new_preroll))),
new_preroll: Some(Box::new(new_preroll)),
..self
}
}
@ -97,7 +88,7 @@ impl AppSinkCallbacksBuilder {
new_sample: F,
) -> Self {
Self {
new_sample: Some(RefCell::new(Box::new(new_sample))),
new_sample: Some(Box::new(new_sample)),
..self
}
}
@ -106,7 +97,7 @@ impl AppSinkCallbacksBuilder {
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
pub fn new_event<F: FnMut(&AppSink) -> bool + Send + 'static>(self, new_event: F) -> Self {
Self {
new_event: Some(RefCell::new(Box::new(new_event))),
new_event: Some(Box::new(new_event)),
..self
}
}
@ -159,23 +150,21 @@ fn post_panic_error_message(element: &AppSink, err: &dyn std::any::Any) {
}
unsafe extern "C" fn trampoline_eos(appsink: *mut ffi::GstAppSink, callbacks: gpointer) {
let callbacks = &*(callbacks as *const AppSinkCallbacks);
let callbacks = callbacks as *mut AppSinkCallbacks;
let element: Borrowed<AppSink> = from_glib_borrow(appsink);
if callbacks.panicked.load(Ordering::Relaxed) {
if (*callbacks).panicked.load(Ordering::Relaxed) {
let element: Borrowed<AppSink> = from_glib_borrow(appsink);
gst::element_error!(element, gst::LibraryError::Failed, ["Panicked"]);
return;
}
if let Some(ref eos) = callbacks.eos {
let result = panic::catch_unwind(panic::AssertUnwindSafe(|| {
(&mut *eos.borrow_mut())(&element)
}));
if let Some(ref mut eos) = (*callbacks).eos {
let result = panic::catch_unwind(panic::AssertUnwindSafe(|| eos(&element)));
match result {
Ok(result) => result,
Err(err) => {
callbacks.panicked.store(true, Ordering::Relaxed);
(*callbacks).panicked.store(true, Ordering::Relaxed);
post_panic_error_message(&element, &err);
}
}
@ -186,23 +175,21 @@ unsafe extern "C" fn trampoline_new_preroll(
appsink: *mut ffi::GstAppSink,
callbacks: gpointer,
) -> gst::ffi::GstFlowReturn {
let callbacks = &*(callbacks as *const AppSinkCallbacks);
let callbacks = callbacks as *mut AppSinkCallbacks;
let element: Borrowed<AppSink> = from_glib_borrow(appsink);
if callbacks.panicked.load(Ordering::Relaxed) {
if (*callbacks).panicked.load(Ordering::Relaxed) {
let element: Borrowed<AppSink> = from_glib_borrow(appsink);
gst::element_error!(element, gst::LibraryError::Failed, ["Panicked"]);
return gst::FlowReturn::Error.into_glib();
}
let ret = if let Some(ref new_preroll) = callbacks.new_preroll {
let result = panic::catch_unwind(panic::AssertUnwindSafe(|| {
(&mut *new_preroll.borrow_mut())(&element).into()
}));
let ret = if let Some(ref mut new_preroll) = (*callbacks).new_preroll {
let result = panic::catch_unwind(panic::AssertUnwindSafe(|| new_preroll(&element).into()));
match result {
Ok(result) => result,
Err(err) => {
callbacks.panicked.store(true, Ordering::Relaxed);
(*callbacks).panicked.store(true, Ordering::Relaxed);
post_panic_error_message(&element, &err);
gst::FlowReturn::Error
@ -219,23 +206,21 @@ unsafe extern "C" fn trampoline_new_sample(
appsink: *mut ffi::GstAppSink,
callbacks: gpointer,
) -> gst::ffi::GstFlowReturn {
let callbacks = &*(callbacks as *const AppSinkCallbacks);
let callbacks = callbacks as *mut AppSinkCallbacks;
let element: Borrowed<AppSink> = from_glib_borrow(appsink);
if callbacks.panicked.load(Ordering::Relaxed) {
if (*callbacks).panicked.load(Ordering::Relaxed) {
let element: Borrowed<AppSink> = from_glib_borrow(appsink);
gst::element_error!(element, gst::LibraryError::Failed, ["Panicked"]);
return gst::FlowReturn::Error.into_glib();
}
let ret = if let Some(ref new_sample) = callbacks.new_sample {
let result = panic::catch_unwind(panic::AssertUnwindSafe(|| {
(&mut *new_sample.borrow_mut())(&element).into()
}));
let ret = if let Some(ref mut new_sample) = (*callbacks).new_sample {
let result = panic::catch_unwind(panic::AssertUnwindSafe(|| new_sample(&element).into()));
match result {
Ok(result) => result,
Err(err) => {
callbacks.panicked.store(true, Ordering::Relaxed);
(*callbacks).panicked.store(true, Ordering::Relaxed);
post_panic_error_message(&element, &err);
gst::FlowReturn::Error
@ -252,23 +237,21 @@ unsafe extern "C" fn trampoline_new_event(
appsink: *mut ffi::GstAppSink,
callbacks: gpointer,
) -> glib::ffi::gboolean {
let callbacks = &*(callbacks as *const AppSinkCallbacks);
let callbacks = callbacks as *mut AppSinkCallbacks;
let element: Borrowed<AppSink> = from_glib_borrow(appsink);
if callbacks.panicked.load(Ordering::Relaxed) {
if (*callbacks).panicked.load(Ordering::Relaxed) {
let element: Borrowed<AppSink> = from_glib_borrow(appsink);
gst::element_error!(element, gst::LibraryError::Failed, ["Panicked"]);
return false.into_glib();
}
let ret = if let Some(ref new_event) = callbacks.new_event {
let result = panic::catch_unwind(panic::AssertUnwindSafe(|| {
(&mut *new_event.borrow_mut())(&element)
}));
let ret = if let Some(ref mut new_event) = (*callbacks).new_event {
let result = panic::catch_unwind(panic::AssertUnwindSafe(|| new_event(&element)));
match result {
Ok(result) => result,
Err(err) => {
callbacks.panicked.store(true, Ordering::Relaxed);
(*callbacks).panicked.store(true, Ordering::Relaxed);
post_panic_error_message(&element, &err);
false

View file

@ -6,7 +6,6 @@ use glib::prelude::*;
use glib::translate::*;
use crate::AppSrc;
use std::cell::RefCell;
use std::mem;
use std::panic;
use std::pin::Pin;
@ -17,7 +16,7 @@ use std::task::{Context, Poll, Waker};
#[allow(clippy::type_complexity)]
pub struct AppSrcCallbacks {
need_data: Option<RefCell<Box<dyn FnMut(&AppSrc, u32) + Send + 'static>>>,
need_data: Option<Box<dyn FnMut(&AppSrc, u32) + Send + 'static>>,
enough_data: Option<Box<dyn Fn(&AppSrc) + Send + Sync + 'static>>,
seek_data: Option<Box<dyn Fn(&AppSrc, u64) -> bool + Send + Sync + 'static>>,
panicked: AtomicBool,
@ -42,7 +41,7 @@ impl AppSrcCallbacks {
#[allow(clippy::type_complexity)]
#[must_use = "The builder must be built to be used"]
pub struct AppSrcCallbacksBuilder {
need_data: Option<RefCell<Box<dyn FnMut(&AppSrc, u32) + Send + 'static>>>,
need_data: Option<Box<dyn FnMut(&AppSrc, u32) + Send + 'static>>,
enough_data: Option<Box<dyn Fn(&AppSrc) + Send + Sync + 'static>>,
seek_data: Option<Box<dyn Fn(&AppSrc, u64) -> bool + Send + Sync + 'static>>,
}
@ -50,7 +49,7 @@ pub struct AppSrcCallbacksBuilder {
impl AppSrcCallbacksBuilder {
pub fn need_data<F: FnMut(&AppSrc, u32) + Send + 'static>(self, need_data: F) -> Self {
Self {
need_data: Some(RefCell::new(Box::new(need_data))),
need_data: Some(Box::new(need_data)),
..self
}
}
@ -126,23 +125,21 @@ unsafe extern "C" fn trampoline_need_data(
length: u32,
callbacks: gpointer,
) {
let callbacks = &*(callbacks as *const AppSrcCallbacks);
let callbacks = callbacks as *mut AppSrcCallbacks;
let element: Borrowed<AppSrc> = from_glib_borrow(appsrc);
if callbacks.panicked.load(Ordering::Relaxed) {
if (*callbacks).panicked.load(Ordering::Relaxed) {
let element: Borrowed<AppSrc> = from_glib_borrow(appsrc);
gst::element_error!(element, gst::LibraryError::Failed, ["Panicked"]);
return;
}
if let Some(ref need_data) = callbacks.need_data {
let result = panic::catch_unwind(panic::AssertUnwindSafe(|| {
(&mut *need_data.borrow_mut())(&element, length)
}));
if let Some(ref mut need_data) = (*callbacks).need_data {
let result = panic::catch_unwind(panic::AssertUnwindSafe(|| need_data(&element, length)));
match result {
Ok(result) => result,
Err(err) => {
callbacks.panicked.store(true, Ordering::Relaxed);
(*callbacks).panicked.store(true, Ordering::Relaxed);
post_panic_error_message(&element, &err);
}
}
@ -150,21 +147,21 @@ unsafe extern "C" fn trampoline_need_data(
}
unsafe extern "C" fn trampoline_enough_data(appsrc: *mut ffi::GstAppSrc, callbacks: gpointer) {
let callbacks = &*(callbacks as *const AppSrcCallbacks);
let callbacks = callbacks as *const AppSrcCallbacks;
let element: Borrowed<AppSrc> = from_glib_borrow(appsrc);
if callbacks.panicked.load(Ordering::Relaxed) {
if (*callbacks).panicked.load(Ordering::Relaxed) {
let element: Borrowed<AppSrc> = from_glib_borrow(appsrc);
gst::element_error!(element, gst::LibraryError::Failed, ["Panicked"]);
return;
}
if let Some(ref enough_data) = callbacks.enough_data {
let result = panic::catch_unwind(panic::AssertUnwindSafe(|| (*enough_data)(&element)));
if let Some(ref enough_data) = (*callbacks).enough_data {
let result = panic::catch_unwind(panic::AssertUnwindSafe(|| enough_data(&element)));
match result {
Ok(result) => result,
Err(err) => {
callbacks.panicked.store(true, Ordering::Relaxed);
(*callbacks).panicked.store(true, Ordering::Relaxed);
post_panic_error_message(&element, &err);
}
}
@ -176,22 +173,21 @@ unsafe extern "C" fn trampoline_seek_data(
offset: u64,
callbacks: gpointer,
) -> gboolean {
let callbacks = &*(callbacks as *const AppSrcCallbacks);
let callbacks = callbacks as *const AppSrcCallbacks;
let element: Borrowed<AppSrc> = from_glib_borrow(appsrc);
if callbacks.panicked.load(Ordering::Relaxed) {
if (*callbacks).panicked.load(Ordering::Relaxed) {
let element: Borrowed<AppSrc> = from_glib_borrow(appsrc);
gst::element_error!(element, gst::LibraryError::Failed, ["Panicked"]);
return false.into_glib();
}
let ret = if let Some(ref seek_data) = callbacks.seek_data {
let result =
panic::catch_unwind(panic::AssertUnwindSafe(|| (*seek_data)(&element, offset)));
let ret = if let Some(ref seek_data) = (*callbacks).seek_data {
let result = panic::catch_unwind(panic::AssertUnwindSafe(|| seek_data(&element, offset)));
match result {
Ok(result) => result,
Err(err) => {
callbacks.panicked.store(true, Ordering::Relaxed);
(*callbacks).panicked.store(true, Ordering::Relaxed);
post_panic_error_message(&element, &err);
false

View file

@ -1,3 +1,3 @@
Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)

View file

@ -7,14 +7,18 @@ libc = "0.2"
[dependencies.glib]
package = "glib-sys"
git = "https://github.com/gtk-rs/gtk-rs-core"
branch = "0.15"
version = "0.15"
[dependencies.gst_base]
package = "gstreamer-base-sys"
path = "../../gstreamer-base/sys"
version = "0.18"
[dependencies.gst]
package = "gstreamer-sys"
path = "../../gstreamer/sys"
version = "0.18"
[dev-dependencies]
shell-words = "1.0.0"
@ -47,7 +51,7 @@ license = "MIT"
name = "gstreamer-app-sys"
readme = "README.md"
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
version = "0.18.0"
version = "0.18.8"
edition = "2021"
rust-version = "1.56"
[package.metadata.docs.rs]
@ -72,4 +76,4 @@ version = "1.16"
version = "1.18"
[package.metadata.system-deps.gstreamer_app_1_0.v1_20]
version = "1.19.1"
version = "1.20"

View file

@ -1,6 +1,6 @@
// Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
// from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
// Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
#[cfg(not(feature = "dox"))]

View file

@ -1,6 +1,6 @@
// Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
// from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
// Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
#![allow(non_camel_case_types, non_upper_case_globals, non_snake_case)]

View file

@ -1,6 +1,6 @@
// Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
// from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
// Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
use gstreamer_app_sys::*;
@ -111,6 +111,7 @@ impl Results {
}
#[test]
#[cfg(target_os = "linux")]
fn cross_validate_constants_with_c() {
let mut c_constants: Vec<(String, String)> = Vec::new();
@ -151,6 +152,7 @@ fn cross_validate_constants_with_c() {
}
#[test]
#[cfg(target_os = "linux")]
fn cross_validate_layout_with_c() {
let mut c_layouts = Vec::new();

View file

@ -1,6 +1,6 @@
// Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
// from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
// Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
#include "manual.h"

View file

@ -1,6 +1,6 @@
// Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
// from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
// Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
#include "manual.h"

View file

@ -1,11 +1,11 @@
[package]
name = "gstreamer-audio"
version = "0.18.0"
version = "0.18.8"
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
categories = ["api-bindings", "multimedia"]
description = "Rust bindings for GStreamer Audio library"
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
license = "MIT/Apache-2.0"
license = "MIT OR Apache-2.0"
readme = "README.md"
homepage = "https://gstreamer.freedesktop.org"
documentation = "https://gstreamer.pages.freedesktop.org/gstreamer-rs/stable/latest/docs/gstreamer_audio/"
@ -17,10 +17,10 @@ rust-version = "1.56"
libc = "0.2"
cfg-if = "1.0"
bitflags = "1.0"
ffi = { package = "gstreamer-audio-sys", path = "sys", features = ["v1_8"] }
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
gst = { package = "gstreamer", path = "../gstreamer" }
gst-base = { package = "gstreamer-base", path = "../gstreamer-base" }
ffi = { package = "gstreamer-audio-sys", version = "0.18", path = "sys", features = ["v1_8"] }
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.15", version = "0.15" }
gst = { package = "gstreamer", version = "0.18", path = "../gstreamer" }
gst-base = { package = "gstreamer-base", version = "0.18", path = "../gstreamer-base" }
array-init = "2.0"
once_cell = "1.0"

View file

@ -17,6 +17,8 @@ external_libraries = [
]
generate = [
"GstAudio.AudioAggregatorConvertPad",
"GstAudio.AudioAggregatorPad",
"GstAudio.AudioBaseSrc",
"GstAudio.AudioChannelPosition",
"GstAudio.AudioDitherMethod",
@ -45,6 +47,8 @@ manual = [
"GstAudio.AudioLevelMeta",
"GstAudio.AudioMeta",
"GstAudio.AudioRingBufferSpec",
"GstBase.Aggregator",
"GstBase.AggregatorPad",
"GstBase.BaseSink",
"GstBase.BaseSrc",
]
@ -70,6 +74,20 @@ name = "Gst.Object"
status = "manual"
trait_name = "GstObjectExt"
[[object]]
name = "GstAudio.AudioAggregator"
status = "generate"
[[object.function]]
name = "set_sink_caps"
# capsref
manual = true
[[object.property]]
name = "output-buffer-duration-fraction"
# fraction
manual = true
[[object]]
name = "GstAudio.AudioBaseSink"
status = "generate"

View file

@ -1,7 +1,7 @@
# gstreamer-rs [![crates.io](https://img.shields.io/crates/v/gstreamer-audio.svg)](https://crates.io/crates/gstreamer-audio) [![pipeline status](https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/badges/master/pipeline.svg)](https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/commits/master)
[GStreamer](https://gstreamer.freedesktop.org/) (Audio library) bindings for Rust.
Documentation can be found [here](https://slomo.pages.freedesktop.org/rustdocs/gstreamer/gstreamer_audio/).
Documentation can be found [here](https://gstreamer.pages.freedesktop.org/gstreamer-rs/stable/latest/docs/gstreamer_audio/).
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.

View file

@ -0,0 +1,104 @@
use crate::auto::AudioAggregator;
use crate::auto::AudioAggregatorPad;
use glib::object::{Cast, IsA};
use glib::signal::{connect_raw, SignalHandlerId};
use glib::translate::*;
use std::mem::transmute;
pub trait AudioAggregatorExtManual: 'static {
#[doc(alias = "gst_audio_aggregator_set_sink_caps")]
fn set_sink_caps(&self, pad: &impl IsA<AudioAggregatorPad>, caps: &gst::CapsRef);
#[cfg(any(feature = "v1_18", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))]
#[doc(alias = "output-buffer-duration-fraction")]
fn output_buffer_duration_fraction(&self) -> gst::Fraction;
#[cfg(any(feature = "v1_18", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))]
#[doc(alias = "output-buffer-duration-fraction")]
fn set_output_buffer_duration_fraction(&self, output_buffer_duration_fraction: gst::Fraction);
#[cfg(any(feature = "v1_18", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))]
#[doc(alias = "output-buffer-duration-fraction")]
fn connect_output_buffer_duration_fraction_notify<F: Fn(&Self) + Send + Sync + 'static>(
&self,
f: F,
) -> SignalHandlerId;
fn current_caps(&self) -> Option<gst::Caps>;
fn current_audio_info(&self) -> Option<crate::AudioInfo>;
}
impl<O: IsA<AudioAggregator>> AudioAggregatorExtManual for O {
fn set_sink_caps(&self, pad: &impl IsA<AudioAggregatorPad>, caps: &gst::CapsRef) {
unsafe {
ffi::gst_audio_aggregator_set_sink_caps(
self.as_ref().to_glib_none().0,
pad.as_ref().to_glib_none().0,
caps.as_mut_ptr(),
);
}
}
#[cfg(any(feature = "v1_18", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))]
fn output_buffer_duration_fraction(&self) -> gst::Fraction {
glib::ObjectExt::property(self.as_ref(), "output-buffer-duration-fraction")
}
#[cfg(any(feature = "v1_18", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))]
fn set_output_buffer_duration_fraction(&self, output_buffer_duration_fraction: gst::Fraction) {
glib::ObjectExt::set_property(
self.as_ref(),
"output-buffer-duration-fraction",
output_buffer_duration_fraction,
)
}
#[cfg(any(feature = "v1_18", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))]
fn connect_output_buffer_duration_fraction_notify<F: Fn(&Self) + Send + Sync + 'static>(
&self,
f: F,
) -> SignalHandlerId {
unsafe extern "C" fn notify_output_buffer_duration_fraction_trampoline<
P: IsA<AudioAggregator>,
F: Fn(&P) + Send + Sync + 'static,
>(
this: *mut ffi::GstAudioAggregator,
_param_spec: glib::ffi::gpointer,
f: glib::ffi::gpointer,
) {
let f: &F = &*(f as *const F);
f(AudioAggregator::from_glib_borrow(this).unsafe_cast_ref())
}
unsafe {
let f: Box<F> = Box::new(f);
connect_raw(
self.as_ptr() as *mut _,
b"notify::output-buffer-duration-fraction\0".as_ptr() as *const _,
Some(transmute::<_, unsafe extern "C" fn()>(
notify_output_buffer_duration_fraction_trampoline::<Self, F> as *const (),
)),
Box::into_raw(f),
)
}
}
fn current_caps(&self) -> Option<gst::Caps> {
unsafe {
let ptr = self.as_ptr() as *mut ffi::GstAudioAggregator;
let _guard = crate::utils::MutexGuard::lock(&(*(ptr as *mut gst::ffi::GstObject)).lock);
from_glib_none((*ptr).current_caps)
}
}
fn current_audio_info(&self) -> Option<crate::AudioInfo> {
self.current_caps()
.and_then(|caps| crate::AudioInfo::from_caps(&caps).ok())
}
}

View file

@ -0,0 +1,64 @@
use crate::auto::AudioAggregatorConvertPad;
use glib::object::IsA;
use glib::signal::{connect_raw, SignalHandlerId};
use glib::translate::*;
use glib::Cast;
use std::mem::transmute;
pub trait AudioAggregatorConvertPadExtManual: 'static {
#[doc(alias = "converter-config")]
fn converter_config(&self) -> Option<crate::AudioConverterConfig>;
#[doc(alias = "converter-config")]
fn set_converter_config(&self, converter_config: Option<&crate::AudioConverterConfig>);
#[doc(alias = "converter-config")]
fn connect_converter_config_notify<F: Fn(&Self) + Send + Sync + 'static>(
&self,
f: F,
) -> SignalHandlerId;
}
impl<O: IsA<AudioAggregatorConvertPad>> AudioAggregatorConvertPadExtManual for O {
fn converter_config(&self) -> Option<crate::AudioConverterConfig> {
glib::ObjectExt::property::<Option<gst::Structure>>(self.as_ref(), "converter-config")
.map(|c| c.try_into().unwrap())
}
fn set_converter_config(&self, converter_config: Option<&crate::AudioConverterConfig>) {
glib::ObjectExt::set_property(
self.as_ref(),
"converter-config",
converter_config.map(|s| s.as_ref()),
)
}
fn connect_converter_config_notify<F: Fn(&Self) + Send + Sync + 'static>(
&self,
f: F,
) -> SignalHandlerId {
unsafe extern "C" fn notify_converter_config_trampoline<
P: IsA<AudioAggregatorConvertPad>,
F: Fn(&P) + Send + Sync + 'static,
>(
this: *mut ffi::GstAudioAggregatorConvertPad,
_param_spec: glib::ffi::gpointer,
f: glib::ffi::gpointer,
) {
let f: &F = &*(f as *const F);
f(AudioAggregatorConvertPad::from_glib_borrow(this).unsafe_cast_ref())
}
unsafe {
let f: Box<F> = Box::new(f);
connect_raw(
self.as_ptr() as *mut _,
b"notify::converter-config\0".as_ptr() as *const _,
Some(transmute::<_, unsafe extern "C" fn()>(
notify_converter_config_trampoline::<Self, F> as *const (),
)),
Box::into_raw(f),
)
}
}
}

View file

@ -0,0 +1,26 @@
use crate::auto::AudioAggregatorPad;
use glib::object::IsA;
use glib::translate::*;
pub trait AudioAggregatorPadExtManual: 'static {
fn audio_info(&self) -> Option<crate::AudioInfo>;
}
impl<O: IsA<AudioAggregatorPad>> AudioAggregatorPadExtManual for O {
fn audio_info(&self) -> Option<crate::AudioInfo> {
unsafe {
let ptr = self.as_ptr() as *mut ffi::GstAudioAggregatorPad;
let _guard = crate::utils::MutexGuard::lock(&(*(ptr as *mut gst::ffi::GstObject)).lock);
let info = &(*ptr).info;
if !info.finfo.is_null() && info.channels > 0 && info.rate > 0 && info.bpf > 0 {
return None;
}
Some(from_glib_none(mut_override(
info as *const ffi::GstAudioInfo,
)))
}
}
}

View file

@ -341,6 +341,10 @@ impl<T> AudioBufferRef<T> {
));
}
if self.plane_size() == 0 {
return Ok(&[]);
}
unsafe {
Ok(slice::from_raw_parts(
(*self.audio_buffer.planes.add(plane as usize)) as *const u8,
@ -470,6 +474,10 @@ impl<'a> AudioBufferRef<&'a mut gst::BufferRef> {
));
}
if self.plane_size() == 0 {
return Ok(&mut []);
}
unsafe {
Ok(slice::from_raw_parts_mut(
(*self.audio_buffer.planes.add(plane as usize)) as *mut u8,

View file

@ -57,6 +57,10 @@ pub trait AudioDecoderExtManual: 'static {
function: &str,
line: u32,
) -> Result<gst::FlowSuccess, gst::FlowError>;
fn sink_pad(&self) -> gst::Pad;
fn src_pad(&self) -> gst::Pad;
}
impl<O: IsA<AudioDecoder>> AudioDecoderExtManual for O {
@ -173,6 +177,20 @@ impl<O: IsA<AudioDecoder>> AudioDecoderExtManual for O {
))
}
}
fn sink_pad(&self) -> gst::Pad {
unsafe {
let elt: &ffi::GstAudioDecoder = &*(self.as_ptr() as *const _);
from_glib_none(elt.sinkpad)
}
}
fn src_pad(&self) -> gst::Pad {
unsafe {
let elt: &ffi::GstAudioDecoder = &*(self.as_ptr() as *const _);
from_glib_none(elt.srcpad)
}
}
}
#[macro_export]

View file

@ -23,6 +23,10 @@ pub trait AudioEncoderExtManual: 'static {
#[doc(alias = "get_allocator")]
#[doc(alias = "gst_audio_encoder_get_allocator")]
fn allocator(&self) -> (Option<gst::Allocator>, gst::AllocationParams);
fn sink_pad(&self) -> gst::Pad;
fn src_pad(&self) -> gst::Pad;
}
impl<O: IsA<AudioEncoder>> AudioEncoderExtManual for O {
@ -79,4 +83,18 @@ impl<O: IsA<AudioEncoder>> AudioEncoderExtManual for O {
(from_glib_full(allocator), params.into())
}
}
fn sink_pad(&self) -> gst::Pad {
unsafe {
let elt: &ffi::GstAudioEncoder = &*(self.as_ptr() as *const _);
from_glib_none(elt.sinkpad)
}
}
fn src_pad(&self) -> gst::Pad {
unsafe {
let elt: &ffi::GstAudioEncoder = &*(self.as_ptr() as *const _);
from_glib_none(elt.srcpad)
}
}
}

View file

@ -0,0 +1,242 @@
// This file was generated by gir (https://github.com/gtk-rs/gir)
// from gir-files (https://github.com/gtk-rs/gir-files)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git)
// DO NOT EDIT
use glib::object::Cast;
use glib::object::IsA;
use glib::signal::connect_raw;
use glib::signal::SignalHandlerId;
use glib::translate::*;
use glib::StaticType;
use glib::ToValue;
use std::boxed::Box as Box_;
use std::mem::transmute;
glib::wrapper! {
#[doc(alias = "GstAudioAggregator")]
pub struct AudioAggregator(Object<ffi::GstAudioAggregator, ffi::GstAudioAggregatorClass>) @extends gst_base::Aggregator, gst::Element, gst::Object;
match fn {
type_ => || ffi::gst_audio_aggregator_get_type(),
}
}
impl AudioAggregator {
pub const NONE: Option<&'static AudioAggregator> = None;
}
unsafe impl Send for AudioAggregator {}
unsafe impl Sync for AudioAggregator {}
pub trait AudioAggregatorExt: 'static {
#[doc(alias = "alignment-threshold")]
fn alignment_threshold(&self) -> u64;
#[doc(alias = "alignment-threshold")]
fn set_alignment_threshold(&self, alignment_threshold: u64);
#[doc(alias = "discont-wait")]
fn discont_wait(&self) -> u64;
#[doc(alias = "discont-wait")]
fn set_discont_wait(&self, discont_wait: u64);
#[cfg(any(feature = "v1_20", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
#[doc(alias = "ignore-inactive-pads")]
fn ignores_inactive_pads(&self) -> bool;
#[cfg(any(feature = "v1_20", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
#[doc(alias = "ignore-inactive-pads")]
fn set_ignore_inactive_pads(&self, ignore_inactive_pads: bool);
#[doc(alias = "output-buffer-duration")]
fn output_buffer_duration(&self) -> u64;
#[doc(alias = "output-buffer-duration")]
fn set_output_buffer_duration(&self, output_buffer_duration: u64);
#[doc(alias = "alignment-threshold")]
fn connect_alignment_threshold_notify<F: Fn(&Self) + Send + Sync + 'static>(
&self,
f: F,
) -> SignalHandlerId;
#[doc(alias = "discont-wait")]
fn connect_discont_wait_notify<F: Fn(&Self) + Send + Sync + 'static>(
&self,
f: F,
) -> SignalHandlerId;
#[cfg(any(feature = "v1_20", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
#[doc(alias = "ignore-inactive-pads")]
fn connect_ignore_inactive_pads_notify<F: Fn(&Self) + Send + Sync + 'static>(
&self,
f: F,
) -> SignalHandlerId;
#[doc(alias = "output-buffer-duration")]
fn connect_output_buffer_duration_notify<F: Fn(&Self) + Send + Sync + 'static>(
&self,
f: F,
) -> SignalHandlerId;
}
impl<O: IsA<AudioAggregator>> AudioAggregatorExt for O {
fn alignment_threshold(&self) -> u64 {
glib::ObjectExt::property(self.as_ref(), "alignment-threshold")
}
fn set_alignment_threshold(&self, alignment_threshold: u64) {
glib::ObjectExt::set_property(self.as_ref(), "alignment-threshold", &alignment_threshold)
}
fn discont_wait(&self) -> u64 {
glib::ObjectExt::property(self.as_ref(), "discont-wait")
}
fn set_discont_wait(&self, discont_wait: u64) {
glib::ObjectExt::set_property(self.as_ref(), "discont-wait", &discont_wait)
}
#[cfg(any(feature = "v1_20", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
fn ignores_inactive_pads(&self) -> bool {
glib::ObjectExt::property(self.as_ref(), "ignore-inactive-pads")
}
#[cfg(any(feature = "v1_20", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
fn set_ignore_inactive_pads(&self, ignore_inactive_pads: bool) {
glib::ObjectExt::set_property(self.as_ref(), "ignore-inactive-pads", &ignore_inactive_pads)
}
fn output_buffer_duration(&self) -> u64 {
glib::ObjectExt::property(self.as_ref(), "output-buffer-duration")
}
fn set_output_buffer_duration(&self, output_buffer_duration: u64) {
glib::ObjectExt::set_property(
self.as_ref(),
"output-buffer-duration",
&output_buffer_duration,
)
}
fn connect_alignment_threshold_notify<F: Fn(&Self) + Send + Sync + 'static>(
&self,
f: F,
) -> SignalHandlerId {
unsafe extern "C" fn notify_alignment_threshold_trampoline<
P: IsA<AudioAggregator>,
F: Fn(&P) + Send + Sync + 'static,
>(
this: *mut ffi::GstAudioAggregator,
_param_spec: glib::ffi::gpointer,
f: glib::ffi::gpointer,
) {
let f: &F = &*(f as *const F);
f(AudioAggregator::from_glib_borrow(this).unsafe_cast_ref())
}
unsafe {
let f: Box_<F> = Box_::new(f);
connect_raw(
self.as_ptr() as *mut _,
b"notify::alignment-threshold\0".as_ptr() as *const _,
Some(transmute::<_, unsafe extern "C" fn()>(
notify_alignment_threshold_trampoline::<Self, F> as *const (),
)),
Box_::into_raw(f),
)
}
}
fn connect_discont_wait_notify<F: Fn(&Self) + Send + Sync + 'static>(
&self,
f: F,
) -> SignalHandlerId {
unsafe extern "C" fn notify_discont_wait_trampoline<
P: IsA<AudioAggregator>,
F: Fn(&P) + Send + Sync + 'static,
>(
this: *mut ffi::GstAudioAggregator,
_param_spec: glib::ffi::gpointer,
f: glib::ffi::gpointer,
) {
let f: &F = &*(f as *const F);
f(AudioAggregator::from_glib_borrow(this).unsafe_cast_ref())
}
unsafe {
let f: Box_<F> = Box_::new(f);
connect_raw(
self.as_ptr() as *mut _,
b"notify::discont-wait\0".as_ptr() as *const _,
Some(transmute::<_, unsafe extern "C" fn()>(
notify_discont_wait_trampoline::<Self, F> as *const (),
)),
Box_::into_raw(f),
)
}
}
#[cfg(any(feature = "v1_20", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
fn connect_ignore_inactive_pads_notify<F: Fn(&Self) + Send + Sync + 'static>(
&self,
f: F,
) -> SignalHandlerId {
unsafe extern "C" fn notify_ignore_inactive_pads_trampoline<
P: IsA<AudioAggregator>,
F: Fn(&P) + Send + Sync + 'static,
>(
this: *mut ffi::GstAudioAggregator,
_param_spec: glib::ffi::gpointer,
f: glib::ffi::gpointer,
) {
let f: &F = &*(f as *const F);
f(AudioAggregator::from_glib_borrow(this).unsafe_cast_ref())
}
unsafe {
let f: Box_<F> = Box_::new(f);
connect_raw(
self.as_ptr() as *mut _,
b"notify::ignore-inactive-pads\0".as_ptr() as *const _,
Some(transmute::<_, unsafe extern "C" fn()>(
notify_ignore_inactive_pads_trampoline::<Self, F> as *const (),
)),
Box_::into_raw(f),
)
}
}
fn connect_output_buffer_duration_notify<F: Fn(&Self) + Send + Sync + 'static>(
&self,
f: F,
) -> SignalHandlerId {
unsafe extern "C" fn notify_output_buffer_duration_trampoline<
P: IsA<AudioAggregator>,
F: Fn(&P) + Send + Sync + 'static,
>(
this: *mut ffi::GstAudioAggregator,
_param_spec: glib::ffi::gpointer,
f: glib::ffi::gpointer,
) {
let f: &F = &*(f as *const F);
f(AudioAggregator::from_glib_borrow(this).unsafe_cast_ref())
}
unsafe {
let f: Box_<F> = Box_::new(f);
connect_raw(
self.as_ptr() as *mut _,
b"notify::output-buffer-duration\0".as_ptr() as *const _,
Some(transmute::<_, unsafe extern "C" fn()>(
notify_output_buffer_duration_trampoline::<Self, F> as *const (),
)),
Box_::into_raw(f),
)
}
}
}

View file

@ -0,0 +1,81 @@
// This file was generated by gir (https://github.com/gtk-rs/gir)
// from gir-files (https://github.com/gtk-rs/gir-files)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git)
// DO NOT EDIT
use crate::AudioAggregatorPad;
use glib::object::Cast;
use glib::object::IsA;
use glib::signal::connect_raw;
use glib::signal::SignalHandlerId;
use glib::translate::*;
use std::boxed::Box as Box_;
use std::mem::transmute;
glib::wrapper! {
#[doc(alias = "GstAudioAggregatorConvertPad")]
pub struct AudioAggregatorConvertPad(Object<ffi::GstAudioAggregatorConvertPad, ffi::GstAudioAggregatorConvertPadClass>) @extends AudioAggregatorPad, gst_base::AggregatorPad, gst::Object;
match fn {
type_ => || ffi::gst_audio_aggregator_convert_pad_get_type(),
}
}
impl AudioAggregatorConvertPad {
pub const NONE: Option<&'static AudioAggregatorConvertPad> = None;
}
unsafe impl Send for AudioAggregatorConvertPad {}
unsafe impl Sync for AudioAggregatorConvertPad {}
pub trait AudioAggregatorConvertPadExt: 'static {
//#[doc(alias = "converter-config")]
//fn converter_config(&self) -> /*Ignored*/Option<gst::Structure>;
//#[doc(alias = "converter-config")]
//fn set_converter_config(&self, converter_config: /*Ignored*/Option<&gst::Structure>);
#[doc(alias = "converter-config")]
fn connect_converter_config_notify<F: Fn(&Self) + Send + Sync + 'static>(
&self,
f: F,
) -> SignalHandlerId;
}
impl<O: IsA<AudioAggregatorConvertPad>> AudioAggregatorConvertPadExt for O {
//fn converter_config(&self) -> /*Ignored*/Option<gst::Structure> {
// glib::ObjectExt::property(self.as_ref(), "converter-config")
//}
//fn set_converter_config(&self, converter_config: /*Ignored*/Option<&gst::Structure>) {
// glib::ObjectExt::set_property(self.as_ref(),"converter-config", &converter_config)
//}
fn connect_converter_config_notify<F: Fn(&Self) + Send + Sync + 'static>(
&self,
f: F,
) -> SignalHandlerId {
unsafe extern "C" fn notify_converter_config_trampoline<
P: IsA<AudioAggregatorConvertPad>,
F: Fn(&P) + Send + Sync + 'static,
>(
this: *mut ffi::GstAudioAggregatorConvertPad,
_param_spec: glib::ffi::gpointer,
f: glib::ffi::gpointer,
) {
let f: &F = &*(f as *const F);
f(AudioAggregatorConvertPad::from_glib_borrow(this).unsafe_cast_ref())
}
unsafe {
let f: Box_<F> = Box_::new(f);
connect_raw(
self.as_ptr() as *mut _,
b"notify::converter-config\0".as_ptr() as *const _,
Some(transmute::<_, unsafe extern "C" fn()>(
notify_converter_config_trampoline::<Self, F> as *const (),
)),
Box_::into_raw(f),
)
}
}
}

View file

@ -0,0 +1,110 @@
// This file was generated by gir (https://github.com/gtk-rs/gir)
// from gir-files (https://github.com/gtk-rs/gir-files)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git)
// DO NOT EDIT
#[cfg(any(feature = "v1_20", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
use glib::object::Cast;
use glib::object::IsA;
#[cfg(any(feature = "v1_20", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
use glib::signal::connect_raw;
#[cfg(any(feature = "v1_20", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
use glib::signal::SignalHandlerId;
#[cfg(any(feature = "v1_20", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
use glib::translate::*;
#[cfg(any(feature = "v1_20", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
use glib::StaticType;
#[cfg(any(feature = "v1_20", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
use glib::ToValue;
#[cfg(any(feature = "v1_20", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
use std::boxed::Box as Box_;
#[cfg(any(feature = "v1_20", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
use std::mem::transmute;
glib::wrapper! {
#[doc(alias = "GstAudioAggregatorPad")]
pub struct AudioAggregatorPad(Object<ffi::GstAudioAggregatorPad, ffi::GstAudioAggregatorPadClass>) @extends gst_base::AggregatorPad, gst::Object;
match fn {
type_ => || ffi::gst_audio_aggregator_pad_get_type(),
}
}
impl AudioAggregatorPad {
pub const NONE: Option<&'static AudioAggregatorPad> = None;
}
unsafe impl Send for AudioAggregatorPad {}
unsafe impl Sync for AudioAggregatorPad {}
pub trait AudioAggregatorPadExt: 'static {
#[cfg(any(feature = "v1_20", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
#[doc(alias = "qos-messages")]
fn is_qos_messages(&self) -> bool;
#[cfg(any(feature = "v1_20", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
#[doc(alias = "qos-messages")]
fn set_qos_messages(&self, qos_messages: bool);
#[cfg(any(feature = "v1_20", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
#[doc(alias = "qos-messages")]
fn connect_qos_messages_notify<F: Fn(&Self) + Send + Sync + 'static>(
&self,
f: F,
) -> SignalHandlerId;
}
impl<O: IsA<AudioAggregatorPad>> AudioAggregatorPadExt for O {
#[cfg(any(feature = "v1_20", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
fn is_qos_messages(&self) -> bool {
glib::ObjectExt::property(self.as_ref(), "qos-messages")
}
#[cfg(any(feature = "v1_20", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
fn set_qos_messages(&self, qos_messages: bool) {
glib::ObjectExt::set_property(self.as_ref(), "qos-messages", &qos_messages)
}
#[cfg(any(feature = "v1_20", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
fn connect_qos_messages_notify<F: Fn(&Self) + Send + Sync + 'static>(
&self,
f: F,
) -> SignalHandlerId {
unsafe extern "C" fn notify_qos_messages_trampoline<
P: IsA<AudioAggregatorPad>,
F: Fn(&P) + Send + Sync + 'static,
>(
this: *mut ffi::GstAudioAggregatorPad,
_param_spec: glib::ffi::gpointer,
f: glib::ffi::gpointer,
) {
let f: &F = &*(f as *const F);
f(AudioAggregatorPad::from_glib_borrow(this).unsafe_cast_ref())
}
unsafe {
let f: Box_<F> = Box_::new(f);
connect_raw(
self.as_ptr() as *mut _,
b"notify::qos-messages\0".as_ptr() as *const _,
Some(transmute::<_, unsafe extern "C" fn()>(
notify_qos_messages_trampoline::<Self, F> as *const (),
)),
Box_::into_raw(f),
)
}
}
}

View file

@ -3,6 +3,27 @@
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git)
// DO NOT EDIT
#[cfg(any(feature = "v1_14", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
mod audio_aggregator;
#[cfg(any(feature = "v1_14", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
pub use self::audio_aggregator::AudioAggregator;
#[cfg(any(feature = "v1_14", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
mod audio_aggregator_convert_pad;
#[cfg(any(feature = "v1_14", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
pub use self::audio_aggregator_convert_pad::AudioAggregatorConvertPad;
#[cfg(any(feature = "v1_14", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
mod audio_aggregator_pad;
#[cfg(any(feature = "v1_14", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
pub use self::audio_aggregator_pad::AudioAggregatorPad;
mod audio_base_sink;
pub use self::audio_base_sink::AudioBaseSink;
@ -50,6 +71,15 @@ pub use self::flags::AudioPackFlags;
#[doc(hidden)]
pub mod traits {
#[cfg(any(feature = "v1_14", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
pub use super::audio_aggregator::AudioAggregatorExt;
#[cfg(any(feature = "v1_14", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
pub use super::audio_aggregator_convert_pad::AudioAggregatorConvertPadExt;
#[cfg(any(feature = "v1_14", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
pub use super::audio_aggregator_pad::AudioAggregatorPadExt;
pub use super::audio_base_sink::AudioBaseSinkExt;
pub use super::audio_base_src::AudioBaseSrcExt;
pub use super::audio_decoder::AudioDecoderExt;

View file

@ -1,3 +1,3 @@
Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)

View file

@ -45,6 +45,15 @@ mod audio_channel_position;
pub use crate::audio_channel_position::*;
#[cfg(any(feature = "v1_14", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
mod audio_aggregator;
#[cfg(any(feature = "v1_14", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
mod audio_aggregator_convert_pad;
#[cfg(any(feature = "v1_14", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
mod audio_aggregator_pad;
#[cfg(any(feature = "v1_14", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
mod audio_stream_align;
mod functions;
pub use crate::functions::*;
@ -61,6 +70,10 @@ mod audio_encoder;
mod audio_converter;
pub use crate::audio_converter::AudioConverterConfig;
#[cfg(any(feature = "v1_14", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
mod utils;
// Re-export all the traits in a prelude module, so that applications
// can always "use gst_audio::prelude::*" without getting conflicts
pub mod prelude {
@ -69,7 +82,17 @@ pub mod prelude {
pub use super::audio_decoder::AudioDecoderExtManual;
pub use super::audio_encoder::AudioEncoderExtManual;
#[cfg(any(feature = "v1_14", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
pub use crate::audio_aggregator::AudioAggregatorExtManual;
#[cfg(any(feature = "v1_14", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
pub use crate::audio_aggregator_convert_pad::AudioAggregatorConvertPadExtManual;
#[cfg(any(feature = "v1_14", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
pub use crate::audio_aggregator_pad::AudioAggregatorPadExtManual;
pub use crate::audio_format::AudioFormatIteratorExt;
pub use crate::auto::traits::*;
}

View file

@ -0,0 +1,161 @@
// Take a look at the license at the top of the repository in the LICENSE file.
use glib::translate::*;
use gst_base::prelude::*;
use gst_base::subclass::prelude::*;
use std::ptr;
use crate::AudioAggregator;
use crate::AudioAggregatorPad;
pub trait AudioAggregatorImpl: AudioAggregatorImplExt + AggregatorImpl {
fn create_output_buffer(&self, element: &Self::Type, num_frames: u32) -> Option<gst::Buffer> {
self.parent_create_output_buffer(element, num_frames)
}
#[allow(clippy::too_many_arguments)]
fn aggregate_one_buffer(
&self,
element: &Self::Type,
pad: &AudioAggregatorPad,
inbuf: &gst::BufferRef,
in_offset: u32,
outbuf: &mut gst::BufferRef,
out_offset: u32,
num_frames: u32,
) -> bool {
self.parent_aggregate_one_buffer(
element, pad, inbuf, in_offset, outbuf, out_offset, num_frames,
)
}
}
pub trait AudioAggregatorImplExt: ObjectSubclass {
fn parent_create_output_buffer(
&self,
element: &Self::Type,
num_frames: u32,
) -> Option<gst::Buffer>;
#[allow(clippy::too_many_arguments)]
fn parent_aggregate_one_buffer(
&self,
element: &Self::Type,
pad: &AudioAggregatorPad,
inbuf: &gst::BufferRef,
in_offset: u32,
outbuf: &mut gst::BufferRef,
out_offset: u32,
num_frames: u32,
) -> bool;
}
impl<T: AudioAggregatorImpl> AudioAggregatorImplExt for T {
fn parent_create_output_buffer(
&self,
element: &Self::Type,
num_frames: u32,
) -> Option<gst::Buffer> {
unsafe {
let data = Self::type_data();
let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioAggregatorClass;
let f = (*parent_class)
.create_output_buffer
.expect("Missing parent function `create_output_buffer`");
from_glib_full(f(
element
.unsafe_cast_ref::<AudioAggregator>()
.to_glib_none()
.0,
num_frames,
))
}
}
fn parent_aggregate_one_buffer(
&self,
element: &Self::Type,
pad: &AudioAggregatorPad,
inbuf: &gst::BufferRef,
in_offset: u32,
outbuf: &mut gst::BufferRef,
out_offset: u32,
num_frames: u32,
) -> bool {
unsafe {
let data = Self::type_data();
let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioAggregatorClass;
let f = (*parent_class)
.aggregate_one_buffer
.expect("Missing parent function `aggregate_one_buffer`");
from_glib(f(
element
.unsafe_cast_ref::<AudioAggregator>()
.to_glib_none()
.0,
pad.to_glib_none().0,
inbuf.as_mut_ptr(),
in_offset,
outbuf.as_mut_ptr(),
out_offset,
num_frames,
))
}
}
}
unsafe impl<T: AudioAggregatorImpl> IsSubclassable<T> for AudioAggregator {
fn class_init(klass: &mut glib::Class<Self>) {
Self::parent_class_init::<T>(klass);
let klass = klass.as_mut();
klass.create_output_buffer = Some(audio_aggregator_create_output_buffer::<T>);
klass.aggregate_one_buffer = Some(audio_aggregator_aggregate_one_buffer::<T>);
}
}
unsafe extern "C" fn audio_aggregator_create_output_buffer<T: AudioAggregatorImpl>(
ptr: *mut ffi::GstAudioAggregator,
num_frames: u32,
) -> *mut gst::ffi::GstBuffer {
let instance = &*(ptr as *mut T::Instance);
let imp = instance.imp();
let wrap: Borrowed<AudioAggregator> = from_glib_borrow(ptr);
gst::panic_to_error!(&wrap, imp.panicked(), None, {
imp.create_output_buffer(wrap.unsafe_cast_ref(), num_frames)
})
.map(|buffer| buffer.into_ptr())
.unwrap_or(ptr::null_mut())
}
unsafe extern "C" fn audio_aggregator_aggregate_one_buffer<T: AudioAggregatorImpl>(
ptr: *mut ffi::GstAudioAggregator,
pad: *mut ffi::GstAudioAggregatorPad,
inbuf: *mut gst::ffi::GstBuffer,
in_offset: u32,
outbuf: *mut gst::ffi::GstBuffer,
out_offset: u32,
num_frames: u32,
) -> glib::ffi::gboolean {
let instance = &*(ptr as *mut T::Instance);
let imp = instance.imp();
let wrap: Borrowed<AudioAggregator> = from_glib_borrow(ptr);
gst::panic_to_error!(&wrap, imp.panicked(), true, {
imp.aggregate_one_buffer(
wrap.unsafe_cast_ref(),
&from_glib_borrow(pad),
gst::BufferRef::from_ptr(inbuf),
in_offset,
gst::BufferRef::from_mut_ptr(outbuf),
out_offset,
num_frames,
)
})
.into_glib()
}

View file

@ -0,0 +1,10 @@
// Take a look at the license at the top of the repository in the LICENSE file.
use gst_base::subclass::prelude::*;
use super::prelude::AudioAggregatorPadImpl;
use crate::AudioAggregatorConvertPad;
pub trait AudioAggregatorConvertPadImpl: AudioAggregatorPadImpl {}
unsafe impl<T: AudioAggregatorConvertPadImpl> IsSubclassable<T> for AudioAggregatorConvertPad {}

View file

@ -0,0 +1,116 @@
// Take a look at the license at the top of the repository in the LICENSE file.
use glib::translate::*;
use gst_base::prelude::*;
use gst_base::subclass::prelude::*;
use std::ptr;
use crate::AudioAggregatorPad;
pub trait AudioAggregatorPadImpl: AudioAggregatorPadImplExt + AggregatorPadImpl {
const HANDLE_CONVERSION: bool = false;
fn update_conversion_info(&self, pad: &Self::Type) {
self.parent_update_conversion_info(pad)
}
fn convert_buffer(
&self,
pad: &Self::Type,
in_info: &crate::AudioInfo,
out_info: &crate::AudioInfo,
buffer: &gst::Buffer,
) -> Option<gst::Buffer> {
self.parent_convert_buffer(pad, in_info, out_info, buffer)
}
}
pub trait AudioAggregatorPadImplExt: ObjectSubclass {
fn parent_update_conversion_info(&self, pad: &Self::Type);
fn parent_convert_buffer(
&self,
pad: &Self::Type,
in_info: &crate::AudioInfo,
out_info: &crate::AudioInfo,
buffer: &gst::Buffer,
) -> Option<gst::Buffer>;
}
impl<T: AudioAggregatorPadImpl> AudioAggregatorPadImplExt for T {
fn parent_update_conversion_info(&self, pad: &Self::Type) {
unsafe {
let data = Self::type_data();
let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioAggregatorPadClass;
if let Some(f) = (*parent_class).update_conversion_info {
f(pad.unsafe_cast_ref::<AudioAggregatorPad>().to_glib_none().0);
}
}
}
fn parent_convert_buffer(
&self,
pad: &Self::Type,
in_info: &crate::AudioInfo,
out_info: &crate::AudioInfo,
buffer: &gst::Buffer,
) -> Option<gst::Buffer> {
unsafe {
let data = Self::type_data();
let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioAggregatorPadClass;
let f = (*parent_class)
.convert_buffer
.expect("Missing parent function `convert_buffer`");
from_glib_full(f(
pad.unsafe_cast_ref::<AudioAggregatorPad>().to_glib_none().0,
mut_override(in_info.to_glib_none().0),
mut_override(out_info.to_glib_none().0),
buffer.as_mut_ptr(),
))
}
}
}
unsafe impl<T: AudioAggregatorPadImpl> IsSubclassable<T> for AudioAggregatorPad {
fn class_init(klass: &mut glib::Class<Self>) {
Self::parent_class_init::<T>(klass);
let klass = klass.as_mut();
if T::HANDLE_CONVERSION {
klass.update_conversion_info = Some(audio_aggregator_pad_update_conversion_info::<T>);
klass.convert_buffer = Some(audio_aggregator_pad_convert_buffer::<T>);
}
}
}
unsafe extern "C" fn audio_aggregator_pad_update_conversion_info<T: AudioAggregatorPadImpl>(
ptr: *mut ffi::GstAudioAggregatorPad,
) {
let instance = &*(ptr as *mut T::Instance);
let imp = instance.imp();
let wrap: Borrowed<AudioAggregatorPad> = from_glib_borrow(ptr);
imp.update_conversion_info(wrap.unsafe_cast_ref());
}
unsafe extern "C" fn audio_aggregator_pad_convert_buffer<T: AudioAggregatorPadImpl>(
ptr: *mut ffi::GstAudioAggregatorPad,
in_info: *mut ffi::GstAudioInfo,
out_info: *mut ffi::GstAudioInfo,
buffer: *mut gst::ffi::GstBuffer,
) -> *mut gst::ffi::GstBuffer {
let instance = &*(ptr as *mut T::Instance);
let imp = instance.imp();
let wrap: Borrowed<AudioAggregatorPad> = from_glib_borrow(ptr);
imp.convert_buffer(
wrap.unsafe_cast_ref(),
&from_glib_none(in_info),
&from_glib_none(out_info),
&from_glib_borrow(buffer),
)
.map(|buffer| buffer.into_ptr())
.unwrap_or(ptr::null_mut())
}

View file

@ -294,7 +294,11 @@ unsafe extern "C" fn audiosink_write<T: AudioSinkImpl>(
let instance = &*(ptr as *mut T::Instance);
let imp = instance.imp();
let wrap: Borrowed<AudioSink> = from_glib_borrow(ptr);
let data_slice = std::slice::from_raw_parts(data as *const u8, length as usize);
let data_slice = if length == 0 {
&[]
} else {
std::slice::from_raw_parts(data as *const u8, length as usize)
};
gst::panic_to_error!(&wrap, imp.panicked(), -1, {
imp.write(wrap.unsafe_cast_ref(), data_slice).unwrap_or(-1)

View file

@ -311,7 +311,11 @@ unsafe extern "C" fn audiosrc_read<T: AudioSrcImpl>(
let instance = &*(ptr as *mut T::Instance);
let imp = instance.imp();
let wrap: Borrowed<AudioSrc> = from_glib_borrow(ptr);
let data_slice = std::slice::from_raw_parts_mut(data as *mut u8, length as usize);
let data_slice = if length == 0 {
&mut []
} else {
std::slice::from_raw_parts_mut(data as *mut u8, length as usize)
};
gst::panic_to_error!(&wrap, imp.panicked(), 0, {
let (res, timestamp_res) = imp

View file

@ -2,6 +2,15 @@
#![allow(clippy::cast_ptr_alignment)]
#[cfg(any(feature = "v1_14", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
mod audio_aggregator;
#[cfg(any(feature = "v1_14", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
mod audio_aggregator_convert_pad;
#[cfg(any(feature = "v1_14", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
mod audio_aggregator_pad;
mod audio_base_sink;
mod audio_base_src;
mod audio_decoder;
@ -13,6 +22,15 @@ pub mod prelude {
#[doc(hidden)]
pub use gst_base::subclass::prelude::*;
#[cfg(any(feature = "v1_14", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
pub use super::audio_aggregator::{AudioAggregatorImpl, AudioAggregatorImplExt};
#[cfg(any(feature = "v1_14", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
pub use super::audio_aggregator_convert_pad::AudioAggregatorConvertPadImpl;
#[cfg(any(feature = "v1_14", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
pub use super::audio_aggregator_pad::{AudioAggregatorPadImpl, AudioAggregatorPadImplExt};
pub use super::audio_base_sink::AudioBaseSinkImpl;
pub use super::audio_base_src::AudioBaseSrcImpl;
pub use super::audio_decoder::{AudioDecoderImpl, AudioDecoderImplExt};

View file

@ -0,0 +1,28 @@
// Take a look at the license at the top of the repository in the LICENSE file.
use glib::translate::mut_override;
#[must_use = "if unused the Mutex will immediately unlock"]
#[doc(alias = "GMutex")]
pub struct MutexGuard<'a>(&'a glib::ffi::GMutex);
impl<'a> MutexGuard<'a> {
#[allow(clippy::trivially_copy_pass_by_ref)]
#[allow(dead_code)]
#[doc(alias = "g_mutex_lock")]
pub fn lock(mutex: &'a glib::ffi::GMutex) -> Self {
skip_assert_initialized!();
unsafe {
glib::ffi::g_mutex_lock(mut_override(mutex));
}
MutexGuard(mutex)
}
}
impl<'a> Drop for MutexGuard<'a> {
fn drop(&mut self) {
unsafe {
glib::ffi::g_mutex_unlock(mut_override(self.0));
}
}
}

View file

@ -7,18 +7,24 @@ libc = "0.2"
[dependencies.glib]
package = "glib-sys"
git = "https://github.com/gtk-rs/gtk-rs-core"
branch = "0.15"
version = "0.15"
[dependencies.gobject]
package = "gobject-sys"
git = "https://github.com/gtk-rs/gtk-rs-core"
branch = "0.15"
version = "0.15"
[dependencies.gst_base]
package = "gstreamer-base-sys"
path = "../../gstreamer-base/sys"
version = "0.18"
[dependencies.gst]
package = "gstreamer-sys"
path = "../../gstreamer/sys"
version = "0.18"
[dev-dependencies]
shell-words = "1.0.0"
@ -51,7 +57,7 @@ license = "MIT"
name = "gstreamer-audio-sys"
readme = "README.md"
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
version = "0.18.0"
version = "0.18.8"
edition = "2021"
rust-version = "1.56"
[package.metadata.docs.rs]
@ -76,4 +82,4 @@ version = "1.16"
version = "1.18"
[package.metadata.system-deps.gstreamer_audio_1_0.v1_20]
version = "1.19.1"
version = "1.20"

View file

@ -1,6 +1,6 @@
// Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
// from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
// Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
#[cfg(not(feature = "dox"))]

View file

@ -1,6 +1,6 @@
// Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
// from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
// Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
#![allow(non_camel_case_types, non_upper_case_globals, non_snake_case)]
@ -1706,6 +1706,9 @@ extern "C" {
//=========================================================================
pub fn gst_audio_info_get_type() -> GType;
pub fn gst_audio_info_new() -> *mut GstAudioInfo;
#[cfg(any(feature = "v1_20", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
pub fn gst_audio_info_new_from_caps(caps: *const gst::GstCaps) -> *mut GstAudioInfo;
pub fn gst_audio_info_convert(
info: *const GstAudioInfo,
src_fmt: gst::GstFormat,

View file

@ -1,6 +1,6 @@
// Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
// from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
// Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
use gstreamer_audio_sys::*;
@ -111,6 +111,7 @@ impl Results {
}
#[test]
#[cfg(target_os = "linux")]
fn cross_validate_constants_with_c() {
let mut c_constants: Vec<(String, String)> = Vec::new();
@ -151,6 +152,7 @@ fn cross_validate_constants_with_c() {
}
#[test]
#[cfg(target_os = "linux")]
fn cross_validate_layout_with_c() {
let mut c_layouts = Vec::new();

View file

@ -1,6 +1,6 @@
// Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
// from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
// Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
#include "manual.h"

View file

@ -1,6 +1,6 @@
// Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
// from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
// Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
#include "manual.h"

View file

@ -1,11 +1,11 @@
[package]
name = "gstreamer-base"
version = "0.18.0"
version = "0.18.8"
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
categories = ["api-bindings", "multimedia"]
description = "Rust bindings for GStreamer Base library"
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
license = "MIT/Apache-2.0"
license = "MIT OR Apache-2.0"
readme = "README.md"
homepage = "https://gstreamer.freedesktop.org"
documentation = "https://gstreamer.pages.freedesktop.org/gstreamer-rs/stable/latest/docs/gstreamer_base/"
@ -17,9 +17,10 @@ rust-version = "1.56"
cfg-if = "1.0"
libc = "0.2"
bitflags = "1.0"
ffi = { package = "gstreamer-base-sys", path = "sys", features = ["v1_8"] }
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
gst = { package = "gstreamer", path = "../gstreamer" }
ffi = { package = "gstreamer-base-sys", version = "0.18", path = "sys", features = ["v1_8"] }
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.15", version = "0.15" }
gst = { package = "gstreamer", version = "0.18", path = "../gstreamer" }
atomic_refcell = "0.1"
[dev-dependencies]
gir-format-check = "0.1"

View file

@ -1,7 +1,7 @@
# gstreamer-rs [![crates.io](https://img.shields.io/crates/v/gstreamer-base.svg)](https://crates.io/crates/gstreamer-base) [![pipeline status](https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/badges/master/pipeline.svg)](https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/commits/master)
[GStreamer](https://gstreamer.freedesktop.org/) (Base library) bindings for Rust.
Documentation can be found [here](https://slomo.pages.freedesktop.org/rustdocs/gstreamer/gstreamer_base/).
Documentation can be found [here](https://gstreamer.pages.freedesktop.org/gstreamer-rs/stable/latest/docs/gstreamer_base/).
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.

View file

@ -87,6 +87,8 @@ pub trait AggregatorExtManual: 'static {
) -> SignalHandlerId
where
P: IsA<Aggregator>;
fn src_pad(&self) -> gst::Pad;
}
impl<O: IsA<Aggregator>> AggregatorExtManual for O {
@ -274,6 +276,14 @@ impl<O: IsA<Aggregator>> AggregatorExtManual for O {
)
}
}
fn src_pad(&self) -> gst::Pad {
unsafe {
let ptr: &ffi::GstAggregator = &*(self.as_ptr() as *const _);
from_glib_none(ptr.srcpad)
}
}
}
#[cfg(any(feature = "v1_16", feature = "dox"))]

View file

@ -1,3 +1,3 @@
Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)

View file

@ -13,6 +13,8 @@ pub trait BaseSinkExtManual: 'static {
fn query_latency(
&self,
) -> Result<(bool, bool, Option<gst::ClockTime>, Option<gst::ClockTime>), glib::BoolError>;
fn sink_pad(&self) -> gst::Pad;
}
impl<O: IsA<BaseSink>> BaseSinkExtManual for O {
@ -55,4 +57,12 @@ impl<O: IsA<BaseSink>> BaseSinkExtManual for O {
}
}
}
fn sink_pad(&self) -> gst::Pad {
unsafe {
let ptr: &ffi::GstBaseSink = &*(self.as_ptr() as *const _);
from_glib_none(ptr.sinkpad)
}
}
}

View file

@ -24,6 +24,8 @@ pub trait BaseSrcExtManual: 'static {
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))]
#[doc(alias = "gst_base_src_new_segment")]
fn new_segment(&self, segment: &gst::Segment) -> Result<(), glib::BoolError>;
fn src_pad(&self) -> gst::Pad;
}
impl<O: IsA<BaseSrc>> BaseSrcExtManual for O {
@ -92,4 +94,12 @@ impl<O: IsA<BaseSrc>> BaseSrcExtManual for O {
}
}
}
fn src_pad(&self) -> gst::Pad {
unsafe {
let ptr: &ffi::GstBaseSrc = &*(self.as_ptr() as *const _);
from_glib_none(ptr.srcpad)
}
}
}

View file

@ -13,6 +13,10 @@ pub trait BaseTransformExtManual: 'static {
#[doc(alias = "get_segment")]
fn segment(&self) -> gst::Segment;
fn sink_pad(&self) -> gst::Pad;
fn src_pad(&self) -> gst::Pad;
}
impl<O: IsA<BaseTransform>> BaseTransformExtManual for O {
@ -36,4 +40,18 @@ impl<O: IsA<BaseTransform>> BaseTransformExtManual for O {
from_glib_none(&trans.segment as *const _)
}
}
fn sink_pad(&self) -> gst::Pad {
unsafe {
let elt: &ffi::GstBaseTransform = &*(self.as_ptr() as *const _);
from_glib_none(elt.sinkpad)
}
}
fn src_pad(&self) -> gst::Pad {
unsafe {
let elt: &ffi::GstBaseTransform = &*(self.as_ptr() as *const _);
from_glib_none(elt.srcpad)
}
}
}

View file

@ -3,18 +3,30 @@
use glib::prelude::*;
use glib::translate::*;
use gst::prelude::*;
use gst::subclass::prelude::*;
use gst::{gst_debug, gst_error};
use std::mem;
use std::ptr;
use atomic_refcell::AtomicRefCell;
use crate::prelude::BaseSrcExtManual;
use crate::BaseSrc;
#[derive(Default)]
pub(super) struct InstanceData {
pub(super) pending_buffer_list: AtomicRefCell<Option<gst::BufferList>>,
}
#[derive(Debug)]
pub enum CreateSuccess {
FilledBuffer,
NewBuffer(gst::Buffer),
#[cfg(any(feature = "v1_14", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
NewBufferList(gst::BufferList),
}
pub trait BaseSrcImpl: BaseSrcImplExt + ElementImpl {
@ -362,18 +374,47 @@ impl<T: BaseSrcImpl> BaseSrcImplExt for T {
// https://gitlab.freedesktop.org/gstreamer/gstreamer-rs-sys/issues/3
let buffer_ref = &mut buffer_ptr as *mut _ as *mut gst::ffi::GstBuffer;
gst::FlowSuccess::try_from_glib(
let instance_data = self.instance_data::<InstanceData>(BaseSrc::static_type()).unwrap();
if let Err(err) = gst::FlowSuccess::try_from_glib(
f(
element.unsafe_cast_ref::<BaseSrc>().to_glib_none().0,
offset,
length,
buffer_ref,
)
)?;
) {
*instance_data.pending_buffer_list.borrow_mut() = None;
return Err(err);
}
let pending_buffer_list = instance_data.pending_buffer_list.borrow_mut().take();
if pending_buffer_list.is_some() &&
(buffer.is_some() || element.unsafe_cast_ref::<BaseSrc>().src_pad().mode() == gst::PadMode::Pull) {
panic!("Buffer lists can only be returned in push mode");
}
if buffer_ptr.is_null() && pending_buffer_list.is_none() {
gst_error!(
gst::CAT_RUST,
obj: element.unsafe_cast_ref::<BaseSrc>(),
"No buffer and no buffer list returned"
);
return Err(gst::FlowError::Error);
}
if !buffer_ptr.is_null() && pending_buffer_list.is_some() {
gst_error!(
gst::CAT_RUST,
obj: element.unsafe_cast_ref::<BaseSrc>(),
"Both buffer and buffer list returned"
);
return Err(gst::FlowError::Error);
}
if let Some(passed_buffer) = buffer {
if buffer_ptr != orig_buffer_ptr {
let new_buffer = gst::BufferRef::from_ptr(buffer_ptr);
let new_buffer = gst::Buffer::from_glib_full(buffer_ptr);
gst_debug!(
gst::CAT_PERFORMANCE,
@ -415,6 +456,16 @@ impl<T: BaseSrcImpl> BaseSrcImplExt for T {
} else {
Ok(CreateSuccess::FilledBuffer)
}
} else if let Some(buffer_list) = pending_buffer_list {
#[cfg(feature = "v1_14")]
{
Ok(CreateSuccess::NewBufferList(buffer_list))
}
#[cfg(not(feature = "v1_14"))]
{
let _ = buffer_list;
unreachable!()
}
} else {
Ok(CreateSuccess::NewBuffer(from_glib_full(buffer_ptr)))
}
@ -632,6 +683,12 @@ unsafe impl<T: BaseSrcImpl> IsSubclassable<T> for BaseSrc {
klass.unlock_stop = Some(base_src_unlock_stop::<T>);
klass.decide_allocation = Some(base_src_decide_allocation::<T>);
}
fn instance_init(instance: &mut glib::subclass::InitializingObject<T>) {
Self::parent_instance_init(instance);
instance.set_instance_data(BaseSrc::static_type(), InstanceData::default());
}
}
unsafe extern "C" fn base_src_start<T: BaseSrcImpl>(
@ -789,7 +846,16 @@ unsafe extern "C" fn base_src_create<T: BaseSrcImpl>(
Some(gst::BufferRef::from_mut_ptr(*buffer_ptr))
};
gst::panic_to_error!(&wrap, imp.panicked(), gst::FlowReturn::Error, {
let instance_data = imp
.instance_data::<InstanceData>(BaseSrc::static_type())
.unwrap();
// If there is a pending buffer list at this point then unset it.
if wrap.type_() == T::Type::static_type() {
*instance_data.pending_buffer_list.borrow_mut() = None;
}
let res = gst::panic_to_error!(&wrap, imp.panicked(), gst::FlowReturn::Error, {
match imp.create(
wrap.unsafe_cast_ref(),
offset,
@ -849,11 +915,42 @@ unsafe extern "C" fn base_src_create<T: BaseSrcImpl>(
gst::FlowReturn::Ok
}
}
#[cfg(any(feature = "v1_14", feature = "dox"))]
Ok(CreateSuccess::NewBufferList(new_buffer_list)) => {
if buffer.is_some()
|| wrap.unsafe_cast_ref::<BaseSrc>().src_pad().mode() == gst::PadMode::Pull
{
panic!("Buffer lists can only be returned in push mode");
}
*buffer_ptr = ptr::null_mut();
// If this is the final type then submit the buffer list. This can only be done
// once so can only really be done here.
// FIXME: This won't work if a non-Rust subclass of a Rust subclass is created.
if wrap.type_() == T::Type::static_type() {
ffi::gst_base_src_submit_buffer_list(
wrap.to_glib_none().0,
new_buffer_list.into_ptr(),
);
} else {
*instance_data.pending_buffer_list.borrow_mut() = Some(new_buffer_list);
}
gst::FlowReturn::Ok
}
Ok(CreateSuccess::FilledBuffer) => gst::FlowReturn::Ok,
Err(err) => gst::FlowReturn::from(err),
}
})
.into_glib()
.into_glib();
// If there is a pending buffer list at this point then unset it.
if wrap.type_() == T::Type::static_type() {
*instance_data.pending_buffer_list.borrow_mut() = None;
}
res
}
unsafe extern "C" fn base_src_do_seek<T: BaseSrcImpl>(

View file

@ -3,12 +3,14 @@
use glib::prelude::*;
use glib::subclass::prelude::*;
use glib::translate::*;
use gst::prelude::*;
use gst::{gst_debug, gst_error};
use std::ptr;
use super::base_src::{BaseSrcImpl, CreateSuccess};
use crate::prelude::BaseSrcExtManual;
use crate::PushSrc;
pub trait PushSrcImpl: PushSrcImplExt + BaseSrcImpl {
@ -113,17 +115,46 @@ impl<T: PushSrcImpl> PushSrcImplExt for T {
// FIXME: Wrong signature in -sys bindings
// https://gitlab.freedesktop.org/gstreamer/gstreamer-rs-sys/issues/3
let buffer_ref = &mut buffer_ptr as *mut _ as *mut gst::ffi::GstBuffer;
let instance_data = self.instance_data::<super::base_src::InstanceData>(crate::BaseSrc::static_type()).unwrap();
gst::FlowSuccess::try_from_glib(
if let Err(err) = gst::FlowSuccess::try_from_glib(
f(
element.unsafe_cast_ref::<PushSrc>().to_glib_none().0,
buffer_ref,
)
)?;
) {
*instance_data.pending_buffer_list.borrow_mut() = None;
return Err(err);
}
let pending_buffer_list = instance_data.pending_buffer_list.borrow_mut().take();
if pending_buffer_list.is_some() &&
(buffer.is_some() || element.unsafe_cast_ref::<PushSrc>().src_pad().mode() == gst::PadMode::Pull) {
panic!("Buffer lists can only be returned in push mode");
}
let pending_buffer_list = instance_data.pending_buffer_list.borrow_mut().take();
if buffer_ptr.is_null() && pending_buffer_list.is_none() {
gst_error!(
gst::CAT_RUST,
obj: element.unsafe_cast_ref::<PushSrc>(),
"No buffer and no buffer list returned"
);
return Err(gst::FlowError::Error);
}
if !buffer_ptr.is_null() && pending_buffer_list.is_some() {
gst_error!(
gst::CAT_RUST,
obj: element.unsafe_cast_ref::<PushSrc>(),
"Both buffer and buffer list returned"
);
return Err(gst::FlowError::Error);
}
if let Some(passed_buffer) = buffer {
if buffer_ptr != orig_buffer_ptr {
let new_buffer = gst::BufferRef::from_ptr(buffer_ptr);
let new_buffer = gst::Buffer::from_glib_full(buffer_ptr);
gst_debug!(
gst::CAT_PERFORMANCE,
@ -165,6 +196,16 @@ impl<T: PushSrcImpl> PushSrcImplExt for T {
} else {
Ok(CreateSuccess::FilledBuffer)
}
} else if let Some(buffer_list) = pending_buffer_list {
#[cfg(feature = "v1_14")]
{
Ok(CreateSuccess::NewBufferList(buffer_list))
}
#[cfg(not(feature = "v1_14"))]
{
let _ = buffer_list;
unreachable!()
}
} else {
Ok(CreateSuccess::NewBuffer(from_glib_full(buffer_ptr)))
}
@ -240,9 +281,16 @@ unsafe extern "C" fn push_src_create<T: PushSrcImpl>(
Some(gst::BufferRef::from_mut_ptr(*buffer_ptr))
};
gst::panic_to_error!(&wrap, imp.panicked(), gst::FlowReturn::Error, {
let instance_data = imp
.instance_data::<super::base_src::InstanceData>(crate::BaseSrc::static_type())
.unwrap();
let res = gst::panic_to_error!(&wrap, imp.panicked(), gst::FlowReturn::Error, {
match PushSrcImpl::create(imp, wrap.unsafe_cast_ref(), buffer.as_deref_mut()) {
Ok(CreateSuccess::NewBuffer(new_buffer)) => {
// Clear any pending buffer list
*instance_data.pending_buffer_list.borrow_mut() = None;
if let Some(passed_buffer) = buffer {
if passed_buffer.as_ptr() != new_buffer.as_ptr() {
gst_debug!(
@ -295,9 +343,32 @@ unsafe extern "C" fn push_src_create<T: PushSrcImpl>(
gst::FlowReturn::Ok
}
}
Ok(CreateSuccess::FilledBuffer) => gst::FlowReturn::Ok,
#[cfg(any(feature = "v1_14", feature = "dox"))]
Ok(CreateSuccess::NewBufferList(new_buffer_list)) => {
if buffer.is_some()
|| wrap.unsafe_cast_ref::<PushSrc>().src_pad().mode() == gst::PadMode::Pull
{
panic!("Buffer lists can only be returned in push mode");
}
*buffer_ptr = ptr::null_mut();
// Store it in the instance data so that in the end base_src_create() can
// submit it.
*instance_data.pending_buffer_list.borrow_mut() = Some(new_buffer_list);
gst::FlowReturn::Ok
}
Ok(CreateSuccess::FilledBuffer) => {
// Clear any pending buffer list
*instance_data.pending_buffer_list.borrow_mut() = None;
gst::FlowReturn::Ok
}
Err(err) => gst::FlowReturn::from(err),
}
})
.into_glib()
.into_glib();
res
}

View file

@ -7,14 +7,19 @@ libc = "0.2"
[dependencies.glib]
package = "glib-sys"
git = "https://github.com/gtk-rs/gtk-rs-core"
branch = "0.15"
version = "0.15"
[dependencies.gobject]
package = "gobject-sys"
git = "https://github.com/gtk-rs/gtk-rs-core"
branch = "0.15"
version = "0.15"
[dependencies.gst]
package = "gstreamer-sys"
path = "../../gstreamer/sys"
version = "0.18"
[dev-dependencies]
shell-words = "1.0.0"
@ -51,7 +56,7 @@ license = "MIT"
name = "gstreamer-base-sys"
readme = "README.md"
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
version = "0.18.0"
version = "0.18.8"
edition = "2021"
rust-version = "1.56"
[package.metadata.docs.rs]
@ -85,4 +90,4 @@ version = "1.16"
version = "1.18"
[package.metadata.system-deps.gstreamer_base_1_0.v1_20]
version = "1.19.1"
version = "1.20"

View file

@ -1,6 +1,6 @@
// Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
// from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
// Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
#[cfg(not(feature = "dox"))]

View file

@ -1,6 +1,6 @@
// Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
// from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
// Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
#![allow(non_camel_case_types, non_upper_case_globals, non_snake_case)]

View file

@ -1,6 +1,6 @@
// Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
// from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
// Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
use gstreamer_base_sys::*;
@ -111,6 +111,7 @@ impl Results {
}
#[test]
#[cfg(target_os = "linux")]
fn cross_validate_constants_with_c() {
let mut c_constants: Vec<(String, String)> = Vec::new();
@ -151,6 +152,7 @@ fn cross_validate_constants_with_c() {
}
#[test]
#[cfg(target_os = "linux")]
fn cross_validate_layout_with_c() {
let mut c_layouts = Vec::new();

View file

@ -1,6 +1,6 @@
// Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
// from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
// Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
#include "manual.h"

View file

@ -1,6 +1,6 @@
// Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
// from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
// Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
#include "manual.h"

View file

@ -1,11 +1,11 @@
[package]
name = "gstreamer-check"
version = "0.18.0"
version = "0.18.8"
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
categories = ["api-bindings", "multimedia"]
description = "Rust bindings for GStreamer Check library"
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
license = "MIT/Apache-2.0"
license = "MIT OR Apache-2.0"
readme = "README.md"
homepage = "https://gstreamer.freedesktop.org"
documentation = "https://gstreamer.pages.freedesktop.org/gstreamer-rs/stable/latest/docs/gstreamer_check/"
@ -15,9 +15,9 @@ rust-version = "1.56"
[dependencies]
bitflags = "1.0"
ffi = { package = "gstreamer-check-sys", path = "sys", features = ["v1_8"] }
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
gst = { package = "gstreamer", path = "../gstreamer" }
ffi = { package = "gstreamer-check-sys", version = "0.18", path = "sys", features = ["v1_8"] }
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.15", version = "0.15" }
gst = { package = "gstreamer", version = "0.18", path = "../gstreamer" }
[dev-dependencies]
gir-format-check = "0.1"

View file

@ -1,7 +1,7 @@
# gstreamer-rs [![crates.io](https://img.shields.io/crates/v/gstreamer-check.svg)](https://crates.io/crates/gstreamer-check) [![pipeline status](https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/badges/master/pipeline.svg)](https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/commits/master)
[GStreamer](https://gstreamer.freedesktop.org/) (Check library) bindings for Rust.
Documentation can be found [here](https://slomo.pages.freedesktop.org/rustdocs/gstreamer/gstreamer_check/).
Documentation can be found [here](https://gstreamer.pages.freedesktop.org/gstreamer-rs/stable/latest/docs/gstreamer_check/).
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.

View file

@ -1,3 +1,3 @@
Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)

View file

@ -7,14 +7,19 @@ libc = "0.2"
[dependencies.glib]
package = "glib-sys"
git = "https://github.com/gtk-rs/gtk-rs-core"
branch = "0.15"
version = "0.15"
[dependencies.gobject]
package = "gobject-sys"
git = "https://github.com/gtk-rs/gtk-rs-core"
branch = "0.15"
version = "0.15"
[dependencies.gst]
package = "gstreamer-sys"
path = "../../gstreamer/sys"
version = "0.18"
[dev-dependencies]
shell-words = "1.0.0"
@ -47,7 +52,7 @@ license = "MIT"
name = "gstreamer-check-sys"
readme = "README.md"
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
version = "0.18.0"
version = "0.18.8"
edition = "2021"
rust-version = "1.56"
[package.metadata.docs.rs]
@ -72,4 +77,4 @@ version = "1.16"
version = "1.18"
[package.metadata.system-deps.gstreamer_check_1_0.v1_20]
version = "1.19.1"
version = "1.20"

View file

@ -1,6 +1,6 @@
// Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
// from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
// Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
#[cfg(not(feature = "dox"))]

View file

@ -1,6 +1,6 @@
// Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
// from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
// Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
#![allow(non_camel_case_types, non_upper_case_globals, non_snake_case)]

View file

@ -1,6 +1,6 @@
// Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
// from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
// Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
use gstreamer_check_sys::*;
@ -111,6 +111,7 @@ impl Results {
}
#[test]
#[cfg(target_os = "linux")]
fn cross_validate_constants_with_c() {
let mut c_constants: Vec<(String, String)> = Vec::new();
@ -151,6 +152,7 @@ fn cross_validate_constants_with_c() {
}
#[test]
#[cfg(target_os = "linux")]
fn cross_validate_layout_with_c() {
let mut c_layouts = Vec::new();

View file

@ -1,6 +1,6 @@
// Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
// from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
// Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
#include "manual.h"

View file

@ -1,6 +1,6 @@
// Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
// from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
// Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
#include "manual.h"

View file

@ -1,11 +1,11 @@
[package]
name = "gstreamer-controller"
version = "0.18.0"
version = "0.18.8"
authors = ["Alexey Galakhov <agalakhov@gmail.com>", "Sebastian Dröge <sebastian@centricular.com>"]
categories = ["api-bindings", "multimedia"]
description = "Rust bindings for GStreamer Controller library"
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
license = "MIT/Apache-2.0"
license = "MIT OR Apache-2.0"
readme = "README.md"
homepage = "https://gstreamer.freedesktop.org"
documentation = "https://gstreamer.pages.freedesktop.org/gstreamer-rs/stable/latest/docs/gstreamer_controller/"
@ -16,9 +16,9 @@ rust-version = "1.56"
[dependencies]
bitflags = "1.0"
once_cell = "1.0"
ffi = { package = "gstreamer-controller-sys", path = "sys", features = ["v1_8"] }
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
gst = { package = "gstreamer", path = "../gstreamer" }
ffi = { package = "gstreamer-controller-sys", version = "0.18", path = "sys", features = ["v1_8"] }
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.15", version = "0.15" }
gst = { package = "gstreamer", version = "0.18", path = "../gstreamer" }
[dev-dependencies]
gir-format-check = "0.1"

View file

@ -1,7 +1,7 @@
# gstreamer-rs [![crates.io](https://img.shields.io/crates/v/gstreamer-controller.svg)](https://crates.io/crates/gstreamer-controller) [![pipeline status](https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/badges/master/pipeline.svg)](https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/commits/master)
[GStreamer](https://gstreamer.freedesktop.org/) (App library) bindings for Rust.
Documentation can be found [here](https://slomo.pages.freedesktop.org/rustdocs/gstreamer/gstreamer_controller/).
Documentation can be found [here](https://gstreamer.pages.freedesktop.org/gstreamer-rs/stable/latest/docs/gstreamer_controller/).
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.

View file

@ -1,3 +1,3 @@
Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)

View file

@ -8,14 +8,19 @@ libc = "0.2"
[dependencies.glib]
package = "glib-sys"
git = "https://github.com/gtk-rs/gtk-rs-core"
branch = "0.15"
version = "0.15"
[dependencies.gobject]
package = "gobject-sys"
git = "https://github.com/gtk-rs/gtk-rs-core"
branch = "0.15"
version = "0.15"
[dependencies.gst]
package = "gstreamer-sys"
path = "../../gstreamer/sys"
version = "0.18"
[dev-dependencies]
shell-words = "1.0.0"
@ -48,7 +53,7 @@ license = "MIT"
name = "gstreamer-controller-sys"
readme = "README.md"
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
version = "0.18.0"
version = "0.18.8"
edition = "2021"
rust-version = "1.56"
[package.metadata.docs.rs]
@ -73,4 +78,4 @@ version = "1.16"
version = "1.18"
[package.metadata.system-deps.gstreamer_controller_1_0.v1_20]
version = "1.19.1"
version = "1.20"

View file

@ -1,6 +1,6 @@
// Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
// from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
// Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
#[cfg(not(feature = "dox"))]

View file

@ -1,6 +1,6 @@
// Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
// from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
// Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
#![allow(non_camel_case_types, non_upper_case_globals, non_snake_case)]

View file

@ -1,6 +1,6 @@
// Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
// from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
// Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
use gstreamer_controller_sys::*;
@ -111,6 +111,7 @@ impl Results {
}
#[test]
#[cfg(target_os = "linux")]
fn cross_validate_constants_with_c() {
let mut c_constants: Vec<(String, String)> = Vec::new();
@ -151,6 +152,7 @@ fn cross_validate_constants_with_c() {
}
#[test]
#[cfg(target_os = "linux")]
fn cross_validate_layout_with_c() {
let mut c_layouts = Vec::new();

View file

@ -1,6 +1,6 @@
// Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
// from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
// Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
#include "manual.h"

View file

@ -1,6 +1,6 @@
// Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
// from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
// Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
#include "manual.h"

View file

@ -1,11 +1,11 @@
[package]
name = "gstreamer-editing-services"
version = "0.18.0"
version = "0.18.8"
authors = ["Thibault Saunier <tsaunier@igalia.com>", "Sebastian Dröge <sebastian@centricular.com>"]
categories = ["api-bindings", "multimedia"]
description = "Rust bindings for GStreamer Editing Services"
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
license = "MIT/Apache-2.0"
license = "MIT OR Apache-2.0"
readme = "README.md"
homepage = "https://gstreamer.freedesktop.org"
documentation = "https://gstreamer.pages.freedesktop.org/gstreamer-rs/stable/latest/docs/gstreamer_editing_services/"
@ -16,12 +16,12 @@ rust-version = "1.56"
[dependencies]
libc = "0.2"
bitflags = "1.0"
ffi = { package = "gstreamer-editing-services-sys", path = "sys", features = ["v1_8"]}
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
gio = { git = "https://github.com/gtk-rs/gtk-rs-core" }
gst = { package = "gstreamer", path = "../gstreamer" }
gst-base = { package = "gstreamer-base", path = "../gstreamer-base" }
gst-pbutils = { package = "gstreamer-pbutils", path = "../gstreamer-pbutils" }
ffi = { package = "gstreamer-editing-services-sys", version = "0.18", path = "sys", features = ["v1_8"]}
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.15", version = "0.15.3" }
gio = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.15", version = "0.15" }
gst = { package = "gstreamer", version = "0.18", path = "../gstreamer" }
gst-base = { package = "gstreamer-base", version = "0.18", path = "../gstreamer-base" }
gst-pbutils = { package = "gstreamer-pbutils", version = "0.18", path = "../gstreamer-pbutils" }
[dev-dependencies]
gir-format-check = "0.1"

View file

@ -1,7 +1,7 @@
# gstreamer-rs [![crates.io](https://img.shields.io/crates/v/gstreamer-editing-services.svg)](https://crates.io/crates/gstreamer-editing-services) [![pipeline status](https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/badges/master/pipeline.svg)](https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/commits/master)
[GStreamer Editing Services](https://gstreamer.freedesktop.org/) bindings for Rust.
Documentation can be found [here](https://slomo.pages.freedesktop.org/rustdocs/gstreamer/gstreamer_editing_services/).
Documentation can be found [here](https://gstreamer.pages.freedesktop.org/gstreamer-rs/stable/latest/docs/gstreamer_editing_services/).
NOTE: The GStreamer Editing Services API is not Thread Safe and before the 1.16
release this was not properly expressed in the code, leading to possible data

View file

@ -60,16 +60,28 @@ impl Asset {
}
#[doc(alias = "ges_asset_request_async")]
pub fn request_async<P: FnOnce(Result<Asset, glib::Error>) + Send + 'static>(
pub fn request_async<P: FnOnce(Result<Asset, glib::Error>) + 'static>(
extractable_type: glib::types::Type,
id: Option<&str>,
cancellable: Option<&impl IsA<gio::Cancellable>>,
callback: P,
) {
assert_initialized_main_thread!();
let user_data: Box_<P> = Box_::new(callback);
let main_context = glib::MainContext::ref_thread_default();
let is_main_context_owner = main_context.is_owner();
let has_acquired_main_context = (!is_main_context_owner)
.then(|| main_context.acquire().ok())
.flatten();
assert!(
is_main_context_owner || has_acquired_main_context.is_some(),
"Async operations only allowed if the thread is owning the MainContext"
);
let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
Box_::new(glib::thread_guard::ThreadGuard::new(callback));
unsafe extern "C" fn request_async_trampoline<
P: FnOnce(Result<Asset, glib::Error>) + Send + 'static,
P: FnOnce(Result<Asset, glib::Error>) + 'static,
>(
_source_object: *mut glib::gobject_ffi::GObject,
res: *mut gio::ffi::GAsyncResult,
@ -82,7 +94,9 @@ impl Asset {
} else {
Err(from_glib_full(error))
};
let callback: Box_<P> = Box_::from_raw(user_data as *mut _);
let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
Box_::from_raw(user_data as *mut _);
let callback: P = callback.into_inner();
callback(result);
}
let callback = request_async_trampoline::<P>;

View file

@ -1,3 +1,3 @@
Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)

View file

@ -7,22 +7,30 @@ libc = "0.2"
[dependencies.gio]
package = "gio-sys"
git = "https://github.com/gtk-rs/gtk-rs-core"
branch = "0.15"
version = "0.15"
[dependencies.glib]
package = "glib-sys"
git = "https://github.com/gtk-rs/gtk-rs-core"
branch = "0.15"
version = "0.15"
[dependencies.gobject]
package = "gobject-sys"
git = "https://github.com/gtk-rs/gtk-rs-core"
branch = "0.15"
version = "0.15"
[dependencies.gst_pbutils]
package = "gstreamer-pbutils-sys"
path = "../../gstreamer-pbutils/sys"
version = "0.18"
[dependencies.gst]
package = "gstreamer-sys"
path = "../../gstreamer/sys"
version = "0.18"
[dev-dependencies]
shell-words = "1.0.0"
@ -55,7 +63,7 @@ license = "MIT"
name = "gstreamer-editing-services-sys"
readme = "README.md"
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
version = "0.18.0"
version = "0.18.8"
edition = "2021"
rust-version = "1.56"
[package.metadata.docs.rs]
@ -80,4 +88,4 @@ version = "1.16"
version = "1.18"
[package.metadata.system-deps.gst_editing_services_1_0.v1_20]
version = "1.19.1"
version = "1.20"

View file

@ -1,6 +1,6 @@
// Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
// from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
// Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
#[cfg(not(feature = "dox"))]

View file

@ -1,6 +1,6 @@
// Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
// from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
// Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
#![allow(non_camel_case_types, non_upper_case_globals, non_snake_case)]
@ -189,9 +189,9 @@ pub const GES_PADDING: c_int = 4;
pub const GES_PADDING_LARGE: c_int = 20;
pub const GES_TIMELINE_ELEMENT_NO_LAYER_PRIORITY: u32 = 4294967295;
pub const GES_VERSION_MAJOR: c_int = 1;
pub const GES_VERSION_MICRO: c_int = 3;
pub const GES_VERSION_MINOR: c_int = 19;
pub const GES_VERSION_NANO: c_int = 1;
pub const GES_VERSION_MICRO: c_int = 0;
pub const GES_VERSION_MINOR: c_int = 20;
pub const GES_VERSION_NANO: c_int = 0;
// Flags
pub type GESMarkerFlags = c_uint;

View file

@ -1,6 +1,6 @@
// Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
// from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
// Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
use gstreamer_editing_services_sys::*;
@ -111,6 +111,7 @@ impl Results {
}
#[test]
#[cfg(target_os = "linux")]
fn cross_validate_constants_with_c() {
let mut c_constants: Vec<(String, String)> = Vec::new();
@ -151,6 +152,7 @@ fn cross_validate_constants_with_c() {
}
#[test]
#[cfg(target_os = "linux")]
fn cross_validate_layout_with_c() {
let mut c_layouts = Vec::new();
@ -1135,9 +1137,9 @@ const RUST_CONSTANTS: &[(&str, &str)] = &[
("(guint) GES_TRACK_TYPE_UNKNOWN", "1"),
("(guint) GES_TRACK_TYPE_VIDEO", "4"),
("GES_VERSION_MAJOR", "1"),
("GES_VERSION_MICRO", "3"),
("GES_VERSION_MINOR", "19"),
("GES_VERSION_NANO", "1"),
("GES_VERSION_MICRO", "0"),
("GES_VERSION_MINOR", "20"),
("GES_VERSION_NANO", "0"),
(
"(gint) GES_VIDEO_STANDARD_TRANSITION_TYPE_BARNDOOR_DBL",
"45",

View file

@ -1,6 +1,6 @@
// Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
// from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
// Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
#include "manual.h"

View file

@ -1,6 +1,6 @@
// Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
// from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
// Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
// from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)
// DO NOT EDIT
#include "manual.h"

View file

@ -1,6 +1,6 @@
[package]
name = "gstreamer-gl"
version = "0.18.0"
version = "0.18.8"
authors = [
"Sebastian Dröge <sebastian@centricular.com>",
"Víctor M. Jáquez L. <vjaquez@igalia.com>"
@ -8,7 +8,7 @@ authors = [
categories = ["api-bindings", "multimedia"]
description = "Rust bindings for GStreamer GL library"
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
license = "MIT/Apache-2.0"
license = "MIT OR Apache-2.0"
readme = "README.md"
homepage = "https://gstreamer.freedesktop.org"
documentation = "https://gstreamer.pages.freedesktop.org/gstreamer-rs/stable/latest/docs/gstreamer_gl/"
@ -22,11 +22,11 @@ byteorder = "1"
cfg-if = "1"
libc = "0.2"
once_cell = "1.0"
ffi = { package = "gstreamer-gl-sys", path = "sys" }
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
gst = { package = "gstreamer", path = "../gstreamer", features = ["v1_14"] }
gst-base = { package = "gstreamer-base", path = "../gstreamer-base", features = ["v1_14"] }
gst-video = { package = "gstreamer-video", path = "../gstreamer-video", features = ["v1_14"] }
ffi = { package = "gstreamer-gl-sys", version = "0.18", path = "sys" }
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.15", version = "0.15" }
gst = { package = "gstreamer", version = "0.18", path = "../gstreamer", features = ["v1_14"] }
gst-base = { package = "gstreamer-base", version = "0.18", path = "../gstreamer-base", features = ["v1_14"] }
gst-video = { package = "gstreamer-video", version = "0.18", path = "../gstreamer-video", features = ["v1_14"] }
[dev-dependencies]
gir-format-check = "0.1"

View file

@ -2,7 +2,7 @@
[GStreamer](https://gstreamer.freedesktop.org/) (OpenGL library)
bindings for Rust. Documentation can be found
[here](https://slomo.pages.freedesktop.org/rustdocs/gstreamer/gstreamer_gl/).
[here](https://gstreamer.pages.freedesktop.org/gstreamer-rs/stable/latest/docs/gstreamer_gl/).
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.

View file

@ -1,6 +1,6 @@
[package]
name = "gstreamer-gl-egl"
version = "0.18.0"
version = "0.18.8"
authors = [
"Sebastian Dröge <sebastian@centricular.com>",
"Víctor M. Jáquez L. <vjaquez@igalia.com>"
@ -8,7 +8,7 @@ authors = [
categories = ["api-bindings", "multimedia"]
description = "Rust bindings for GStreamer GL library (EGL support)"
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
license = "MIT/Apache-2.0"
license = "MIT OR Apache-2.0"
readme = "README.md"
homepage = "https://gstreamer.freedesktop.org"
documentation = "https://gstreamer.pages.freedesktop.org/gstreamer-rs/stable/latest/docs/gstreamer_gl_egl/"
@ -18,11 +18,11 @@ rust-version = "1.56"
[dependencies]
libc = "0.2"
ffi = { package = "gstreamer-gl-egl-sys", path = "sys" }
ffi = { package = "gstreamer-gl-egl-sys", version = "0.18", path = "sys" }
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
gst = { package = "gstreamer", path = "../../gstreamer", features = ["v1_14"] }
gst-gl = { package = "gstreamer-gl", path = "../" }
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.15", version = "0.15" }
gst = { package = "gstreamer", version = "0.18", path = "../../gstreamer", features = ["v1_14"] }
gst-gl = { package = "gstreamer-gl", version = "0.18", path = "../" }
[dev-dependencies]
gir-format-check = "0.1"

View file

@ -2,7 +2,7 @@
[GStreamer](https://gstreamer.freedesktop.org/) (OpenGL library, EGL support)
bindings for Rust. Documentation can be found
[here](https://slomo.pages.freedesktop.org/rustdocs/gstreamer/gstreamer_gl_egl/).
[here](https://gstreamer.pages.freedesktop.org/gstreamer-rs/stable/latest/docs/gstreamer_gl_egl/).
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.

View file

@ -1,3 +1,3 @@
Generated by gir (https://github.com/gtk-rs/gir @ ee37253c10af)
from gir-files (https://github.com/gtk-rs/gir-files @ 5502d32880f5)
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ f05404723520)
Generated by gir (https://github.com/gtk-rs/gir @ 9aa16ead87e1)
from gir-files (https://github.com/gtk-rs/gir-files @ 3ff4d3275258)
from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 233e3205cb17)

View file

@ -9,7 +9,7 @@ license = "MIT"
name = "gstreamer-gl-egl-sys"
readme = "README.md"
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
version = "0.18.0"
version = "0.18.8"
edition = "2021"
rust-version = "1.56"
[package.metadata.system-deps.gstreamer_gl_egl_1_0]
@ -24,7 +24,7 @@ name = "gstreamer-gl-egl-1.0"
version = "1.18"
[package.metadata.system-deps.gstreamer_gl_egl_1_0.v1_20]
version = "1.19.1"
version = "1.20"
[package.metadata.docs.rs]
features = ["dox"]
@ -37,10 +37,13 @@ libc = "0.2"
[dependencies.glib]
package = "glib-sys"
git = "https://github.com/gtk-rs/gtk-rs-core"
branch = "0.15"
version = "0.15"
[dependencies.gst_gl]
package = "gstreamer-gl-sys"
path = "../../sys"
version = "0.18"
[build-dependencies]
system-deps = "6"

Some files were not shown because too many files have changed in this diff Show more