forked from mirrors/gstreamer-rs
Compare commits
82 commits
Author | SHA1 | Date | |
---|---|---|---|
|
37edd497cc | ||
|
9e8fee59c4 | ||
|
7de3cef890 | ||
|
2c65a5a86a | ||
|
0f2c850785 | ||
|
d77f983b02 | ||
|
38420c7aab | ||
|
cbe627fe8b | ||
|
b9a9464301 | ||
|
559720693d | ||
|
9b2a0f55c7 | ||
|
d05ebfaf45 | ||
|
5cf82ac910 | ||
|
5b0f29003f | ||
|
3c921f9320 | ||
|
f17ef98d4a | ||
|
d703cbcea6 | ||
|
3eacb10d43 | ||
|
1792f72a14 | ||
|
af77bd0b6a | ||
|
24a00b9929 | ||
|
545781d241 | ||
|
011d3535bc | ||
|
0d45fa3f07 | ||
|
a7517cd27b | ||
|
670d8ceec6 | ||
|
b0d6cab254 | ||
|
371713a506 | ||
|
a01a0f2e37 | ||
|
50ec192285 | ||
|
022a340742 | ||
|
42ec126d56 | ||
|
ff488987fa | ||
|
97d55cdacb | ||
|
b611f9702c | ||
|
8d478c3fc9 | ||
|
4a60c71c84 | ||
|
3481f3b6c0 | ||
|
6fb1714114 | ||
|
78ded9ad88 | ||
|
b72533d926 | ||
|
e9644fb733 | ||
|
7d9b7fdaf7 | ||
|
43f29e361e | ||
|
a929123d4d | ||
|
1d9d4cc346 | ||
|
64bc1f7625 | ||
|
87a70b16ba | ||
|
5c88d95553 | ||
|
a9dd58eca0 | ||
|
55ad90cc4d | ||
|
deb49017ec | ||
|
9102546d63 | ||
|
f431630426 | ||
|
6ef6f49e40 | ||
|
18cbbfb1f8 | ||
|
cb6b7a2c2c | ||
|
f0e766e7ee | ||
|
92e2a23a99 | ||
|
7be1db86fd | ||
|
8ef5a045c1 | ||
|
a77a656d04 | ||
|
5171267260 | ||
|
d9ebcc5889 | ||
|
a4c248cba3 | ||
|
4b9ac76020 | ||
|
facdd10eba | ||
|
b78926a7f3 | ||
|
2f41cb99d3 | ||
|
eeefa80227 | ||
|
9446401a46 | ||
|
8afac7d31b | ||
|
dabfc8d181 | ||
|
d1cc1b6715 | ||
|
bc3e1404d6 | ||
|
2354cd6c4f | ||
|
6cb469934d | ||
|
6bd559f5b5 | ||
|
66453fdc02 | ||
|
e901266415 | ||
|
8a02757434 | ||
|
2db1198311 |
108 changed files with 5263 additions and 481 deletions
|
@ -17,7 +17,7 @@
|
|||
# Updating the nightly image should be done by simply running a scheduled ci
|
||||
# pipeline on the upstream repo with the $UPDATE_NIGHTLY variable defined.
|
||||
|
||||
.templates_sha: &templates_sha 567700e483aabed992d0a4fea84994a0472deff6
|
||||
.templates_sha: &templates_sha fddab8aa63e89a8e65214f59860d9c0f030360c9
|
||||
|
||||
include:
|
||||
- project: 'freedesktop/ci-templates'
|
||||
|
@ -56,8 +56,8 @@ variables:
|
|||
# latest release must be at the top
|
||||
# (only relevant on main branch)
|
||||
RELEASES:
|
||||
0.20=0.20
|
||||
0.19=0.19
|
||||
0.18=0.18
|
||||
|
||||
stages:
|
||||
- "trigger"
|
||||
|
@ -89,41 +89,34 @@ trigger:
|
|||
when: 'manual'
|
||||
allow_failure: false
|
||||
|
||||
.debian:11:
|
||||
.debian:12:
|
||||
needs: []
|
||||
variables:
|
||||
FDO_DISTRIBUTION_VERSION: 'bullseye-slim'
|
||||
FDO_DISTRIBUTION_VERSION: 'bookworm-slim'
|
||||
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
|
||||
.debian:12-base:
|
||||
extends: .debian:12
|
||||
variables:
|
||||
FDO_DISTRIBUTION_TAG: 'base-$GST_RS_IMG_TAG'
|
||||
|
||||
.debian:11-stable:
|
||||
extends: .debian:11
|
||||
.debian:12-stable:
|
||||
extends: .debian:12
|
||||
variables:
|
||||
RUST_IMAGE_FULL: "1"
|
||||
FDO_DISTRIBUTION_TAG: '$GST_RS_STABLE-$GST_RS_IMG_TAG'
|
||||
FDO_DISTRIBUTION_EXEC: 'bash ci/install-rust.sh $GST_RS_STABLE $RUST_IMAGE_FULL'
|
||||
|
||||
.debian:11-msrv:
|
||||
extends: .debian:11
|
||||
.debian:12-msrv:
|
||||
extends: .debian:12
|
||||
variables:
|
||||
FDO_DISTRIBUTION_TAG: '$GST_RS_MSRV-$GST_RS_IMG_TAG'
|
||||
FDO_DISTRIBUTION_EXEC: 'bash ci/install-rust.sh $GST_RS_MSRV $RUST_IMAGE_FULL'
|
||||
|
||||
.debian:11-nightly:
|
||||
extends: .debian:11
|
||||
.debian:12-nightly:
|
||||
extends: .debian:12
|
||||
variables:
|
||||
FDO_DISTRIBUTION_TAG: 'nightly-$GST_RS_IMG_TAG'
|
||||
FDO_DISTRIBUTION_EXEC: 'bash ci/install-rust.sh nightly $RUST_IMAGE_FULL'
|
||||
|
@ -145,37 +138,37 @@ trigger:
|
|||
FDO_DISTRIBUTION_EXEC: >-
|
||||
bash ci/install-gst.sh &&
|
||||
bash ci/install-gtk4.sh &&
|
||||
pip3 install git+http://gitlab.freedesktop.org/freedesktop/ci-templates
|
||||
pip3 install --break-system-packages git+http://gitlab.freedesktop.org/freedesktop/ci-templates
|
||||
|
||||
.build-final-image:
|
||||
extends:
|
||||
- .fdo.container-build@debian
|
||||
stage: container-final
|
||||
variables:
|
||||
FDO_BASE_IMAGE: '$CI_REGISTRY_IMAGE/debian/bullseye-slim:base-$GST_RS_IMG_TAG'
|
||||
FDO_BASE_IMAGE: '$CI_REGISTRY_IMAGE/debian/bookworm-slim:base-$GST_RS_IMG_TAG'
|
||||
|
||||
build-base:
|
||||
extends:
|
||||
- .build-base-image
|
||||
- .debian:11-base
|
||||
- .debian:12-base
|
||||
|
||||
build-stable:
|
||||
needs: ["build-base"]
|
||||
extends:
|
||||
- .build-final-image
|
||||
- .debian:11-stable
|
||||
- .debian:12-stable
|
||||
|
||||
build-msrv:
|
||||
needs: ["build-base"]
|
||||
extends:
|
||||
- .build-final-image
|
||||
- .debian:11-msrv
|
||||
- .debian:12-msrv
|
||||
|
||||
build-nightly:
|
||||
needs: ["build-base"]
|
||||
extends:
|
||||
- .build-final-image
|
||||
- .debian:11-nightly
|
||||
- .debian:12-nightly
|
||||
|
||||
update-nightly:
|
||||
extends: build-nightly
|
||||
|
@ -192,17 +185,17 @@ update-nightly:
|
|||
|
||||
.img-stable:
|
||||
extends:
|
||||
- .debian:11-stable
|
||||
- .debian:12-stable
|
||||
- .dist-debian-container
|
||||
|
||||
.img-msrv:
|
||||
extends:
|
||||
- .debian:11-msrv
|
||||
- .debian:12-msrv
|
||||
- .dist-debian-container
|
||||
|
||||
.img-nightly:
|
||||
extends:
|
||||
- .debian:11-nightly
|
||||
- .debian:12-nightly
|
||||
- .dist-debian-container
|
||||
|
||||
# GST_PLUGINS_RS_TOKEN is a variable of type 'Var' defined in gstreamer-rs CI
|
||||
|
|
3138
Cargo.lock
generated
Normal file
3138
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,4 @@
|
|||
variables:
|
||||
GST_RS_IMG_TAG: '2023-01-26.0'
|
||||
GST_RS_STABLE: '1.67.0'
|
||||
GST_RS_IMG_TAG: '2023-03-09.1-bookworm'
|
||||
GST_RS_STABLE: '1.68.0'
|
||||
GST_RS_MSRV: '1.64.0'
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
set -e
|
||||
|
||||
pip3 install meson==1.0.0
|
||||
pip3 install meson==1.0.1 --break-system-packages
|
||||
|
||||
# gstreamer-rs already has a 'gstreamer' directory so don't clone there
|
||||
pushd .
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
set -eux
|
||||
|
||||
BRANCH=4.8.3
|
||||
BRANCH=4.10.0
|
||||
|
||||
git clone https://gitlab.gnome.org/GNOME/gtk.git --branch $BRANCH --depth=1
|
||||
cd gtk
|
||||
|
|
|
@ -5,7 +5,7 @@ source ./ci/env.sh
|
|||
set -e
|
||||
export CARGO_HOME='/usr/local/cargo'
|
||||
|
||||
RUSTUP_VERSION=1.25.1
|
||||
RUSTUP_VERSION=1.25.2
|
||||
RUST_VERSION=$1
|
||||
RUST_IMAGE_FULL=$2
|
||||
RUST_ARCH="x86_64-unknown-linux-gnu"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;
|
||||
|
||||
# Download gstreamer and all its subprojects
|
||||
git clone -b 1.0.0 --depth 1 https://code.videolan.org/videolan/dav1d.git C:\dav1d
|
||||
git clone -b 1.1.0 --depth 1 https://code.videolan.org/videolan/dav1d.git C:\dav1d
|
||||
if (!$?) {
|
||||
Write-Host "Failed to clone dav1d"
|
||||
Exit 1
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
$env:MESON_ARGS = "--prefix=C:\gst-install\"
|
||||
|
||||
# Download gtk and all its subprojects
|
||||
git clone -b 4.8.3 --depth 1 https://gitlab.gnome.org/gnome/gtk.git C:\gtk
|
||||
git clone -b 4.10.0 --depth 1 https://gitlab.gnome.org/gnome/gtk.git C:\gtk
|
||||
if (!$?) {
|
||||
Write-Host "Failed to clone gtk"
|
||||
Exit 1
|
||||
|
|
34
deny.toml
34
deny.toml
|
@ -27,9 +27,43 @@ multiple-versions = "deny"
|
|||
wildcards = "allow"
|
||||
highlight = "all"
|
||||
|
||||
# Various crates depend on an older version of windows-sys
|
||||
[[bans.skip]]
|
||||
name = "windows-sys"
|
||||
version = "0.45"
|
||||
[[bans.skip]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.42"
|
||||
[[bans.skip]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.42"
|
||||
[[bans.skip]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.42"
|
||||
[[bans.skip]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.42"
|
||||
[[bans.skip]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.42"
|
||||
[[bans.skip]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.42"
|
||||
[[bans.skip]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42"
|
||||
[[bans.skip]]
|
||||
name = "windows-targets"
|
||||
version = "0.42"
|
||||
|
||||
[sources]
|
||||
unknown-registry = "deny"
|
||||
unknown-git = "deny"
|
||||
allow-git = [
|
||||
"https://github.com/gtk-rs/gtk-rs-core",
|
||||
]
|
||||
|
||||
# Various crates depend on an older version of syn
|
||||
[[bans.skip]]
|
||||
name = "syn"
|
||||
version = "1.0"
|
||||
|
|
|
@ -1,56 +1,56 @@
|
|||
[package]
|
||||
name = "examples"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
license = "MIT"
|
||||
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
|
||||
edition = "2021"
|
||||
rust-version = "1.64"
|
||||
|
||||
[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 }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.17", version = "0.17" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer", version = "0.20" }
|
||||
gst-gl = { package = "gstreamer-gl", path = "../gstreamer-gl", version = "0.20", optional = true }
|
||||
gst-gl-egl = { package = "gstreamer-gl-egl", path = "../gstreamer-gl/egl", version = "0.20", optional = true }
|
||||
gst-gl-wayland = { package = "gstreamer-gl-wayland", path = "../gstreamer-gl/wayland", version = "0.20", 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-play = { package = "gstreamer-play", path = "../gstreamer-play", optional = true }
|
||||
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 }
|
||||
gst-allocators = { package = "gstreamer-allocators", path = "../gstreamer-allocators", 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 }
|
||||
gst-app = { package = "gstreamer-app", path = "../gstreamer-app", version = "0.20" }
|
||||
gst-audio = { package = "gstreamer-audio", path = "../gstreamer-audio", version = "0.20" }
|
||||
gst-base = { package = "gstreamer-base", path = "../gstreamer-base", version = "0.20" }
|
||||
gst-video = { package = "gstreamer-video", path = "../gstreamer-video", version = "0.20" }
|
||||
gst-pbutils = { package = "gstreamer-pbutils", path = "../gstreamer-pbutils", version = "0.20" }
|
||||
gst-play = { package = "gstreamer-play", path = "../gstreamer-play", version = "0.20", optional = true }
|
||||
gst-player = { package = "gstreamer-player", path = "../gstreamer-player", version = "0.20", optional = true }
|
||||
ges = { package = "gstreamer-editing-services", path = "../gstreamer-editing-services", version = "0.20", optional = true }
|
||||
gst-sdp = { package = "gstreamer-sdp", path = "../gstreamer-sdp", version = "0.20", optional = true }
|
||||
gst-rtsp = { package = "gstreamer-rtsp", path = "../gstreamer-rtsp", version = "0.20", optional = true }
|
||||
gst-rtsp-server = { package = "gstreamer-rtsp-server", path = "../gstreamer-rtsp-server", version = "0.20", optional = true }
|
||||
gst-allocators = { package = "gstreamer-allocators", path = "../gstreamer-allocators", version = "0.20", optional = true }
|
||||
gtk = { git = "https://github.com/gtk-rs/gtk3-rs", branch = "0.17", version = "0.17.0", optional = true }
|
||||
gdk = { git = "https://github.com/gtk-rs/gtk3-rs", branch = "0.17", version = "0.17.0", optional = true }
|
||||
gio = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.17", version = "0.17.0", 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.17", version = "0.17.0", features=["use_glib"], optional = true }
|
||||
pango = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.17", version = "0.17.0", optional = true }
|
||||
pangocairo = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.17", version = "0.17.0", optional = true }
|
||||
glutin = { version = "0.29", optional = true }
|
||||
once_cell = "1.0"
|
||||
image = { version = "0.24", optional = true }
|
||||
memmap2 = { version = "0.5", optional = true }
|
||||
image = { version = "0.24", optional = true, default-features = false, features = ["png", "jpeg"] }
|
||||
memmap2 = { version = "0.7", optional = true }
|
||||
memfd = { version = "0.6", optional = true }
|
||||
uds = { version = "0.2", optional = true }
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
windows = { version = "0.44", features=["Win32_Graphics_Direct3D11",
|
||||
windows = { version = "0.48", features=["Win32_Graphics_Direct3D11",
|
||||
"Win32_Foundation", "Win32_Graphics_Direct3D", "Win32_Graphics_Dxgi",
|
||||
"Win32_Graphics_Dxgi_Common", "Win32_Graphics_Direct2D",
|
||||
"Win32_Graphics_Direct2D_Common", "Win32_Graphics_DirectWrite",
|
||||
"Foundation_Numerics"], optional = true }
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
cocoa = "0.24"
|
||||
cocoa = "0.25"
|
||||
|
||||
[build-dependencies]
|
||||
gl_generator = { version = "0.14", optional = true }
|
||||
|
|
|
@ -133,7 +133,7 @@ fn main() -> Result<()> {
|
|||
// situation and any of failure below would mean we are doing
|
||||
// something in wrong way or driver bug or so.
|
||||
unsafe {
|
||||
let rtv = ID3D11RenderTargetView::from_raw_borrowed(&rtv_raw);
|
||||
let rtv = ID3D11RenderTargetView::from_raw_borrowed(&rtv_raw).unwrap();
|
||||
let resource = rtv.GetResource().unwrap();
|
||||
|
||||
let texture = resource.cast::<ID3D11Texture2D>().unwrap();
|
||||
|
|
|
@ -303,6 +303,12 @@ mod client {
|
|||
self.parent_closed();
|
||||
println!("Client {client:?} closed");
|
||||
}
|
||||
|
||||
fn describe_request(&self, ctx: &gst_rtsp_server::RTSPContext) {
|
||||
self.parent_describe_request(ctx);
|
||||
let request_uri = ctx.uri().unwrap().request_uri();
|
||||
println!("Describe request for uri: {request_uri:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "gstreamer-allocators"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
|
||||
categories = ["api-bindings", "multimedia"]
|
||||
description = "Rust bindings for GStreamer Allocators library"
|
||||
|
@ -16,9 +16,9 @@ rust-version = "1.64"
|
|||
[dependencies]
|
||||
libc = "0.2"
|
||||
bitflags = "1.0"
|
||||
ffi = { package = "gstreamer-allocators-sys", path = "sys" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer" }
|
||||
ffi = { package = "gstreamer-allocators-sys", path = "sys", version = "0.20" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.17", version = "0.17" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer", version = "0.20" }
|
||||
once_cell = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
|
|
|
@ -6,15 +6,20 @@ libc = "0.2"
|
|||
|
||||
[dependencies.glib]
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
package = "glib-sys"
|
||||
|
||||
[dependencies.gobject]
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
package = "gobject-sys"
|
||||
|
||||
[dependencies.gst]
|
||||
package = "gstreamer-sys"
|
||||
path = "../../gstreamer/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dev-dependencies]
|
||||
shell-words = "1.0.0"
|
||||
|
@ -43,7 +48,7 @@ name = "gstreamer-allocators-sys"
|
|||
readme = "README.md"
|
||||
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
|
||||
rust-version = "1.64"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
features = ["dox"]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "gstreamer-app"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
|
||||
categories = ["api-bindings", "multimedia"]
|
||||
description = "Rust bindings for GStreamer App library"
|
||||
|
@ -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" }
|
||||
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", path = "sys", version = "0.20" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.17", version = "0.17" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer", version = "0.20" }
|
||||
gst-base = { package = "gstreamer-base", path = "../gstreamer-base", version = "0.20" }
|
||||
once_cell = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
|
|
|
@ -1090,7 +1090,7 @@ impl AppSinkBuilder {
|
|||
|
||||
pub fn wait_on_eos(self, wait_on_eos: bool) -> Self {
|
||||
Self {
|
||||
builder: self.builder.property("wait_on_eos", wait_on_eos),
|
||||
builder: self.builder.property("wait-on-eos", wait_on_eos),
|
||||
..self
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,14 +7,18 @@ libc = "0.2"
|
|||
[dependencies.glib]
|
||||
package = "glib-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gst_base]
|
||||
package = "gstreamer-base-sys"
|
||||
path = "../../gstreamer-base/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dependencies.gst]
|
||||
package = "gstreamer-sys"
|
||||
path = "../../gstreamer/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dev-dependencies]
|
||||
shell-words = "1.0.0"
|
||||
|
@ -41,7 +45,7 @@ license = "MIT"
|
|||
name = "gstreamer-app-sys"
|
||||
readme = "README.md"
|
||||
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
edition = "2021"
|
||||
rust-version = "1.64"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "gstreamer-audio"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
|
||||
categories = ["api-bindings", "multimedia"]
|
||||
description = "Rust bindings for GStreamer Audio library"
|
||||
|
@ -17,15 +17,15 @@ rust-version = "1.64"
|
|||
libc = "0.2"
|
||||
cfg-if = "1.0"
|
||||
bitflags = "1.0"
|
||||
ffi = { package = "gstreamer-audio-sys", path = "sys" }
|
||||
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", path = "sys", version = "0.20" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.17", version = "0.17" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer", version = "0.20" }
|
||||
gst-base = { package = "gstreamer-base", path = "../gstreamer-base", version = "0.20" }
|
||||
once_cell = "1.0"
|
||||
serde = { version = "1.0", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
itertools = "0.10"
|
||||
itertools = "0.11"
|
||||
serde_json = "1.0"
|
||||
gir-format-check = "0.1"
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use std::{fmt, marker::PhantomData, mem, ops, ptr, slice};
|
||||
|
||||
use glib::translate::{from_glib, Borrowed, FromGlibPtrNone, ToGlibPtr};
|
||||
use glib::translate::{from_glib, Borrowed, ToGlibPtr};
|
||||
|
||||
pub enum Readable {}
|
||||
pub enum Writable {}
|
||||
|
@ -11,7 +11,6 @@ pub struct AudioBuffer<T> {
|
|||
// Has to be boxed because it contains self-references
|
||||
audio_buffer: Box<ffi::GstAudioBuffer>,
|
||||
buffer: gst::Buffer,
|
||||
info: crate::AudioInfo,
|
||||
phantom: PhantomData<T>,
|
||||
}
|
||||
|
||||
|
@ -21,10 +20,10 @@ unsafe impl<T> Sync for AudioBuffer<T> {}
|
|||
impl<T> fmt::Debug for AudioBuffer<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("AudioBuffer")
|
||||
.field("audio_buffer", &self.audio_buffer)
|
||||
.field("buffer", &self.buffer)
|
||||
.field("info", &self.info)
|
||||
.field("phantom", &self.phantom)
|
||||
.field("n_samples", &self.n_samples())
|
||||
.field("n_planes", &self.n_planes())
|
||||
.field("buffer", &self.buffer())
|
||||
.field("info", &self.info())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
@ -32,12 +31,21 @@ impl<T> fmt::Debug for AudioBuffer<T> {
|
|||
impl<T> AudioBuffer<T> {
|
||||
#[inline]
|
||||
pub fn info(&self) -> &crate::AudioInfo {
|
||||
&self.info
|
||||
unsafe {
|
||||
&*(&self.audio_buffer.info as *const ffi::GstAudioInfo as *const crate::AudioInfo)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn into_buffer(self) -> gst::Buffer {
|
||||
unsafe { ptr::read(&mem::ManuallyDrop::new(self).buffer) }
|
||||
unsafe {
|
||||
let mut s = mem::ManuallyDrop::new(self);
|
||||
let buffer = ptr::read(&s.buffer);
|
||||
ffi::gst_audio_buffer_unmap(&mut *s.audio_buffer);
|
||||
ptr::drop_in_place(&mut s.audio_buffer);
|
||||
|
||||
buffer
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -128,10 +136,8 @@ impl<T> AudioBuffer<T> {
|
|||
|
||||
#[inline]
|
||||
pub fn as_audio_buffer_ref(&self) -> AudioBufferRef<&gst::BufferRef> {
|
||||
let info = self.info.clone();
|
||||
AudioBufferRef {
|
||||
audio_buffer: AudioBufferPtr::Borrowed(ptr::NonNull::from(&*self.audio_buffer)),
|
||||
info,
|
||||
unmap: false,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
|
@ -174,13 +180,9 @@ impl AudioBuffer<Readable> {
|
|||
if !res {
|
||||
Err(buffer)
|
||||
} else {
|
||||
let info = crate::AudioInfo::from_glib_none(
|
||||
&audio_buffer.info as *const _ as *mut ffi::GstAudioInfo,
|
||||
);
|
||||
Ok(Self {
|
||||
audio_buffer,
|
||||
buffer,
|
||||
info,
|
||||
phantom: PhantomData,
|
||||
})
|
||||
}
|
||||
|
@ -210,13 +212,9 @@ impl AudioBuffer<Writable> {
|
|||
if !res {
|
||||
Err(buffer)
|
||||
} else {
|
||||
let info = crate::AudioInfo::from_glib_none(
|
||||
&audio_buffer.info as *const _ as *mut ffi::GstAudioInfo,
|
||||
);
|
||||
Ok(Self {
|
||||
audio_buffer,
|
||||
buffer,
|
||||
info,
|
||||
phantom: PhantomData,
|
||||
})
|
||||
}
|
||||
|
@ -245,10 +243,8 @@ impl AudioBuffer<Writable> {
|
|||
|
||||
#[inline]
|
||||
pub fn as_mut_audio_buffer_ref(&mut self) -> AudioBufferRef<&mut gst::BufferRef> {
|
||||
let info = self.info.clone();
|
||||
AudioBufferRef {
|
||||
audio_buffer: AudioBufferPtr::Borrowed(ptr::NonNull::from(&mut *self.audio_buffer)),
|
||||
info,
|
||||
unmap: false,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
|
@ -288,19 +284,32 @@ impl ops::DerefMut for AudioBufferPtr {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct AudioBufferRef<T> {
|
||||
// Has to be boxed because it contains self-references
|
||||
audio_buffer: AudioBufferPtr,
|
||||
info: crate::AudioInfo,
|
||||
unmap: bool,
|
||||
phantom: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T> fmt::Debug for AudioBufferRef<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("AudioBufferRef")
|
||||
.field("n_samples", &self.n_samples())
|
||||
.field("n_planes", &self.n_planes())
|
||||
.field("buffer", &unsafe {
|
||||
gst::BufferRef::from_ptr(self.audio_buffer.buffer)
|
||||
})
|
||||
.field("info", &self.info())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> AudioBufferRef<T> {
|
||||
#[inline]
|
||||
pub fn info(&self) -> &crate::AudioInfo {
|
||||
&self.info
|
||||
unsafe {
|
||||
&*(&self.audio_buffer.info as *const ffi::GstAudioInfo as *const crate::AudioInfo)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -399,14 +408,10 @@ impl<'a> AudioBufferRef<&'a gst::BufferRef> {
|
|||
pub unsafe fn from_glib_borrow(audio_buffer: *const ffi::GstAudioBuffer) -> Borrowed<Self> {
|
||||
debug_assert!(!audio_buffer.is_null());
|
||||
|
||||
let info = crate::AudioInfo::from_glib_none(
|
||||
&(*audio_buffer).info as *const _ as *mut ffi::GstAudioInfo,
|
||||
);
|
||||
Borrowed::new(Self {
|
||||
audio_buffer: AudioBufferPtr::Borrowed(ptr::NonNull::new_unchecked(
|
||||
audio_buffer as *mut _,
|
||||
)),
|
||||
info,
|
||||
unmap: false,
|
||||
phantom: PhantomData,
|
||||
})
|
||||
|
@ -433,12 +438,8 @@ impl<'a> AudioBufferRef<&'a gst::BufferRef> {
|
|||
if !res {
|
||||
Err(glib::bool_error!("Failed to map AudioBuffer"))
|
||||
} else {
|
||||
let info = crate::AudioInfo::from_glib_none(
|
||||
&audio_buffer.info as *const _ as *mut ffi::GstAudioInfo,
|
||||
);
|
||||
Ok(Self {
|
||||
audio_buffer: AudioBufferPtr::Owned(audio_buffer),
|
||||
info,
|
||||
unmap: true,
|
||||
phantom: PhantomData,
|
||||
})
|
||||
|
@ -457,12 +458,8 @@ impl<'a> AudioBufferRef<&'a mut gst::BufferRef> {
|
|||
pub unsafe fn from_glib_borrow_mut(audio_buffer: *mut ffi::GstAudioBuffer) -> Borrowed<Self> {
|
||||
debug_assert!(!audio_buffer.is_null());
|
||||
|
||||
let info = crate::AudioInfo::from_glib_none(
|
||||
&(*audio_buffer).info as *const _ as *mut ffi::GstAudioInfo,
|
||||
);
|
||||
Borrowed::new(Self {
|
||||
audio_buffer: AudioBufferPtr::Borrowed(ptr::NonNull::new_unchecked(audio_buffer)),
|
||||
info,
|
||||
unmap: false,
|
||||
phantom: PhantomData,
|
||||
})
|
||||
|
@ -489,12 +486,8 @@ impl<'a> AudioBufferRef<&'a mut gst::BufferRef> {
|
|||
if !res {
|
||||
Err(glib::bool_error!("Failed to map AudioBuffer"))
|
||||
} else {
|
||||
let info = crate::AudioInfo::from_glib_none(
|
||||
&audio_buffer.info as *const _ as *mut ffi::GstAudioInfo,
|
||||
);
|
||||
Ok(Self {
|
||||
audio_buffer: AudioBufferPtr::Owned(audio_buffer),
|
||||
info,
|
||||
unmap: true,
|
||||
phantom: PhantomData,
|
||||
})
|
||||
|
|
|
@ -9,6 +9,7 @@ use gst::prelude::*;
|
|||
|
||||
#[doc(alias = "GstAudioInfo")]
|
||||
#[derive(Clone)]
|
||||
#[repr(transparent)]
|
||||
pub struct AudioInfo(ffi::GstAudioInfo);
|
||||
|
||||
impl fmt::Debug for AudioInfo {
|
||||
|
|
|
@ -11,7 +11,19 @@ pub struct AudioCapsBuilder<T> {
|
|||
}
|
||||
|
||||
impl AudioCapsBuilder<gst::caps::NoFeature> {
|
||||
// rustdoc-stripper-ignore-next
|
||||
/// Constructs an `AudioCapsBuilder` for the "audio/x-raw" encoding.
|
||||
///
|
||||
/// If left unchanged, the resulting `Caps` will be initialized with:
|
||||
/// - "audio/x-raw" encoding.
|
||||
/// - maximum rate range.
|
||||
/// - maximum channels range.
|
||||
/// - both interleaved and non-interleaved layouts.
|
||||
/// - all available formats.
|
||||
///
|
||||
/// Use [`AudioCapsBuilder::for_encoding`] to specify another encoding.
|
||||
pub fn new() -> Self {
|
||||
assert_initialized_main_thread!();
|
||||
let builder = Caps::builder(glib::gstr!("audio/x-raw"));
|
||||
let builder = AudioCapsBuilder { builder };
|
||||
builder
|
||||
|
@ -21,10 +33,34 @@ impl AudioCapsBuilder<gst::caps::NoFeature> {
|
|||
.format_list(AudioFormat::iter_raw())
|
||||
}
|
||||
|
||||
// rustdoc-stripper-ignore-next
|
||||
/// Constructs an `AudioCapsBuilder` for the "audio/x-raw" encoding
|
||||
/// with interleaved layout.
|
||||
///
|
||||
/// If left unchanged, the resulting `Caps` will be initialized with:
|
||||
/// - "audio/x-raw" encoding.
|
||||
/// - maximum rate range.
|
||||
/// - maximum channels range.
|
||||
/// - interleaved layout.
|
||||
/// - all available formats.
|
||||
///
|
||||
/// Use [`AudioCapsBuilder::for_encoding`] to specify another encoding.
|
||||
pub fn new_interleaved() -> Self {
|
||||
AudioCapsBuilder::new().layout(AudioLayout::Interleaved)
|
||||
}
|
||||
|
||||
// rustdoc-stripper-ignore-next
|
||||
/// Constructs an `AudioCapsBuilder` for the specified encoding.
|
||||
///
|
||||
/// The resulting `Caps` will use the `encoding` argument as name
|
||||
/// and will not contain any additional fields unless explicitly added.
|
||||
pub fn for_encoding(encoding: impl IntoGStr) -> Self {
|
||||
assert_initialized_main_thread!();
|
||||
AudioCapsBuilder {
|
||||
builder: Caps::builder(encoding),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn any_features(self) -> AudioCapsBuilder<gst::caps::HasFeatures> {
|
||||
AudioCapsBuilder {
|
||||
builder: self.builder.any_features(),
|
||||
|
@ -180,3 +216,22 @@ fn layout_str(layout: AudioLayout) -> &'static glib::GStr {
|
|||
crate::AudioLayout::__Unknown(_) => glib::gstr!("unknown"),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::AudioCapsBuilder;
|
||||
|
||||
#[test]
|
||||
fn default_encoding() {
|
||||
gst::init().unwrap();
|
||||
let caps = AudioCapsBuilder::new().build();
|
||||
assert_eq!(caps.structure(0).unwrap().name(), "audio/x-raw");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn explicit_encoding() {
|
||||
gst::init().unwrap();
|
||||
let caps = AudioCapsBuilder::for_encoding("audio/mpeg").build();
|
||||
assert_eq!(caps.structure(0).unwrap().name(), "audio/mpeg");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,18 +7,24 @@ libc = "0.2"
|
|||
[dependencies.glib]
|
||||
package = "glib-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gobject]
|
||||
package = "gobject-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gst_base]
|
||||
package = "gstreamer-base-sys"
|
||||
path = "../../gstreamer-base/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dependencies.gst]
|
||||
package = "gstreamer-sys"
|
||||
path = "../../gstreamer/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dev-dependencies]
|
||||
shell-words = "1.0.0"
|
||||
|
@ -45,7 +51,7 @@ license = "MIT"
|
|||
name = "gstreamer-audio-sys"
|
||||
readme = "README.md"
|
||||
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
edition = "2021"
|
||||
rust-version = "1.64"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "gstreamer-base"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
|
||||
categories = ["api-bindings", "multimedia"]
|
||||
description = "Rust bindings for GStreamer Base library"
|
||||
|
@ -17,10 +17,11 @@ rust-version = "1.64"
|
|||
cfg-if = "1.0"
|
||||
libc = "0.2"
|
||||
bitflags = "1.0"
|
||||
ffi = { package = "gstreamer-base-sys", path = "sys" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer" }
|
||||
ffi = { package = "gstreamer-base-sys", path = "sys", version = "0.20" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.17", version = "0.17" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer", version = "0.20" }
|
||||
atomic_refcell = "0.1"
|
||||
once_cell = "1"
|
||||
|
||||
[dev-dependencies]
|
||||
gir-format-check = "0.1"
|
||||
|
|
|
@ -104,7 +104,7 @@ impl<O: IsA<Aggregator>> AggregatorExtManual for O {
|
|||
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_16")))]
|
||||
fn set_min_upstream_latency(&self, min_upstream_latency: gst::ClockTime) {
|
||||
self.as_ref()
|
||||
.set_property("min-upstream-latency", &min_upstream_latency);
|
||||
.set_property("min-upstream-latency", min_upstream_latency);
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "v1_16", feature = "dox"))]
|
||||
|
|
|
@ -570,6 +570,13 @@ impl<T: BaseTransformImpl> BaseTransformImplExt for T {
|
|||
PrepareOutputBufferSuccess::Buffer(from_glib_full(outbuf))
|
||||
}
|
||||
})
|
||||
.map_err(|err| {
|
||||
if outbuf != buf as *mut _ {
|
||||
drop(Option::<gst::Buffer>::from_glib_full(outbuf));
|
||||
}
|
||||
|
||||
err
|
||||
})
|
||||
})
|
||||
.unwrap_or(Err(gst::FlowError::NotSupported))
|
||||
}
|
||||
|
@ -828,21 +835,20 @@ impl<T: BaseTransformImpl> BaseTransformImplExt for T {
|
|||
.expect("Missing parent function `generate_output`");
|
||||
|
||||
let mut outbuf = ptr::null_mut();
|
||||
gst::FlowSuccess::try_from_glib(f(
|
||||
let res = gst::FlowSuccess::try_from_glib(f(
|
||||
self.obj()
|
||||
.unsafe_cast_ref::<BaseTransform>()
|
||||
.to_glib_none()
|
||||
.0,
|
||||
&mut outbuf,
|
||||
))
|
||||
.map(|res| {
|
||||
if res == crate::BASE_TRANSFORM_FLOW_DROPPED {
|
||||
GenerateOutputSuccess::Dropped
|
||||
} else if res != gst::FlowSuccess::Ok || outbuf.is_null() {
|
||||
GenerateOutputSuccess::NoOutput
|
||||
} else {
|
||||
GenerateOutputSuccess::Buffer(from_glib_full(outbuf))
|
||||
}
|
||||
));
|
||||
|
||||
let outbuf = Option::<gst::Buffer>::from_glib_full(outbuf);
|
||||
|
||||
res.map(move |res| match (res, outbuf) {
|
||||
(crate::BASE_TRANSFORM_FLOW_DROPPED, _) => GenerateOutputSuccess::Dropped,
|
||||
(gst::FlowSuccess::Ok, Some(outbuf)) => GenerateOutputSuccess::Buffer(outbuf),
|
||||
_ => GenerateOutputSuccess::NoOutput,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1141,6 +1147,8 @@ unsafe extern "C" fn base_transform_prepare_output_buffer<T: BaseTransformImpl>(
|
|||
true => InputBuffer::Writable(gst::BufferRef::from_mut_ptr(inbuf)),
|
||||
};
|
||||
|
||||
*outbuf = ptr::null_mut();
|
||||
|
||||
gst::panic_to_error!(imp, gst::FlowReturn::Error, {
|
||||
match imp.prepare_output_buffer(buffer) {
|
||||
Ok(PrepareOutputBufferSuccess::InputBuffer) => {
|
||||
|
@ -1378,3 +1386,133 @@ unsafe extern "C" fn base_transform_generate_output<T: BaseTransformImpl>(
|
|||
})
|
||||
.into_glib()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
pub mod imp {
|
||||
use super::*;
|
||||
use std::sync::atomic::{self, AtomicBool};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct TestTransform {
|
||||
drop_next: AtomicBool,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
impl ObjectSubclass for TestTransform {
|
||||
const NAME: &'static str = "TestTransform";
|
||||
type Type = super::TestTransform;
|
||||
type ParentType = crate::BaseTransform;
|
||||
}
|
||||
|
||||
impl ObjectImpl for TestTransform {}
|
||||
|
||||
impl GstObjectImpl for TestTransform {}
|
||||
|
||||
impl ElementImpl for TestTransform {
|
||||
fn metadata() -> Option<&'static gst::subclass::ElementMetadata> {
|
||||
use once_cell::sync::Lazy;
|
||||
static ELEMENT_METADATA: Lazy<gst::subclass::ElementMetadata> = Lazy::new(|| {
|
||||
gst::subclass::ElementMetadata::new(
|
||||
"Test Transform",
|
||||
"Generic",
|
||||
"Does nothing",
|
||||
"Sebastian Dröge <sebastian@centricular.com>",
|
||||
)
|
||||
});
|
||||
|
||||
Some(&*ELEMENT_METADATA)
|
||||
}
|
||||
|
||||
fn pad_templates() -> &'static [gst::PadTemplate] {
|
||||
use once_cell::sync::Lazy;
|
||||
static PAD_TEMPLATES: Lazy<Vec<gst::PadTemplate>> = Lazy::new(|| {
|
||||
let caps = gst::Caps::new_any();
|
||||
vec![
|
||||
gst::PadTemplate::new(
|
||||
"src",
|
||||
gst::PadDirection::Src,
|
||||
gst::PadPresence::Always,
|
||||
&caps,
|
||||
)
|
||||
.unwrap(),
|
||||
gst::PadTemplate::new(
|
||||
"sink",
|
||||
gst::PadDirection::Sink,
|
||||
gst::PadPresence::Always,
|
||||
&caps,
|
||||
)
|
||||
.unwrap(),
|
||||
]
|
||||
});
|
||||
|
||||
PAD_TEMPLATES.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl BaseTransformImpl for TestTransform {
|
||||
const MODE: BaseTransformMode = BaseTransformMode::AlwaysInPlace;
|
||||
|
||||
const PASSTHROUGH_ON_SAME_CAPS: bool = false;
|
||||
|
||||
const TRANSFORM_IP_ON_PASSTHROUGH: bool = false;
|
||||
|
||||
fn transform_ip(
|
||||
&self,
|
||||
_buf: &mut gst::BufferRef,
|
||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||
if self.drop_next.load(atomic::Ordering::SeqCst) {
|
||||
self.drop_next.store(false, atomic::Ordering::SeqCst);
|
||||
Ok(crate::BASE_TRANSFORM_FLOW_DROPPED)
|
||||
} else {
|
||||
self.drop_next.store(true, atomic::Ordering::SeqCst);
|
||||
Ok(gst::FlowSuccess::Ok)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glib::wrapper! {
|
||||
pub struct TestTransform(ObjectSubclass<imp::TestTransform>) @extends crate::BaseTransform, gst::Element, gst::Object;
|
||||
}
|
||||
|
||||
impl TestTransform {
|
||||
pub fn new(name: Option<&str>) -> Self {
|
||||
glib::Object::builder().property("name", name).build()
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_transform_subclass() {
|
||||
gst::init().unwrap();
|
||||
|
||||
let element = TestTransform::new(Some("test"));
|
||||
|
||||
assert_eq!(element.name(), "test");
|
||||
|
||||
let pipeline = gst::Pipeline::default();
|
||||
let src = gst::ElementFactory::make("audiotestsrc")
|
||||
.property("num-buffers", 100i32)
|
||||
.build()
|
||||
.unwrap();
|
||||
let sink = gst::ElementFactory::make("fakesink").build().unwrap();
|
||||
|
||||
pipeline
|
||||
.add_many(&[&src, element.upcast_ref(), &sink])
|
||||
.unwrap();
|
||||
gst::Element::link_many(&[&src, element.upcast_ref(), &sink]).unwrap();
|
||||
|
||||
pipeline.set_state(gst::State::Playing).unwrap();
|
||||
let bus = pipeline.bus().unwrap();
|
||||
|
||||
let eos = bus.timed_pop_filtered(gst::ClockTime::NONE, &[gst::MessageType::Eos]);
|
||||
assert!(eos.is_some());
|
||||
|
||||
let stats = sink.property::<gst::Structure>("stats");
|
||||
assert_eq!(stats.get::<u64>("rendered").unwrap(), 50);
|
||||
|
||||
pipeline.set_state(gst::State::Null).unwrap();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,14 +7,19 @@ libc = "0.2"
|
|||
[dependencies.glib]
|
||||
package = "glib-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gobject]
|
||||
package = "gobject-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gst]
|
||||
package = "gstreamer-sys"
|
||||
path = "../../gstreamer/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dev-dependencies]
|
||||
shell-words = "1.0.0"
|
||||
|
@ -43,7 +48,7 @@ license = "MIT"
|
|||
name = "gstreamer-base-sys"
|
||||
readme = "README.md"
|
||||
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
edition = "2021"
|
||||
rust-version = "1.64"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "gstreamer-check"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
|
||||
categories = ["api-bindings", "multimedia"]
|
||||
description = "Rust bindings for GStreamer Check library"
|
||||
|
@ -15,9 +15,9 @@ rust-version = "1.64"
|
|||
|
||||
[dependencies]
|
||||
bitflags = "1.0"
|
||||
ffi = { package = "gstreamer-check-sys", path = "sys" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer" }
|
||||
ffi = { package = "gstreamer-check-sys", path = "sys", version = "0.20" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.17", version = "0.17" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer", version = "0.20" }
|
||||
|
||||
[dev-dependencies]
|
||||
gir-format-check = "0.1"
|
||||
|
|
|
@ -7,14 +7,19 @@ libc = "0.2"
|
|||
[dependencies.glib]
|
||||
package = "glib-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gobject]
|
||||
package = "gobject-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gst]
|
||||
package = "gstreamer-sys"
|
||||
path = "../../gstreamer/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dev-dependencies]
|
||||
shell-words = "1.0.0"
|
||||
|
@ -41,7 +46,7 @@ license = "MIT"
|
|||
name = "gstreamer-check-sys"
|
||||
readme = "README.md"
|
||||
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
edition = "2021"
|
||||
rust-version = "1.64"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "gstreamer-controller"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
authors = ["Alexey Galakhov <agalakhov@gmail.com>", "Sebastian Dröge <sebastian@centricular.com>"]
|
||||
categories = ["api-bindings", "multimedia"]
|
||||
description = "Rust bindings for GStreamer Controller library"
|
||||
|
@ -16,9 +16,9 @@ rust-version = "1.64"
|
|||
[dependencies]
|
||||
bitflags = "1.0"
|
||||
once_cell = "1.0"
|
||||
ffi = { package = "gstreamer-controller-sys", path = "sys" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer" }
|
||||
ffi = { package = "gstreamer-controller-sys", path = "sys", version = "0.20" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.17", version = "0.17" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer", version = "0.20" }
|
||||
|
||||
[dev-dependencies]
|
||||
gir-format-check = "0.1"
|
||||
|
|
|
@ -8,14 +8,19 @@ libc = "0.2"
|
|||
[dependencies.glib]
|
||||
package = "glib-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gobject]
|
||||
package = "gobject-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gst]
|
||||
package = "gstreamer-sys"
|
||||
path = "../../gstreamer/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dev-dependencies]
|
||||
shell-words = "1.0.0"
|
||||
|
@ -42,7 +47,7 @@ license = "MIT"
|
|||
name = "gstreamer-controller-sys"
|
||||
readme = "README.md"
|
||||
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
edition = "2021"
|
||||
rust-version = "1.64"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "gstreamer-editing-services"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
authors = ["Thibault Saunier <tsaunier@igalia.com>", "Sebastian Dröge <sebastian@centricular.com>"]
|
||||
categories = ["api-bindings", "multimedia"]
|
||||
description = "Rust bindings for GStreamer Editing Services"
|
||||
|
@ -16,12 +16,12 @@ rust-version = "1.64"
|
|||
[dependencies]
|
||||
libc = "0.2"
|
||||
bitflags = "1.0"
|
||||
ffi = { package = "gstreamer-editing-services-sys", path = "sys"}
|
||||
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", path = "sys", version = "0.20"}
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.17", version = "0.17" }
|
||||
gio = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.17", version = "0.17" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer", version = "0.20" }
|
||||
gst-base = { package = "gstreamer-base", path = "../gstreamer-base", version = "0.20" }
|
||||
gst-pbutils = { package = "gstreamer-pbutils", path = "../gstreamer-pbutils", version = "0.20" }
|
||||
serde = { version = "1.0", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
|
|
|
@ -59,11 +59,9 @@ generate = [
|
|||
"GES.BaseTransitionClip",
|
||||
"GES.BaseXmlFormatter",
|
||||
"GES.ChildrenControlMode",
|
||||
"GES.ClipAsset",
|
||||
"GES.CommandLineFormatter",
|
||||
"GES.Edge",
|
||||
"GES.EditMode",
|
||||
"GES.EffectAsset",
|
||||
"GES.EffectClip",
|
||||
"GES.Error",
|
||||
"GES.ExtractableCheckId",
|
||||
|
@ -83,7 +81,6 @@ generate = [
|
|||
"GES.PipelineFlags",
|
||||
"GES.Source",
|
||||
"GES.SourceClip",
|
||||
"GES.SourceClipAsset",
|
||||
"GES.TestClip",
|
||||
"GES.TextHAlign",
|
||||
"GES.TextOverlay",
|
||||
|
@ -91,12 +88,9 @@ generate = [
|
|||
"GES.TextVAlign",
|
||||
"GES.TitleClip",
|
||||
"GES.TitleSource",
|
||||
"GES.TrackElementAsset",
|
||||
"GES.TrackType",
|
||||
"GES.Transition",
|
||||
"GES.TransitionClip",
|
||||
"GES.UriClipAsset",
|
||||
"GES.UriSourceAsset",
|
||||
"GES.VideoSource",
|
||||
"GES.VideoStandardTransitionType",
|
||||
"GES.VideoTestPattern",
|
||||
|
@ -110,6 +104,7 @@ generate = [
|
|||
[[object]]
|
||||
name = "GES.Asset"
|
||||
status = "generate"
|
||||
concurrency = "send+sync"
|
||||
[[object.function]]
|
||||
name = "set_proxy"
|
||||
[object.function.return]
|
||||
|
@ -161,6 +156,11 @@ status = "generate"
|
|||
[object.function.return]
|
||||
nullable_return_is_error = "Failed to split clip"
|
||||
|
||||
[[object]]
|
||||
name = "GES.ClipAsset"
|
||||
status = "generate"
|
||||
concurrency = "send+sync"
|
||||
|
||||
[[object]]
|
||||
name = "GES.Container"
|
||||
status = "generate"
|
||||
|
@ -188,6 +188,11 @@ status = "generate"
|
|||
[object.function.return]
|
||||
nullable_return_is_error = "Failed to create effect from description"
|
||||
|
||||
[[object]]
|
||||
name = "GES.EffectAsset"
|
||||
status = "generate"
|
||||
concurrency = "send+sync"
|
||||
|
||||
[[object]]
|
||||
name = "GES.Extractable"
|
||||
status = "generate"
|
||||
|
@ -256,6 +261,11 @@ status = "generate"
|
|||
[object.function.return]
|
||||
bool_return_is_error = "Failed to remove asset"
|
||||
|
||||
[[object]]
|
||||
name = "GES.SourceClipAsset"
|
||||
status = "generate"
|
||||
concurrency = "send+sync"
|
||||
|
||||
[[object]]
|
||||
name = "GES.Timeline"
|
||||
status = "generate"
|
||||
|
@ -462,6 +472,11 @@ status = "generate"
|
|||
name = "value"
|
||||
const = true
|
||||
|
||||
[[object]]
|
||||
name = "GES.TrackElementAsset"
|
||||
status = "generate"
|
||||
concurrency = "send+sync"
|
||||
|
||||
[[object]]
|
||||
name = "GES.UriClip"
|
||||
status = "generate"
|
||||
|
@ -470,6 +485,16 @@ status = "generate"
|
|||
[object.function.return]
|
||||
nullable_return_is_error = "Failed to create Uri clip from Uri"
|
||||
|
||||
[[object]]
|
||||
name = "GES.UriClipAsset"
|
||||
status = "generate"
|
||||
concurrency = "send+sync"
|
||||
|
||||
[[object]]
|
||||
name = "GES.UriSourceAsset"
|
||||
status = "generate"
|
||||
concurrency = "send+sync"
|
||||
|
||||
[[object]]
|
||||
name = "Gst.Buffer"
|
||||
status = "manual"
|
||||
|
|
|
@ -126,6 +126,9 @@ impl Asset {
|
|||
}
|
||||
}
|
||||
|
||||
unsafe impl Send for Asset {}
|
||||
unsafe impl Sync for Asset {}
|
||||
|
||||
pub trait AssetExt: 'static {
|
||||
#[doc(alias = "ges_asset_extract")]
|
||||
fn extract(&self) -> Result<Extractable, glib::Error>;
|
||||
|
@ -162,10 +165,13 @@ pub trait AssetExt: 'static {
|
|||
fn unproxy(&self, proxy: &impl IsA<Asset>) -> Result<(), glib::error::BoolError>;
|
||||
|
||||
#[doc(alias = "proxy")]
|
||||
fn connect_proxy_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
|
||||
fn connect_proxy_notify<F: Fn(&Self) + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId;
|
||||
|
||||
#[doc(alias = "proxy-target")]
|
||||
fn connect_proxy_target_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
|
||||
fn connect_proxy_target_notify<F: Fn(&Self) + Send + Sync + 'static>(
|
||||
&self,
|
||||
f: F,
|
||||
) -> SignalHandlerId;
|
||||
}
|
||||
|
||||
impl<O: IsA<Asset>> AssetExt for O {
|
||||
|
@ -241,8 +247,11 @@ impl<O: IsA<Asset>> AssetExt for O {
|
|||
}
|
||||
}
|
||||
|
||||
fn connect_proxy_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
|
||||
unsafe extern "C" fn notify_proxy_trampoline<P: IsA<Asset>, F: Fn(&P) + 'static>(
|
||||
fn connect_proxy_notify<F: Fn(&Self) + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId {
|
||||
unsafe extern "C" fn notify_proxy_trampoline<
|
||||
P: IsA<Asset>,
|
||||
F: Fn(&P) + Send + Sync + 'static,
|
||||
>(
|
||||
this: *mut ffi::GESAsset,
|
||||
_param_spec: glib::ffi::gpointer,
|
||||
f: glib::ffi::gpointer,
|
||||
|
@ -263,8 +272,14 @@ impl<O: IsA<Asset>> AssetExt for O {
|
|||
}
|
||||
}
|
||||
|
||||
fn connect_proxy_target_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
|
||||
unsafe extern "C" fn notify_proxy_target_trampoline<P: IsA<Asset>, F: Fn(&P) + 'static>(
|
||||
fn connect_proxy_target_notify<F: Fn(&Self) + Send + Sync + 'static>(
|
||||
&self,
|
||||
f: F,
|
||||
) -> SignalHandlerId {
|
||||
unsafe extern "C" fn notify_proxy_target_trampoline<
|
||||
P: IsA<Asset>,
|
||||
F: Fn(&P) + Send + Sync + 'static,
|
||||
>(
|
||||
this: *mut ffi::GESAsset,
|
||||
_param_spec: glib::ffi::gpointer,
|
||||
f: glib::ffi::gpointer,
|
||||
|
|
|
@ -30,6 +30,9 @@ impl ClipAsset {
|
|||
pub const NONE: Option<&'static ClipAsset> = None;
|
||||
}
|
||||
|
||||
unsafe impl Send for ClipAsset {}
|
||||
unsafe impl Sync for ClipAsset {}
|
||||
|
||||
pub trait ClipAssetExt: 'static {
|
||||
#[cfg(any(feature = "v1_18", feature = "dox"))]
|
||||
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))]
|
||||
|
@ -51,7 +54,10 @@ pub trait ClipAssetExt: 'static {
|
|||
fn set_supported_formats(&self, supportedformats: TrackType);
|
||||
|
||||
#[doc(alias = "supported-formats")]
|
||||
fn connect_supported_formats_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
|
||||
fn connect_supported_formats_notify<F: Fn(&Self) + Send + Sync + 'static>(
|
||||
&self,
|
||||
f: F,
|
||||
) -> SignalHandlerId;
|
||||
}
|
||||
|
||||
impl<O: IsA<ClipAsset>> ClipAssetExt for O {
|
||||
|
@ -102,10 +108,13 @@ impl<O: IsA<ClipAsset>> ClipAssetExt for O {
|
|||
}
|
||||
}
|
||||
|
||||
fn connect_supported_formats_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
|
||||
fn connect_supported_formats_notify<F: Fn(&Self) + Send + Sync + 'static>(
|
||||
&self,
|
||||
f: F,
|
||||
) -> SignalHandlerId {
|
||||
unsafe extern "C" fn notify_supported_formats_trampoline<
|
||||
P: IsA<ClipAsset>,
|
||||
F: Fn(&P) + 'static,
|
||||
F: Fn(&P) + Send + Sync + 'static,
|
||||
>(
|
||||
this: *mut ffi::GESClipAsset,
|
||||
_param_spec: glib::ffi::gpointer,
|
||||
|
|
|
@ -17,3 +17,6 @@ glib::wrapper! {
|
|||
impl EffectAsset {
|
||||
pub const NONE: Option<&'static EffectAsset> = None;
|
||||
}
|
||||
|
||||
unsafe impl Send for EffectAsset {}
|
||||
unsafe impl Sync for EffectAsset {}
|
||||
|
|
|
@ -17,3 +17,6 @@ glib::wrapper! {
|
|||
impl SourceClipAsset {
|
||||
pub const NONE: Option<&'static SourceClipAsset> = None;
|
||||
}
|
||||
|
||||
unsafe impl Send for SourceClipAsset {}
|
||||
unsafe impl Sync for SourceClipAsset {}
|
||||
|
|
|
@ -27,6 +27,9 @@ impl TrackElementAsset {
|
|||
pub const NONE: Option<&'static TrackElementAsset> = None;
|
||||
}
|
||||
|
||||
unsafe impl Send for TrackElementAsset {}
|
||||
unsafe impl Sync for TrackElementAsset {}
|
||||
|
||||
pub trait TrackElementAssetExt: 'static {
|
||||
#[cfg(any(feature = "v1_18", feature = "dox"))]
|
||||
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))]
|
||||
|
@ -42,7 +45,10 @@ pub trait TrackElementAssetExt: 'static {
|
|||
fn set_track_type(&self, type_: TrackType);
|
||||
|
||||
#[doc(alias = "track-type")]
|
||||
fn connect_track_type_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
|
||||
fn connect_track_type_notify<F: Fn(&Self) + Send + Sync + 'static>(
|
||||
&self,
|
||||
f: F,
|
||||
) -> SignalHandlerId;
|
||||
}
|
||||
|
||||
impl<O: IsA<TrackElementAsset>> TrackElementAssetExt for O {
|
||||
|
@ -82,10 +88,13 @@ impl<O: IsA<TrackElementAsset>> TrackElementAssetExt for O {
|
|||
}
|
||||
}
|
||||
|
||||
fn connect_track_type_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
|
||||
fn connect_track_type_notify<F: Fn(&Self) + Send + Sync + 'static>(
|
||||
&self,
|
||||
f: F,
|
||||
) -> SignalHandlerId {
|
||||
unsafe extern "C" fn notify_track_type_trampoline<
|
||||
P: IsA<TrackElementAsset>,
|
||||
F: Fn(&P) + 'static,
|
||||
F: Fn(&P) + Send + Sync + 'static,
|
||||
>(
|
||||
this: *mut ffi::GESTrackElementAsset,
|
||||
_param_spec: glib::ffi::gpointer,
|
||||
|
|
|
@ -65,6 +65,9 @@ impl UriClipAsset {
|
|||
}
|
||||
}
|
||||
|
||||
unsafe impl Send for UriClipAsset {}
|
||||
unsafe impl Sync for UriClipAsset {}
|
||||
|
||||
pub trait UriClipAssetExt: 'static {
|
||||
#[doc(alias = "ges_uri_clip_asset_get_duration")]
|
||||
#[doc(alias = "get_duration")]
|
||||
|
@ -97,12 +100,18 @@ pub trait UriClipAssetExt: 'static {
|
|||
fn is_nested_timeline(&self) -> bool;
|
||||
|
||||
#[doc(alias = "duration")]
|
||||
fn connect_duration_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
|
||||
fn connect_duration_notify<F: Fn(&Self) + Send + Sync + 'static>(
|
||||
&self,
|
||||
f: F,
|
||||
) -> SignalHandlerId;
|
||||
|
||||
#[cfg(any(feature = "v1_18", feature = "dox"))]
|
||||
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))]
|
||||
#[doc(alias = "is-nested-timeline")]
|
||||
fn connect_is_nested_timeline_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
|
||||
fn connect_is_nested_timeline_notify<F: Fn(&Self) + Send + Sync + 'static>(
|
||||
&self,
|
||||
f: F,
|
||||
) -> SignalHandlerId;
|
||||
}
|
||||
|
||||
impl<O: IsA<UriClipAsset>> UriClipAssetExt for O {
|
||||
|
@ -160,10 +169,13 @@ impl<O: IsA<UriClipAsset>> UriClipAssetExt for O {
|
|||
glib::ObjectExt::property(self.as_ref(), "is-nested-timeline")
|
||||
}
|
||||
|
||||
fn connect_duration_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
|
||||
fn connect_duration_notify<F: Fn(&Self) + Send + Sync + 'static>(
|
||||
&self,
|
||||
f: F,
|
||||
) -> SignalHandlerId {
|
||||
unsafe extern "C" fn notify_duration_trampoline<
|
||||
P: IsA<UriClipAsset>,
|
||||
F: Fn(&P) + 'static,
|
||||
F: Fn(&P) + Send + Sync + 'static,
|
||||
>(
|
||||
this: *mut ffi::GESUriClipAsset,
|
||||
_param_spec: glib::ffi::gpointer,
|
||||
|
@ -187,10 +199,13 @@ impl<O: IsA<UriClipAsset>> UriClipAssetExt for O {
|
|||
|
||||
#[cfg(any(feature = "v1_18", feature = "dox"))]
|
||||
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))]
|
||||
fn connect_is_nested_timeline_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
|
||||
fn connect_is_nested_timeline_notify<F: Fn(&Self) + Send + Sync + 'static>(
|
||||
&self,
|
||||
f: F,
|
||||
) -> SignalHandlerId {
|
||||
unsafe extern "C" fn notify_is_nested_timeline_trampoline<
|
||||
P: IsA<UriClipAsset>,
|
||||
F: Fn(&P) + 'static,
|
||||
F: Fn(&P) + Send + Sync + 'static,
|
||||
>(
|
||||
this: *mut ffi::GESUriClipAsset,
|
||||
_param_spec: glib::ffi::gpointer,
|
||||
|
|
|
@ -19,6 +19,9 @@ impl UriSourceAsset {
|
|||
pub const NONE: Option<&'static UriSourceAsset> = None;
|
||||
}
|
||||
|
||||
unsafe impl Send for UriSourceAsset {}
|
||||
unsafe impl Sync for UriSourceAsset {}
|
||||
|
||||
pub trait UriSourceAssetExt: 'static {
|
||||
#[doc(alias = "ges_uri_source_asset_get_filesource_asset")]
|
||||
#[doc(alias = "get_filesource_asset")]
|
||||
|
|
73
gstreamer-editing-services/src/formatter.rs
Normal file
73
gstreamer-editing-services/src/formatter.rs
Normal file
|
@ -0,0 +1,73 @@
|
|||
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||
use crate::prelude::*;
|
||||
use gst::glib::translate::*;
|
||||
|
||||
pub trait FormatterExtManual: 'static {
|
||||
fn can_load_uri(&self, uri: &str) -> Result<(), glib::Error>;
|
||||
#[doc(alias = "ges_formatter_class_register_metas")]
|
||||
fn register(
|
||||
type_: glib::types::Type,
|
||||
name: &str,
|
||||
description: Option<&str>,
|
||||
extensions: Option<&str>,
|
||||
caps: Option<&str>,
|
||||
version: f64,
|
||||
rank: gst::Rank,
|
||||
);
|
||||
}
|
||||
|
||||
impl<O: IsA<crate::Formatter>> FormatterExtManual for O {
|
||||
fn can_load_uri(&self, uri: &str) -> Result<(), glib::Error> {
|
||||
unsafe {
|
||||
let klass = self.class_of::<crate::Formatter>().unwrap();
|
||||
|
||||
let f = klass.as_ref().can_load_uri.ok_or_else(|| {
|
||||
glib::Error::new(gst::CoreError::Failed, "No `can_load_uri` method defined")
|
||||
})?;
|
||||
|
||||
let mut err = std::ptr::null_mut();
|
||||
let res = f(
|
||||
self.as_ref().to_glib_none().0,
|
||||
uri.to_glib_none().0,
|
||||
&mut err,
|
||||
);
|
||||
|
||||
if res == glib::ffi::GTRUE {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(from_glib_full(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "ges_formatter_class_register_metas")]
|
||||
fn register(
|
||||
type_: glib::types::Type,
|
||||
name: &str,
|
||||
description: Option<&str>,
|
||||
extensions: Option<&str>,
|
||||
caps: Option<&str>,
|
||||
version: f64,
|
||||
rank: gst::Rank,
|
||||
) {
|
||||
skip_assert_initialized!();
|
||||
|
||||
unsafe {
|
||||
let klass = mut_override(
|
||||
gst::glib::Class::<crate::Formatter>::from_type(type_)
|
||||
.unwrap()
|
||||
.as_ref(),
|
||||
);
|
||||
|
||||
ffi::ges_formatter_class_register_metas(
|
||||
klass,
|
||||
name.to_glib_none().0,
|
||||
description.to_glib_none().0,
|
||||
extensions.to_glib_none().0,
|
||||
caps.to_glib_none().0,
|
||||
version,
|
||||
rank.into_glib(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -54,7 +54,9 @@ macro_rules! skip_assert_initialized {
|
|||
#[allow(deprecated)]
|
||||
#[allow(unused_imports)]
|
||||
mod auto;
|
||||
mod formatter;
|
||||
pub use crate::auto::*;
|
||||
pub mod subclass;
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
mod flag_serde;
|
||||
|
@ -65,9 +67,12 @@ pub mod prelude {
|
|||
#[doc(hidden)]
|
||||
pub use gio::prelude::*;
|
||||
#[doc(hidden)]
|
||||
pub use glib::prelude::*;
|
||||
#[doc(hidden)]
|
||||
pub use gst_base::prelude::*;
|
||||
#[doc(hidden)]
|
||||
pub use gst_pbutils::prelude::*;
|
||||
|
||||
pub use crate::auto::traits::*;
|
||||
pub use crate::formatter::FormatterExtManual;
|
||||
}
|
||||
|
|
363
gstreamer-editing-services/src/subclass/formatter.rs
Normal file
363
gstreamer-editing-services/src/subclass/formatter.rs
Normal file
|
@ -0,0 +1,363 @@
|
|||
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::Formatter;
|
||||
use glib::{subclass::prelude::*, translate::*};
|
||||
|
||||
pub trait FormatterImpl: FormatterImplExt + ObjectImpl + Send + Sync {
|
||||
fn can_load_uri(&self, uri: &str) -> Result<(), glib::Error> {
|
||||
self.parent_can_load_uri(uri)
|
||||
}
|
||||
|
||||
fn load_from_uri(&self, timeline: &crate::Timeline, uri: &str) -> Result<(), glib::Error> {
|
||||
self.parent_load_from_uri(timeline, uri)
|
||||
}
|
||||
|
||||
fn save_to_uri(
|
||||
&self,
|
||||
timeline: &crate::Timeline,
|
||||
uri: &str,
|
||||
overwrite: bool,
|
||||
) -> Result<(), glib::Error> {
|
||||
self.parent_save_to_uri(timeline, uri, overwrite)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait FormatterImplExt: ObjectSubclass {
|
||||
fn parent_can_load_uri(&self, uri: &str) -> Result<(), glib::Error>;
|
||||
|
||||
fn parent_load_from_uri(
|
||||
&self,
|
||||
timeline: &crate::Timeline,
|
||||
uri: &str,
|
||||
) -> Result<(), glib::Error>;
|
||||
|
||||
fn parent_save_to_uri(
|
||||
&self,
|
||||
timeline: &crate::Timeline,
|
||||
uri: &str,
|
||||
overwrite: bool,
|
||||
) -> Result<(), glib::Error>;
|
||||
}
|
||||
|
||||
impl<T: FormatterImpl> FormatterImplExt for T {
|
||||
fn parent_can_load_uri(&self, uri: &str) -> Result<(), glib::Error> {
|
||||
unsafe {
|
||||
let data = Self::type_data();
|
||||
let parent_class = data.as_ref().parent_class() as *mut ffi::GESFormatterClass;
|
||||
|
||||
let f = (*parent_class)
|
||||
.can_load_uri
|
||||
.expect("Missing parent function `can_load_uri`");
|
||||
|
||||
let mut error = std::ptr::null_mut();
|
||||
let res = f(
|
||||
self.obj()
|
||||
.unsafe_cast_ref::<crate::Formatter>()
|
||||
.to_glib_none()
|
||||
.0,
|
||||
uri.to_glib_none().0,
|
||||
&mut error,
|
||||
);
|
||||
|
||||
if res == glib::ffi::GFALSE {
|
||||
if error.is_null() {
|
||||
Err(glib::Error::new(
|
||||
gst::CoreError::Failed,
|
||||
"Can load uri failed",
|
||||
))
|
||||
} else {
|
||||
Err(from_glib_full(error))
|
||||
}
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parent_load_from_uri(
|
||||
&self,
|
||||
timeline: &crate::Timeline,
|
||||
uri: &str,
|
||||
) -> Result<(), glib::Error> {
|
||||
unsafe {
|
||||
let data = Self::type_data();
|
||||
let parent_class = data.as_ref().parent_class() as *mut ffi::GESFormatterClass;
|
||||
|
||||
let f = (*parent_class)
|
||||
.load_from_uri
|
||||
.expect("Missing parent function `load_from_uri`");
|
||||
|
||||
let mut error = std::ptr::null_mut();
|
||||
let res = f(
|
||||
self.obj()
|
||||
.unsafe_cast_ref::<crate::Formatter>()
|
||||
.to_glib_none()
|
||||
.0,
|
||||
timeline
|
||||
.unsafe_cast_ref::<crate::Timeline>()
|
||||
.to_glib_none()
|
||||
.0,
|
||||
uri.to_glib_none().0,
|
||||
&mut error,
|
||||
);
|
||||
|
||||
if res == glib::ffi::GFALSE {
|
||||
if error.is_null() {
|
||||
Err(glib::Error::new(
|
||||
gst::CoreError::Failed,
|
||||
"Load from uri failed",
|
||||
))
|
||||
} else {
|
||||
Err(from_glib_full(error))
|
||||
}
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
fn parent_save_to_uri(
|
||||
&self,
|
||||
timeline: &crate::Timeline,
|
||||
uri: &str,
|
||||
overwrite: bool,
|
||||
) -> Result<(), glib::Error> {
|
||||
unsafe {
|
||||
let data = Self::type_data();
|
||||
let parent_class = data.as_ref().parent_class() as *mut ffi::GESFormatterClass;
|
||||
|
||||
let f = (*parent_class)
|
||||
.save_to_uri
|
||||
.expect("Missing parent function `save_to_uri`");
|
||||
|
||||
let mut error = std::ptr::null_mut();
|
||||
let res = f(
|
||||
self.obj()
|
||||
.unsafe_cast_ref::<crate::Formatter>()
|
||||
.to_glib_none()
|
||||
.0,
|
||||
timeline
|
||||
.unsafe_cast_ref::<crate::Timeline>()
|
||||
.to_glib_none()
|
||||
.0,
|
||||
uri.to_glib_none().0,
|
||||
overwrite.into_glib(),
|
||||
&mut error,
|
||||
);
|
||||
|
||||
if res == glib::ffi::GFALSE {
|
||||
if error.is_null() {
|
||||
Err(glib::Error::new(
|
||||
gst::CoreError::Failed,
|
||||
"Save to uri failed",
|
||||
))
|
||||
} else {
|
||||
Err(from_glib_full(error))
|
||||
}
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: FormatterImpl> IsSubclassable<T> for Formatter {
|
||||
fn class_init(klass: &mut glib::Class<Self>) {
|
||||
Self::parent_class_init::<T>(klass);
|
||||
let klass = klass.as_mut();
|
||||
klass.can_load_uri = Some(formatter_can_load_uri::<T>);
|
||||
klass.load_from_uri = Some(formatter_load_from_uri::<T>);
|
||||
klass.save_to_uri = Some(formatter_save_to_uri::<T>);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" fn formatter_can_load_uri<T: FormatterImpl>(
|
||||
ptr: *mut ffi::GESFormatter,
|
||||
uri: *const libc::c_char,
|
||||
error: *mut *mut glib::ffi::GError,
|
||||
) -> glib::ffi::gboolean {
|
||||
let instance = &*(ptr as *mut T::Instance);
|
||||
let imp = instance.imp();
|
||||
|
||||
match imp.can_load_uri(glib::GString::from_glib_borrow(uri).as_str()) {
|
||||
Err(err) => {
|
||||
if !error.is_null() {
|
||||
*error = err.into_glib_ptr();
|
||||
}
|
||||
|
||||
glib::ffi::GFALSE
|
||||
}
|
||||
Ok(_) => glib::ffi::GTRUE,
|
||||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" fn formatter_load_from_uri<T: FormatterImpl>(
|
||||
ptr: *mut ffi::GESFormatter,
|
||||
timeline: *mut ffi::GESTimeline,
|
||||
uri: *const libc::c_char,
|
||||
error: *mut *mut glib::ffi::GError,
|
||||
) -> glib::ffi::gboolean {
|
||||
let instance = &*(ptr as *mut T::Instance);
|
||||
let imp = instance.imp();
|
||||
let timeline = from_glib_borrow(timeline);
|
||||
|
||||
match imp.load_from_uri(&timeline, glib::GString::from_glib_borrow(uri).as_str()) {
|
||||
Err(err) => {
|
||||
if !error.is_null() {
|
||||
*error = err.into_glib_ptr();
|
||||
}
|
||||
|
||||
glib::ffi::GFALSE
|
||||
}
|
||||
Ok(_) => glib::ffi::GTRUE,
|
||||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" fn formatter_save_to_uri<T: FormatterImpl>(
|
||||
ptr: *mut ffi::GESFormatter,
|
||||
timeline: *mut ffi::GESTimeline,
|
||||
uri: *const libc::c_char,
|
||||
overwrite: glib::ffi::gboolean,
|
||||
error: *mut *mut glib::ffi::GError,
|
||||
) -> glib::ffi::gboolean {
|
||||
let instance = &*(ptr as *mut T::Instance);
|
||||
let imp = instance.imp();
|
||||
let timeline = from_glib_borrow(timeline);
|
||||
|
||||
match imp.save_to_uri(
|
||||
&timeline,
|
||||
glib::GString::from_glib_borrow(uri).as_str(),
|
||||
from_glib(overwrite),
|
||||
) {
|
||||
Err(err) => {
|
||||
if !error.is_null() {
|
||||
*error = err.into_glib_ptr();
|
||||
}
|
||||
|
||||
glib::ffi::GFALSE
|
||||
}
|
||||
Ok(_) => glib::ffi::GTRUE,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::Formatter;
|
||||
|
||||
pub mod imp {
|
||||
use super::*;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct SimpleFormatter;
|
||||
|
||||
#[glib::object_subclass]
|
||||
impl ObjectSubclass for SimpleFormatter {
|
||||
const NAME: &'static str = "SimpleFormatter";
|
||||
type Type = super::SimpleFormatter;
|
||||
type ParentType = Formatter;
|
||||
}
|
||||
impl ObjectImpl for SimpleFormatter {}
|
||||
impl FormatterImpl for SimpleFormatter {
|
||||
fn can_load_uri(&self, uri: &str) -> Result<(), glib::Error> {
|
||||
if uri.starts_with("ges:test") {
|
||||
Ok(())
|
||||
} else {
|
||||
self.parent_can_load_uri(uri)
|
||||
}
|
||||
}
|
||||
|
||||
fn load_from_uri(
|
||||
&self,
|
||||
timeline: &crate::Timeline,
|
||||
_uri: &str,
|
||||
) -> Result<(), glib::Error> {
|
||||
timeline.append_layer();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn save_to_uri(
|
||||
&self,
|
||||
timeline: &crate::Timeline,
|
||||
uri: &str,
|
||||
_overwrite: bool,
|
||||
) -> Result<(), glib::Error> {
|
||||
unsafe { timeline.set_data("saved", uri.to_string()) };
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glib::wrapper! {
|
||||
pub struct SimpleFormatter(ObjectSubclass<imp::SimpleFormatter>) @extends Formatter, gst::Object;
|
||||
}
|
||||
|
||||
impl SimpleFormatter {
|
||||
pub fn new() -> Self {
|
||||
glib::Object::builder().build()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for SimpleFormatter {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_formatter_subclass() {
|
||||
crate::init().unwrap();
|
||||
|
||||
let formatter = SimpleFormatter::new();
|
||||
formatter
|
||||
.can_load_uri("ges:test:")
|
||||
.expect("We can load anything...");
|
||||
|
||||
assert!(formatter.can_load_uri("nottest").is_err());
|
||||
|
||||
let timeline = crate::Timeline::new();
|
||||
assert_eq!(timeline.layers().len(), 0);
|
||||
#[allow(deprecated)]
|
||||
formatter
|
||||
.load_from_uri(&timeline, "test")
|
||||
.expect("We can load anything...");
|
||||
assert_eq!(timeline.layers().len(), 1);
|
||||
|
||||
unsafe {
|
||||
assert_eq!(timeline.data::<Option<String>>("saved"), None);
|
||||
}
|
||||
#[allow(deprecated)]
|
||||
formatter
|
||||
.save_to_uri(&timeline, "test", false)
|
||||
.expect("We can save anything...");
|
||||
unsafe {
|
||||
assert_eq!(
|
||||
timeline.data::<String>("saved").unwrap().as_ref(),
|
||||
&"test".to_string()
|
||||
);
|
||||
}
|
||||
|
||||
Formatter::register(
|
||||
SimpleFormatter::static_type(),
|
||||
"SimpleFormatter",
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
1.0,
|
||||
gst::Rank::Primary,
|
||||
);
|
||||
|
||||
let proj = crate::Project::new(Some("ges:test:"));
|
||||
let timeline = proj
|
||||
.extract()
|
||||
.unwrap()
|
||||
.downcast::<crate::Timeline>()
|
||||
.unwrap();
|
||||
assert_eq!(timeline.layers().len(), 1);
|
||||
|
||||
let proj = crate::Project::new(Some("ges:notest:"));
|
||||
assert!(proj.extract().is_err());
|
||||
}
|
||||
}
|
13
gstreamer-editing-services/src/subclass/mod.rs
Normal file
13
gstreamer-editing-services/src/subclass/mod.rs
Normal file
|
@ -0,0 +1,13 @@
|
|||
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||
|
||||
#![allow(clippy::cast_ptr_alignment)]
|
||||
|
||||
mod formatter;
|
||||
|
||||
pub mod prelude {
|
||||
#[doc(hidden)]
|
||||
pub use glib::subclass::prelude::*;
|
||||
pub use gst::subclass::prelude::*;
|
||||
|
||||
pub use super::formatter::{FormatterImpl, FormatterImplExt};
|
||||
}
|
|
@ -7,22 +7,30 @@ libc = "0.2"
|
|||
[dependencies.gio]
|
||||
package = "gio-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.glib]
|
||||
package = "glib-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gobject]
|
||||
package = "gobject-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gst_pbutils]
|
||||
package = "gstreamer-pbutils-sys"
|
||||
path = "../../gstreamer-pbutils/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dependencies.gst]
|
||||
package = "gstreamer-sys"
|
||||
path = "../../gstreamer/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dev-dependencies]
|
||||
shell-words = "1.0.0"
|
||||
|
@ -49,7 +57,7 @@ license = "MIT"
|
|||
name = "gstreamer-editing-services-sys"
|
||||
readme = "README.md"
|
||||
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
edition = "2021"
|
||||
rust-version = "1.64"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "gstreamer-gl"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
authors = [
|
||||
"Sebastian Dröge <sebastian@centricular.com>",
|
||||
"Víctor M. Jáquez L. <vjaquez@igalia.com>"
|
||||
|
@ -20,11 +20,11 @@ rust-version = "1.64"
|
|||
bitflags = "1.0"
|
||||
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" }
|
||||
gst-base = { package = "gstreamer-base", path = "../gstreamer-base" }
|
||||
gst-video = { package = "gstreamer-video", path = "../gstreamer-video" }
|
||||
ffi = { package = "gstreamer-gl-sys", path = "sys", version = "0.20" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.17", version = "0.17" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer", version = "0.20" }
|
||||
gst-base = { package = "gstreamer-base", path = "../gstreamer-base", version = "0.20" }
|
||||
gst-video = { package = "gstreamer-video", path = "../gstreamer-video", version = "0.20" }
|
||||
serde = { version = "1.0", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "gstreamer-gl-egl"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
authors = [
|
||||
"Sebastian Dröge <sebastian@centricular.com>",
|
||||
"Víctor M. Jáquez L. <vjaquez@igalia.com>"
|
||||
|
@ -18,11 +18,11 @@ rust-version = "1.64"
|
|||
|
||||
[dependencies]
|
||||
libc = "0.2"
|
||||
ffi = { package = "gstreamer-gl-egl-sys", path = "sys" }
|
||||
ffi = { package = "gstreamer-gl-egl-sys", path = "sys", version = "0.20" }
|
||||
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
|
||||
gst = { package = "gstreamer", path = "../../gstreamer" }
|
||||
gst-gl = { package = "gstreamer-gl", path = "../" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.17", version = "0.17" }
|
||||
gst = { package = "gstreamer", path = "../../gstreamer", version = "0.20" }
|
||||
gst-gl = { package = "gstreamer-gl", path = "../", version = "0.20" }
|
||||
|
||||
[dev-dependencies]
|
||||
gir-format-check = "0.1"
|
||||
|
|
|
@ -9,7 +9,7 @@ license = "MIT"
|
|||
name = "gstreamer-gl-egl-sys"
|
||||
readme = "README.md"
|
||||
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
edition = "2021"
|
||||
rust-version = "1.64"
|
||||
|
||||
|
@ -42,10 +42,13 @@ libc = "0.2"
|
|||
[dependencies.glib]
|
||||
package = "glib-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gst_gl]
|
||||
package = "gstreamer-gl-sys"
|
||||
path = "../../sys"
|
||||
version = "0.20"
|
||||
|
||||
[build-dependencies]
|
||||
system-deps = "6"
|
||||
|
|
|
@ -7,22 +7,29 @@ libc = "0.2"
|
|||
[dependencies.glib]
|
||||
package = "glib-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gobject]
|
||||
package = "gobject-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gst_base]
|
||||
package = "gstreamer-base-sys"
|
||||
path = "../../gstreamer-base/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dependencies.gst]
|
||||
package = "gstreamer-sys"
|
||||
path = "../../gstreamer/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dependencies.gst_video]
|
||||
package = "gstreamer-video-sys"
|
||||
path = "../../gstreamer-video/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dev-dependencies]
|
||||
shell-words = "1.0.0"
|
||||
|
@ -49,7 +56,7 @@ license = "MIT"
|
|||
name = "gstreamer-gl-sys"
|
||||
readme = "README.md"
|
||||
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
edition = "2021"
|
||||
rust-version = "1.64"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "gstreamer-gl-wayland"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
authors = [
|
||||
"Sebastian Dröge <sebastian@centricular.com>",
|
||||
"Víctor M. Jáquez L. <vjaquez@igalia.com>"
|
||||
|
@ -18,11 +18,11 @@ rust-version = "1.64"
|
|||
|
||||
[dependencies]
|
||||
libc = "0.2"
|
||||
ffi = { package = "gstreamer-gl-wayland-sys", path = "sys" }
|
||||
ffi = { package = "gstreamer-gl-wayland-sys", path = "sys", version = "0.20" }
|
||||
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
|
||||
gst = { package = "gstreamer", path = "../../gstreamer" }
|
||||
gst-gl = { package = "gstreamer-gl", path = "../" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.17", version = "0.17" }
|
||||
gst = { package = "gstreamer", path = "../../gstreamer", version = "0.20" }
|
||||
gst-gl = { package = "gstreamer-gl", path = "../", version = "0.20" }
|
||||
|
||||
[dev-dependencies]
|
||||
gir-format-check = "0.1"
|
||||
|
|
|
@ -9,7 +9,7 @@ license = "MIT"
|
|||
name = "gstreamer-gl-wayland-sys"
|
||||
readme = "README.md"
|
||||
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
edition = "2021"
|
||||
rust-version = "1.64"
|
||||
|
||||
|
@ -42,10 +42,13 @@ libc = "0.2"
|
|||
[dependencies.glib]
|
||||
package = "glib-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gst_gl]
|
||||
package = "gstreamer-gl-sys"
|
||||
path = "../../sys"
|
||||
version = "0.20"
|
||||
|
||||
[build-dependencies]
|
||||
system-deps = "6"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "gstreamer-gl-x11"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
authors = [
|
||||
"Sebastian Dröge <sebastian@centricular.com>",
|
||||
"Víctor M. Jáquez L. <vjaquez@igalia.com>"
|
||||
|
@ -18,11 +18,11 @@ rust-version = "1.64"
|
|||
|
||||
[dependencies]
|
||||
libc = "0.2"
|
||||
ffi = { package = "gstreamer-gl-x11-sys", path = "sys" }
|
||||
ffi = { package = "gstreamer-gl-x11-sys", path = "sys", version = "0.20" }
|
||||
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
|
||||
gst = { package = "gstreamer", path = "../../gstreamer" }
|
||||
gst-gl = { package = "gstreamer-gl", path = "../" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.17", version = "0.17" }
|
||||
gst = { package = "gstreamer", path = "../../gstreamer", version = "0.20" }
|
||||
gst-gl = { package = "gstreamer-gl", path = "../", version = "0.20" }
|
||||
|
||||
[dev-dependencies]
|
||||
gir-format-check = "0.1"
|
||||
|
|
|
@ -9,7 +9,7 @@ license = "MIT"
|
|||
name = "gstreamer-gl-x11-sys"
|
||||
readme = "README.md"
|
||||
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
edition = "2021"
|
||||
rust-version = "1.64"
|
||||
|
||||
|
@ -42,10 +42,13 @@ libc = "0.2"
|
|||
[dependencies.glib]
|
||||
package = "glib-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gst_gl]
|
||||
package = "gstreamer-gl-sys"
|
||||
path = "../../sys"
|
||||
version = "0.20"
|
||||
|
||||
[build-dependencies]
|
||||
system-deps = "6"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "gstreamer-mpegts"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
authors = ["Sebastian Dröge <sebastian@centricular.com>", "Rafael Caricio <rafael@caricio.com>"]
|
||||
categories = ["api-bindings", "multimedia"]
|
||||
description = "Rust bindings for GStreamer MpegTs library"
|
||||
|
@ -14,9 +14,9 @@ edition = "2021"
|
|||
rust-version = "1.64"
|
||||
|
||||
[dependencies]
|
||||
ffi = { package = "gstreamer-mpegts-sys", path = "sys" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer" }
|
||||
ffi = { package = "gstreamer-mpegts-sys", path = "sys", version = "0.20" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.17", version = "0.17" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer", version = "0.20" }
|
||||
|
||||
[dev-dependencies]
|
||||
gir-format-check = "0.1"
|
||||
|
|
|
@ -9,7 +9,7 @@ license = "MIT"
|
|||
name = "gstreamer-mpegts-sys"
|
||||
readme = "README.md"
|
||||
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
edition = "2021"
|
||||
rust-version = "1.64"
|
||||
|
||||
|
@ -44,14 +44,18 @@ libc = "0.2"
|
|||
[dependencies.glib]
|
||||
package = "glib-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gst_base]
|
||||
package = "gstreamer-base-sys"
|
||||
path = "../../gstreamer-base/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dependencies.gst]
|
||||
package = "gstreamer-sys"
|
||||
path = "../../gstreamer/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dev-dependencies]
|
||||
shell-words = "1.0.0"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "gstreamer-net"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
|
||||
categories = ["api-bindings", "multimedia"]
|
||||
description = "Rust bindings for GStreamer Net library"
|
||||
|
@ -14,10 +14,10 @@ edition = "2021"
|
|||
rust-version = "1.64"
|
||||
|
||||
[dependencies]
|
||||
ffi = { package = "gstreamer-net-sys", path = "sys" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer" }
|
||||
gio = { git = "https://github.com/gtk-rs/gtk-rs-core" }
|
||||
ffi = { package = "gstreamer-net-sys", path = "sys", version = "0.20" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.17", version = "0.17" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer", version = "0.20" }
|
||||
gio = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.17", version = "0.17" }
|
||||
|
||||
[dev-dependencies]
|
||||
gir-format-check = "0.1"
|
||||
|
|
|
@ -7,14 +7,19 @@ libc = "0.2"
|
|||
[dependencies.gio]
|
||||
package = "gio-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.glib]
|
||||
package = "glib-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gst]
|
||||
package = "gstreamer-sys"
|
||||
path = "../../gstreamer/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dev-dependencies]
|
||||
shell-words = "1.0.0"
|
||||
|
@ -41,7 +46,7 @@ license = "MIT"
|
|||
name = "gstreamer-net-sys"
|
||||
readme = "README.md"
|
||||
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
edition = "2021"
|
||||
rust-version = "1.64"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "gstreamer-pbutils"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
|
||||
categories = ["api-bindings", "multimedia"]
|
||||
description = "Rust bindings for GStreamer Base Utils library"
|
||||
|
@ -16,11 +16,11 @@ rust-version = "1.64"
|
|||
[dependencies]
|
||||
bitflags = "1.0"
|
||||
libc = "0.2"
|
||||
ffi = { package = "gstreamer-pbutils-sys", path = "sys" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer" }
|
||||
gst-video = { package = "gstreamer-video", path = "../gstreamer-video" }
|
||||
gst-audio = { package = "gstreamer-audio", path = "../gstreamer-audio" }
|
||||
ffi = { package = "gstreamer-pbutils-sys", path = "sys", version = "0.20" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.17", version = "0.17" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer", version = "0.20" }
|
||||
gst-video = { package = "gstreamer-video", path = "../gstreamer-video", version = "0.20" }
|
||||
gst-audio = { package = "gstreamer-audio", path = "../gstreamer-audio", version = "0.20" }
|
||||
thiserror = "1.0"
|
||||
serde = { version = "1.0", optional = true }
|
||||
|
||||
|
|
|
@ -279,6 +279,10 @@ final_type = false
|
|||
name = "list_free"
|
||||
ignore = true
|
||||
|
||||
[[object.function]]
|
||||
name = "get_stream_id"
|
||||
manual = true
|
||||
|
||||
[[object]]
|
||||
name = "GstPbutils.DiscovererSubtitleInfo"
|
||||
status = "generate"
|
||||
|
|
|
@ -40,10 +40,6 @@ pub trait DiscovererStreamInfoExt: 'static {
|
|||
#[must_use]
|
||||
fn previous(&self) -> Option<DiscovererStreamInfo>;
|
||||
|
||||
#[doc(alias = "gst_discoverer_stream_info_get_stream_id")]
|
||||
#[doc(alias = "get_stream_id")]
|
||||
fn stream_id(&self) -> glib::GString;
|
||||
|
||||
#[cfg(any(feature = "v1_20", feature = "dox"))]
|
||||
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
|
||||
#[doc(alias = "gst_discoverer_stream_info_get_stream_number")]
|
||||
|
@ -96,14 +92,6 @@ impl<O: IsA<DiscovererStreamInfo>> DiscovererStreamInfoExt for O {
|
|||
}
|
||||
}
|
||||
|
||||
fn stream_id(&self) -> glib::GString {
|
||||
unsafe {
|
||||
from_glib_none(ffi::gst_discoverer_stream_info_get_stream_id(
|
||||
self.as_ref().to_glib_none().0,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "v1_20", feature = "dox"))]
|
||||
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
|
||||
fn stream_number(&self) -> i32 {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||
|
||||
use std::{boxed::Box as Box_, mem::transmute};
|
||||
use std::{boxed::Box as Box_, fmt, mem::transmute};
|
||||
|
||||
use glib::{
|
||||
prelude::*,
|
||||
|
@ -8,11 +8,11 @@ use glib::{
|
|||
translate::*,
|
||||
};
|
||||
|
||||
use crate::auto::Discoverer;
|
||||
use crate::{auto::Discoverer, DiscovererInfo};
|
||||
|
||||
impl Discoverer {
|
||||
pub fn set_timeout(&self, timeout: gst::ClockTime) {
|
||||
self.set_property("timeout", &timeout);
|
||||
self.set_property("timeout", timeout);
|
||||
}
|
||||
|
||||
pub fn timeout(&self) -> gst::ClockTime {
|
||||
|
@ -48,3 +48,75 @@ unsafe extern "C" fn notify_timeout_trampoline<P, F: Fn(&P) + Send + Sync + 'sta
|
|||
let f: &F = &*(f as *const F);
|
||||
f(Discoverer::from_glib_borrow(this).unsafe_cast_ref())
|
||||
}
|
||||
|
||||
pub struct DebugInfo<'a>(&'a DiscovererInfo);
|
||||
|
||||
impl<'a> fmt::Debug for DebugInfo<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let stream_info = self.0.stream_info();
|
||||
let stream_list = self.0.stream_list();
|
||||
let container_streams = self.0.container_streams();
|
||||
let audio_streams = self.0.audio_streams();
|
||||
let video_streams = self.0.video_streams();
|
||||
let subtitle_streams = self.0.subtitle_streams();
|
||||
|
||||
f.debug_struct("DiscovererInfo")
|
||||
.field("uri", &self.0.uri())
|
||||
.field("result", &self.0.result())
|
||||
.field("duration", &self.0.duration())
|
||||
.field("is-live", &self.0.is_live())
|
||||
.field("is-seekable", &self.0.is_seekable())
|
||||
.field(
|
||||
"stream-info",
|
||||
&stream_info.as_ref().map(|info| info.debug()),
|
||||
)
|
||||
.field(
|
||||
"stream-list",
|
||||
&stream_list
|
||||
.iter()
|
||||
.map(|info| info.debug())
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
.field(
|
||||
"container-streams",
|
||||
&container_streams
|
||||
.iter()
|
||||
.map(|info| info.debug())
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
.field(
|
||||
"audio-streams",
|
||||
&audio_streams
|
||||
.iter()
|
||||
.map(|info| info.debug())
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
.field(
|
||||
"video-streams",
|
||||
&video_streams
|
||||
.iter()
|
||||
.map(|info| info.debug())
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
.field(
|
||||
"subtitle-streams",
|
||||
&subtitle_streams
|
||||
.iter()
|
||||
.map(|info| info.debug())
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
.field("toc", &self.0.toc())
|
||||
.field("misc", &self.0.misc())
|
||||
.field(
|
||||
"missing-elements-installer-details",
|
||||
&self.0.missing_elements_installer_details(),
|
||||
)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl DiscovererInfo {
|
||||
pub fn debug(&self) -> DebugInfo {
|
||||
DebugInfo(self)
|
||||
}
|
||||
}
|
||||
|
|
32
gstreamer-pbutils/src/discoverer_audio_info.rs
Normal file
32
gstreamer-pbutils/src/discoverer_audio_info.rs
Normal file
|
@ -0,0 +1,32 @@
|
|||
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||
|
||||
use std::fmt;
|
||||
|
||||
use glib::Cast;
|
||||
|
||||
use crate::{DiscovererAudioInfo, DiscovererStreamInfo};
|
||||
|
||||
pub struct Debug<'a>(&'a DiscovererAudioInfo);
|
||||
|
||||
impl<'a> fmt::Debug for Debug<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let info = self.0.upcast_ref::<DiscovererStreamInfo>();
|
||||
|
||||
f.debug_struct("DiscovererAudioInfo")
|
||||
.field("channels", &self.0.channels())
|
||||
.field("sample-rate", &self.0.sample_rate())
|
||||
.field("depth", &self.0.depth())
|
||||
.field("bitrate", &self.0.bitrate())
|
||||
.field("max-bitrate", &self.0.max_bitrate())
|
||||
.field("channel-mask", &self.0.channel_mask())
|
||||
.field("language", &self.0.language())
|
||||
.field("stream", &info.debug())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl DiscovererAudioInfo {
|
||||
pub fn debug(&self) -> Debug {
|
||||
Debug(self)
|
||||
}
|
||||
}
|
32
gstreamer-pbutils/src/discoverer_container_info.rs
Normal file
32
gstreamer-pbutils/src/discoverer_container_info.rs
Normal file
|
@ -0,0 +1,32 @@
|
|||
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||
use std::fmt;
|
||||
|
||||
use crate::{prelude::*, DiscovererContainerInfo};
|
||||
|
||||
pub struct Debug<'a>(&'a DiscovererContainerInfo);
|
||||
|
||||
impl<'a> fmt::Debug for Debug<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let streams = self.0.streams();
|
||||
|
||||
let mut d = f.debug_struct("DiscovererContainerInfo");
|
||||
|
||||
d.field("tags", &self.0.tags()).field(
|
||||
"streams",
|
||||
&streams.iter().map(|info| info.debug()).collect::<Vec<_>>(),
|
||||
);
|
||||
|
||||
#[cfg(feature = "v1_20")]
|
||||
d.field("stream-number", &self.0.stream_number());
|
||||
#[cfg(feature = "v1_20")]
|
||||
d.field("tags", &self.0.tags());
|
||||
|
||||
d.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl DiscovererContainerInfo {
|
||||
pub fn debug(&self) -> Debug {
|
||||
Debug(self)
|
||||
}
|
||||
}
|
|
@ -1,4 +1,7 @@
|
|||
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||
use std::fmt;
|
||||
|
||||
use glib::translate::*;
|
||||
|
||||
use crate::{prelude::*, DiscovererStreamInfo};
|
||||
|
||||
|
@ -28,20 +31,65 @@ impl Iterator for Iter {
|
|||
}
|
||||
}
|
||||
|
||||
impl DiscovererStreamInfo {
|
||||
pub fn next_iter(&self) -> Iter {
|
||||
impl std::iter::FusedIterator for Iter {}
|
||||
|
||||
pub trait DiscovererStreamInfoExtManual: 'static {
|
||||
fn next_iter(&self) -> Iter;
|
||||
fn previous_iter(&self) -> Iter;
|
||||
#[doc(alias = "gst_discoverer_stream_info_get_stream_id")]
|
||||
#[doc(alias = "get_stream_id")]
|
||||
fn stream_id(&self) -> glib::GString;
|
||||
}
|
||||
|
||||
impl<O: IsA<DiscovererStreamInfo>> DiscovererStreamInfoExtManual for O {
|
||||
fn next_iter(&self) -> Iter {
|
||||
Iter {
|
||||
stream_info: self.next(),
|
||||
direction_forward: true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn previous_iter(&self) -> Iter {
|
||||
fn previous_iter(&self) -> Iter {
|
||||
Iter {
|
||||
stream_info: self.previous(),
|
||||
direction_forward: false,
|
||||
}
|
||||
}
|
||||
|
||||
fn stream_id(&self) -> glib::GString {
|
||||
unsafe {
|
||||
let ptr = ffi::gst_discoverer_stream_info_get_stream_id(self.as_ref().to_glib_none().0);
|
||||
|
||||
if ptr.is_null() {
|
||||
glib::GString::new()
|
||||
} else {
|
||||
from_glib_none(ptr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::iter::FusedIterator for Iter {}
|
||||
pub struct Debug<'a>(&'a DiscovererStreamInfo);
|
||||
|
||||
impl<'a> fmt::Debug for Debug<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let mut d = f.debug_struct("DiscovererStreamInfo");
|
||||
d.field("caps", &self.0.caps())
|
||||
.field("stream-id", &self.0.stream_id())
|
||||
.field("misc", &self.0.misc())
|
||||
.field("stream-type-nick", &self.0.stream_type_nick())
|
||||
.field("tags", &self.0.tags())
|
||||
.field("toc", &self.0.toc());
|
||||
|
||||
#[cfg(feature = "v1_20")]
|
||||
d.field("stream-number", &self.0.stream_number());
|
||||
|
||||
d.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl DiscovererStreamInfo {
|
||||
pub fn debug(&self) -> Debug {
|
||||
Debug(self)
|
||||
}
|
||||
}
|
||||
|
|
26
gstreamer-pbutils/src/discoverer_subtitle_info.rs
Normal file
26
gstreamer-pbutils/src/discoverer_subtitle_info.rs
Normal file
|
@ -0,0 +1,26 @@
|
|||
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||
|
||||
use std::fmt;
|
||||
|
||||
use glib::Cast;
|
||||
|
||||
use crate::{DiscovererStreamInfo, DiscovererSubtitleInfo};
|
||||
|
||||
pub struct Debug<'a>(&'a DiscovererSubtitleInfo);
|
||||
|
||||
impl<'a> fmt::Debug for Debug<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let info = self.0.upcast_ref::<DiscovererStreamInfo>();
|
||||
|
||||
f.debug_struct("DiscovererSubtitleInfo")
|
||||
.field("language", &self.0.language())
|
||||
.field("stream", &info.debug())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl DiscovererSubtitleInfo {
|
||||
pub fn debug(&self) -> Debug {
|
||||
Debug(self)
|
||||
}
|
||||
}
|
|
@ -1,8 +1,10 @@
|
|||
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||
|
||||
use glib::translate::*;
|
||||
use std::fmt;
|
||||
|
||||
use crate::DiscovererVideoInfo;
|
||||
use glib::{translate::*, Cast};
|
||||
|
||||
use crate::{DiscovererStreamInfo, DiscovererVideoInfo};
|
||||
|
||||
impl DiscovererVideoInfo {
|
||||
#[doc(alias = "get_framerate")]
|
||||
|
@ -28,4 +30,27 @@ impl DiscovererVideoInfo {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn debug(&self) -> Debug {
|
||||
Debug(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Debug<'a>(&'a DiscovererVideoInfo);
|
||||
|
||||
impl<'a> fmt::Debug for Debug<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let info = self.0.upcast_ref::<DiscovererStreamInfo>();
|
||||
|
||||
f.debug_struct("DiscovererVideoInfo")
|
||||
.field("width", &self.0.width())
|
||||
.field("height", &self.0.height())
|
||||
.field("depth", &self.0.depth())
|
||||
.field("bitrate", &self.0.bitrate())
|
||||
.field("max-bitrate", &self.0.max_bitrate())
|
||||
.field("is-image", &self.0.is_image())
|
||||
.field("is-interlaced", &self.0.is_interlaced())
|
||||
.field("stream", &info.debug())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,10 @@ mod flag_serde;
|
|||
mod discoverer;
|
||||
pub use crate::discoverer::*;
|
||||
|
||||
mod discoverer_audio_info;
|
||||
mod discoverer_container_info;
|
||||
pub mod discoverer_stream_info;
|
||||
mod discoverer_subtitle_info;
|
||||
mod discoverer_video_info;
|
||||
|
||||
pub mod encoding_profile;
|
||||
|
@ -62,6 +65,7 @@ pub mod prelude {
|
|||
pub use crate::{
|
||||
audio_visualizer::*,
|
||||
auto::traits::*,
|
||||
discoverer_stream_info::DiscovererStreamInfoExtManual,
|
||||
encoding_profile::{
|
||||
EncodingProfileBuilder, EncodingProfileExtManual, EncodingProfileHasRestrictionGetter,
|
||||
},
|
||||
|
|
|
@ -7,22 +7,29 @@ libc = "0.2"
|
|||
[dependencies.glib]
|
||||
package = "glib-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gobject]
|
||||
package = "gobject-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gst_audio]
|
||||
package = "gstreamer-audio-sys"
|
||||
path = "../../gstreamer-audio/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dependencies.gst]
|
||||
package = "gstreamer-sys"
|
||||
path = "../../gstreamer/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dependencies.gst_video]
|
||||
package = "gstreamer-video-sys"
|
||||
path = "../../gstreamer-video/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dev-dependencies]
|
||||
shell-words = "1.0.0"
|
||||
|
@ -49,7 +56,7 @@ license = "MIT"
|
|||
name = "gstreamer-pbutils-sys"
|
||||
readme = "README.md"
|
||||
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
edition = "2021"
|
||||
rust-version = "1.64"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "gstreamer-play"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
|
||||
categories = ["api-bindings", "multimedia"]
|
||||
description = "Rust bindings for GStreamer Play library"
|
||||
|
@ -16,10 +16,10 @@ rust-version = "1.64"
|
|||
[dependencies]
|
||||
bitflags = "1.0"
|
||||
libc = "0.2"
|
||||
ffi = { package = "gstreamer-play-sys", path = "sys" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer", features = ["v1_20"] }
|
||||
gst-video = { package = "gstreamer-video", path = "../gstreamer-video", features = ["v1_20"] }
|
||||
ffi = { package = "gstreamer-play-sys", path = "sys", version = "0.20" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.17", version = "0.17" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer", version = "0.20", features = ["v1_20"] }
|
||||
gst-video = { package = "gstreamer-video", path = "../gstreamer-video", version = "0.20", features = ["v1_20"] }
|
||||
once_cell = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
|
|
|
@ -37,3 +37,9 @@ impl Play {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Play {
|
||||
fn default() -> Self {
|
||||
Self::new(None::<crate::PlayVideoRenderer>)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,18 +7,24 @@ libc = "0.2"
|
|||
[dependencies.glib]
|
||||
package = "glib-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gobject]
|
||||
package = "gobject-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gst]
|
||||
package = "gstreamer-sys"
|
||||
path = "../../gstreamer/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dependencies.gst_video]
|
||||
package = "gstreamer-video-sys"
|
||||
path = "../../gstreamer-video/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dev-dependencies]
|
||||
shell-words = "1.0.0"
|
||||
|
@ -42,7 +48,7 @@ license = "MIT"
|
|||
name = "gstreamer-play-sys"
|
||||
readme = "README.md"
|
||||
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
edition = "2021"
|
||||
rust-version = "1.64"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "gstreamer-player"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
|
||||
categories = ["api-bindings", "multimedia"]
|
||||
description = "Rust bindings for GStreamer Player library"
|
||||
|
@ -16,10 +16,10 @@ rust-version = "1.64"
|
|||
[dependencies]
|
||||
bitflags = "1.0"
|
||||
libc = "0.2"
|
||||
ffi = { package = "gstreamer-player-sys", path = "sys" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer" }
|
||||
gst-video = { package = "gstreamer-video", path = "../gstreamer-video" }
|
||||
ffi = { package = "gstreamer-player-sys", path = "sys", version = "0.20" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.17", version = "0.17" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer", version = "0.20" }
|
||||
gst-video = { package = "gstreamer-video", path = "../gstreamer-video", version = "0.20" }
|
||||
once_cell = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
|
|
|
@ -98,6 +98,15 @@ impl Player {
|
|||
}
|
||||
}
|
||||
|
||||
impl Default for Player {
|
||||
fn default() -> Self {
|
||||
Self::new(
|
||||
None::<crate::PlayerVideoRenderer>,
|
||||
None::<crate::PlayerSignalDispatcher>,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" fn duration_changed_trampoline<
|
||||
F: Fn(&Player, Option<gst::ClockTime>) + Send + 'static,
|
||||
>(
|
||||
|
|
|
@ -7,18 +7,24 @@ libc = "0.2"
|
|||
[dependencies.glib]
|
||||
package = "glib-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gobject]
|
||||
package = "gobject-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gst]
|
||||
package = "gstreamer-sys"
|
||||
path = "../../gstreamer/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dependencies.gst_video]
|
||||
package = "gstreamer-video-sys"
|
||||
path = "../../gstreamer-video/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dev-dependencies]
|
||||
shell-words = "1.0.0"
|
||||
|
@ -45,7 +51,7 @@ license = "MIT"
|
|||
name = "gstreamer-player-sys"
|
||||
readme = "README.md"
|
||||
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
edition = "2021"
|
||||
rust-version = "1.64"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "gstreamer-rtp"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
authors = ["Mathieu Duponchelle <mathieu@centricular.com>", "Sebastian Dröge <sebastian@centricular.com>"]
|
||||
categories = ["api-bindings", "multimedia"]
|
||||
description = "Rust bindings for GStreamer Rtp library"
|
||||
|
@ -17,9 +17,9 @@ rust-version = "1.64"
|
|||
bitflags = "1.0"
|
||||
once_cell = "1.0"
|
||||
libc = "0.2"
|
||||
ffi = { package = "gstreamer-rtp-sys", path = "sys" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer" }
|
||||
ffi = { package = "gstreamer-rtp-sys", path = "sys", version = "0.20" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.17", version = "0.17" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer", version = "0.20" }
|
||||
serde = { version = "1.0", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
|
|
|
@ -7,14 +7,18 @@ libc = "0.2"
|
|||
[dependencies.glib]
|
||||
package = "glib-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gst_base]
|
||||
package = "gstreamer-base-sys"
|
||||
path = "../../gstreamer-base/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dependencies.gst]
|
||||
package = "gstreamer-sys"
|
||||
path = "../../gstreamer/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dev-dependencies]
|
||||
shell-words = "1.0.0"
|
||||
|
@ -41,7 +45,7 @@ license = "MIT"
|
|||
name = "gstreamer-rtp-sys"
|
||||
readme = "README.md"
|
||||
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
edition = "2021"
|
||||
rust-version = "1.64"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "gstreamer-rtsp-server"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
authors = ["Mathieu Duponchelle <mathieu@centricular.com>", "Sebastian Dröge <sebastian@centricular.com>"]
|
||||
categories = ["api-bindings", "multimedia"]
|
||||
description = "Rust bindings for GStreamer RTSP Server library"
|
||||
|
@ -17,13 +17,13 @@ rust-version = "1.64"
|
|||
bitflags = "1.0"
|
||||
libc = "0.2"
|
||||
once_cell = "1.0"
|
||||
ffi = { package = "gstreamer-rtsp-server-sys", path = "sys" }
|
||||
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-sdp = { package = "gstreamer-sdp", path = "../gstreamer-sdp" }
|
||||
gst-rtsp = { package = "gstreamer-rtsp", path = "../gstreamer-rtsp" }
|
||||
gst-net = { package = "gstreamer-net", path = "../gstreamer-net" }
|
||||
ffi = { package = "gstreamer-rtsp-server-sys", path = "sys", version = "0.20" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.17", version = "0.17" }
|
||||
gio = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.17", version = "0.17" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer", version = "0.20" }
|
||||
gst-sdp = { package = "gstreamer-sdp", path = "../gstreamer-sdp", version = "0.20" }
|
||||
gst-rtsp = { package = "gstreamer-rtsp", path = "../gstreamer-rtsp", version = "0.20" }
|
||||
gst-net = { package = "gstreamer-net", path = "../gstreamer-net", version = "0.20" }
|
||||
serde = { version = "1.0", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||
|
||||
use std::{marker::PhantomData, ptr};
|
||||
use std::{
|
||||
marker::PhantomData,
|
||||
ptr::{self, addr_of},
|
||||
};
|
||||
|
||||
use glib::translate::*;
|
||||
use gst_rtsp::RTSPUrl;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
#[doc(alias = "GstRTSPContext")]
|
||||
#[repr(transparent)]
|
||||
pub struct RTSPContext(ptr::NonNull<ffi::GstRTSPContext>);
|
||||
|
||||
impl RTSPContext {
|
||||
|
@ -22,7 +27,22 @@ impl RTSPContext {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: Add various getters for all the contained fields as needed
|
||||
#[inline]
|
||||
pub fn uri(&self) -> Option<&RTSPUrl> {
|
||||
unsafe {
|
||||
let ptr = self.0.as_ptr();
|
||||
if (*ptr).uri.is_null() {
|
||||
None
|
||||
} else {
|
||||
let uri = RTSPUrl::from_glib_ptr_borrow(
|
||||
addr_of!((*ptr).uri) as *const *const gst_rtsp::ffi::GstRTSPUrl
|
||||
);
|
||||
Some(uri)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Add additional getters for all the contained fields as needed
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
|
|
|
@ -736,6 +736,236 @@ unsafe impl<T: RTSPClientImpl> IsSubclassable<T> for RTSPClient {
|
|||
fn class_init(klass: &mut glib::Class<Self>) {
|
||||
Self::parent_class_init::<T>(klass);
|
||||
let klass = klass.as_mut();
|
||||
|
||||
// There was unintentional ABI breakage in 1.18 so let's work around that
|
||||
// for now by casting to the old struct layout.
|
||||
#[cfg(not(feature = "v1_18"))]
|
||||
{
|
||||
if gst::version() < (1, 18, 0, 0) {
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(C)]
|
||||
pub struct CompatClass {
|
||||
pub parent_class: glib::gobject_ffi::GObjectClass,
|
||||
pub create_sdp: Option<
|
||||
unsafe extern "C" fn(
|
||||
*mut ffi::GstRTSPClient,
|
||||
*mut ffi::GstRTSPMedia,
|
||||
)
|
||||
-> *mut gst_sdp::ffi::GstSDPMessage,
|
||||
>,
|
||||
pub configure_client_media: Option<
|
||||
unsafe extern "C" fn(
|
||||
*mut ffi::GstRTSPClient,
|
||||
*mut ffi::GstRTSPMedia,
|
||||
*mut ffi::GstRTSPStream,
|
||||
*mut ffi::GstRTSPContext,
|
||||
) -> glib::ffi::gboolean,
|
||||
>,
|
||||
pub configure_client_transport: Option<
|
||||
unsafe extern "C" fn(
|
||||
*mut ffi::GstRTSPClient,
|
||||
*mut ffi::GstRTSPContext,
|
||||
*mut gst_rtsp::ffi::GstRTSPTransport,
|
||||
) -> glib::ffi::gboolean,
|
||||
>,
|
||||
pub params_set: Option<
|
||||
unsafe extern "C" fn(
|
||||
*mut ffi::GstRTSPClient,
|
||||
*mut ffi::GstRTSPContext,
|
||||
)
|
||||
-> gst_rtsp::ffi::GstRTSPResult,
|
||||
>,
|
||||
pub params_get: Option<
|
||||
unsafe extern "C" fn(
|
||||
*mut ffi::GstRTSPClient,
|
||||
*mut ffi::GstRTSPContext,
|
||||
)
|
||||
-> gst_rtsp::ffi::GstRTSPResult,
|
||||
>,
|
||||
pub make_path_from_uri: Option<
|
||||
unsafe extern "C" fn(
|
||||
*mut ffi::GstRTSPClient,
|
||||
*const gst_rtsp::ffi::GstRTSPUrl,
|
||||
) -> *mut libc::c_char,
|
||||
>,
|
||||
pub closed: Option<unsafe extern "C" fn(*mut ffi::GstRTSPClient)>,
|
||||
pub new_session: Option<
|
||||
unsafe extern "C" fn(*mut ffi::GstRTSPClient, *mut ffi::GstRTSPSession),
|
||||
>,
|
||||
pub options_request: Option<
|
||||
unsafe extern "C" fn(*mut ffi::GstRTSPClient, *mut ffi::GstRTSPContext),
|
||||
>,
|
||||
pub describe_request: Option<
|
||||
unsafe extern "C" fn(*mut ffi::GstRTSPClient, *mut ffi::GstRTSPContext),
|
||||
>,
|
||||
pub setup_request: Option<
|
||||
unsafe extern "C" fn(*mut ffi::GstRTSPClient, *mut ffi::GstRTSPContext),
|
||||
>,
|
||||
pub play_request: Option<
|
||||
unsafe extern "C" fn(*mut ffi::GstRTSPClient, *mut ffi::GstRTSPContext),
|
||||
>,
|
||||
pub pause_request: Option<
|
||||
unsafe extern "C" fn(*mut ffi::GstRTSPClient, *mut ffi::GstRTSPContext),
|
||||
>,
|
||||
pub teardown_request: Option<
|
||||
unsafe extern "C" fn(*mut ffi::GstRTSPClient, *mut ffi::GstRTSPContext),
|
||||
>,
|
||||
pub set_parameter_request: Option<
|
||||
unsafe extern "C" fn(*mut ffi::GstRTSPClient, *mut ffi::GstRTSPContext),
|
||||
>,
|
||||
pub get_parameter_request: Option<
|
||||
unsafe extern "C" fn(*mut ffi::GstRTSPClient, *mut ffi::GstRTSPContext),
|
||||
>,
|
||||
pub handle_response: Option<
|
||||
unsafe extern "C" fn(*mut ffi::GstRTSPClient, *mut ffi::GstRTSPContext),
|
||||
>,
|
||||
pub tunnel_http_response: Option<
|
||||
unsafe extern "C" fn(
|
||||
*mut ffi::GstRTSPClient,
|
||||
*mut gst_rtsp::ffi::GstRTSPMessage,
|
||||
*mut gst_rtsp::ffi::GstRTSPMessage,
|
||||
),
|
||||
>,
|
||||
pub send_message: Option<
|
||||
unsafe extern "C" fn(
|
||||
*mut ffi::GstRTSPClient,
|
||||
*mut ffi::GstRTSPContext,
|
||||
*mut gst_rtsp::ffi::GstRTSPMessage,
|
||||
),
|
||||
>,
|
||||
pub handle_sdp: Option<
|
||||
unsafe extern "C" fn(
|
||||
*mut ffi::GstRTSPClient,
|
||||
*mut ffi::GstRTSPContext,
|
||||
*mut ffi::GstRTSPMedia,
|
||||
*mut gst_sdp::ffi::GstSDPMessage,
|
||||
) -> glib::ffi::gboolean,
|
||||
>,
|
||||
pub announce_request: Option<
|
||||
unsafe extern "C" fn(*mut ffi::GstRTSPClient, *mut ffi::GstRTSPContext),
|
||||
>,
|
||||
pub record_request: Option<
|
||||
unsafe extern "C" fn(*mut ffi::GstRTSPClient, *mut ffi::GstRTSPContext),
|
||||
>,
|
||||
pub check_requirements: Option<
|
||||
unsafe extern "C" fn(
|
||||
*mut ffi::GstRTSPClient,
|
||||
*mut ffi::GstRTSPContext,
|
||||
*mut *mut libc::c_char,
|
||||
) -> *mut libc::c_char,
|
||||
>,
|
||||
pub pre_options_request: Option<
|
||||
unsafe extern "C" fn(
|
||||
*mut ffi::GstRTSPClient,
|
||||
*mut ffi::GstRTSPContext,
|
||||
)
|
||||
-> gst_rtsp::ffi::GstRTSPStatusCode,
|
||||
>,
|
||||
pub pre_describe_request: Option<
|
||||
unsafe extern "C" fn(
|
||||
*mut ffi::GstRTSPClient,
|
||||
*mut ffi::GstRTSPContext,
|
||||
)
|
||||
-> gst_rtsp::ffi::GstRTSPStatusCode,
|
||||
>,
|
||||
pub pre_setup_request: Option<
|
||||
unsafe extern "C" fn(
|
||||
*mut ffi::GstRTSPClient,
|
||||
*mut ffi::GstRTSPContext,
|
||||
)
|
||||
-> gst_rtsp::ffi::GstRTSPStatusCode,
|
||||
>,
|
||||
pub pre_play_request: Option<
|
||||
unsafe extern "C" fn(
|
||||
*mut ffi::GstRTSPClient,
|
||||
*mut ffi::GstRTSPContext,
|
||||
)
|
||||
-> gst_rtsp::ffi::GstRTSPStatusCode,
|
||||
>,
|
||||
pub pre_pause_request: Option<
|
||||
unsafe extern "C" fn(
|
||||
*mut ffi::GstRTSPClient,
|
||||
*mut ffi::GstRTSPContext,
|
||||
)
|
||||
-> gst_rtsp::ffi::GstRTSPStatusCode,
|
||||
>,
|
||||
pub pre_teardown_request: Option<
|
||||
unsafe extern "C" fn(
|
||||
*mut ffi::GstRTSPClient,
|
||||
*mut ffi::GstRTSPContext,
|
||||
)
|
||||
-> gst_rtsp::ffi::GstRTSPStatusCode,
|
||||
>,
|
||||
pub pre_set_parameter_request: Option<
|
||||
unsafe extern "C" fn(
|
||||
*mut ffi::GstRTSPClient,
|
||||
*mut ffi::GstRTSPContext,
|
||||
)
|
||||
-> gst_rtsp::ffi::GstRTSPStatusCode,
|
||||
>,
|
||||
pub pre_get_parameter_request: Option<
|
||||
unsafe extern "C" fn(
|
||||
*mut ffi::GstRTSPClient,
|
||||
*mut ffi::GstRTSPContext,
|
||||
)
|
||||
-> gst_rtsp::ffi::GstRTSPStatusCode,
|
||||
>,
|
||||
pub pre_announce_request: Option<
|
||||
unsafe extern "C" fn(
|
||||
*mut ffi::GstRTSPClient,
|
||||
*mut ffi::GstRTSPContext,
|
||||
)
|
||||
-> gst_rtsp::ffi::GstRTSPStatusCode,
|
||||
>,
|
||||
pub pre_record_request: Option<
|
||||
unsafe extern "C" fn(
|
||||
*mut ffi::GstRTSPClient,
|
||||
*mut ffi::GstRTSPContext,
|
||||
)
|
||||
-> gst_rtsp::ffi::GstRTSPStatusCode,
|
||||
>,
|
||||
pub _gst_reserved: [glib::ffi::gpointer; 4],
|
||||
}
|
||||
|
||||
let klass = unsafe {
|
||||
std::mem::transmute::<&mut ffi::GstRTSPClientClass, &mut CompatClass>(klass)
|
||||
};
|
||||
|
||||
klass.create_sdp = Some(client_create_sdp::<T>);
|
||||
klass.configure_client_media = Some(client_configure_client_media::<T>);
|
||||
klass.params_set = Some(client_params_set::<T>);
|
||||
klass.params_get = Some(client_params_get::<T>);
|
||||
klass.make_path_from_uri = Some(client_make_path_from_uri::<T>);
|
||||
klass.closed = Some(client_closed::<T>);
|
||||
klass.new_session = Some(client_new_session::<T>);
|
||||
klass.options_request = Some(client_options_request::<T>);
|
||||
klass.describe_request = Some(client_describe_request::<T>);
|
||||
klass.setup_request = Some(client_setup_request::<T>);
|
||||
klass.play_request = Some(client_play_request::<T>);
|
||||
klass.pause_request = Some(client_pause_request::<T>);
|
||||
klass.teardown_request = Some(client_teardown_request::<T>);
|
||||
klass.set_parameter_request = Some(client_set_parameter_request::<T>);
|
||||
klass.get_parameter_request = Some(client_get_parameter_request::<T>);
|
||||
klass.announce_request = Some(client_announce_request::<T>);
|
||||
klass.record_request = Some(client_record_request::<T>);
|
||||
klass.handle_response = Some(client_handle_response::<T>);
|
||||
klass.handle_sdp = Some(client_handle_sdp::<T>);
|
||||
klass.check_requirements = Some(client_check_requirements::<T>);
|
||||
klass.pre_options_request = Some(client_pre_options_request::<T>);
|
||||
klass.pre_describe_request = Some(client_pre_describe_request::<T>);
|
||||
klass.pre_setup_request = Some(client_pre_setup_request::<T>);
|
||||
klass.pre_play_request = Some(client_pre_play_request::<T>);
|
||||
klass.pre_pause_request = Some(client_pre_pause_request::<T>);
|
||||
klass.pre_teardown_request = Some(client_pre_teardown_request::<T>);
|
||||
klass.pre_set_parameter_request = Some(client_pre_set_parameter_request::<T>);
|
||||
klass.pre_get_parameter_request = Some(client_pre_get_parameter_request::<T>);
|
||||
klass.pre_announce_request = Some(client_pre_announce_request::<T>);
|
||||
klass.pre_record_request = Some(client_pre_record_request::<T>);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
klass.create_sdp = Some(client_create_sdp::<T>);
|
||||
klass.configure_client_media = Some(client_configure_client_media::<T>);
|
||||
klass.params_set = Some(client_params_set::<T>);
|
||||
|
|
|
@ -7,30 +7,40 @@ libc = "0.2"
|
|||
[dependencies.gio]
|
||||
package = "gio-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.glib]
|
||||
package = "glib-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gobject]
|
||||
package = "gobject-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gst_net]
|
||||
package = "gstreamer-net-sys"
|
||||
path = "../../gstreamer-net/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dependencies.gst_rtsp]
|
||||
package = "gstreamer-rtsp-sys"
|
||||
path = "../../gstreamer-rtsp/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dependencies.gst_sdp]
|
||||
package = "gstreamer-sdp-sys"
|
||||
path = "../../gstreamer-sdp/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dependencies.gst]
|
||||
package = "gstreamer-sys"
|
||||
path = "../../gstreamer/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dev-dependencies]
|
||||
shell-words = "1.0.0"
|
||||
|
@ -57,7 +67,7 @@ license = "MIT"
|
|||
name = "gstreamer-rtsp-server-sys"
|
||||
readme = "README.md"
|
||||
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
edition = "2021"
|
||||
rust-version = "1.64"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "gstreamer-rtsp"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
authors = ["Mathieu Duponchelle <mathieu@centricular.com>", "Sebastian Dröge <sebastian@centricular.com>"]
|
||||
categories = ["api-bindings", "multimedia"]
|
||||
description = "Rust bindings for GStreamer Rtsp library"
|
||||
|
@ -16,10 +16,10 @@ rust-version = "1.64"
|
|||
[dependencies]
|
||||
bitflags = "1.0"
|
||||
libc = "0.2"
|
||||
ffi = { package = "gstreamer-rtsp-sys", path = "sys" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer" }
|
||||
gst-sdp = { package = "gstreamer-sdp", path = "../gstreamer-sdp" }
|
||||
ffi = { package = "gstreamer-rtsp-sys", path = "sys", version = "0.20" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.17", version = "0.17" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer", version = "0.20" }
|
||||
gst-sdp = { package = "gstreamer-sdp", path = "../gstreamer-sdp", version = "0.20" }
|
||||
serde = { version = "1.0", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
|
|
|
@ -7,22 +7,30 @@ libc = "0.2"
|
|||
[dependencies.gio]
|
||||
package = "gio-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.glib]
|
||||
package = "glib-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gobject]
|
||||
package = "gobject-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gst_sdp]
|
||||
package = "gstreamer-sdp-sys"
|
||||
path = "../../gstreamer-sdp/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dependencies.gst]
|
||||
package = "gstreamer-sys"
|
||||
path = "../../gstreamer/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dev-dependencies]
|
||||
shell-words = "1.0.0"
|
||||
|
@ -49,7 +57,7 @@ license = "MIT"
|
|||
name = "gstreamer-rtsp-sys"
|
||||
readme = "README.md"
|
||||
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
edition = "2021"
|
||||
rust-version = "1.64"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "gstreamer-sdp"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
authors = ["Mathieu Duponchelle <mathieu@centricular.com>", "Sebastian Dröge <sebastian@centricular.com>"]
|
||||
categories = ["api-bindings", "multimedia"]
|
||||
description = "Rust bindings for GStreamer Sdp library"
|
||||
|
@ -14,9 +14,9 @@ edition = "2021"
|
|||
rust-version = "1.64"
|
||||
|
||||
[dependencies]
|
||||
ffi = { package = "gstreamer-sdp-sys", path = "sys" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer" }
|
||||
ffi = { package = "gstreamer-sdp-sys", path = "sys", version = "0.20" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.17", version = "0.17" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer", version = "0.20" }
|
||||
|
||||
[dev-dependencies]
|
||||
gir-format-check = "0.1"
|
||||
|
|
|
@ -7,10 +7,13 @@ libc = "0.2"
|
|||
[dependencies.glib]
|
||||
package = "glib-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gst]
|
||||
package = "gstreamer-sys"
|
||||
path = "../../gstreamer/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dev-dependencies]
|
||||
shell-words = "1.0.0"
|
||||
|
@ -37,7 +40,7 @@ license = "MIT"
|
|||
name = "gstreamer-sdp-sys"
|
||||
readme = "README.md"
|
||||
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
edition = "2021"
|
||||
rust-version = "1.64"
|
||||
|
||||
|
|
|
@ -7,14 +7,19 @@ libc = "0.2"
|
|||
[dependencies.glib]
|
||||
package = "glib-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gobject]
|
||||
package = "gobject-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gst]
|
||||
package = "gstreamer-sys"
|
||||
path = "../../gstreamer/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dev-dependencies]
|
||||
shell-words = "1.0.0"
|
||||
|
@ -41,7 +46,7 @@ license = "MIT"
|
|||
name = "gstreamer-tag-sys"
|
||||
readme = "README.md"
|
||||
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
edition = "2021"
|
||||
rust-version = "1.64"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "gstreamer-utils"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
authors = ["Mathieu Duponchelle <mathieu@centricular.com>", "Thibault Saunier <tsaunier@igalia.com>"]
|
||||
categories = ["multimedia"]
|
||||
description = "Exposes an object to build several Gst pipeline with one producer and several consumer"
|
||||
|
@ -16,9 +16,9 @@ rust-version = "1.64"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
gst = { package = "gstreamer", path = "../gstreamer", features = ["v1_20"] }
|
||||
gst_app = { package = "gstreamer-app", path = "../gstreamer-app", features = ["v1_20"] }
|
||||
gst_video = { package = "gstreamer-video", path = "../gstreamer-video", features = ["v1_20"] }
|
||||
gst = { package = "gstreamer", path = "../gstreamer", version = "0.20", features = ["v1_20"] }
|
||||
gst_app = { package = "gstreamer-app", path = "../gstreamer-app", version = "0.20", features = ["v1_20"] }
|
||||
gst_video = { package = "gstreamer-video", path = "../gstreamer-video", version = "0.20", features = ["v1_20"] }
|
||||
once_cell = "1"
|
||||
thiserror = "1"
|
||||
|
||||
|
|
|
@ -235,7 +235,7 @@ impl StreamProducer {
|
|||
}
|
||||
}
|
||||
|
||||
/// configure if EOS from appsrc should be forwarded to all the consumers
|
||||
/// configure if EOS from appsrc should be forwarded to all the consumers (default: `true`)
|
||||
pub fn set_forward_eos(&self, forward_eos: bool) {
|
||||
self.consumers.lock().unwrap().forward_eos = forward_eos;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "gstreamer-validate"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
authors = ["Philippe Normand <philn@igalia.com>"]
|
||||
categories = ["api-bindings", "multimedia"]
|
||||
description = "Rust bindings for GStreamer WebRTC library"
|
||||
|
@ -15,9 +15,9 @@ rust-version = "1.64"
|
|||
|
||||
[dependencies]
|
||||
libc = "0.2"
|
||||
ffi = { package = "gstreamer-validate-sys", path = "sys" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer", features = ["v1_22"] }
|
||||
ffi = { package = "gstreamer-validate-sys", path = "sys", version = "0.20" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.17", version = "0.17" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer", version = "0.20", features = ["v1_22"] }
|
||||
bitflags = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
|
|
|
@ -9,7 +9,7 @@ license = "MIT"
|
|||
name = "gstreamer-validate-sys"
|
||||
readme = "README.md"
|
||||
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
edition = "2021"
|
||||
rust-version = "1.57"
|
||||
|
||||
|
@ -32,18 +32,25 @@ libc = "0.2"
|
|||
[dependencies.glib]
|
||||
package = "glib-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gobject]
|
||||
package = "gobject-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gio]
|
||||
package = "gio-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gst]
|
||||
package = "gstreamer-sys"
|
||||
path = "../../gstreamer/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dev-dependencies]
|
||||
shell-words = "1.0.0"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "gstreamer-video"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
|
||||
categories = ["api-bindings", "multimedia"]
|
||||
description = "Rust bindings for GStreamer Video library"
|
||||
|
@ -17,16 +17,16 @@ rust-version = "1.64"
|
|||
bitflags = "1.0"
|
||||
libc = "0.2"
|
||||
cfg-if = "1.0"
|
||||
ffi = { package = "gstreamer-video-sys", path = "sys" }
|
||||
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-video-sys", path = "sys", version = "0.20" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.17", version = "0.17" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer", version = "0.20" }
|
||||
gst-base = { package = "gstreamer-base", path = "../gstreamer-base", version = "0.20" }
|
||||
once_cell = "1.0"
|
||||
futures-channel = "0.3"
|
||||
serde = { version = "1.0", optional = true, features = ["derive"] }
|
||||
|
||||
[dev-dependencies]
|
||||
itertools = "0.10"
|
||||
itertools = "0.11"
|
||||
serde_json = "1.0"
|
||||
gir-format-check = "0.1"
|
||||
|
||||
|
|
|
@ -10,7 +10,18 @@ pub struct VideoCapsBuilder<T> {
|
|||
}
|
||||
|
||||
impl VideoCapsBuilder<gst::caps::NoFeature> {
|
||||
// rustdoc-stripper-ignore-next
|
||||
/// Constructs an `VideoCapsBuilder` for the "video/x-raw" encoding.
|
||||
///
|
||||
/// If left unchanged, the resulting `Caps` will be initialized with:
|
||||
/// - "video/x-raw" encoding.
|
||||
/// - all available formats.
|
||||
/// - maximum width range.
|
||||
/// - maximum height range.
|
||||
///
|
||||
/// Use [`VideoCapsBuilder::for_encoding`] to specify another encoding.
|
||||
pub fn new() -> Self {
|
||||
assert_initialized_main_thread!();
|
||||
let builder = Caps::builder(glib::gstr!("video/x-raw"));
|
||||
let builder = VideoCapsBuilder { builder };
|
||||
builder
|
||||
|
@ -20,6 +31,18 @@ impl VideoCapsBuilder<gst::caps::NoFeature> {
|
|||
.framerate_range(..)
|
||||
}
|
||||
|
||||
// rustdoc-stripper-ignore-next
|
||||
/// Constructs an `VideoCapsBuilder` for the specified encoding.
|
||||
///
|
||||
/// The resulting `Caps` will use the `encoding` argument as name
|
||||
/// and will not contain any additional fields unless explicitly added.
|
||||
pub fn for_encoding(encoding: impl IntoGStr) -> Self {
|
||||
assert_initialized_main_thread!();
|
||||
VideoCapsBuilder {
|
||||
builder: Caps::builder(encoding),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn any_features(self) -> VideoCapsBuilder<gst::caps::HasFeatures> {
|
||||
VideoCapsBuilder {
|
||||
builder: self.builder.any_features(),
|
||||
|
@ -283,41 +306,60 @@ fn next_fraction(fraction: gst::Fraction) -> gst::Fraction {
|
|||
gst::Fraction::new(new_num, new_den)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_0_1_fraction() {
|
||||
gst::init().unwrap();
|
||||
let zero_over_one = gst::Fraction::new(0, 1);
|
||||
let prev = previous_fraction(zero_over_one);
|
||||
assert_eq!(prev.numer(), -1);
|
||||
assert_eq!(prev.denom(), i32::MAX);
|
||||
let next = next_fraction(zero_over_one);
|
||||
assert_eq!(next.numer(), 1);
|
||||
assert_eq!(next.denom(), i32::MAX);
|
||||
}
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{next_fraction, previous_fraction, VideoCapsBuilder};
|
||||
|
||||
#[test]
|
||||
fn test_25_1() {
|
||||
gst::init().unwrap();
|
||||
let twentyfive = gst::Fraction::new(25, 1);
|
||||
let next = next_fraction(twentyfive);
|
||||
//25.000000011641532
|
||||
assert_eq!(next.numer(), 2147483626);
|
||||
assert_eq!(next.denom(), 85899345);
|
||||
let prev = previous_fraction(twentyfive);
|
||||
//24.999999988358468
|
||||
assert_eq!(prev.numer(), 2147483624);
|
||||
assert_eq!(prev.denom(), 85899345);
|
||||
}
|
||||
#[test]
|
||||
fn test_1_25() {
|
||||
gst::init().unwrap();
|
||||
let twentyfive = gst::Fraction::new(1, 25);
|
||||
let next = next_fraction(twentyfive);
|
||||
//0.040000000018626
|
||||
assert_eq!(next.numer(), 85899345);
|
||||
assert_eq!(next.denom(), 2147483624);
|
||||
let prev = previous_fraction(twentyfive);
|
||||
//0.039999999981374
|
||||
assert_eq!(prev.numer(), 85899345);
|
||||
assert_eq!(prev.denom(), 2147483626);
|
||||
#[test]
|
||||
fn default_encoding() {
|
||||
gst::init().unwrap();
|
||||
let caps = VideoCapsBuilder::new().build();
|
||||
assert_eq!(caps.structure(0).unwrap().name(), "video/x-raw");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn explicit_encoding() {
|
||||
gst::init().unwrap();
|
||||
let caps = VideoCapsBuilder::for_encoding("video/mpeg").build();
|
||||
assert_eq!(caps.structure(0).unwrap().name(), "video/mpeg");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_0_1_fraction() {
|
||||
gst::init().unwrap();
|
||||
let zero_over_one = gst::Fraction::new(0, 1);
|
||||
let prev = previous_fraction(zero_over_one);
|
||||
assert_eq!(prev.numer(), -1);
|
||||
assert_eq!(prev.denom(), i32::MAX);
|
||||
let next = next_fraction(zero_over_one);
|
||||
assert_eq!(next.numer(), 1);
|
||||
assert_eq!(next.denom(), i32::MAX);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_25_1() {
|
||||
gst::init().unwrap();
|
||||
let twentyfive = gst::Fraction::new(25, 1);
|
||||
let next = next_fraction(twentyfive);
|
||||
//25.000000011641532
|
||||
assert_eq!(next.numer(), 2147483626);
|
||||
assert_eq!(next.denom(), 85899345);
|
||||
let prev = previous_fraction(twentyfive);
|
||||
//24.999999988358468
|
||||
assert_eq!(prev.numer(), 2147483624);
|
||||
assert_eq!(prev.denom(), 85899345);
|
||||
}
|
||||
#[test]
|
||||
fn test_1_25() {
|
||||
gst::init().unwrap();
|
||||
let twentyfive = gst::Fraction::new(1, 25);
|
||||
let next = next_fraction(twentyfive);
|
||||
//0.040000000018626
|
||||
assert_eq!(next.numer(), 85899345);
|
||||
assert_eq!(next.denom(), 2147483624);
|
||||
let prev = previous_fraction(twentyfive);
|
||||
//0.039999999981374
|
||||
assert_eq!(prev.numer(), 85899345);
|
||||
assert_eq!(prev.denom(), 2147483626);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -502,9 +502,7 @@ impl fmt::Debug for VideoFormatInfo {
|
|||
{
|
||||
fmt.field(
|
||||
"tile-info",
|
||||
&(0..self.n_planes())
|
||||
.into_iter()
|
||||
.map(|plane| self.tile_info(plane)),
|
||||
&(0..self.n_planes()).map(|plane| self.tile_info(plane)),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ pub enum Writable {}
|
|||
pub struct VideoFrame<T> {
|
||||
frame: ffi::GstVideoFrame,
|
||||
buffer: gst::Buffer,
|
||||
info: crate::VideoInfo,
|
||||
phantom: PhantomData<T>,
|
||||
}
|
||||
|
||||
|
@ -20,10 +19,10 @@ unsafe impl<T> Sync for VideoFrame<T> {}
|
|||
impl<T> fmt::Debug for VideoFrame<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("VideoFrame")
|
||||
.field("frame", &self.frame)
|
||||
.field("buffer", &self.buffer)
|
||||
.field("info", &self.info)
|
||||
.field("phantom", &self.phantom)
|
||||
.field("flags", &self.flags())
|
||||
.field("id", &self.id())
|
||||
.field("buffer", &self.buffer())
|
||||
.field("info", &self.info())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +30,7 @@ impl<T> fmt::Debug for VideoFrame<T> {
|
|||
impl<T> VideoFrame<T> {
|
||||
#[inline]
|
||||
pub fn info(&self) -> &crate::VideoInfo {
|
||||
&self.info
|
||||
unsafe { &*(&self.frame.info as *const ffi::GstVideoInfo as *const crate::VideoInfo) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -46,8 +45,12 @@ impl<T> VideoFrame<T> {
|
|||
|
||||
#[inline]
|
||||
pub fn into_buffer(self) -> gst::Buffer {
|
||||
let s = mem::ManuallyDrop::new(self);
|
||||
unsafe { ptr::read(&s.buffer) }
|
||||
unsafe {
|
||||
let mut s = mem::ManuallyDrop::new(self);
|
||||
let buffer = ptr::read(&s.buffer);
|
||||
ffi::gst_video_frame_unmap(&mut s.frame);
|
||||
buffer
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_video_frame_copy")]
|
||||
|
@ -250,12 +253,10 @@ impl<T> VideoFrame<T> {
|
|||
|
||||
#[inline]
|
||||
pub unsafe fn from_glib_full(frame: ffi::GstVideoFrame) -> Self {
|
||||
let info = crate::VideoInfo(ptr::read(&frame.info));
|
||||
let buffer = gst::Buffer::from_glib_none(frame.buffer);
|
||||
Self {
|
||||
frame,
|
||||
buffer,
|
||||
info,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
@ -263,10 +264,8 @@ impl<T> VideoFrame<T> {
|
|||
#[inline]
|
||||
pub fn as_video_frame_ref(&self) -> VideoFrameRef<&gst::BufferRef> {
|
||||
let frame = unsafe { ptr::read(&self.frame) };
|
||||
let info = self.info.clone();
|
||||
VideoFrameRef {
|
||||
frame,
|
||||
info,
|
||||
unmap: false,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
|
@ -279,7 +278,11 @@ impl<T> VideoFrame<T> {
|
|||
|
||||
#[inline]
|
||||
pub fn into_raw(self) -> ffi::GstVideoFrame {
|
||||
mem::ManuallyDrop::new(self).frame
|
||||
unsafe {
|
||||
let mut s = mem::ManuallyDrop::new(self);
|
||||
ptr::drop_in_place(&mut s.buffer);
|
||||
s.frame
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -315,11 +318,9 @@ impl VideoFrame<Readable> {
|
|||
Err(buffer)
|
||||
} else {
|
||||
let frame = frame.assume_init();
|
||||
let info = crate::VideoInfo(ptr::read(&frame.info));
|
||||
Ok(Self {
|
||||
frame,
|
||||
buffer,
|
||||
info,
|
||||
phantom: PhantomData,
|
||||
})
|
||||
}
|
||||
|
@ -350,11 +351,9 @@ impl VideoFrame<Readable> {
|
|||
Err(buffer)
|
||||
} else {
|
||||
let frame = frame.assume_init();
|
||||
let info = crate::VideoInfo(ptr::read(&frame.info));
|
||||
Ok(Self {
|
||||
frame,
|
||||
buffer,
|
||||
info,
|
||||
phantom: PhantomData,
|
||||
})
|
||||
}
|
||||
|
@ -392,11 +391,9 @@ impl VideoFrame<Writable> {
|
|||
Err(buffer)
|
||||
} else {
|
||||
let frame = frame.assume_init();
|
||||
let info = crate::VideoInfo(ptr::read(&frame.info));
|
||||
Ok(Self {
|
||||
frame,
|
||||
buffer,
|
||||
info,
|
||||
phantom: PhantomData,
|
||||
})
|
||||
}
|
||||
|
@ -429,11 +426,9 @@ impl VideoFrame<Writable> {
|
|||
Err(buffer)
|
||||
} else {
|
||||
let frame = frame.assume_init();
|
||||
let info = crate::VideoInfo(ptr::read(&frame.info));
|
||||
Ok(Self {
|
||||
frame,
|
||||
buffer,
|
||||
info,
|
||||
phantom: PhantomData,
|
||||
})
|
||||
}
|
||||
|
@ -489,10 +484,8 @@ impl VideoFrame<Writable> {
|
|||
#[inline]
|
||||
pub fn as_mut_video_frame_ref(&mut self) -> VideoFrameRef<&mut gst::BufferRef> {
|
||||
let frame = unsafe { ptr::read(&self.frame) };
|
||||
let info = self.info.clone();
|
||||
VideoFrameRef {
|
||||
frame,
|
||||
info,
|
||||
unmap: false,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
|
@ -504,18 +497,29 @@ impl VideoFrame<Writable> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct VideoFrameRef<T> {
|
||||
frame: ffi::GstVideoFrame,
|
||||
info: crate::VideoInfo,
|
||||
unmap: bool,
|
||||
phantom: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T> fmt::Debug for VideoFrameRef<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("VideoFrameRef")
|
||||
.field("flags", &self.flags())
|
||||
.field("id", &self.id())
|
||||
.field("buffer", &unsafe {
|
||||
gst::BufferRef::from_ptr(self.frame.buffer)
|
||||
})
|
||||
.field("info", &self.info())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> VideoFrameRef<T> {
|
||||
#[inline]
|
||||
pub fn info(&self) -> &crate::VideoInfo {
|
||||
&self.info
|
||||
unsafe { &*(&self.frame.info as *const ffi::GstVideoInfo as *const crate::VideoInfo) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -735,10 +739,8 @@ impl<'a> VideoFrameRef<&'a gst::BufferRef> {
|
|||
debug_assert!(!frame.is_null());
|
||||
|
||||
let frame = ptr::read(frame);
|
||||
let info = crate::VideoInfo(ptr::read(&frame.info));
|
||||
Borrowed::new(Self {
|
||||
frame,
|
||||
info,
|
||||
unmap: false,
|
||||
phantom: PhantomData,
|
||||
})
|
||||
|
@ -746,10 +748,8 @@ impl<'a> VideoFrameRef<&'a gst::BufferRef> {
|
|||
|
||||
#[inline]
|
||||
pub unsafe fn from_glib_full(frame: ffi::GstVideoFrame) -> Self {
|
||||
let info = crate::VideoInfo(ptr::read(&frame.info));
|
||||
Self {
|
||||
frame,
|
||||
info,
|
||||
unmap: true,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
|
@ -777,10 +777,8 @@ impl<'a> VideoFrameRef<&'a gst::BufferRef> {
|
|||
Err(glib::bool_error!("Failed to map VideoFrame"))
|
||||
} else {
|
||||
let frame = frame.assume_init();
|
||||
let info = crate::VideoInfo(ptr::read(&frame.info));
|
||||
Ok(Self {
|
||||
frame,
|
||||
info,
|
||||
unmap: true,
|
||||
phantom: PhantomData,
|
||||
})
|
||||
|
@ -812,10 +810,8 @@ impl<'a> VideoFrameRef<&'a gst::BufferRef> {
|
|||
Err(glib::bool_error!("Failed to map VideoFrame"))
|
||||
} else {
|
||||
let frame = frame.assume_init();
|
||||
let info = crate::VideoInfo(ptr::read(&frame.info));
|
||||
Ok(Self {
|
||||
frame,
|
||||
info,
|
||||
unmap: true,
|
||||
phantom: PhantomData,
|
||||
})
|
||||
|
@ -835,10 +831,8 @@ impl<'a> VideoFrameRef<&'a mut gst::BufferRef> {
|
|||
debug_assert!(!frame.is_null());
|
||||
|
||||
let frame = ptr::read(frame);
|
||||
let info = crate::VideoInfo(ptr::read(&frame.info));
|
||||
Self {
|
||||
frame,
|
||||
info,
|
||||
unmap: false,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
|
@ -846,10 +840,8 @@ impl<'a> VideoFrameRef<&'a mut gst::BufferRef> {
|
|||
|
||||
#[inline]
|
||||
pub unsafe fn from_glib_full_mut(frame: ffi::GstVideoFrame) -> Self {
|
||||
let info = crate::VideoInfo(ptr::read(&frame.info));
|
||||
Self {
|
||||
frame,
|
||||
info,
|
||||
unmap: true,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
|
@ -879,10 +871,8 @@ impl<'a> VideoFrameRef<&'a mut gst::BufferRef> {
|
|||
Err(glib::bool_error!("Failed to map VideoFrame"))
|
||||
} else {
|
||||
let frame = frame.assume_init();
|
||||
let info = crate::VideoInfo(ptr::read(&frame.info));
|
||||
Ok(Self {
|
||||
frame,
|
||||
info,
|
||||
unmap: true,
|
||||
phantom: PhantomData,
|
||||
})
|
||||
|
@ -916,10 +906,8 @@ impl<'a> VideoFrameRef<&'a mut gst::BufferRef> {
|
|||
Err(glib::bool_error!("Failed to map VideoFrame"))
|
||||
} else {
|
||||
let frame = frame.assume_init();
|
||||
let info = crate::VideoInfo(ptr::read(&frame.info));
|
||||
Ok(Self {
|
||||
frame,
|
||||
info,
|
||||
unmap: true,
|
||||
phantom: PhantomData,
|
||||
})
|
||||
|
|
|
@ -92,6 +92,7 @@ impl From<VideoColorRange> for glib::Value {
|
|||
|
||||
#[doc(alias = "GstVideoColorimetry")]
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(transparent)]
|
||||
pub struct VideoColorimetry(ffi::GstVideoColorimetry);
|
||||
|
||||
impl VideoColorimetry {
|
||||
|
@ -267,6 +268,7 @@ impl TryFrom<crate::VideoMultiviewMode> for crate::VideoMultiviewFramePacking {
|
|||
|
||||
#[doc(alias = "GstVideoInfo")]
|
||||
#[derive(Clone)]
|
||||
#[repr(transparent)]
|
||||
pub struct VideoInfo(pub(crate) ffi::GstVideoInfo);
|
||||
|
||||
impl fmt::Debug for VideoInfo {
|
||||
|
@ -854,7 +856,7 @@ impl VideoInfo {
|
|||
pub fn align_full(
|
||||
&mut self,
|
||||
align: &mut crate::VideoAlignment,
|
||||
) -> Result<([usize; crate::VIDEO_MAX_PLANES]), glib::BoolError> {
|
||||
) -> Result<[usize; crate::VIDEO_MAX_PLANES], glib::BoolError> {
|
||||
let mut plane_size = [0; crate::VIDEO_MAX_PLANES];
|
||||
|
||||
unsafe {
|
||||
|
|
|
@ -7,18 +7,24 @@ libc = "0.2"
|
|||
[dependencies.glib]
|
||||
package = "glib-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gobject]
|
||||
package = "gobject-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gst_base]
|
||||
package = "gstreamer-base-sys"
|
||||
path = "../../gstreamer-base/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dependencies.gst]
|
||||
package = "gstreamer-sys"
|
||||
path = "../../gstreamer/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dev-dependencies]
|
||||
shell-words = "1.0.0"
|
||||
|
@ -45,7 +51,7 @@ license = "MIT"
|
|||
name = "gstreamer-video-sys"
|
||||
readme = "README.md"
|
||||
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
edition = "2021"
|
||||
rust-version = "1.64"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "gstreamer-webrtc"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
|
||||
categories = ["api-bindings", "multimedia"]
|
||||
description = "Rust bindings for GStreamer WebRTC library"
|
||||
|
@ -15,10 +15,10 @@ rust-version = "1.64"
|
|||
|
||||
[dependencies]
|
||||
libc = "0.2"
|
||||
ffi = { package = "gstreamer-webrtc-sys", path = "sys" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer" }
|
||||
gst-sdp = { package = "gstreamer-sdp", path = "../gstreamer-sdp" }
|
||||
ffi = { package = "gstreamer-webrtc-sys", path = "sys", version = "0.20" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.17", version = "0.17" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer", version = "0.20" }
|
||||
gst-sdp = { package = "gstreamer-sdp", path = "../gstreamer-sdp", version = "0.20" }
|
||||
|
||||
[dev-dependencies]
|
||||
gir-format-check = "0.1"
|
||||
|
|
|
@ -22,10 +22,16 @@ pub use crate::auto::*;
|
|||
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
|
||||
mod web_rtc_ice_candidate_stats;
|
||||
mod web_rtc_session_description;
|
||||
#[cfg(any(feature = "v1_22", feature = "dox"))]
|
||||
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
|
||||
mod web_rtcice;
|
||||
|
||||
// Re-export all the traits in a prelude module, so that applications
|
||||
// can always "use gst_webrtc::prelude::*" without getting conflicts
|
||||
pub mod prelude {
|
||||
#[cfg(any(feature = "v1_22", feature = "dox"))]
|
||||
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
|
||||
pub use crate::web_rtcice::WebRTCICEExtManual;
|
||||
#[doc(hidden)]
|
||||
pub use gst_sdp::prelude::*;
|
||||
}
|
||||
|
|
46
gstreamer-webrtc/src/web_rtcice.rs
Normal file
46
gstreamer-webrtc/src/web_rtcice.rs
Normal file
|
@ -0,0 +1,46 @@
|
|||
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||
|
||||
use glib::{prelude::*, translate::*};
|
||||
|
||||
use crate::{WebRTCICE, WebRTCICEStream};
|
||||
|
||||
pub trait WebRTCICEExtManual: 'static {
|
||||
#[doc(alias = "gst_webrtc_ice_add_candidate")]
|
||||
fn add_candidate(&self, stream: &impl IsA<WebRTCICEStream>, candidate: &str);
|
||||
}
|
||||
|
||||
impl<O: IsA<WebRTCICE>> WebRTCICEExtManual for O {
|
||||
fn add_candidate(&self, stream: &impl IsA<WebRTCICEStream>, candidate: &str) {
|
||||
unsafe {
|
||||
use std::{mem, ptr};
|
||||
|
||||
if gst::version() >= (1, 23, 0, 0) {
|
||||
let func = mem::transmute::<
|
||||
unsafe extern "C" fn(
|
||||
*mut ffi::GstWebRTCICE,
|
||||
*mut ffi::GstWebRTCICEStream,
|
||||
*const std::os::raw::c_char,
|
||||
),
|
||||
unsafe extern "C" fn(
|
||||
*mut ffi::GstWebRTCICE,
|
||||
*mut ffi::GstWebRTCICEStream,
|
||||
*const std::os::raw::c_char,
|
||||
*mut gst::ffi::GstPromise,
|
||||
),
|
||||
>(ffi::gst_webrtc_ice_add_candidate);
|
||||
func(
|
||||
self.as_ref().to_glib_none().0,
|
||||
stream.as_ref().to_glib_none().0,
|
||||
candidate.to_glib_none().0,
|
||||
ptr::null_mut(),
|
||||
);
|
||||
} else {
|
||||
ffi::gst_webrtc_ice_add_candidate(
|
||||
self.as_ref().to_glib_none().0,
|
||||
stream.as_ref().to_glib_none().0,
|
||||
candidate.to_glib_none().0,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,14 +7,18 @@ libc = "0.2"
|
|||
[dependencies.glib]
|
||||
package = "glib-sys"
|
||||
git = "https://github.com/gtk-rs/gtk-rs-core"
|
||||
branch = "0.17"
|
||||
version = "0.17"
|
||||
|
||||
[dependencies.gst]
|
||||
package = "gstreamer-sys"
|
||||
path = "../../gstreamer/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dependencies.gst_sdp]
|
||||
package = "gstreamer-sdp-sys"
|
||||
path = "../../gstreamer-sdp/sys"
|
||||
version = "0.20"
|
||||
|
||||
[dev-dependencies]
|
||||
shell-words = "1.0.0"
|
||||
|
@ -42,7 +46,7 @@ license = "MIT"
|
|||
name = "gstreamer-webrtc-sys"
|
||||
readme = "README.md"
|
||||
repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
edition = "2021"
|
||||
rust-version = "1.64"
|
||||
|
||||
|
|
|
@ -5,6 +5,64 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
|||
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html),
|
||||
specifically the [variant used by Rust](http://doc.crates.io/manifest.html#the-version-field).
|
||||
|
||||
## [0.20.7] - 2023-07-05
|
||||
### Fixed
|
||||
- Fix `wait-for-eos` property name string in `appsink`.
|
||||
- Fix various memory leaks in `BaseTransform` subclassing bindings.
|
||||
- Mark some GES APIs as `Send+Sync`.
|
||||
|
||||
### Added
|
||||
- Implement `DiscovererInfo::debug()` and on related structs.
|
||||
+ Add subclassing bindings for `GESFormatter`.
|
||||
|
||||
## [0.20.6] - 2023-06-06
|
||||
### Added
|
||||
- Getter for the `gst_rtsp_server::RTSPContext` URI field.
|
||||
|
||||
### Fixed
|
||||
- `gst_pbutils::DiscovererStreamInfo::stream_id()` can return `NULL`. This is
|
||||
mapped to the empty string for this release to keep backwards compatibility.
|
||||
- `gst_pbutils::DiscovererStreamInfo` iterator methods can be called on any
|
||||
subclass directly now without casting.
|
||||
- Debug logs use the actual function name against instead of the name of a
|
||||
closure generated by the log macros.
|
||||
|
||||
### Changed
|
||||
- Minor performance improvements to debug logging.
|
||||
|
||||
## [0.20.5] - 2023-04-22
|
||||
### Added
|
||||
- `glib::HasParamSpec` impl for miniobjects to allow using them with the
|
||||
properties derive macro.
|
||||
- `Default` impl for `gst_player::Player`.
|
||||
|
||||
## [0.20.4] - 2023-04-07
|
||||
### Fixed
|
||||
- Work around `gst_webrtc::WebRTCICE::add_candidate()` API breakage in 1.24.
|
||||
|
||||
### Changed
|
||||
- Reduce size of `gst_audio::AudioBuffer` and `gst_video::VideoFrame` by a
|
||||
factor of two by not storing an unnecessary copy of the audio/video info.
|
||||
|
||||
## [0.20.3] - 2023-03-14
|
||||
### Fixed
|
||||
- `gst::ParamSpecArray` uses the correct `glib::Type` now.
|
||||
- Work around accidental ABI breakage in 1.18 gst-rtsp-server `GstRTSPClient`.
|
||||
|
||||
### Added
|
||||
- Document `gst_utils::StreamProducer::forward_eos()` default value.
|
||||
|
||||
## [0.20.2] - 2023-02-21
|
||||
### Added
|
||||
- `glib::HasParamSpec` impl for `gst::ClockTime`
|
||||
- `Default` impl for `gst_play::Play`
|
||||
- Constructors for non-raw `gst_audio::AudioCapsBuilder` / `gst_video::VideoCapsBuilder`
|
||||
|
||||
## [0.20.1] - 2023-02-13
|
||||
### Fixed
|
||||
- Fix memory leaks when converting a `gst_audio::AudioBuffer` or
|
||||
`gst_video::VideoFrame` to a `gst::Buffer` or FFI type.
|
||||
|
||||
## [0.20.0] - 2023-02-10
|
||||
### Fixed
|
||||
- Make `gst_gL::GLDisplay::create_context()` `other_context` parameter optional.
|
||||
|
@ -1474,7 +1532,10 @@ specifically the [variant used by Rust](http://doc.crates.io/manifest.html#the-v
|
|||
(< 0.8.0) of the bindings can be found [here](https://github.com/arturoc/gstreamer1.0-rs).
|
||||
The API of the two is incompatible.
|
||||
|
||||
[Unreleased]: https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/compare/0.20.0...HEAD
|
||||
[Unreleased]: https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/compare/0.20.3...HEAD
|
||||
[0.20.3]: https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/compare/0.20.2...0.20.3
|
||||
[0.20.2]: https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/compare/0.20.1...0.20.2
|
||||
[0.20.1]: https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/compare/0.20.0...0.20.1
|
||||
[0.20.0]: https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/compare/0.19.8...0.20.0
|
||||
[0.19.8]: https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/compare/0.19.7...0.19.8
|
||||
[0.19.7]: https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/compare/0.19.6...0.19.7
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "gstreamer"
|
||||
version = "0.20.0"
|
||||
version = "0.20.7"
|
||||
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
|
||||
categories = ["api-bindings", "multimedia"]
|
||||
description = "Rust bindings for GStreamer"
|
||||
|
@ -17,8 +17,8 @@ rust-version = "1.64"
|
|||
bitflags = "1.0"
|
||||
cfg-if = "1.0"
|
||||
libc = "0.2"
|
||||
ffi = { package = "gstreamer-sys", path = "sys" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
|
||||
ffi = { package = "gstreamer-sys", path = "sys", version = "0.20" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.17", version = "0.17" }
|
||||
num-integer = { version = "0.1", default-features = false, features = [] }
|
||||
num-rational = { version = "0.4", default-features = false, features = [] }
|
||||
once_cell = "1.0"
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue