Compare commits

..

1031 commits

Author SHA1 Message Date
Francisco Javier Velázquez-García 8fc652f208 webrtcsink: Refactor value retrieval to avoid lock poisoning
When setting an incorrect property name in settings,
start_stream_discovery_if_needed would panic because it attempts to
unwrap a poisoned lock for settings.

This refactor avoids that situation.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1594>
2024-05-31 08:10:23 +00:00
Francisco Javier Velázquez-García 568e8533fa webrtcsink: Fix typo in property name for av1enc
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1594>
2024-05-31 08:10:23 +00:00
Sebastian Dröge 91bc39367b deny: Add another override for librespot for nix 2024-05-31 10:06:14 +03:00
Arun Raghavan 04e9e5284c webrtc: signaller: A couple of minor doc fixups
The expectation is `Returns:`, not `Return:`

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1525>
2024-05-30 22:16:46 +03:00
Arun Raghavan 1c54c77840 webrtcsink: Add a mechanism for SDP munging
Unfortunately, server implementations might have odd SDP-related quirks,
so let's allow clients a way to work around these oddities themselves.
For now, this means that a client can fix up the H.264 profile-level-id
as required by Twitch (whose media pipeline is more permissive than the
WHIP implementation).

Fixes: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/516
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1525>
2024-05-30 22:16:46 +03:00
Taruntej Kanakamalla 83f76280f5 net/webrtc: Example for whipserver
rudimentary sample to test multiple WHIP client connections

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1339>
2024-05-29 21:03:27 +00:00
Taruntej Kanakamalla 712d4757c3 net/webrtc/whip_signaller: multiple client support in the server
- generate a new session id for every new client
use the session id in the resource url

- remove the producer-peer-id property in the WhipServer signaler as it
is redundant to have producer id in a session having only one producer

- read the 'producer-peer-id' property on the signaller conditionally
if it exists else use the session id as producer id

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1339>
2024-05-29 21:03:27 +00:00
Taruntej Kanakamalla de726ca8d2 net/webrtc: multi producer support in webrtcsrc
- Add a new structure Session
  - manage each producer using a session
  - avoid send EOS when a session terminates, instead keep running
    waiting for any new producer to connect

- Maintain a bin element per session
  - each session bin encapsulates webrtcbin and the decoder if needed
    as well as the parser and filter if requested by the application
    (through request-encoded-filter)
  - this will be helpful to cleanup the session's respective elements
    when the corresponding producer terminates the session

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1339>
2024-05-29 21:03:27 +00:00
Seungha Yang ebdcc403cf transcriberbin: Fix mux-method=cea708
* Update "translation-languages" property to include G_PARAM_CONSTRUCT
so that it can be applied to initial state.

* Change default "translation-languages" value to be None instead of
cea608 specific one. Transcriberbin will be able to configure initia
state depending on selected mux method if "translation-languages" is
unspecified.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1589>
2024-05-30 04:40:09 +09:00
Matthew Waters 45800d7636 tttocea708: ensure periodic sync points in roll up mode
Otherwise, without the relevant DefineWindow, then a receiver cannot
begin to display the captions from the middle of a stream.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1591>
2024-05-29 11:15:10 +00:00
Sebastian Dröge a7418fb483 rtp: Use released version of rtcp-types 2024-05-29 10:30:40 +03:00
Matthew Waters df32e1ebfa rtpsend: ensure only a single rtcp pad push
Otherwise, it can occur that multiple rtcp packets may be produced out
of order.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1426>
2024-05-28 19:58:09 +10:00
Matthew Waters 525179f666 rtpbin2: handle ssrc collisions
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1426>
2024-05-28 19:58:09 +10:00
Nirbheek Chauhan 9485265769 rtspsrc2: Update rtpbin2 support to use rtprecv and rtpsend
USE_RTPBIN2 is now USE_RTP2 because there is no "rtpbin2" now.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1426>
2024-05-28 19:58:09 +10:00
Matthew Waters 1600d3b055 rtpbin2: split send and receive halves into separate elements
There is now two elements, rtpsend and rtprecv that represent the two
halves of a rtpsession.  This avoids the potential pipeline loop if two
peers are sending/receiving data towards each other.  The two halves can
be connected by setting the rtp-id property on each element to the same
value and they will behave like a combined rtpbin-like element.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1426>
2024-05-28 19:58:09 +10:00
Matthew Waters 0121d78482 rtpbin2: expose session signals for new/bye ssrc
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1426>
2024-05-28 19:58:09 +10:00
Matthew Waters d480c6c2d3 rtpbin2/config: add stats to session GObject
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1426>
2024-05-28 19:58:09 +10:00
Matthew Waters 7d5789032a rtpbin2/config: add a new-ssrc signal
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1426>
2024-05-28 19:58:09 +10:00
Matthew Waters 06f40e72cb rtpbin2: implement a session configuration object
Currently only contains pt-map

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1426>
2024-05-28 19:58:09 +10:00
Matthew Waters 48e7a2ed06 jitterbuffer: handle flush-start/stop
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1426>
2024-05-28 19:58:09 +10:00
Matthew Waters 66306e32f2 jitterbuffer: remove mpsc channel for every packet
It is very slow.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1426>
2024-05-28 19:58:09 +10:00
Mathieu Duponchelle 327f563e80 jitterbuffer: implement support for serialized events / queries
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1426>
2024-05-28 19:58:09 +10:00
Mathieu Duponchelle 74ec83a0ff rtpbin2: implement and use synchronization context
Co-authored-by: Sebastian Dröge <sebastian@centricular.com>
Co-Authored-By: Matthew Waters <matthew@centricular.com>
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1426>
2024-05-28 19:58:09 +10:00
Mathieu Duponchelle 1865899621 rtpbin2: implement jitterbuffer
The jitterbuffer implements both reordering and duplicate packet
handling.

Co-Authored-By: Sebastian Dröge <sebastian@centricular.com>
Co-Authored-By: Matthew Waters <matthew@centricular.com>
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1426>
2024-05-28 17:35:41 +10:00
Sebastian Dröge 2b4ec75bc5 rtpbin2: Add support for receiving rtcp-mux packets
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1426>
2024-05-28 17:35:41 +10:00
Sebastian Dröge e09ad990fa rtpbin2: Implement support for reduced size RTCP (RFC 5506)
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1426>
2024-05-28 17:35:41 +10:00
Sebastian Dröge 1e4a966c92 rtpbin2: Add support for sending NACK/PLI and FIR
Co-Authored-By: Matthew Waters <matthew@centricular.com>
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1426>
2024-05-28 17:35:41 +10:00
Sebastian Dröge 66c9840ad8 rtpbin2: Add handling for receiving NACK/PLI and FIR
Co-Authored-By: Matthew Waters <matthew@centricular.com>
Co-Authored-By: Mathieu Duponchelle <mathieu@centricular.com>
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1426>
2024-05-28 17:35:41 +10:00
Matthew Waters 2c86f18a99 rtpbin2: add support for RFC 4585 (RTP/AVPF)
Implements the timing rules for RTP/AVPF

Co-Authored-By: Sebastian Dröge <sebastian@centricular.com>
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1426>
2024-05-28 17:35:41 +10:00
Matthew Waters 27ad26c258 rtp: Initial rtpbin2 element
Can receive and recevie one or more RTP sessions containing multiple
pt/ssrc combinations.

Demultiplexing happens internally instead of relying on separate
elements.

Co-Authored-By: François Laignel <francois@centricular.com>
Co-Authored-By: Mathieu Duponchelle <mathieu@centricular.com>
Co-Authored-By: Sebastian Dröge <sebastian@centricular.com>
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1426>
2024-05-28 17:35:41 +10:00
Sebastian Dröge 984a9fe5ff rtp: Don't restrict payload types for payloaders
WebRTC uses payload types 35-63 as dynamic payload types too to be able
to place more codec variants into the SDP offer.

Instead of allowing just certain payload types, completely remove any
restrictions and let the user decide. There's technically nothing wrong
with using any payload type, especially when using the encoding-name.

Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/551

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1587>
2024-05-27 09:34:16 +00:00
Liam b4fd6cf362 aws: Add system-defined metadata options to both sinks
Add to awss3sink and awss3putobjectsink elements the following
paramerters which are set on the uploaded S3 objects:

* cache-control;
* content-encoding; and
* content-language

Bugfix: Set the content-type and content-disposition values in the S3
putobject call. Previously the params were defined on the element but
unused.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1585>
2024-05-27 10:25:22 +03:00
Tim-Philipp Müller 4f74cb7958 rtp: klv: add test for fragmented payloads with packet loss
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1580>
2024-05-26 12:34:44 +03:00
Tim-Philipp Müller b6e24668a7 rtp: klv: add unit test with some packet loss
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1580>
2024-05-26 12:34:44 +03:00
Tim-Philipp Müller 92a1e222f4 rtp: tests: add functionality to drop RTP packets after payloading
Add ExpectedPacket::drop() to flag RTP packets that should not
be forwarded to the depayloader.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1580>
2024-05-26 12:34:44 +03:00
Tim-Philipp Müller de71e9dadd rtp: tests: print rtp timestamp mismatch minus the initial offset
Unit tests specify a 0-based offset, so printing that plus the
random initial offset on failure is just needlessly confusing,
so subtract the initial offset when printing expected/actual
values. The real values are still printed as part of the assert.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1580>
2024-05-26 12:34:44 +03:00
Tim-Philipp Müller be7da027f8 rtp: klv: add some basic tests
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1580>
2024-05-26 12:34:44 +03:00
Tim-Philipp Müller 1e33926dc5 fixup: klv payloader indentation
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1580>
2024-05-26 12:34:44 +03:00
Tim-Philipp Müller c2f67bd3c9 fixup: klv depay: debug log indentation
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1580>
2024-05-26 12:34:44 +03:00
Tim-Philipp Müller e7d0e0702a fixup: payloader
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1580>
2024-05-26 12:34:44 +03:00
Tim-Philipp Müller 566e6443f4 rtp: Add KLV RTP payloader/depayloader
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1580>
2024-05-25 20:21:50 +03:00
François Laignel 4259d284bd webrtc: add android webrtcsrc example
This commit adds an Android `webrtcsrc` based example with the following
features:

* A first view allows retrieving the producer list from the signaller (peer ids
  are uuids which are too long to tap, especially using an onscreen keyboard).
* Selecting a producer opens a second view. The first available video stream is
  rendered on a native Surface. All the audio streams are rendered using
  `autoaudiosink`.

Available Settings:

* Signaller URI.
* A toggle to prefer hardware decoding for OPUS, otherwise the app defaults to
  raising `opusdec`'s rank. Hardware decoding was moved aside since it was found
  to crash the app on all tested devices (2 smartphones, 1 tv).

**Warning**: in order to ease testing, this demonstration application enables
unencrypted network communication. See `AndroidManifest.xml`.

The application uses the technologies currenlty proposed by Android Studio when
creating a new project:

* Kotlin as the default language, which is fully interoperable with Java and
  uses the same SDK.
* gradle 8.6.
* kotlin dialect for gradle. The structure is mostly the same as the previously
  preferred dialect, for which examples can be found online readily.
* However, JNI code generation still uses Makefiles (instead of CMake) due to
  the need to call [`gstreamer-1.0.mk`] for `gstreamer_android` generation.
  Note: on-going work on that front:
  - https://gitlab.freedesktop.org/gstreamer/cerbero/-/merge_requests/1466
  - https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6794

Current limitations:

* x86 support is currently discarded as `gstreamer_android` libs generation
  fails (observed with `gstreamer-1.0-android-universal-1.24.3`).
* A selector could be added to let the user chose the video streams and
  possibly decide whether to render all audio streams or just select one.

Nice to have:

* Support for the synchronization features of the `webrtc-precise-sync-recv`
  example (NTP clock, RFC 7273).
* It could be nice to use Rust for the specific native code.

[`gstreamer-1.0.mk`]: https://gitlab.freedesktop.org/gstreamer/cerbero/-/blob/main/data/ndk-build/gstreamer-1.0.mk

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1578>
2024-05-24 16:14:13 +00:00
Sebastian Dröge 58e91c154c rtp: basedepay: Reset last used ext seqnum on discontinuities
The ext seqnum counting is reset too so keeping the old one around will
cause problems with timestamping of the next outgoing buffer.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1584>
2024-05-24 10:23:06 +03:00
Sebastian Dröge 28bd6f07a2 Update CHANGELOG.md for 0.12.6 2024-05-23 17:27:21 +03:00
Sebastian Dröge b1ad123595 gtk4: Fix Python example in the non-GL code path 2024-05-23 16:15:52 +03:00
cdelguercio c99cabfbc5 webrtcsink: Add VP9 parser after the encoder for VP9 too
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1572>
2024-05-23 10:16:59 +03:00
cdelguercio f5a7de9dc3 webrtcsink: Support av1 via nvav1enc, av1enc, and rav1enc
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1572>
2024-05-23 10:16:59 +03:00
Sebastian Dröge b12da2c543 deny: Update with itertool 0.12 override
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1579>
2024-05-20 14:36:39 +03:00
Sebastian Dröge 02cd2c42fd Update Cargo.lock
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1579>
2024-05-20 14:33:23 +03:00
Sebastian Dröge dcc0b47349 rtp: basepay: Fix header extension negotiation
Only configure header extensions from the source pad caps if they exist
already in the source pad caps, otherwise the configuration will fail.
Extensions that are added via the signals might not exist in the source
pad caps yet and would be added later.

Also, if configuring an existing extension from the new caps fails,
remove it and try to request a new extension for it.

Additionally don't remove extensions from the caps that can't be
provided. No header extensions for them would be added to the packets,
but that's not a problem. Removing them on the other hand would cause
negotiation to fail. This only affects extensions that are already
included in the caps.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1577>
2024-05-20 07:53:50 +00:00
Sebastian Dröge 0d33077df6 rtp: basedepay: Clean up header extension negotiation
If configuring an existing extension from the new caps fails, remove it
and try to request a new extension for it.

Also remove all extensions from the list that are not provided in the
caps, instead of passing RTP packets to all of them anyway.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1577>
2024-05-20 07:53:50 +00:00
Tim-Philipp Müller 16608d2541 rtp: opus: add multichannel depay/pay test
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1571>
2024-05-18 09:29:29 +00:00
Tim-Philipp Müller bab3498c6a rtp: opus: add multichannel pay/depay test
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1571>
2024-05-18 09:29:29 +00:00
Tim-Philipp Müller 72006215cb rtp: tests: add run_test_pipeline_full() that checks output caps too
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1571>
2024-05-18 09:29:29 +00:00
Tim-Philipp Müller 10e0294d5a rtp: opus: fix payloader caps query handling and add tests
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1571>
2024-05-18 09:29:29 +00:00
Tim-Philipp Müller 61523baa7b rtp: opus: add minimal depayload / re-payload test
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1571>
2024-05-18 09:29:29 +00:00
Tim-Philipp Müller 6f871e6ce2 rtp: opus: add simple payload / depayload test
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1571>
2024-05-18 09:29:29 +00:00
Tim-Philipp Müller 92c0cf1285 rtp: opus: add test for payloader dtx packet handling
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1571>
2024-05-18 09:29:29 +00:00
Tim-Philipp Müller 2585639054 rtp: Add Opus RTP payloader/depayloader
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1571>
2024-05-18 09:29:29 +00:00
Sebastian Dröge 0215339c5a Update Cargo.lock
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1576>
2024-05-17 07:50:51 +00:00
Sebastian Dröge 539000574b aws: Update to base32 0.5
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1576>
2024-05-17 07:50:51 +00:00
Robert Ayrapetyan bac5845be1 webrtc: add support for insecure tls connections
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1553>
2024-05-16 19:34:57 +00:00
Mathieu Duponchelle c282bc1bca examples/dash_vod: compare durations to the millisecond
Otherwise when the segment durations aren't as clean cut as in the
example, multiple segments with the exact same duration in milliseconds
will get output, even though they could have been repeated.

Fix this so that people copying this code don't encounter the bug.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1574>
2024-05-15 06:28:14 +00:00
Martin Nordholts 9a7f37e2b7 rtpgccbwe: Support linear regression based delay estimation
In our tests, the slope (found with linear regression) on a
history of the (smoothed) accumulated inter-group delays
gives a more stable congestion control. In particular,
low-end devices becomes less sensitive to spikes in
inter-group delay measurements.

This flavour of delay based bandwidth estimation with Google
Congestion Control is also what Chromium is using.

To make it easy to experiment with the new estimator, as
well as add support for new ones in the future, also add
infrastructure for making delay estimator flavour selectable
at runtime.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1566>
2024-05-14 16:25:48 +00:00
Martin Nordholts 71e9c2bb04 rtpgccbwe: Also log self.measure in overuse_filter()
Also log `self.measure` in overuse_filter() since tracking
`self.measure` over time help a lot in making sense of
`self.estimate` (and `amplified_estimate`).

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1566>
2024-05-14 16:25:48 +00:00
Martin Nordholts d9aa0731f4 rtpgccbwe: Rename variable t to amplified_estimate
We normally multiply `self.estimate` with `MAX_DELTAS` (60).
Rename the variables that holds the result of this
calculation to `amplified_estimate` to make the distinction
clearer.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1566>
2024-05-14 16:25:48 +00:00
Sebastian Dröge 49d3dd17a2 gtk4: Clean up Python example
It's not more or less equivalent to the Rust example.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1573>
2024-05-13 10:06:32 +03:00
Tamas Levai 71cd80f204 net/quinn: Enable client to keep QUIC conn alive
Co-authored-by: Felician Nemeth <nemethf@tmit.bme.hu>
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1568>
2024-05-11 08:51:00 +02:00
Rafael Caricio 5549dc7a15 fmp4mux: Support AV1 packaging in the fragmented mp4 plugin
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1544>
2024-05-10 20:59:49 +00:00
Sebastian Dröge 613ed56675 webrtcsink: Add a custom signaller example in Python
This re-implements the default webrtcsink/src signalling protocol in
Python for demonstration purposes.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1569>
2024-05-10 15:59:12 +00:00
Martin Nordholts a719cbfcc6 rtp: Change RtpBasePay2::ssrc_collision from AtomicU64 to Option<u32>
Rust targets without support for `AtomicU64` is still
somewhat common. Running

    git grep -i 'max_atomic_width: Some(32)' | wc -l

in the Rust compiler repo currently counts to 34 targets.

Change the `RtpBasePay2::ssrc_collision` from `AtomicU64` to
`Mutex<Option<u32>>`. This way we keep support for these
targets.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1562>
2024-05-10 14:23:41 +00:00
Rafael Caricio 7d75e263f8 fmp4mux: Add language from tags
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1557>
2024-05-10 13:01:58 +00:00
Martin Nordholts aabb011f5a rtpgccbwe: Log effective bitrate in more places
While monitoring and debugging rtpgccbwe, it is very helpful
to get continuous values of what it considers the effective
bitrate. Right now such prints will stop coming once the
algorithm stabilizes. Print it in more places so it keeps
coming. Use the same format to make it simpler to extract
the values by parsing the logs.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1567>
2024-05-10 11:56:51 +00:00
Martin Nordholts e845e3575c rtpgccbwe: Add mising 'ps' suffix to 'kbps' of 'effective bitrate'
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1567>
2024-05-10 11:56:51 +00:00
Sebastian Dröge f265c3197b Update plugins cache JSON for new CI GStreamer version
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1570>
2024-05-10 14:14:51 +03:00
Sebastian Dröge e8e173d0d0 webrtc: Update Signallable interface to new interface definition API
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1570>
2024-05-10 14:13:55 +03:00
Sebastian Dröge f842aff6df Update Cargo.lock
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1570>
2024-05-10 14:09:27 +03:00
Sebastian Dröge 7e09481adc rtp: Add JPEG RTP payloader/depayloader
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1543>
2024-05-10 11:12:49 +03:00
Sebastian Dröge 1b48fb7ae7 deny: Re-add rustls override because the AWS SDK still uses an old version 2024-05-10 09:41:19 +03:00
Sanchayan Maity fe55acb4c9 net/hlssink3: Refactor out HlsBaseSink & hlscmafsink from hlssink3
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1564>
2024-05-09 21:50:32 +05:30
Tamas Levai fe3607bd14 net/quinn: Remove dependency locks
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1565>
2024-05-09 16:45:38 +02:00
Tamas Levai 5884c00bd0 net/quinn: Improve stream shutdown process
Co-authored-by: Sanchayan Maity <sanchayan@asymptotic.io>
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1565>
2024-05-09 16:43:26 +02:00
Tamas Levai 13c3db7857 net/quinn: Port to quinn 0.11 and rustls 0.23
Co-authored-by: Felician Nemeth <nemethf@tmit.bme.hu>
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1565>
2024-05-09 13:49:33 +02:00
Martin Nordholts 2b7488a4c8 rtpgccbwe: Log delay and loss target bitrates separately
When debugging rtpgccbwe it is helpful to know if it is
delay based or loss based band-width estimation that puts a
bound on the current target bitrate, so add logs for that.

To minimize the time we need to hold the state lock, perform
the logging after we have released the state lock.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1561>
2024-05-08 19:12:44 +00:00
Sebastian Dröge b4576a0074 gtk4: Fix description of the plugin
A paintable is not a widget and that aspect does not belong in the short
description anyway.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1563>
2024-05-07 20:21:03 +03:00
Mathieu Duponchelle 8861fc493b webrtcsink: improve error when no discovery pipeline runs
If for instance no encoder was found or the RTP plugin was missing,
it is possible that no discovery pipeline will run for a given stream.

Provide a more helpful error message for that case.

Fixes: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/534
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1560>
2024-05-06 11:39:48 +00:00
Sanchayan Maity 2bfb6ee016 Add quinn to default-members
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1558>
2024-05-02 16:39:29 +00:00
Sanchayan Maity edd7c258c8 Add quinn plugin to README
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1558>
2024-05-02 16:39:29 +00:00
Sanchayan Maity 3a3cec96ff net/quinn: Add pipeline example
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1558>
2024-05-02 16:39:29 +00:00
Sanchayan Maity 80f8664564 net/quinn: Use camel case acronym
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1558>
2024-05-02 16:39:29 +00:00
Sebastian Dröge be3ae583bc Fix new Rust 1.78 clippy warnings
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1559>
2024-05-02 18:36:23 +03:00
Sebastian Dröge 58106a42a9 quinn: Fix up dependencies 2024-05-02 09:59:55 +03:00
Sanchayan Maity 096538989b docs: Add documentation for gst-plugin-quinn
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1036>
2024-05-01 22:30:23 +05:30
Sanchayan Maity 150ad7a545 net/quinn: Use separate property for certificate & private key file
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1036>
2024-05-01 22:30:23 +05:30
Sanchayan Maity 0d2f054c15 Move net/quic to net/quinn
While at it, add this to meson.build.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1036>
2024-05-01 22:30:23 +05:30
Sanchayan Maity 18cf5292b7 net/quic: Fix inconsistencies around secure connection handling
This set of changes implements the below fixes:

- Allow certificates to be specified for client/quicsink
- Secure connection being true on server/quicsrc and false on
  client/quicsink still resulted in a successful connection
  instead of server rejecting the connection
- Using secure connection with ALPN was not working

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1036>
2024-05-01 18:09:16 +05:30
Sanchayan Maity 97d8a79d36 net/quic: Drop private key type property
Use read_all helper from rustls_pemfile and drop the requirement for the
user having to specify the private key type.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1036>
2024-05-01 18:09:16 +05:30
Sanchayan Maity a306b1ce94 net/quic: Use a custom ALPN string
`h3` does not make sense as the default ALPN, as there likely isn't
going to be a HTTP/3 application layer, especially as our transport
is unidirectional for now. Use a custom string `gst-quinn` for now.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1036>
2024-05-01 18:09:16 +05:30
Sanchayan Maity 22c6a98914 net/quic: Rename to quinnquicsink/src
There might be other QUIC elements in the future based on other
libraries. To prevent namespace collision, namespace the elements
with `quinn` prefix.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1036>
2024-05-01 18:09:16 +05:30
Sanchayan Maity 8b64c734e7 net/quic: Use separate property for address and port
While at it, do not duplicate call to settings lock in property
getter and setter for every property.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1036>
2024-05-01 18:01:49 +05:30
Tamas Levai befd8d4bd2 net/quic: Allow SSL keylog file for debugging
rustls has a KeyLog implementation that opens a file whose name is
given by the `SSLKEYLOGFILE` environment variable, and writes keys
into it. If SSLKEYLOGFILE is not set, this does nothing.

See
https://docs.rs/rustls/latest/rustls/struct.KeyLogFile.html
https://docs.rs/rustls/latest/rustls/trait.KeyLog.html

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1036>
2024-05-01 18:01:49 +05:30
Sanchayan Maity ce930eab5f net/quic: Allow setting multiple ALPN transport parameters
For reference, see
https://datatracker.ietf.org/doc/html/rfc9000#section-7.4
https://datatracker.ietf.org/doc/html/rfc7301

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1036>
2024-05-01 18:01:49 +05:30
Tamas Levai 75b25d011f net/quic: Allow specifying an ALPN transport parameter
See https://datatracker.ietf.org/doc/html/rfc9000#section-7.4.

This controls the Transport Layer Security (TLS) extension for
application-layer protocol negotiation within the TLS handshake.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1036>
2024-05-01 18:01:49 +05:30
Sanchayan Maity 953f6a3fd7 net: Add QUIC source and sink
To test, run receiver as

```bash
gst-launch-1.0 -v -e quicsrc caps=audio/x-opus use-datagram=true ! opusparse ! opusdec ! audio/x-raw,format=S16LE,rate=48000,channels=2,layout=interleaved ! audioconvert ! autoaudiosink
```

run sender as

```bash
gst-launch-1.0 -v -e audiotestsrc num-buffers=512 ! audio/x-raw,format=S16LE,rate=48000,channels=2,layout=interleaved ! opusenc ! quicsink use-datagram=true
```

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1036>
2024-05-01 18:01:49 +05:30
Robert Mader 8e675de690 gtk4paintablesink: Add some documentation
And sync with `README.md` in order to make the environment variables
`GST_GTK4_WINDOW` and `GST_GTK4_WINDOW_FULLSCREEN` discoverable - and
because it's generally useful.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1555>
2024-04-30 09:59:49 +03:00
Robert Mader 4326c3bfce gtk4paintablesink: Also create window for gst-play
So it can be easily tested with
```
gst-play-1.0 --videosink=gtk4paintablesink ...
```

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1555>
2024-04-29 22:44:56 +02:00
Robert Mader 47b788d44b gtk4paintablesink: Add env var to fullscreen window
For testing purposes with e.g. gst-launch.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1555>
2024-04-29 20:44:05 +00:00
François Laignel 16b0a4d762 rtp: add mp4gpay
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1551>
2024-04-29 13:33:42 +00:00
François Laignel b588ee59bc rtp: add mp4gdepay
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1551>
2024-04-29 13:33:42 +00:00
François Laignel 5466cafc24 rtp: add mp4apay
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1551>
2024-04-29 13:33:42 +00:00
François Laignel 812fe0a9bd rtp: add mp4adepay
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1551>
2024-04-29 13:33:42 +00:00
Sebastian Dröge c55c4ca42a Update CHANGELOG.md for 0.12.5 2024-04-29 13:49:17 +03:00
Sebastian Dröge 83bd7be92a deny: Remove syn override 2024-04-29 11:54:38 +03:00
Sebastian Dröge 70397a9f05 Update CHANGELOG.md for 0.12.4 2024-04-29 11:46:19 +03:00
Maksym Khomenko a87eaa4b79 hrtfrender: use bitmask, not int, to prevent a capsnego failure
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1549>
2024-04-26 20:24:19 +00:00
Philippe Normand 88cbc93338 dav1ddec: Negotiate bt709 colorimetry when values from seq header are unspecified
With unknown range colorimetry validation would fail in video-info. As our
decoder outputs only YUV formats Bt709 should be a reasonable default.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1548>
2024-04-26 19:35:41 +00:00
Sebastian Dröge 927c3fcdb6 gtk4paintablesink: Update README.md with all the new features
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1547>
2024-04-26 12:29:10 +03:00
Sebastian Dröge 5803904deb gtk4paintablesink: meson: Add auto-detection of GTK4 versions and dmabuf feature
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1547>
2024-04-26 12:29:10 +03:00
Sebastian Dröge c95e07a897 gtk4paintablesink: Improve scaling logic
If force-aspect-ratio=false then make sure to fully fill the given
width/height with the video frame and avoid rounding errors. This makes
sure that the video is rendered in the exact position selected by the
caller and that graphics offloading is going to work more likely.

In other cases and for all overlays, make sure that the calculated
positions are staying inside (0, 0, width, height) as rendering outside
is not allowed by GTK.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1547>
2024-04-26 12:29:10 +03:00
Sebastian Dröge b42bd3d026 gtk4paintablesink: Add force-aspect-ratio property like in other video sinks
Unlike in other sinks this defaults to false as generally every user of
GDK paintables already ensures that the aspect ratio is kept and the
paintable is layed out in the most optimal way based on the context.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1547>
2024-04-26 12:29:10 +03:00
Sebastian Dröge 3dd800ac77 gtk4paintablesink: Implement child proxy interface
This allows setting properties on the paintable from gst-launch-1.0.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1547>
2024-04-26 12:29:10 +03:00
Sebastian Dröge c92462b240 gtk4: Implement support for directly importing dmabufs
Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/441

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1547>
2024-04-26 12:29:10 +03:00
Sebastian Dröge 7573caa8e9 rtpgccbwe: Move away from deprecated time::Instant to std::time::Instant
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1554>
2024-04-25 15:37:28 +03:00
Sebastian Dröge c12585377c Update Cargo.lock
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1554>
2024-04-25 14:46:45 +03:00
Mathieu Duponchelle 17d7997137 transcriberbin: add support for consuming secondary audio streams
In some situations, a translated alternate audio stream for a content
might be available.

Instead of going through transcription and translation of the original
audio stream, it may be preferrable for accuracy purposes to simply
transcribe the secondary audio stream.

This MR adds support for doing just that:

* Secondary audio sink pads can be requested as "sink_audio_%u"

* Sometimes audio source pads are added at that point to pass through
  the audio, as "src_audio_%u"

* The main transcription bin now contains per-input stream transcription
  bins. Those can be individually controlled through properties on the
  sink pads, for instance translation-languages can be dynamically set
  per audio stream

* Some properties that originally existed on the main element still
  remain, but are now simply mapped to the always audio sink pad

* Releasing of secondary sink pads is nominally implemented, but not
  tested in states other than NULL

An example launch line for this would be:

```
$ gst-launch-1.0 transcriberbin name=transcriberbin latency=8000 accumulate-time=0 \
      cc-caps="closedcaption/x-cea-708, format=cc_data" sink_audio_0::language-code="es-US" \
      sink_audio_0::translation-languages="languages, transcript=cc3"
    uridecodebin uri=file:///home/meh/Music/chaplin.mkv name=d
      d. ! videoconvert ! transcriberbin.sink_video
      d. ! clocksync ! audioconvert ! transcriberbin.sink_audio
      transcriberbin.src_video ! cea608overlay field=1 ! videoconvert ! autovideosink \
      transcriberbin.src_audio ! audioconvert ! fakesink \
    uridecodebin uri=file:///home/meh/Music/chaplin-spanish.webm name=d2 \
      d2. ! audioconvert ! transcriberbin.sink_audio_0 \
      transcriberbin.src_audio_0 ! fakesink
```

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1546>
2024-04-25 11:56:01 +02:00
Sebastian Dröge 66030f36ad tracers: Add a pad push durations tracer
This tracer measures the time it takes for a buffer/buffer list push to return.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1506>
2024-04-17 16:20:43 +03:00
Seungha Yang b3d3895ae7 cea608overlay: Fix black-background setting
Apply the property to newly created renderer

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1542>
2024-04-15 15:38:31 +00:00
Sebastian Dröge d6a855ff1b rtp: Add VP8/9 RTP payloader/depayloader
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1487>
2024-04-15 14:03:56 +00:00
François Laignel 542030fd82 webrtcsink: don't panic if input CAPS are not supported
If a user constrained the supported CAPS, for instance using `video-caps`:

```shell
gst-launch-1.0 videotestsrc ! video/x-raw,format=I420 ! x264enc \
    ! webrtcsink video-caps=video/x-vp8
```

... a panic would occur which was internally caught without the user being
informed except for the following message which was written to stderr:

> thread 'tokio-runtime-worker' panicked at net/webrtc/src/webrtcsink/imp.rs:3533:22:
>   expected audio or video raw caps: video/x-h264, [...] <br>
> note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

The pipeline kept running.

This commit converts the panic into an `Error` which bubbles up as an element
`StreamError::CodecNotFound` which can be handled by the application.
With the above `gst-launch`, this terminates the pipeline with:

> [...] ERROR  webrtcsink net/webrtc/src/webrtcsink/imp.rs:3771:gstrswebrtc::
>   webrtcsink:👿:BaseWebRTCSink::start_stream_discovery_if_needed::{{closure}}:<webrtcsink0>
> Error running discovery: Unsupported caps: video/x-h264, [...] <br>
> ERROR: from element /GstPipeline:pipeline0/GstWebRTCSink:webrtcsink0:
>   There is no codec present that can handle the stream's type. <br>
> Additional debug info: <br>
> net/webrtc/src/webrtcsink/imp.rs(3772): gstrswebrtc::webrtcsink:👿:BaseWebRTCSink::
> start_stream_discovery_if_needed::{{closure}} (): /GstPipeline:pipeline0/GstWebRTCSink:webrtcsink0:
> Failed to look up output caps: Unsupported caps: video/x-h264, [...] <br>
> Execution ended after 0:00:00.055716661 <br>
> Setting pipeline to NULL ...

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1540>
2024-04-14 23:09:09 +02:00
François Laignel 3fc38be5c4 webrtc: add missing tokio feature for precise sync examples
Clippy caught the missing feature `signal` which is used by the WebRTC precise
synchronization examples. When running `cargo` `check`, `build` or `clippy`
without `no-default-dependencies`, this feature was already present due to
dependents crates.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1541>
2024-04-14 16:50:33 +02:00
François Laignel 168af88eda webrtc: add features for specific signallers
When swapping between several development branches, compilation times can be
frustrating. This commit proposes adding features to control which signaller
to include when building the webrtc plugin. By default, all signallers are
included, just like before.

Compiling the `webrtc-precise-sync` examples with `--no-default-features`
reduces compilation to 267 crates instead of 429 when all signallers are
compiled in.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1539>
2024-04-12 19:10:42 +02:00
François Laignel 83d70d3471 webrtc: add RFC 7273 support
This commit implements [RFC 7273] (NTP & PTP clock signalling & synchronization)
for `webrtcsink` by adding the "ts-refclk" & "mediaclk" SDP media attributes to
identify the clock. These attributes are handled by `rtpjitterbuffer` on the
consumer side. They MUST be part of the SDP offer.

When used with an NTP or PTP clock, "mediaclk" indicates the RTP offset at the
clock's origin. Because the payloaders are not instantiated when the offer is
sent to the consumer, the RTP offset is set to 0 and the payloader
`timstamp-offset`s are set accordingly when they are created.

The `webrtc-precise-sync` examples were updated to be able to start with an NTP
(default), a PTP or the system clock (on the receiver only). The rtp jitter
buffer will synchronize with the clock signalled in the SDP offer provided the
sender is started with `--do-clock-signalling` & the receiver with
`--expect-clock-signalling`.

[RFC 7273]: https://datatracker.ietf.org/doc/html/rfc7273

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1500>
2024-04-12 14:18:09 +02:00
Guillaume Desmottes 596a9177ce uriplaylistbin: disable racy test
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1537>
2024-04-12 10:17:40 +00:00
Philippe Normand 2341ee6935 dav1d: Set colorimetry parameters on src pad caps
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1514>
2024-04-12 09:14:34 +00:00
Guillaume Desmottes 61c9cbdc8f uriplaylistbin: allow to change 'iterations' property while playing
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1492>
2024-04-11 11:13:20 +02:00
Guillaume Desmottes 00b56ca845 uriplaylistbin: stop using an iterator to manage the playlist
Will make it easier to update the playlist while playing.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1492>
2024-04-11 10:48:50 +02:00
François Laignel 42158cbcb0 gccbwe: don't log an error when handling a buffer list while stopping
When `webrtcsink` was stopped, `gccbwe` could log an error if it was handling a
buffer list. This commit logs an error only if `push_list()` returned an error
other than `Flushing`.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1535>
2024-04-11 01:29:53 +00:00
Matthew Waters 4dcc44687a cea608overlay: move Send impl lower in the stack
Try to avoid hiding another non-Send object in the State struct.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1519>
2024-04-10 06:55:34 +00:00
Matthew Waters fbce73f6fc closedcaption: implement cea708overlay element
Can overlay any single CEA-708 service or any single CEA-608 channel.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1519>
2024-04-10 06:55:34 +00:00
Matthew Waters f0c38621c1 cea608overlay: also print bytes that failed to decode
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1519>
2024-04-10 06:55:34 +00:00
Sanchayan Maity a3e30b499f aws: Introduce a property to use path-style addressing
AWS SDK switched to virtual addressing as default instead of path
style earlier. While MinIO supports virtual host style requests,
path style requests are the default.

Introduce a property to allow the use of path style addressing if
required.

For more information, see
https://github.com/minio/minio/blob/master/docs/config/README.md#domain
https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1527>
2024-04-10 00:23:22 +00:00
François Laignel 2ad452ee89 webrtcsink: don't panic with bitrate handling unsupported encoders
When an encoder was not supported by the `VideoEncoder` `bitrate` accessors, an
`unimplemented` panic would occur which would poison `state` & `settings`
`Mutex`s resulting in other threads panicking, notably entering `end_session()`,
which lead to many failures in `BinImplExt::parent_remove_element()` until a
segmentation fault ended the process. This was observed using `vaapivp9enc`.

This commit logs a warning if an encoder isn't supported by the `bitrate`
accessors and silently by-passes `bitrate`-related operations when unsupported.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1534>
2024-04-09 15:48:59 +00:00
Simonas Kazlauskas 5d939498f1 mp4/fmp4: support flac inside the iso (f)mp4 container
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1401>
2024-04-09 14:37:05 +03:00
Taruntej Kanakamalla f4b086738b webrtcsrc: change the producer-id type for request-encoded-filter
With https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1477
the producer id used while emitting the request-encoded-filter
can be a None if the msid of the webrtcbin's pad is None.
This might not affect the signal handler written in C but
can panic in an existing Rust application with signal
handler which can only handle valid String type as its param
for the producer id.

So change the param type to Option<String> in the signal builder
for request-encoded-fiter signal

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1528>
2024-04-09 06:01:15 +00:00
Tim-Philipp Müller 6b30266145 ci: tag linter and sanity check jobs as a "placeholder" jobs
They hardly use any resources and almost finish immediately.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1533>
2024-04-08 23:42:23 +00:00
Tim-Philipp Müller c8180e714e ci: make sure version Cargo.toml matches version in meson.build
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1532>
2024-04-08 14:46:00 +01:00
Sebastian Dröge 0b356ee203 deny: Update
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1530>
2024-04-06 11:12:16 +03:00
Sebastian Dröge c2ebb3083a Update Cargo.lock
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1530>
2024-04-06 11:12:16 +03:00
Sebastian Dröge 921938fd20 fmp4mux: Require gstreamer-pbutils 1.20 for the examples
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1530>
2024-04-06 11:10:58 +03:00
Sebastian Dröge fab246f82e webrtchttp: Update to reqwest 0.12
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1530>
2024-04-06 11:07:16 +03:00
Sebastian Dröge 7757e06e36 onvifmetadataparse: Reset state in PAUSED->READY after pad deactivation
Otherwise the clock id will simply be overridden instead of unscheduling
it, and if the streaming thread of the source pad currently waits on it
then it will wait potentially for a very long time and deactivating the
pad would wait for that to happen.

Also unschedule the clock id on `Drop` of the state to be one the safe
side and not simply forget about it.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1526>
2024-04-05 15:19:37 +00:00
Taruntej Kanakamalla 70adedb142 net/webrtc: fix inconsistencies in documentation of object names
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1529>
2024-04-05 14:10:35 +00:00
Matthew Waters 7f6929b98d closedcaption: remove libcaption code entirely
It is now unused.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1517>
2024-04-05 19:29:24 +11:00
Matthew Waters 2575013faa cea608tott: use our own CEA-608 frame handling instead of libcaption
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1517>
2024-04-05 19:29:24 +11:00
Matthew Waters d8fe1c64f1 cea608overlay: use or own CEA-608 caption frame handling instead of libcaption
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1517>
2024-04-05 19:29:24 +11:00
Matthew Waters fea85ff9c8 closedcaption: use cea608-types for parsing 608 captions instead of libcaption
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1517>
2024-04-05 19:29:24 +11:00
François Laignel cc43935036 webrtc: add precise synchronization example
This example demonstrates a sender / receiver setup which ensures precise
synchronization of multiple streams in a single session.

[RFC 6051]-style rapid synchronization of RTP streams is available as an option.
See the [Instantaneous RTP synchronization...] blog post for details about this
mode and an example based on RTSP instead of WebRTC.

[RFC 6051]: https://datatracker.ietf.org/doc/html/rfc6051
[Instantaneous RTP synchronization...]: https://coaxion.net/blog/2022/05/instantaneous-rtp-synchronization-retrieval-of-absolute-sender-clock-times-with-gstreamer/

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1463>
2024-04-03 19:10:40 +02:00
Guillaume Desmottes b5cbc47cf7 web: webrtcsink: improve panic message on unexpected caps during discovery
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1524>
2024-04-02 14:25:58 +02:00
Guillaume Desmottes 35b84d219f webrtc: webrtcsink: set perfect-timestamp=true on audio encoders
Chrome audio decoder doesn't cope well with not perfect ts, generating
noises in the audio.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1524>
2024-04-02 14:25:51 +02:00
Sebastian Dröge 0aabbb3186 fmp4: Update to dash-mpd 0.16
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1523>
2024-03-31 09:36:53 +03:00
Sebastian Dröge 4dd6b102c4 Update Cargo.lock
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1523>
2024-03-31 09:35:46 +03:00
Sebastian Dröge 0dd03da91f ci: Ignore env_logger for cargo-outdated
It requires Rust >= 1.71.
2024-03-29 11:03:04 +02:00
Matthew Waters e1cd52178e transcriberbin: also support 608 inside 708
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1406>
2024-03-28 13:46:28 +11:00
Matthew Waters 55b4de779c tttocea708: add support for writing 608 compatibility bytes
608 compatibility bytes are generated using the same functionality as
tttocea608.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1406>
2024-03-28 13:46:28 +11:00
Matthew Waters 9db4290d2d tttocea608: move functionality to a separate object
Will be used by tttocea708 later.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1406>
2024-03-28 13:46:28 +11:00
Matthew Waters df30d2fbd3 transcriberbin: add support for generating cea708 captions
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1406>
2024-03-28 13:46:28 +11:00
Matthew Waters b0cf7e5c81 cea708mux: add element muxing multiple 708 caption services together
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1406>
2024-03-28 13:46:28 +11:00
Matthew Waters 756abbf807 tttocea708: add element converting from text to cea708 captions
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1406>
2024-03-28 13:46:28 +11:00
Martin Nordholts 5d7e068a8b rtpgccbwe: Add increasing_duration and counter to existing gst::log!()
Add `self.increasing_duration` and `self.increasing_counter`
to logs to provide more details of why `overuse_filter()`
determines overuse of network.

To get access to the latest values of those fields we need
to move down the log call. But that is fine, since no other
logged data is modified between the old and new location of
`gst::log!()`.

We do not bother logging `self.last_overuse_estimate` since
that is simply the previously logged value of `estimate`. We
must put the log call before we write the latest value to it
though, in case we want to log it in the future.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1522>
2024-03-27 15:08:23 +00:00
François Laignel a870d60621 aws: improve error message logs
The `Display` and `Debug` trait for the AWS error messages are not very useful.

- `Display` only prints the high level error, e.g.: "service error".
- `Debug` prints all the fields in the error stack, resulting in hard to read
  messages with redudant or unnecessary information. E.g.:

> ServiceError(ServiceError { source: BadRequestException(BadRequestException {
> message: Some("1 validation error detected: Value 'test' at 'languageCode'
> failed to satisfy constraint: Member must satisfy enum value set: [ar-AE,
> zh-HK, en-US, ar-SA, zh-CN, fi-FI, pl-PL, no-NO, nl-NL, pt-PT, es-ES, th-TH,
> de-DE, it-IT, fr-FR, ko-KR, hi-IN, en-AU, pt-BR, sv-SE, ja-JP, ca-ES, es-US,
> fr-CA, en-GB]"), meta: ErrorMetadata { code: Some("BadRequestException"),
> message: Some("1 validation error detected: Value 'test' at 'languageCode'
> failed to satisfy constraint: Member must satisfy enum value set: [ar-AE,
> zh-HK, en-US, ar-SA, zh-CN, fi-FI, pl-PL, no-NO, nl-NL, pt-PT, es-ES, th-TH,
> de-DE, it-IT, fr-FR, ko-KR, hi-IN, en-AU, pt-BR, sv-SE, ja-JP, ca-ES, es-US,
> fr-CA, en-GB]"), extras: Some({"aws_request_id": "1b8bbafd-5b71-4ba5-8676-28432381e6a9"}) } }),
> raw: Response { status: StatusCode(400), headers: Headers { headers:
> {"x-amzn-requestid": HeaderValue { _private: H0("1b8bbafd-5b71-4ba5-8676-28432381e6a9") },
> "x-amzn-errortype": HeaderValue { _private:
> H0("BadRequestException:http://internal.amazon.com/coral/com.amazonaws.transcribe.streaming/") },
> "date": HeaderValue { _private: H0("Tue, 26 Mar 2024 17:41:31 GMT") },
> "content-type": HeaderValue { _private: H0("application/x-amz-json-1.1") },
> "content-length": HeaderValue { _private: H0("315") }} }, body: SdkBody {
> inner: Once(Some(b"{\"Message\":\"1 validation error detected: Value 'test'
> at 'languageCode' failed to satisfy constraint: Member must satisfy enum value
> set: [ar-AE, zh-HK, en-US, ar-SA, zh-CN, fi-FI, pl-PL, no-NO, nl-NL, pt-PT,
> es-ES, th-TH, de-DE, it-IT, fr-FR, ko-KR, hi-IN, en-AU, pt-BR, sv-SE, ja-JP,
> ca-ES, es-US, fr-CA, en-GB]\"}")), retryable: true }, extensions: Extensions {
> extensions_02x: Extensions, extensions_1x: Extensions } } })

This commit adopts the most informative and concise solution I could come up
with to log AWS errors. With the above error case, this results in:

> service error: Error { code: "BadRequestException", message: "1 validation
> error detected: Value 'test' at 'languageCode' failed to satisfy constraint:
> Member must satisfy enum value set: [ar-AE, zh-HK, en-US, ar-SA, zh-CN, fi-FI,
> pl-PL, no-NO, nl-NL, pt-PT, es-ES, th-TH, de-DE, it-IT, fr-FR, ko-KR, hi-IN,
> en-AU, pt-BR, sv-SE, ja-JP, ca-ES, es-US, fr-CA, en-GB]",
> aws_request_id: "a40a32a8-7b0b-4228-a348-f8502087a9f0" }

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1521>
2024-03-26 20:05:32 +01:00
François Laignel 9f27bde36a aws: use fixed BehaviorVersion
Quoting [`BehaviorVersion` documentation]:

> Over time, new best-practice behaviors are introduced. However, these
> behaviors might not be backwards compatible. For example, a change which
> introduces new default timeouts or a new retry-mode for all operations might
> be the ideal behavior but could break existing applications.

This commit uses `BehaviorVersion::v2023_11_09()`, which is the latest
major version at the moment. When a new major version is released, the method
will be deprecated, which will warn us of the new version and let us decide
when to upgrade, after any changes if required. This is safer that using
`latest()` which would silently use a different major version, possibly
breaking existing code.

[`BehaviorVersion` documentation]: https://docs.rs/aws-config/1.1.8/aws_config/struct.BehaviorVersion.html

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1520>
2024-03-26 17:44:16 +01:00
Matthew Waters e868f81189 gopbuffer: implement element buffering of an entire GOP
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1349>
2024-03-26 15:29:48 +11:00
Sebastian Dröge bac2e02160 deny: Add overrides for duplicates hyper / reqwest dependencies 2024-03-24 11:30:30 +02:00
Nirbheek Chauhan ae7c68dbf8 ci: Add a job to trigger a cerbero build, similar to the monorepo
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1513>
2024-03-23 23:02:27 +00:00
Sebastian Dröge 0b11209674 Update Cargo.lock
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1510>
2024-03-23 14:33:07 +02:00
Sebastian Dröge f97150aa58 reqwest: Update to reqwest 0.12
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1510>
2024-03-23 14:30:31 +02:00
Philippe Normand 7e1ab086de dav1d: Require dav1d-rs 0.10
This version depends on libdav1d >= 1.3.0. Older versions are no longer
supported, due to an ABI/API break introduced in 1.3.0.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1512>
2024-03-21 17:33:32 +00:00
Philippe Normand be12c0a5f7 Fix clippy warnings after upgrade to Rust 1.77
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1512>
2024-03-21 17:33:32 +00:00
Sebastian Dröge 317f46ad97 Update CHANGELOG.md for 0.12.3 2024-03-21 18:55:29 +02:00
François Laignel c5e7e76e4d webrtcsrc: add do-retransmission property
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1509>
2024-03-21 07:25:30 +00:00
Sebastian Dröge 6556d31ab8 livesync: Ignore another racy test
Same problem as https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/328
2024-03-21 09:27:09 +02:00
François Laignel 5476e3d759 webrtcsink: prevent video-info error log for audio streams
The following error is logged when `webrtcsink` is feeded with an audio stream:

> ERROR video-info video-info.c:540:gst_video_info_from_caps:
>       wrong name 'audio/x-raw', expected video/ or image/

This commit bypasses `VideoInfo::from_caps` for audio streams.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1511>
2024-03-20 19:57:45 +01:00
François Laignel cc7b7d508d rtp: gccbwe: don't break downstream assumptions pushing buffer lists
Some elements in the RTP stack assume all buffers in a `gst::BufferList`
correspond to the same timestamp. See in [`rtpsession`] for instance.
This also had the effect that `rtpsession` did not create correct RTCP as it
only saw some of the SSRCs in the stream.

`rtpgccbwe` formed a packet group by gathering buffers in a `gst::BufferList`,
regardless of whether they corresponded to the same timestamp, which broke
synchronization under certain circonstances.

This commit makes `rtpgccbwe` push the buffers as they were received: one by one.

[`rtpsession`]: bc858976db/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpsession.c (L2462)

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1502>
2024-03-20 18:19:14 +00:00
Sebastian Dröge 2b9272c7eb fmp4mux: Move away from deprecated chrono function
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1503>
2024-03-20 15:37:18 +02:00
Sebastian Dröge cca3ebf520 rtp: Switch from chrono to time
Which allows to simplify quite a bit of code and avoids us having to
handle some API deprecations.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1503>
2024-03-20 15:05:39 +02:00
Sebastian Dröge 428f670753 version-helper: Use non-deprecated type alias from toml_edit
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1503>
2024-03-19 18:16:42 +02:00
Sebastian Dröge fadb7d0a26 deny: Add override for heck 0.4
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1503>
2024-03-19 17:52:32 +02:00
Sebastian Dröge 2a88e29454 originalbufferstore: Update for VideoMetaTransform -> VideoMetaTransformScale rename
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1503>
2024-03-19 17:51:41 +02:00
Sebastian Dröge bfff0f7d87 Update Cargo.lock
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1503>
2024-03-19 17:50:32 +02:00
Guillaume Desmottes 96337d5234 webrtc: allow resolution and framerate input changes
Some changes do not require a WebRTC renegotiation so we can allow
those.

Fix #515

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1498>
2024-03-18 14:52:01 +01:00
Tim-Philipp Müller eb49459937 rtp: m2pt: add some unit tests
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1493>
2024-03-16 10:07:37 +00:00
Tim-Philipp Müller ce3960f37f rtp: Add MPEG-TS RTP payloader
Pushes out pending TS packets on EOS.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1493>
2024-03-16 10:07:37 +00:00
Tim-Philipp Müller 9f07ec35e6 rtp: Add MPEG-TS RTP depayloader
Can handle different packet sizes, also see:
https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1310

Has clock-rate=90000 as spec prescribes, see:
https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/issues/691

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1493>
2024-03-16 10:07:37 +00:00
Mathieu Duponchelle f4366f8b2e gstregex: add support for switches exposed by RegexBuilder
The builder allows for instance for switching off case-sensitiveness for
the entire pattern, instead of having to do so inline with `(?i)`.

All the options exposed by the builder at
<https://docs.rs/regex/latest/regex/struct.RegexBuilder.html> can now be
passed as fields of invidual commands, snake-cased.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1497>
2024-03-15 17:41:39 +00:00
Guillaume Desmottes 523a46b4f5 gtk4: scale texture position
Fix regression in 0.12 introduced by 3423d05f77

Code from Ivan Molodetskikh suggested on Matrix.

Fix #519

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1499>
2024-03-15 13:43:32 +01:00
Nirbheek Chauhan 6f8fc5f178 meson: Disable docs completely when the option is disabled
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1496>
2024-03-14 15:30:17 +05:30
Guillaume Desmottes 8f997ea4e3 webrtc: janus: handle 'hangup' messages from Janus
Fix error about this message not being handled:

{
   "janus": "hangup",
   "session_id": 4758817463851315,
   "sender": 4126342934227009,
   "reason": "Close PC"
}

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1481>
2024-03-13 10:14:38 +00:00
Guillaume Desmottes 992f8d9a5d webrtc: janus: handle 'destroyed' messages from Janus
Fix this error when the room is destroyed:

ERROR   webrtc-janusvr-signaller imp.rs:413:gstrswebrtc::janusvr_signaller:👿:Signaller::handle_msg:<GstJanusVRWebRTCSignallerU64@0x55b166a3fe40> Unknown message from server: {
   "janus": "event",
   "session_id": 6667171862739941,
   "sender": 1964690595468240,
   "plugindata": {
      "plugin": "janus.plugin.videoroom",
      "data": {
         "videoroom": "destroyed",
         "room": 8320333573294267
      }
   }
}

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1481>
2024-03-13 10:14:38 +00:00
Guillaume Desmottes 9c6a39d692 webrtc: janus: handle (stopped-)talking events
Expose those events using a signal.

Fix those errors when joining a Janus room configured with
'audiolevel_event: true'.

ERROR   webrtc-janusvr-signaller imp.rs:408:gstrswebrtc::janusvr_signaller:👿:Signaller::handle_msg:<GstJanusVRWebRTCSignaller@0x560cf2a55100> Unknown message from server: {
   "janus": "event",
   "session_id": 2384862538500481,
   "sender": 1867822625190966,
   "plugindata": {
      "plugin": "janus.plugin.videoroom",
      "data": {
         "videoroom": "talking",
         "room": 7564250471742314,
         "id": 6815475717947398,
         "mindex": 0,
         "mid": "0",
         "audio-level-dBov-avg": 37.939998626708984
      }
   }
}
ERROR   webrtc-janusvr-signaller imp.rs:408:gstrswebrtc::janusvr_signaller:👿:Signaller::handle_msg:<GstJanusVRWebRTCSignaller@0x560cf2a55100> Unknown message from server: {
   "janus": "event",
   "session_id": 2384862538500481,
   "sender": 1867822625190966,
   "plugindata": {
      "plugin": "janus.plugin.videoroom",
      "data": {
         "videoroom": "stopped-talking",
         "room": 7564250471742314,
         "id": 6815475717947398,
         "mindex": 0,
         "mid": "0",
         "audio-level-dBov-avg": 40.400001525878906
      }
   }
}

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1481>
2024-03-13 10:14:38 +00:00
Guillaume Desmottes b29a739fb2 uriplaylistbin: disable racy test
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/514

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1494>
2024-03-12 16:57:22 +01:00
Guillaume Desmottes 1dea8f60a8 threadshare: disable racy tests
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/250

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1494>
2024-03-12 16:54:21 +01:00
Guillaume Desmottes 2629719b4e livesync: disable racy tests
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/328
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/357

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1494>
2024-03-12 16:32:47 +01:00
Guillaume Desmottes 9e6e8c618e togglerecord: disable racy test_two_stream_close_open_nonlivein_liveout test
See https://gitlab.freedesktop.org/gdesmott/gst-plugins-rs/-/jobs/56183085

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1494>
2024-03-12 16:21:52 +01:00
François Laignel 995f64513d Update Cargo.lock to use latest gstreamer-rs
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1491>
2024-03-11 14:42:36 +01:00
François Laignel 5b01e43a12 webrtc: update further to WebRTCSessionDescription sdp accessor changes
See: https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/merge_requests/1406
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1491>
2024-03-11 13:39:19 +01:00
Guillaume Desmottes 03abb5c681 spotify: document how to use with non Facebook accounts
See discussion on #203.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1490>
2024-03-11 09:46:40 +01:00
Zhao, Gang 7a46377627 rtp: tests: Simplify loop
All buffers can be added in 100 outer loops. Add buffer less than 200 in the last (i = 99) loop.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1489>
2024-03-10 16:47:30 +08:00
Olivier Crête 15e7a63e7b originalbuffer: Pair of elements to keep and restore original buffer
The goal is to be able to get back the original buffer
after performing analysis on a transformed version. Then put the
various GstMeta back on the original buffer.

An example pipeline would be
.. ! originalbuffersave ! videoscale ! analysis ! originalbufferestore ! draw_overlay ! sink

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1428>
2024-03-08 15:15:13 -05:00
Guillaume Desmottes 612f863ee9 webrtc: janusvrwebrtcsink: add 'use-string-ids' property
Instead of exposing all ids properties as strings, we now have two
signaller implementations exposing those properties using their actual
type. This API is more natural and save the element and application
conversions when using numerical ids (Janus's default).

I also removed the 'joined-id' property as it's actually the same id as
'feed-id'. I think it would be better to have a 'janus-state' property or
something like that for applications willing to know when the room has
been joined.
This id is also no longer generated by the element by default, as Janus
will take care of generating one if not provided.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1486>
2024-03-07 09:34:58 +01:00
Seungha Yang 237f22d131 sccparse: Ignore invalid timecode during seek as well
sccparse holds last timecode in order to ignore invalid timecode
and fallback to the previous timecode. That should happen
when sccparse is handling seek event too. Otherwise single invalid
timecode before the target seek position will cause flow error.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1485>
2024-03-06 11:12:04 +00:00
Sebastian Dröge 2839e0078b rtp: Port RTP AV1 payloader/depayloader to new base classes
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1472>
2024-03-06 09:40:35 +00:00
Jordan Yelloz 0414f468c6 livekit_signaller: Added missing getter for excluded-producer-peer-ids
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1484>
2024-03-04 10:08:11 -07:00
Jordan Yelloz 8b0731b5a2 webrtcsrc: Removed incorrect URIHandler from LiveKit source
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1484>
2024-03-04 09:44:01 -07:00
Guillaume Desmottes 7d0397e1ad uriplaylistbin: re-enable all tests
They now seem to work reliably. \o/

Fix #194

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1471>
2024-03-04 12:00:13 +01:00
Guillaume Desmottes f6476f1e8f uriplaylistbin: use vp9 in test media
The Windows CI runner does not have a Theora decoder so those tests were
failing there.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1471>
2024-03-04 12:00:13 +01:00
Guillaume Desmottes cfebc32b82 uriplaylistbin: tests: use fakesink sync=true
Tests is more reliable when using sync sink.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1471>
2024-03-04 11:17:11 +01:00
Guillaume Desmottes 721b7e9c8c uriplaylistbin: rely on new uridecodebin3 gapless logic
uridecodebin3 can now properly handle gapless switches so use that
instead of our own very complicated logic.

Fix #268
Fix #193

Depends on gst 1.23.90 as the plugin requires recent fixes to work properly.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1471>
2024-03-04 11:17:11 +01:00
Guillaume Desmottes 1e88971ec8 uriplaylistbin: pass valid URI in tests
Fix critical raised by libsoup,
see https://gitlab.gnome.org/GNOME/libsoup/-/merge_requests/346

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1471>
2024-03-04 11:06:19 +01:00
Sebastian Dröge 8a6bcb712f Remove empty line from the CHANGELOG.md that confuses the GitLab renderer 2024-03-01 16:46:21 +02:00
Jordan Yelloz 002dc36ab9 livekit_signaller: Improved shutdown behavior
Without sending a Leave request to the server before disconnecting, the
disconnected client will appear present and stuck in the room for a little
while until the server removes it due to inactivity.

After this change, the disconnecting client will immediately leave the room.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1482>
2024-02-29 08:21:13 -07:00
Sebastian Dröge 9c590f4223 Update Cargo.lock
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1483>
2024-02-29 10:09:09 +00:00
Jordan Yelloz f0b408d823 webrtcsrc: Removed flag setup from WhipServerSrc
It's already done in the base class

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1461>
2024-02-28 11:25:58 -07:00
Jordan Yelloz 17b2640237 webrtcsrc: Updated readme for LiveKit source
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1461>
2024-02-28 11:25:58 -07:00
Jordan Yelloz fa006b9fc9 webrtcsrc: Added LiveKit source element
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1461>
2024-02-28 11:25:58 -07:00
Jordan Yelloz 96037fbcc5 webrtcsink: Updated livekitwebrtcsink for new signaller constructor
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1461>
2024-02-28 11:25:58 -07:00
Jordan Yelloz 730b3459f1 livekit_signaller: Added dual-role support
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1461>
2024-02-28 11:25:49 -07:00
Guillaume Desmottes 60bb72ddc3 webrtc: janus: add joined-id property to the signaller
Fix #504

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1480>
2024-02-28 15:05:11 +01:00
Guillaume Desmottes eabf31e6d0 webrtc: janus: rename RoomId to JanusId
Those weird ids are used in multiple places, not only for the room id,
so best to have a more generic name.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1480>
2024-02-28 15:05:11 +01:00
Guillaume Desmottes 550018c917 webrtc: janus: room id not optional in 'joined' message
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1480>
2024-02-28 14:16:46 +01:00
Guillaume Desmottes 0829898d73 webrtc: janus: remove 'audio' and 'video' from publish messages
Those are deprecated and no longer used.

See https://janus.conf.meetecho.com/docs/videoroom and
https://github.com/meetecho/janus-gateway/blob/master/src/plugins/janus_videoroom.c#L9894

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1480>
2024-02-28 13:39:04 +01:00
Guillaume Desmottes ec17c58dee webrtc: janus: numerical room ids are u64
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1478>
2024-02-28 11:56:44 +01:00
Yorick Smilda 563eff1193 Implement GstWebRTCAPI as class instead of global instance
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1373>
2024-02-27 12:30:13 +00:00
Jordan Yelloz 594400a7f5 webrtcsrc: Made producer-peer-id optional
It may be necessary for some signalling clients but the source element
doesn't need to depend on it.

Also, the value will fall back to the pad's MSID for the first argument
to the request-encoded-filter gobject signal when it isn't available
from the signalling client.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1477>
2024-02-26 13:41:40 -07:00
Sebastian Dröge 47ba068966 Update CHANGELOG.md for 0.12.2 2024-02-26 14:58:58 +02:00
Sebastian Dröge 5df7c01cb5 closedcaption: Port from nom to winnow
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1475>
2024-02-26 14:00:08 +02:00
Xavier Claessens f7ffa13543 janusvr: Add string-ids property
It forces usage of strings even if it can be parsed into an integer.
This allows joining room `"133"` in a server configured with string
room ids.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1466>
2024-02-26 11:10:00 +00:00
Xavier Claessens 23955d2dbb janusvr: Room IDs can be strings
Sponsored-by: Netflix Inc.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1466>
2024-02-26 11:10:00 +00:00
Sebastian Dröge 340d65d7a4 Update Cargo.lock
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1474>
2024-02-26 11:14:01 +02:00
Sebastian Dröge b9195ed309 fmp4mux: Update to dash-mpd 0.15
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1474>
2024-02-26 11:14:01 +02:00
Sebastian Dröge fc1c017fc6 Update CHANGELOG.md for 0.12.1 2024-02-23 19:19:17 +02:00
Sebastian Dröge f563f8334b rtp: Add PCMU/PCMA RTP payloader / depayloader elements
These come with new generic RTP payloader, RTP raw-ish audio payloader
and RTP depayloader base classes.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1424>
2024-02-23 14:43:45 +02:00
Xavier Claessens e09f9e9540 meson: Fix error when default_library=both
Skip duplicated plugin_name when we have both the static and shared
plugin in the plugins list.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1470>
2024-02-22 12:31:23 -05:00
Maksym Khomenko da21dc853d webrtcsink: extensions: separate API and signal checks
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1469>
2024-02-20 19:29:46 +02:00
Maksym Khomenko 2228f882d8 webrtcsink: apply rustfmt
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1469>
2024-02-20 19:29:28 +02:00
Mathieu Duponchelle 8f3a6171ac textwrap: don't split on all whitespaces ..
but only on ASCII whitespaces, as we want to honor non-breaking
whitespaces (\u{a0})

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1468>
2024-02-16 19:38:38 +01:00
Xavier Claessens 2572afbf15 janusvr: Add secret-key property
Every API calls have an optional "apisecret" argument.

Sponsored-by: Netflix Inc.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1465>
2024-02-16 14:04:59 +00:00
Sebastian Dröge 0faac3b875 deny: Add winnow 0.5 override
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1467>
2024-02-16 14:27:29 +02:00
Sebastian Dröge cb0cc764ba Update Cargo.lock
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1467>
2024-02-16 14:26:44 +02:00
Sebastian Dröge 45f55423fb Remove Cargo.lock from .gitignore
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1467>
2024-02-16 14:25:54 +02:00
Sebastian Dröge 8ef12a72e8 rtpgccbwe: Don't reset PTS/DTS to None
The element is usually placed before `rtpsession`, and `rtpsession`
needs the PTS/DTS for correctly determining the running time. The
running time is then used to produce correct RTCP SR, and to potentially
update an NTP-64 RTP header extension if existing on the packets.

Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/496

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1462>
2024-02-14 08:05:54 +00:00
Sebastian Dröge 05884de50c textwrap: Remove unnecessary to_string() in debug output of a string
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1458>
2024-02-12 19:09:06 +02:00
Jordan Yelloz 67b7cf9764 webrtcsink: Added sinkpad with "msid" property
This forwards to the webrtcbin sinkpad's msid when specified.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1442>
2024-02-12 15:04:44 +00:00
Sebastian Dröge 9827106961 Update Cargo.lock
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1455>
2024-02-11 11:55:37 +02:00
Sebastian Dröge b2d5ee48cd Update to async-tungstenite 0.25
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1455>
2024-02-11 11:31:24 +02:00
Sebastian Dröge 7274c725a6 gtk4: Create a window if running from gst-launch-1.0 or GST_GTK4_WINDOW=1 is set
Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/482

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1454>
2024-02-09 15:05:45 +02:00
Sebastian Dröge 66ad059a47 deny: Add zerocopy 0.6 duplicate override for librespot 2024-02-09 10:05:45 +02:00
Sebastian Dröge c0d111e2c1 utils: Update for renamed clippy lint in 1.76 2024-02-08 21:37:17 +02:00
Sebastian Dröge 9116853e6d Update Cargo.lock
Downgrade clap_derive to 4.4.7 to not require Rust 1.74 or newer.
2024-02-08 20:50:44 +02:00
Sebastian Dröge 21aa61b69c Update Cargo.lock 2024-02-08 19:41:00 +02:00
Sebastian Dröge 119d905805 Update version to 0.13.0-alpha.1 2024-02-08 19:41:00 +02:00
Sebastian Dröge 2f964f71bb Update CHANGELOG.md for 0.12.0 2024-02-08 19:31:18 +02:00
Ivan Molodetskikh d8a61edca0 gtk4: Add scaling-filter and use-scaling-filter properties
The property is added under the gtk_v4_10 feature because it requires
GTK 4.10.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1309>
2024-02-08 15:02:36 +02:00
Ivan Molodetskikh 3423d05f77 gtk4: Do scaling with append_texture()
This is equivalent, but will be needed for the scaling filter support.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1309>
2024-02-08 15:02:36 +02:00
Sebastian Dröge 92891a61e8 Fix a couple of compiler/clippy warnings with --no-default-features
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1452>
2024-02-08 13:02:55 +02:00
Sebastian Dröge 76b9836e52 ci: Ignore GTK4 plugin when building with --all-features
And run clippy also with default / no-default features.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1452>
2024-02-08 12:36:37 +02:00
Sebastian Dröge 0fe4e0bf0b gtk4: Add property to the paintable for selecting the background color
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1452>
2024-02-08 12:35:26 +02:00
Sebastian Dröge 9971f71e94 gtk4: Always draw a black background behind the video frame
This makes sure that there is the same background behind the frame, no
matter if black borders have to be added or not. Without this a frame
that has transparency would change rendering depending on the layout.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1452>
2024-02-08 12:35:26 +02:00
Sebastian Dröge 803550111a gtk4: Improve handling of RGBA GL textures in GTK
GTK 4.14 comes with a new GL renderer that does not support GL shader
nodes anymore, so the conversion from non-premultiplied alpha to
premultiplied alpha has to happen differently.

For GTK 4.14 or newer we use the correct format directly when building the
texture, but only if a GLES3+ context is used. In that case the NGL renderer is
used by GTK, which supports non-premultiplied formats correctly and fast.

For GTK 4.10-4.12, or 4.14 and newer if a GLES2 context is used, we use a
self-mask to pre-multiply the alpha.

For GTK before 4.10, we use a GL shader and hope that it works.

Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/488

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1452>
2024-02-08 12:35:26 +02:00
Ruben Gonzalez 09e9c047df gtk4: Fix segfault running gst-inspect -a when GTK4 and GTK3 is installed
Segmentation fault when getting default value of paintable property
from gtk4paintablesink element when libgtk-4.so.1 from libgstgtk4.so
and libgtk-3.so.0 from libgstgtk.so are installed:

> cannot register existing type 'GdkDisplayManager'

Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/490

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1453>
2024-02-08 08:32:14 +00:00
Nirbheek Chauhan cf5e7f6ed3 rtspsrc2: Add some top-level documentation
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1425>
2024-02-08 07:21:51 +05:30
Nirbheek Chauhan 7a1cd675c2 rtspsrc2: Fix RTCP send/recv in the multicast case
Don't use connect(), since that is incompatible with multicast.
Instead, drop received packets that are from senders we do not want.

Also set multicast loopback = false so we don't receive RTCP RRs from
ourselves and interpret them as RTCP SRs.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1425>
2024-02-08 07:21:51 +05:30
Nirbheek Chauhan e59f3bbe58 rtspsrc2: Increase RTP timeout to 5 seconds, matching rtspsrc
Also fix some logging.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1425>
2024-02-08 07:21:51 +05:30
Nirbheek Chauhan 3e963e9239 rtspsrc2: Implement NetAddressMeta support
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1425>
2024-02-08 07:21:51 +05:30
Nirbheek Chauhan 42425abb69 rtspsrc: Factor out SDP → Caps, parse more attributes
This could be a struct of some kind derived from sdp_types::Media etc,
but this is fine for now.

Adds parsing of framesize, and fallbacks for missing or incomplete
rtpmap.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1425>
2024-02-07 20:29:23 +05:30
Nirbheek Chauhan 437326ebfd rtspsrc2: Allocate a buffer pool for UDP RTP data
Control the size with a receive-mtu property

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1425>
2024-02-07 20:29:23 +05:30
Nirbheek Chauhan 44e49a06a0 rtspsrc2: Emit EOS if any ssrc gets a BYE packet or times out
This allows us to exit when the live-stream ends.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1425>
2024-02-07 20:29:23 +05:30
Nirbheek Chauhan 975556c06b rtspsrc2: Allow a SETUP response without a Transports header
If we only send a single Transport in the Transports header, then the
server is allowed to omit it in the response. This has some strange
consequences for UDP transport: specifically, we have no idea what
addr/port we will get the packets from.

In those cases, we connect() on the socket when we receive the first
packet, so we can send RTCP RRs, and also so we can ensure that we
ignore data from other addresses.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1425>
2024-02-07 20:29:23 +05:30
Nirbheek Chauhan 086ffd7aff New RTSP source plugin with live streaming support
GST_PLUGIN_FEATURE_RANK=rtspsrc2:1 gst-play-1.0 [URI]

Features:
* Live streaming N audio and N video
  - With RTCP-based A/V sync
* Lower transports: TCP, UDP, UDP-Multicast
* RTP, RTCP SR, RTCP RR
* OPTIONS DESCRIBE SETUP PLAY TEARDOWN
* Custom UDP socket management, does not use udpsrc/udpsink
* Supports both rtpbin and the rtpbin2 rust rewrite
  - Set USE_RTPBIN2=1 to use rtpbin2 (needs other MRs)
* Properties:
  - protocols selection and priority (NEW!)
  - location supports rtsp[ut]://
  - port-start instead of port-range

Co-Authored-by: Tim-Philipp Müller <tim@centricular.com>
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1425>
2024-02-07 20:29:18 +05:30
Ruben Gonzalez 612ef91af9 meson: Update dav1d dependecies to avoid build error when 1.3
See: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1393
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1447>
2024-02-06 10:13:43 +00:00
Ruben Gonzalez f8572c17dd meson: Use list for dependency version to enable multiple restrictions
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1447>
2024-02-06 10:13:43 +00:00
Sebastian Dröge d7c7784022 deny: Add override for duplicated toml_edit dependency
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1448>
2024-02-06 09:18:35 +02:00
Sebastian Dröge 77cb344650 Update Cargo.lock
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1448>
2024-02-06 09:18:30 +02:00
Sebastian Dröge bb509bd537 version-helper: Update to toml_edit 0.22
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1448>
2024-02-06 09:16:43 +02:00
Bilal Elmoussaoui d25a222bf9 Drop direct muldiv dependency
It is re-exproted in gstreamer's prelude

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1446>
2024-02-05 15:34:31 +01:00
Bilal Elmoussaoui 0615a16124 Use workspace features for crates metadata/deps
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1446>
2024-02-05 15:34:31 +01:00
Sebastian Dröge 91abc62ad0 webrtcsink: Fix new clippy warning
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1445>
2024-02-05 12:53:20 +02:00
Sebastian Dröge d7d2d67558 Update Cargo.lock
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1445>
2024-02-05 12:51:36 +02:00
Sebastian Dröge 1a55c70114 Switch git dependencies to explicitly name branch
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1445>
2024-02-05 12:51:36 +02:00
Sebastian Dröge ffa830ae9b Update for GLib prelude re-organization
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1444>
2024-02-03 12:30:15 +02:00
Sebastian Dröge 59ef053f50 deny: Remove now unnecessary idna override
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1444>
2024-02-03 12:27:53 +02:00
Sebastian Dröge df2f28bf31 Update Cargo.lock
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1444>
2024-02-03 12:27:32 +02:00
Jordan Yelloz 311fda649f livekit_signaller: Added high-quality layer for video streams
This change addresses a cosmetic issue with livekit, where the
connection quality indicator seen by other users shows bad quality
unless the track is added with a high quality layer. The details of the
layer submitted aren't significant for this purpose.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1443>
2024-02-02 20:57:17 +00:00
Robert Ayrapetyan 916a8b959e doc: add http headers for webrtcsink signaller
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1419>
2024-02-01 19:31:58 +00:00
Robert Ayrapetyan 972b9e5474 doc: add docstrings for signaller object
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1419>
2024-02-01 19:31:58 +00:00
Robert Ayrapetyan 7a72b2fc25 webrtcsink-signalling: add headers support
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1419>
2024-02-01 19:31:58 +00:00
François Laignel 91bfd0f7c3 webrtc: signallers: attempt to close the ws when an error occurs
This commit discards the early error returns in the send tasks to log the error
and attempt to close the websocket.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1435>
2024-02-01 18:08:41 +01:00
François Laignel f54d714afd webrtc: only use close() to close websockets
In the signaller clients and servers, the following sequence is used to close
the websocket (in the [send task]):

```rust
    ws_sink.send(WsMessage::Close(None)).await?;
    ws_sink.close().await?;
```

tungstenite's [`WebSocket::close()` doc] states:

> Calling this function is the same as calling `write(Message::Close(..))``

So we might think they are redundant and either could be used for this purpose
(`send()` calls `write()`, then `flush()`).

The result is actually is bit different as `write()` starts by checking the
state of the connection and [returns `SendAfterClosing`] if the socket is no
longer active, which is the case when a closing request has been received from
the peer via a [call to `do_close()`]). Note that `do_close()` also enqueues a
`Close` frame.

This behaviour is visible from the server's logs:

```
1. tungstenite::protocol: Received close frame: None
2. tungstenite::protocol: Replying to close with Frame { header: FrameHeader { .., opcode: Control(Close), .. }, payload: [] }
3. gst_plugin_webrtc_signalling::server: Received message Ok(Close(None))
4. gst_plugin_webrtc_signalling::server: connection closed: None this_id=cb13892f-b4d5-4d59-95e2-b3873a7bd319
5. remove_peer{peer_id="cb13892f-b4d5-4d59-95e2-b3873a7bd319"}: gst_plugin_webrtc_signalling::server: close time.busy=285µs time.idle=55.5µs
6. async_tungstenite: websocket start_send error: WebSocket protocol error: Sending after closing is not allowed
```

1: The server's websocket receives the peer's `Close(None)`.
2: `do_close()` enqueues a `Close` frame.
3: The incoming `Close(None)` is handled by the server.
4 & 5: perform session closing.
6: `ws_sink.send(WsMessage::Close(None))` attempts to `write()` while the ws
   is no longer active. The error causes an early return, which means that
   the enqueued `Close` frame is not flushed.

Depending on the peer's shutdown sequence, this can result in the following
error, which can bubble up as a `Message` on the application's bus:

```
ERROR: from element /GstPipeline:pipeline0/GstWebRTCSrc:webrtcsrc0: GStreamer encountered a general stream error.
Additional debug info:
net/webrtc/src/webrtcsrc/imp.rs(625): gstrswebrtc::webrtcsrc:👿:BaseWebRTCSrc::connect_signaller::{{closure}}::{{closure}} (): /GstPipeline:pipeline0/GstWebRTCSrc:webrtcsrc0:
Signalling error: Error receiving: WebSocket protocol error: Connection reset without closing handshake
```

On the other hand, [`close()` ensures the ws is active] before attempting to
write a `Close` frame. If it's not, it only flushes the stream.

Thus, when we want to be able to close the websocket and/or to honor the closing
handshake in response to the peer `Close` message, the `ws_sink.close()`
variant is preferable.

This can be verified in the resulting server's logs:

```
tungstenite::protocol: Received close frame: None
tungstenite::protocol: Replying to close with Frame { header: FrameHeader { is_final: true, rsv1: false, rsv2: false, rsv3: false, opcode: Control(Close), mask: None}, payload: [] }
gst_plugin_webrtc_signalling::server: Received message Ok(Close(None))
gst_plugin_webrtc_signalling::server: connection closed: None this_id=192ed7ff-3b9d-45c5-be66-872cbe67d190
remove_peer{peer_id="192ed7ff-3b9d-45c5-be66-872cbe67d190"}: gst_plugin_webrtc_signalling::server: close time.busy=22.7µs time.idle=37.4µs
tungstenite::protocol: Sending pong/close
```

We now get the notification `Sending pong/close` (the closing handshake) instead
of `websocket start_send error` from step 6 with previous variant.

The `Connection reset without closing handshake` was not observed after this
change.

[send task]: 63b568f4a0/net/webrtc/signalling/src/server/mod.rs (L165)
[`WebSocket::close()` doc]: https://docs.rs/tungstenite/0.21.0/tungstenite/protocol/struct.WebSocket.html#method.close
[returns `SendAfterClosing`]: 85463b264e/src/protocol/mod.rs (L437)
[call to `do_close()`]: 85463b264e/src/protocol/mod.rs (L601)
[`close()` ensures the ws is active]: 85463b264e/src/protocol/mod.rs (L531)

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1435>
2024-02-01 18:08:41 +01:00
Taruntej Kanakamalla 50e905fe4b webrtc: conditional compile for features with 1_22 dependency
Few features being used in webrtcsink like
the signal `request-aux-sender` are introduced
to webrtcbin in gstreamer release 1.22.

Rename the feature gst1_22 to v1_22 for uniformity.

Add v1_22 to default features.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1241>
2024-02-01 15:08:11 +05:30
Sebastian Dröge f2a7a34abf rtp: gcc: Use x += ... instead of x = x + ... 2024-01-31 18:46:55 +02:00
Sebastian Dröge a82068643d deny: Remove unnecessary toml_edit override
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1441>
2024-01-31 18:07:57 +02:00
Sebastian Dröge 4ad101b53b Use once_cell crate directly again
The glib crate does not depend on it anymore and also does not re-export
it anymore.

Also switch some usages of OnceCell to OnceLock from std.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1441>
2024-01-31 18:07:57 +02:00
Sebastian Dröge 08af298d11 gif: Update to gif 0.13
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1441>
2024-01-31 18:07:57 +02:00
Sebastian Dröge 451d928026 webrtc: Update AWS signaller to http 1
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1441>
2024-01-31 18:07:57 +02:00
Sebastian Dröge 0e86dfa944 Update Cargo.lock
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1441>
2024-01-31 16:51:49 +02:00
Mathieu Duponchelle ad51c61ac8 textwrap: add support for gaps
When accumulate-time is non-zero, we need to drain our accumulated
text once the threshold is reached.

Implement support for gaps the simplest way, by transforming it into
an empty buffer and chaining it through ourself.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1436>
2024-01-30 13:51:05 +01:00
Michael Tretter 4bb867bf52 livesync: add support for image formats
The livesync element is also useful for Motion JPEG streams. However,
Motion JPEG uses image/ caps instead of video/ caps.

The framerate is defined for image/, too.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1440>
2024-01-29 11:07:30 +00:00
Michael Tretter 54f24fe4b0 meson: allow building plugins with GTK 4 examples
Only the examples of the fallbackswitch, livesync, and togglerecord
plugins require the gtk, gio, and gst-plugin-gtk4 features. The plugins
themselves don't actually have a dependency on GTK.

Only add the features (and examples) if the examples are actually
enabled to allow building these plugins without the GTK dependency.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1438>
2024-01-29 10:48:14 +00:00
Guillaume Desmottes 33a1d8de3d tracers: buffer-lateness: display some stats about late buffers
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1437>
2024-01-29 09:24:08 +00:00
Guillaume Desmottes d5740ea844 tracers: buffer-lateness: add argument to display only late buffers
Help to easily spot places where buffers are late when plotting big
pipelines.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1437>
2024-01-29 09:24:08 +00:00
Nirbheek Chauhan 5b0733d535 meson: Add nasm to PATH if meson can find it
Fixes rav1e build on Windows when built inside the monorepo.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1431>
2024-01-26 17:37:38 +00:00
Nirbheek Chauhan 6b79ce605d meson: pkg-config is required at build time
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1431>
2024-01-26 17:37:38 +00:00
Nirbheek Chauhan 8b5a398135 meson: Fix build on Windows with MSVC
Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/480

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1431>
2024-01-26 17:37:38 +00:00
Michael Tretter fcd57e9ac5 meson: remove trailing whitespace and add comma
Cleanup without functional change.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1439>
2024-01-24 12:03:11 +01:00
Sanchayan Maity 95c007953c webrtchttp: Allow audio or video caps to be specified as None with WHEP
We were setting audio and video caps by default even when the user
might have requested only video or audio. This would then result
in a `Could not reuse transceiver` error from the webrtcbin.

Fix this by allowing the user to specify audio or video caps as
None. This allows us to maintain the earlier behaviour for backward
compatibility while allowing the user to not request audio or video
as need be.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1433>
2024-01-18 15:43:19 +05:30
Sebastian Dröge 764143d971 webrtc: Remove unnecessary manual Send+Sync implementations for signallers
These are automatically implemented.

Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/483

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1432>
2024-01-18 10:01:25 +02:00
Sebastian Dröge 1af18f3028 webrtc: Require Send+Sync for signaller implementations
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1432>
2024-01-18 10:01:01 +02:00
Eva Pace 80b58f3b45 net/webrtc/janusvr: add JanusVRWebRTCSink plugin/signaller
The JanusVRWebRTCSink is a new plugin that integrates with the Video
Room plugin of the Janus Gateway, which simplifies WebRTC communication.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1362>
2024-01-17 20:33:57 +00:00
Maksym Khomenko 773ebc7854 webrtcsrc: don't restrict RTP extensions to TWCC only
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1381>
2024-01-17 07:34:01 +00:00
Guillaume Desmottes c616423edb livesync: properly format jitter in debug logs
Easier to read that way.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1430>
2024-01-16 13:46:34 +01:00
Sebastian Dröge 9556abb162 deny: Remove unnecessary overrides and add new one for livekit -> itertools
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1427>
2024-01-16 07:52:48 +00:00
Sebastian Dröge c8bd1293b9 inter: Update to serial_test 3
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1427>
2024-01-16 07:52:48 +00:00
Sebastian Dröge dfa95d8ed3 webrtc: Update to livekit-api / livekit-protocol 0.3
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1427>
2024-01-16 07:52:48 +00:00
Sebastian Dröge c85106e700 Update Cargo.lock
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1427>
2024-01-16 07:52:48 +00:00
Maksym Khomenko fecbe01e06 webrtcsink: make 'extensions' property usage conditional
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1423>
2024-01-16 07:13:56 +00:00
Sebastian Dröge 73a53e38c4 aws: s3: Disable remaining tests too for now
They fail state changes, which cases `GstHarness` to abort.
2024-01-16 09:13:41 +02:00
Arun Raghavan fd3675aac0 aws: s3: Temporarily disable putobject tests
Disabling while we figure out why it's failing.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1429>
2024-01-15 21:43:25 -05:00
Arun Raghavan e70ef7f9e4 Update Cargo.lock
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1416>
2024-01-11 15:38:57 -05:00
Arun Raghavan 8b18ca15b5 Revert "aws: Disable putobjectsink tests for now"
This reverts commit b128d127c2.

Fixes: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/472
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1416>
2024-01-11 15:38:36 -05:00
Arun Raghavan 06213714c5 aws: putobjectsink: Fix a couple of minor log typos
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1416>
2024-01-11 15:38:36 -05:00
Sebastian Dröge fdd33fdeb0 deny: Remove a few de-duplicated dependencies
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1421>
2024-01-04 13:03:20 +02:00
Sebastian Dröge cb78260d22 Update Cargo.lock
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1421>
2024-01-04 13:00:21 +02:00
Sebastian Dröge d36c91d10f rav1e: Update to rav1e 0.7
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1421>
2024-01-04 12:59:50 +02:00
Nirbheek Chauhan 2d85048925 webrtc/signalling: We get the address when accepting
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1412>
2023-12-29 13:28:48 +00:00
Nirbheek Chauhan 63b568f4a0 webrtc/signalling: Fix potential hang and FD leak
If a peer connects via TCP and never initiates TLS, then the server
will get stuck in the accept loop. Spawn a task when accepting a TLS
connection, and timeout if it doesn't complete in 5 seconds.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1412>
2023-12-29 13:28:48 +00:00
Guillaume Desmottes d9397ef174 gtk4: fix build on Windows using winegl
from_glib_full() was not in scope.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1417>
2023-12-26 23:22:35 +01:00
Maksym Khomenko 17f0b61576 webrtcsink: add payloader-setup signal
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1389>
2023-12-23 08:02:08 +00:00
Sebastian Dröge 1ef47cb48e Fix a few new clippy 1.75 warnings
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1415>
2023-12-22 16:40:18 +02:00
Sebastian Dröge 79b8610fbe Update Cargo.lock
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1414>
2023-12-22 15:46:51 +02:00
Sebastian Dröge b128d127c2 aws: Disable putobjectsink tests for now
See https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/472

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1413>
2023-12-22 13:25:12 +02:00
Sebastian Dröge 6686f6415f Update Cargo.lock
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1413>
2023-12-22 13:12:19 +02:00
Sebastian Dröge df1f986239 Update plugin documentation cache
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1413>
2023-12-22 11:41:01 +02:00
Arun Raghavan 06d96ec5a2 aws: Add plugin docs
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1337>
2023-12-18 16:13:48 -05:00
Arun Raghavan 6d47045a60 aws: s3sink: Fix spelling of debug category
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1337>
2023-12-18 16:13:48 -05:00
Arun Raghavan 410d104ad6 aws: s3putobjectsink: Add a flush-on-error property
Makes sure we can send out data even if the pipeline shutdown in error.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1337>
2023-12-18 16:13:48 -05:00
Arun Raghavan 12dbf50ddc aws: s3putobjectsink: Add some thresholds for flushing
Lets us connect when we perform a flush

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1337>
2023-12-18 16:13:48 -05:00
Arun Raghavan a54b2dd39e aws: s3: Add a new awss3putobjectsink
When streaming small amounts of data, using awss3sink might not be a
good idea, as we need to accumulate at least 5 MB of data for a
multipart upload (or we flush on EOS).

The alternative, while inefficient, is to do a complete PutObject of
_all_ the data periodically so as to not lose data in case of a pipeline
failure. This element makes a start on this idea by doing a PutObject
for every buffer.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1337>
2023-12-18 10:39:23 -05:00
Sebastian Dröge 0a27b9e6d9 Update CHANGELOG.md to 0.11.3 2023-12-18 12:22:52 +02:00
Sebastian Dröge 763739e3ae Update for Buffer / Memory API changes
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1409>
2023-12-17 14:07:12 +02:00
Sebastian Dröge 68b9dadf07 Update Cargo.lock
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1409>
2023-12-17 14:07:07 +02:00
Arun Raghavan 1faef49b51 threadshare: Fix a deadlock in used-socket notification
This manifests in a gst-launch-1.0 pipeline using ts-udpsrc, since
notification of used-socket results in the property being read by the
application, and the settings lock causes a deadlock.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1408>
2023-12-14 11:29:10 -05:00
Arun Raghavan 9b1c9b1892 threadshare: Fix a typo while logging
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1408>
2023-12-14 11:29:10 -05:00
Sebastian Dröge 99b68d5b63 Update Cargo.lock
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1407>
2023-12-14 09:11:27 +02:00
Sebastian Dröge 81dd45c814 webrtc: Downgrade aws-smithy-http to 0.60
Version 0.61 was yanked from crates.io.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1407>
2023-12-14 09:11:07 +02:00
Sebastian Dröge caa1451fe8 Update Cargo.lock
Keep dash-mpd at 0.14.5 and xattr at 1.0.1 because otherwise compilation
fails, see:
  - https://github.com/Stebalien/xattr/issues/44
  - https://github.com/bytecodealliance/rustix/issues/945

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1404>
2023-12-09 13:01:25 +02:00
Sebastian Dröge 147df5fd74 deny: Update
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1404>
2023-12-09 12:28:10 +02:00
Sebastian Dröge 2f2bf6ca8f webrtc: Update to aws-smithy-http 0.61
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1404>
2023-12-09 12:21:38 +02:00
Sebastian Dröge 0bae18fe0d rtp: Update to bitstream-io 2.0
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1404>
2023-12-09 12:17:51 +02:00
Sebastian Dröge 181bd13103 Update to async-tungstenite 0.24
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1404>
2023-12-09 12:17:11 +02:00
Guillaume Desmottes 308a0c4532 Cargo.lock: update
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1403>
2023-12-05 09:06:53 +01:00
Guillaume Desmottes 6dfd1c1496 use new debug and parse API
Changes from https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/merge_requests/1355

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1403>
2023-12-04 15:58:21 +01:00
Sebastian Dröge c7f961cc22 Update Cargo.lock
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1400>
2023-11-26 10:26:26 +02:00
Sebastian Dröge f13574d8ed Update further AWS SDK crates to 1.0
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1400>
2023-11-26 10:26:02 +02:00
Mathieu Duponchelle cf1c7600a2 webrtcsink: don't panic on failure to request pad from webrtcbin
webrtcbin will refuse pad requests for all sorts of reasons, and should
be logging an error when doing so, simply post an error message and let
the application deal with it, the reason for the refusal should
hopefully be available in the logs to the user.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1399>
2023-11-24 19:53:38 +01:00
Matthew Waters d644bcd79a closedcaption: update to cea708-types 0.3
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1398>
2023-11-22 10:07:45 +11:00
Matthew Waters 5739a3d86f cea608tocea708: create service's as requested
Allows the ability to push multiple Service blocks of the same service
into the same packet if necessary (unlikely but possible).

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1398>
2023-11-22 00:12:50 +11:00
Matthew Waters ded4261971 closedcaption: move some textstyle helpers to shared files
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1398>
2023-11-21 23:33:09 +11:00
Matthew Waters fb9b511e15 closedcaption: move 708 service writing to shared file
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1398>
2023-11-21 23:33:09 +11:00
Matthew Waters 4333e90220 tttocea608: use crate defined is_* functions instead of reeimplementing them
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1398>
2023-11-21 23:33:09 +11:00
Sebastian Dröge 6c5a0c2795 Update Cargo.lock
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1397>
2023-11-21 10:33:26 +02:00
Sebastian Dröge c3ced8c7e6 Update to AWS SDK 1.0 / 0.60 / 0.39
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1397>
2023-11-21 10:32:59 +02:00
Sebastian Dröge 9251b1ca26 deny: Update for duplicated crypto-bigint dependency 2023-11-20 10:24:20 +02:00
Sebastian Dröge 47d540b7b8 Update Cargo.lock 2023-11-20 10:14:01 +02:00
Sebastian Dröge 1d9c89e3fe Update to AWS SDK 0.101 / 0.59 / 0.38 2023-11-20 10:13:13 +02:00
Sebastian Dröge 66c62d69b9 aws: Stop using deprecated aws_config function in the test 2023-11-18 10:16:24 +02:00
Taruntej Kanakamalla 43ee6bfc1c net/webrtc: add whipserversrc
Implement new signaller WhipServerSignaller
 - an http server using 'warp'
 - handlers for the POST, OPTIONS, PATCH and DELETE
 - fixed path `/whip/endpoint` as the URI
 - fixed value 'whip-client' as the producer peer id
 - fixed resource url `/whip/resource/whip-client`

Derive whipserversrc element from BaseWebRTCSrc
 - implement constructed method for ObjectImpl to set
  non-default signaller, i.e., WhipServerSignaller
 - bind the properties stun-server and turn-servers to those on
   the Signaller

Connect to 'webrtcbin-ready' signal in the constructor of WhipServerSignaller
 - it will be emitted by the webrtcsrc when the webrtcbin element is ready
 - the closure for this signal will in turn connect to webrtcbin's ice-gathering-state
   and perform send with the answer sdp via the channel
 - the WhipServer will hold its HTTP response in POST handler until this signal
   is received or timeout which happens early

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1284>
2023-11-17 18:08:44 +00:00
Taruntej Kanakamalla ed3aa740be net/webrtc: deprecate consumer-added on the signaller
add a new signal webrtcbin-ready in this place doing same
thing but can be used for both consumers and producers

Please note this change is only to the consumer-added
signal on the signaller interface.
The consumer-added signal on the webrtcsink is unchanged

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1284>
2023-11-17 18:08:44 +00:00
Taruntej Kanakamalla 2d3d03b4d3 net/webrtc: rename WhipSignaller as WhipClientSignaller
remove generalized names to accommodate for the WhipServer
- name the Signaller for whipsink as WhipClient
- name the Settings for whipsink as WhipClientSettings
- name the State for whipsink as WhipClientState

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1284>
2023-11-17 18:08:44 +00:00
Taruntej Kanakamalla a0638ec983 net/webrtc: Extract BaseWebRTCSrc
Define a Base for all the webrtcsrc type elements
so they can all be derived from it. Similar to base
element defined for webrtcsink type elements

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1284>
2023-11-17 18:08:44 +00:00
Sebastian Dröge 3fcab67570 Update Cargo.lock
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1395>
2023-11-17 11:23:06 +02:00
Sebastian Dröge ceff8bd127 deny: Add duplicated windows crates version
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1395>
2023-11-17 11:22:47 +02:00
Sebastian Dröge dee27e35b7 Update to latest AWS SDK
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1395>
2023-11-17 11:22:29 +02:00
Sebastian Dröge dd67dc87e3 gtk4: Update to windows-sys 0.52
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1395>
2023-11-17 11:00:55 +02:00
Sebastian Dröge 097de9dbb7 Update Cargo.lock
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1394>
2023-11-15 17:36:17 +02:00
Sebastian Dröge 8045e441a2 deny: Remove unnecessary tracing-log duplicate and add itertools
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1394>
2023-11-15 17:35:55 +02:00
Sebastian Dröge 58723f2a8c Update to AWS SDK 0.36
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1394>
2023-11-15 17:20:58 +02:00
Seungha Yang 8a04a38631 fallbacksrc: Fix timeout scheduling
Other thread can schedule the timeout (e.g., unblock signal
or active pad change) while state lock is released

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1384>
2023-11-15 09:17:39 +00:00
François Laignel 9250c592a7 ndi: don't accumulate meta with audio only streams
Currently, only closed caption metadata are supported. When the next video
frame is received, pending meta are dequeued and parsed. If close captions
are found, they are attached to the video frame.

For audio only streams, it doesn't make sense to enqueue metadata. They would
accumulate in `pending_metadata` and would never be dequeued.

Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/460

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1392>
2023-11-13 19:26:23 +01:00
Sebastian Dröge 636c76b03b uriplaylistbin: Fix new clippy warning
warning: the borrowed expression implements the required traits
    --> utils/uriplaylistbin/src/uriplaylistbin/imp.rs:1691:32
     |
1691 |         self.obj().remove_many(&children_ref).unwrap();
     |                                ^^^^^^^^^^^^^ help: change this to: `children_ref`

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1391>
2023-11-13 17:41:06 +02:00
Sebastian Dröge 39155ef81c ndisrc: Implement zerocopy handling for the received frames if possible
Also move processing from the capture thread to the streaming thread.
The NDI SDK can cause frame drops if not reading fast enough from it.

All frame processing is now handled inside the ndisrcdemux.

Also use a buffer pool for video if copying is necessary.

Additionally, make sure to use different stream ids in the stream-start
event for the audio and video pad.

This plugin now requires GStreamer 1.16 or newer.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1365>
2023-11-13 13:22:48 +02:00
Sebastian Dröge 2afffb39dd ndi: Don't mark private type as public
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1365>
2023-11-13 10:29:25 +02:00
Sebastian Dröge 99d7cce0d6 ndi: Refactor frame structs to have static lifetimes
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1365>
2023-11-13 10:29:25 +02:00
Sebastian Dröge eb137ec6dc ndi: Remove wrong Clone impl on RecvInstance
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1365>
2023-11-13 10:29:25 +02:00
Sebastian Dröge 6c5c09fae9 Update CHANGELOG.md for 0.11.2 2023-11-11 21:00:30 +02:00
Sebastian Dröge 885928ea17 ci: Run cargo update as part of the cargo deny / cargo outdated jobs 2023-11-10 08:55:31 +02:00
Arun Raghavan 771741c10c Revert "s3: tests: Remove emoji-based tests for now"
This reverts commit a49a5dcb11.

Now that hotdoc should work with emoji, let's bring the tests back.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1386>
2023-11-09 11:50:53 -05:00
Sebastian Dröge 63edc84103 Add Cargo.lock to the repository
This makes sure that any broken dependency updates are not breaking our
build, at the cost of requiring us to update the lock file regularly.

See also https://blog.rust-lang.org/2023/08/29/committing-lockfiles.html

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1385>
2023-11-09 10:08:08 +02:00
Sebastian Dröge 8b37d8ec02 deny: Add override for duplicated toml_edit dependency
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1385>
2023-11-09 10:06:55 +02:00
Sebastian Dröge a8205d5b5d version-helper: Update to toml_edit 0.21
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1382>
2023-11-07 09:28:23 +02:00
Maksym Khomenko e5fd2c3568 webrtcsrc: add turn-servers property
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1380>
2023-11-04 10:19:45 +00:00
Mathieu Duponchelle 5371eb52ad Port to AWS SDK 0.57/0.35
Co-authored-by: Sebastian Dröge <sebastian@centricular.com>
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1379>
2023-11-03 15:13:45 +00:00
Sebastian Dröge f7745a336f aws: Update to test-with 0.12
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1379>
2023-11-03 15:13:45 +00:00
Sebastian Dröge a33f29365a sccparse: Fix leading spaces between the tab and caption data
CCExtractor is creating files like this.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1378>
2023-11-02 21:59:02 +02:00
Sebastian Dröge 16b917abb1 Update for gst::Rank API changes 2023-11-02 14:10:59 +02:00
Piotr Brzeziński 436b6d8efb gstwebrtc-api: Patch webrtc-adapter to fix Safari behaviour
There's currently a Safari-side bug causing webrtc-adapter to be unable to correctly shim the empty-candidate scenario
which we're using. This patch is very much a workaround and should be removed as soon as Safari and/or webrtc-adapter
fixes this on their side.

https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/439
https://github.com/webrtcHacks/adapter/issues/1140

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1377>
2023-10-30 16:36:11 +00:00
Sebastian Dröge 16c00ae3f5 Set sync=false in rsfilesink / s3sink
BaseSink defaults to sync=true and that doesn't make much sense for
these elements.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1376>
2023-10-30 17:38:46 +02:00
Sebastian Dröge 855b03a9ea Use let-else instead of match for weak reference upgrades
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1375>
2023-10-30 11:34:35 +02:00
Sebastian Dröge 74c04d79c9 gtk4: Use async-channel instead of the glib MainContext channel
The latter will be removed in favour of using async code in the future,
and async code generally allows for more flexible message handling than the
callback based MainContext channel.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1375>
2023-10-30 11:21:25 +02:00
Sebastian Dröge b771afe8be deny: Update duplicated dependencies
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1374>
2023-10-27 10:20:54 +03:00
Sebastian Dröge 557b249e11 Update to AWS SDK 0.34 and tracing-log 0.2
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1374>
2023-10-27 10:19:15 +03:00
Jan Alexander Steffens (heftig) e3e58ac0be livesync: Remove the stop from outgoing segments
Our buffer duplication can extend a segment indefinitely.

Fixes: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/452
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1372>
2023-10-25 19:34:47 +02:00
Jan Alexander Steffens (heftig) f1ba498b52 livesync: Keep existing buffer duration in some cases
Resize a repeat buffer only if caps gave us a duration to use, or we
consider its current duration unreasonable.

In particular, for audio streams we should prefer reusing the buffer
size upstream gave us, as we did before 6633cc4046.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1372>
2023-10-25 19:34:47 +02:00
Jan Alexander Steffens (heftig) 59beade079 livesync: Split fallback_duration into in_ and out_duration
Make it independent of the `latency`; this was inconsistent anyway,
where the default latency of zero got you a fallback duration of 100 ms
and something else got you half the latency.

Maintain a separate duration for the `in` and the `out` side so we
change the duration of repeat buffers after a caps change, not just
before.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1372>
2023-10-25 19:08:16 +02:00
Guillaume Desmottes f94ecfc7a6 livesync: display jitter when waiting on clock
We already log the result of the clock wait call so may as well log the
returned jitter.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1370>
2023-10-25 14:26:19 +02:00
Guillaume Desmottes 13dae0f0d0 livesync: log new pending segments
The debug print of the event does not display details about the segment:
  Unqueueing Some(Event(Event { ptr: 0x7fa3e0002580, type: "segment", seqnum: Seqnum(479), structure: Some(GstEventSegment { segment: (GstSegment) ((GstSegment*) 0x7fa3e8001d00) }) }))

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1370>
2023-10-25 14:24:35 +02:00
Jan Alexander Steffens (heftig) ee93448de7 livesync: example: Add identities single-segment=1
These let us change the runtime offset of the test buffers via pad
offsets without pushing new segments into livesync, which is necessary
to demo the late-threshold behavior.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1369>
2023-10-25 12:55:06 +02:00
Jan Alexander Steffens (heftig) 6633cc4046 livesync: Use fallback_duration for audio repeat buffers as well
Don't depend on upstream giving us sanely-sized buffers if we want to
repeat.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1369>
2023-10-25 12:55:06 +02:00
Jan Alexander Steffens (heftig) 4ac7d0415b livesync: Separate out_buffer duplicate status from GAP flag
Otherwise we might get confused by upstream GAP buffers.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1369>
2023-10-25 12:10:40 +02:00
Jan Alexander Steffens (heftig) 2f36bd5d77 livesync: Handle flags and late buffer patching after queueing
This makes the chain function almost independent of the output state. We
still do the early discard check with `buffer_is_backwards` so we don't
try to queue buffers we can't use, allowing us to fast-forward upstream
without blocking on the src task.

Don't accept `LateOverThreshold` buffers when we have `pending_caps` or
a `pending_segment`. We need to apply these first before we can sensibly
patch buffers from the new stream.

Deduplicate most of the output buffer patching code into a new
`patch_output_buffer` method.

For: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/450
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1369>
2023-10-25 11:52:41 +02:00
Jan Alexander Steffens (heftig) 7c48a299c3 livesync: Simplify num_duplicate counting
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1369>
2023-10-25 11:52:40 +02:00
Jan Alexander Steffens (heftig) 17a2448237 livesync: Move num_in counting to the src task
This is in preparation for moving more accept/discard logic to the src
task, so we can only count `num_in` here.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1369>
2023-10-25 11:52:40 +02:00
Jan Alexander Steffens (heftig) 1740a8e363 livesync: Move a notify closer to the interesting state change
Move the `notify_all` to where we pop the buffer. We're moving within a
single state lock so no change in behavior.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1369>
2023-10-25 11:52:40 +02:00
Jan Alexander Steffens (heftig) 44f2195674 livesync: Replace an if-let with match
No change in behavior, yet. Separate commit to ease reviewing.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1369>
2023-10-25 11:52:40 +02:00
Jan Alexander Steffens (heftig) 62791bfb47 livesync: Clean up state handling
- Separate resetting state more cleanly, introducing `set_flushing`,
  `sink_reset` and `src_reset`.
- Clear the queue early when we flush, in order to unblock waits on
  query responses.
- Return an error when we fail to start, pause or stop the task.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1369>
2023-10-25 11:52:40 +02:00
Jan Alexander Steffens (heftig) d663f708ef livesync: Log a category error when we are missing the segment
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1369>
2023-10-25 11:52:40 +02:00
Jan Alexander Steffens (heftig) 6567041a3d livesync: Improve audio duration fixups
- An entirely missing duration is now only logged at debug level instead
  of pretending the duration was zero and warning about it.
- Silently fix up a duration difference up to one sample.
- Error when we fail to calculate the duration; don't try to apply the
  `fallback_duration` to a non-video stream.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1369>
2023-10-25 11:52:40 +02:00
Jan Alexander Steffens (heftig) 0a45f776e0 livesync: Simplify start_src_task and src_loop
This should effect no change in behavior.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1369>
2023-10-25 11:03:15 +02:00
Jan Alexander Steffens (heftig) 01386b8451 livesync: Rename activatemode methods to *_activatemode
This matches the other plugins.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1369>
2023-10-25 11:03:14 +02:00
Arun Raghavan d27a04e067 hlssink3: Close the playlist giostreamsink on stop if possible
This is a property that will be available from GStreamer 1.24, and will
ensure that we are able to flush the playlist during the READY->NULL
transition instead of when the element is freed.

Fixes: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/423
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1360>
2023-10-24 21:03:14 +00:00
Arun Raghavan a49a5dcb11 s3: tests: Remove emoji-based tests for now
These break hotdoc, which we need to fix first.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1333>
2023-10-24 12:52:12 -04:00
Arun Raghavan bb26e04a55 aws: s3: Properly percent-decode GstS3Url
We previously only percent-decoded the first fragment. This doesn't
necessarily harm anything, but for consistency we keep the structure
un-encoded, and encode when converting to a string representation.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1333>
2023-10-24 12:52:12 -04:00
Arun Raghavan 51129febeb aws: s3sink: Fix handling of special characters in key
Properly URL-encode the string if needed, and add some tests for a
couple of cases.

Fixes: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/431
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1333>
2023-10-24 12:52:12 -04:00
Sebastian Dröge 829469d0fe rtpav1depay: Don't push stale temporal delimiters downstream
Only push them downstream once a complete OBU was assembled.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1367>
2023-10-24 11:13:35 +00:00
Sebastian Dröge 1f5e9a9335 rtpav1depay: Skip unexpected leading fragments
If a packet is starting with a leading fragment but we do not expect to
receive one, then skip over it to the next OBU.

Not doing so would cause parsing of the middle of an OBU, which would
most likely fail and cause unnecessary warning messages about a
corrupted stream.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1367>
2023-10-24 11:13:35 +00:00
Sebastian Dröge b1894a0acb deny: Remove unnecessary ignore entry
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1368>
2023-10-24 09:55:54 +03:00
Sebastian Dröge 73ff822d24 Update to quick-xml 0.31
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1368>
2023-10-24 09:55:50 +03:00
Jordan Petridis a2d7f42138 Fix compilation after glib bindings changes
loggable_error! can now expand variables and we no longer need
the format! on our side.

https://github.com/gtk-rs/gtk-rs-core/pull/1210

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1366>
2023-10-22 01:20:56 +03:00
Nirbheek Chauhan 895ee1d00b ci: Make meson warnings fatal
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1364>
2023-10-18 18:49:02 +05:30
Nirbheek Chauhan 235e609eff meson: Bump requirement to 1.1
WARNING: Project specifies a minimum meson_version '>= 0.60' but uses features which were added in newer versions:
* 1.1.0: {'feature_option.enable_if()'}

Caused by https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1363

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1364>
2023-10-18 18:07:50 +05:30
Nirbheek Chauhan 84b0dd8980 meson: Enable the RTP option when WebRTC is enabled
And make the webrtc option yielding, see:

https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5505

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1363>
2023-10-18 14:47:16 +05:30
Nirbheek Chauhan c4a788b97b .gitignore: Ignore the meson subproject wrap hash
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1363>
2023-10-18 14:47:16 +05:30
Olivier Crête a946895fad Revert "deny: Temporarily allow a duplicated tungstenite dependency"
LiveKit has now been fixed.

This reverts commit 23e1bfa720.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1293>
2023-10-18 10:31:14 +03:00
Sebastian Dröge 2ce04c6a78 webrtc: Update to livekit 0.2
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1293>
2023-10-18 10:30:59 +03:00
Sebastian Dröge aacfe546d5 deny: Update for duplicated redox_syscall dependency 2023-10-18 10:25:27 +03:00
Sebastian Dröge d468e1e4a6 Clean up usage of pad probes
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1361>
2023-10-17 08:44:06 +03:00
François Laignel 50dd519c4f net/webrtcsrc: define signaller property as CONSTRUCT_ONLY
The "signaller" property used to be defined as MUTABLE_READY which meant that
the property was always set after `constructed()` was called.

Since `connect_signaller()` was called from `constructed()`, only the default
signaller was used.

This commit sets the "signaller" property as CONSTRUCT_ONLY. Using a builder,
this property will now be set before the call to `constructed()`.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1324>
2023-10-12 17:38:09 +00:00
François Laignel 785c9557c8 net/webrtcsink: drop State lock before calling set-local-description
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1325>
2023-10-12 15:45:58 +00:00
François Laignel c021e2b69f net/webrtcsink: don't miss ice candidates
During `on_remote_description_set()` processing, current session is removed
from the sessions `HashMap`. If an ice candidate is submitted to `handle_ice()`
by that time, the session can't be found and the candidate is ignored.

This commit wraps the Session in the sessions `HashMap` so an entry is kept
while `on_remote_description_set()` is running. Incoming candidates received by
`handle_ice()` will be processed immediately or enqueued and handled when the
session is restored by `on_remote_description_set()`.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1325>
2023-10-12 15:45:58 +00:00
Sebastian Dröge 42008fb895 aws: Update to test-with 0.11
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1358>
2023-10-12 06:57:28 +00:00
Lieven Paulissen 05aa9fa431 ndisrc: Assume input with more than 8 raw audio channels is unpositioned
gst_audio_channel_positions_from_mask() will otherwise print warnings
all the time.

Fixes #444

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1357>
2023-10-12 09:12:02 +03:00
François Laignel 022afa6375 ndi: use v210 encoding for cc and attach to video frame
The NDI closed captions specifications [1] define a variation where metadata is
attached to the video frame. This requires the AFD buffer to be v210 encoded.
This commit applies this strategy.

Another difference with previous version is that when an error occurs while
encoding or decoding a meta, next meta are also tried instead of failing
immediately.

Receiving closed captions as a standalone metadata is kept for interoperability
purposes. In this case, metadata is also expected to be v210 encoded.

[1]: http://www.sienna-tv.com/ndi/ndiclosedcaptions.html

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1356>
2023-10-11 21:25:29 +02:00
Maksym Khomenko 5b03f7d7b0 webrtcsrc: use @watch instead of @to-owned
@to-owned increases refcount of the element, which prevents the object from proper destruction, as the initial refcount with ElementFactory::make is larger than 1.

Instead, use @watch to create a weak reference and unbind the closure automatically if the object gets destroyed

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1355>
2023-10-11 11:54:51 +03:00
Sebastian Dröge 3fc6220009 Update to AWS SDK 0.33
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1354>
2023-10-09 11:28:05 +03:00
Taruntej Kanakamalla 245185d2f6 net/webrtc/whip_signaller: Use the correct URL during redirect
Copy of 90e06dc3 for whipclientsink

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1351>
2023-10-06 13:11:46 +00:00
Maksym Khomenko e4096b5157 webrtcsink: README: add documentation for custom signaller
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1340>
2023-10-06 12:58:04 +03:00
Maksym Khomenko a9719cada2 webrtcsink: add custom signaller example
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1340>
2023-10-06 12:58:03 +03:00
Sebastian Dröge 1c4833bc5d Update to AWS SDK 0.32
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1352>
2023-10-06 09:11:17 +03:00
Sebastian Dröge 3343fd9813 Update CHANGELOG.md for 0.11.1 2023-10-04 23:56:23 +03:00
Sebastian Dröge 41a6075fb5 deny: Simplify license handling
Deny all copyleft licenses except for the MPL-2.0 and add an exception
for gst-plugin-threadshare to allow LGPL-2.1.
2023-10-04 19:00:08 +03:00
Sebastian Dröge 5ac3162fca deny: Remove unnecessary toml_edit exception 2023-10-04 18:57:17 +03:00
Sebastian Dröge 85c46ede5b ci: Run cargo-deny on the whole workspace with all features enabled 2023-10-04 18:56:50 +03:00
Stéphane Cerveau 68c2d27e8d fmp4mux: specify the fragment duration unit
The fragment duration is expressed in nanoseconds.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1348>
2023-10-04 12:47:15 +02:00
Sebastian Dröge 4569b7eca6 Fix various new 1.73 clippy warnings
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1347>
2023-10-03 17:47:30 +03:00
Sebastian Dröge d57b83fa08 threadshare: Fix docs typos 2023-10-03 11:13:07 +03:00
Sebastian Dröge 747d9bfc6e Update plugins cache for updated raw video caps 2023-10-03 11:12:39 +03:00
François Laignel a1ad3379ca generic: threadshare: macOS fixes
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1344>
2023-10-02 15:09:26 +02:00
Sebastian Dröge 450ffbe452 Update for VideoFrame / GLVideoFrame API changes
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1345>
2023-10-02 13:25:25 +03:00
Sebastian Dröge 95581d7fbc deny: Update with some new overrides 2023-10-02 09:29:39 +03:00
François Laignel 436798b360 generic: threadshare: port to polling 3.1.0
Also use `rustix` & `std::ffi` instead of `libc`.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1336>
2023-10-01 17:45:29 +02:00
Piotr Brzeziński fe4273ca2a webrtc: Fix paths in README
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1342>
2023-09-29 17:05:29 +02:00
Sebastian Dröge 980dd74852 version-helper: Update version to 0.8.0 and MSRV to 1.66
Previous release was 0.7.5 and 1.63, but toml_edit unfortunately
requires Rust 1.66 at least.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1341>
2023-09-29 12:05:07 +00:00
Sebastian Dröge 6159f299be version-helper: Also try parsing release date from Cargo.toml
The `package.metadata.gstreamer.release_date` date string can be used to
specify the release date.

This is used if there's no git repository as a fallback before using the
mtime of the Cargo.toml. Using the mtime will fail when building a crate
packaged by cargo because cargo sets the mtimes to bogus values.

Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/440

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1341>
2023-09-29 12:05:07 +00:00
Philippe Normand 4d9263f932 audiornnoise: Attach audio level meta to output buffers
This is useful downstream for processing of audio voice payloads, for
instance feeding a speech recognition library such as Whisper.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1231>
2023-09-28 17:58:38 +02:00
Sean DuBois 90e06dc37b net: webrtc/webrtchttp: Respect HTTP redirects
Properly follow redirect URL. Before new request would be made, but with
original URL again.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1335>
2023-09-26 19:29:41 -04:00
Seungha Yang ed4181617a hlssink3: Update plugin docs
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1306>
2023-09-25 21:34:59 +09:00
Seungha Yang 22cc8c4986 hlssink3: Update README
Mention newly added hlscmafsink element and new properties

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1306>
2023-09-25 21:34:05 +09:00
Seungha Yang 1888a2eb82 hlscmafsink: Add live recording example
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1306>
2023-09-25 21:34:05 +09:00
Seungha Yang 52117e4b11 hlsbasesink: Add enable-endlist property
Write "EXT-X-ENDLIST" tag at the end of stream if enabled, and
default to "TRUE" which is the hlssink2's behavior as well

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1306>
2023-09-25 21:34:05 +09:00
Seungha Yang 7835d78b3d hlssink3: Add hlscmafsink element
Adding cmafmux based hls sink element

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1306>
2023-09-25 21:34:00 +09:00
Seungha Yang 5b563006f9 hlssink3: Add baseclass implementation
Adding HlsBaseSink class to make code reusable

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1306>
2023-09-25 21:32:16 +09:00
Seungha Yang 0fe69cea9f hlssink3: Various cleanup
* Simplify state/playlist management
* Fix a bug that segment is not deleted if location contains directory
and playlist-root is unset
* Split playlist update routine into two steps, adding segment
to playlist and playlist write

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1306>
2023-09-25 21:32:16 +09:00
Seungha Yang d8546dd140 hlssink3: Don't remove uri from playlist if playlist-length is zero
Behave as documented in property description

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1306>
2023-09-25 21:32:16 +09:00
Seungha Yang 8e4863e9cd hlssink3: Don't remove old files if max-files is zero
Follow hlssink2 element's behavior

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1306>
2023-09-25 21:32:16 +09:00
Seungha Yang a8d67cc607 hlssink3: Remove unused deps
gstreamer-base dep is unused. And use gst::glib

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1306>
2023-09-25 21:32:16 +09:00
Seungha Yang c4d371d163 hlssink3: Use Path API for getting file name
Current implementation does not support Windows path separator.
Use Path API instead.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1306>
2023-09-25 21:32:16 +09:00
Seungha Yang 7f16ac3915 hlssink3: Use sprintf for segment name formatting
The zero-padded naming requirement is unnecessary. Use simple
sprintf instead

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1306>
2023-09-25 21:32:16 +09:00
Sebastian Dröge 559313402e deny: Remove obsolete entries
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1334>
2023-09-25 13:37:16 +03:00
Sebastian Dröge 9595c6a1e5 Update to AWS SDK 0.31
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1334>
2023-09-25 13:36:12 +03:00
Arun Raghavan 8bbfb10cba hlssink3: Minor PDT-related naming fixups
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1332>
2023-09-20 16:52:55 -04:00
rajneeshksoni a7fe24a294 hlssink3: Add property track-pipeline-clock-for-pdt.
This is required to take care of clock skew between
system time and pipeline time.
`track-pipeline-clock-for-pdt: true` mean utd time is
sampled for first segment and for subsequent segments
keep adding the time based on pipeline clock. difference
of segment duration and PDT time will match.
track-pipeline-clock-for-pdt: false` mean utd time is
sampled for each segment. system time may jump forward
or backward based on adjustments. If application needs
to synchronization of external events `false` is
recommended.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1145>
2023-09-20 13:54:48 +03:00
rajneeshksoni 4be24fdcaf hlssink3: Allow adding EXT-X-PROGRAM-DATE-TIME tag.
- connect to `format-location-full` it provide the first
sample of the fragment. preserve the running-time of the
first sample in fragment.
- on fragment-close message, find the mapping of running-time
to UTC time.
- on each subsequent fragment, calculate the offset of the
running-time with first fragment and add offset to base
utc time

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1145>
2023-09-20 13:54:48 +03:00
Sebastian Dröge 95a7a3c0ec gtk4: Only support RGBA/RGB in the GL code path
For all other component orderings a shader is necessary to re-order the
components for what GTK expects.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1312>
2023-09-20 13:22:41 +03:00
Ivan Molodetskikh c237cf2c34 gtk4: Premultiply alpha in GL textures
GTK expects GL textures to have premultiplied alpha. The ones we get
from GStreamer don't, leading to incorrect rendering of semitransparent
frames.

GTK 4.12 gained an API to set a different GL texture format, but it
won't help for older GTK versions. Plus, at the time of writing, it
causes a very slow download/upload path in GTK.

So, use a GTK GL shader node to premultiply the alpha without leaving
the GPU.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1312>
2023-09-20 13:04:59 +03:00
Sebastian Dröge b12278e334 onvifmetadataparse: Skip metadata frames with unrepresentable UTC time
Previously we would panic, which causes the element to post an error
message. Instead, simply skip metadata frames if their UTC time since
the UNIX epoch can't be represented as nanoseconds in u64.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1326>
2023-09-16 10:59:27 +03:00
Seungha Yang 225482f7ed webrtcsink: Propagate GstContext messages
Implement CustomBusStream so that NEED_CONTEXT and HAVE_CONTEXT
messages from session/discovery can be forwarded to parent
pipeline and also GstContext can be shared.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1322>
2023-09-15 00:26:08 +09:00
Seungha Yang 1de7754616 webrtcsink: Add support for d3d11 memory and qsvh264enc
Adding d3d11 memory and qsvh264enc support

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1322>
2023-09-15 00:26:04 +09:00
Robert Ayrapetyan 18967dadbf gstwebrtc-api: drop guacamole
fixes: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/417

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1317>
2023-09-11 19:21:41 +00:00
François Laignel 029fa9b8dc net/ndi: improve interoperability robustness
`quick-xml::reader::Reader::trim_text(true)` doesn't remove white spaces and
tabs from XML text. Besides, for interoperability robustness we also need to
remove carriage returns and line feeds.

Also improve the default capacities for the `SmallVec`s.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1321>
2023-09-11 06:22:41 +00:00
Mathieu Duponchelle 2381558169 webrtcsink: fix codec selection discoveries
Since ab1ec126983f949804684e11e0e58c7cf3b22bc4:

webrtcsink: Add support for pre encoded streams

Discovery pipelines for remote offers were no longer fed any buffers.

While some encoders could already produce caps with no input buffers,
others, such as x264enc, simply hung forever. This resulted in no answer
getting produced if for instance video-caps were constrained to H264.

Fix this by tracking discovery pipelines at the State rather than the
InputStream level, removing the useless distinction of Initial vs.
CodecSelection discoveries, and always feeding all the current
discovery pipelines with incoming buffers.

For reference, the issue here was that codec selection discoveries were
assigned to local clones of InputStreams, not tracked anywhere, and thus
not iterated for discoveries when queuing incoming buffers from the
chain function, as it only looked at the original instance of
InputStream's in state.streams.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1319>
2023-09-08 12:58:08 +00:00
François Laignel 9604dea90a net/ndi: add closed caption support
Closed caption support in NDI is described as a proposal in [1] & [2].

The proposal consists in encapsulating c608 or c708 closed caption in ADF
packets and pushing them in an XML tag as part of NDI Metadata.

This commit implements this proposal.

[1]: http://www.sienna-tv.com/ndi/ndiclosedcaptions.html
[2]: http://www.sienna-tv.com/ndi/ndiclosedcaptions608.html

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1320>
2023-09-07 14:28:24 +02:00
Robert Ayrapetyan e83238b681 webrtcsink: fix TWCC extension adding
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1310>
2023-09-04 18:27:51 +00:00
Sebastian Dröge ba9fa989ff fmp4mux: Update to dash-mpd 0.14
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1318>
2023-09-04 17:28:30 +03:00
Jakub Adam 67b9622bf5 tutorial/2: update the text to match the latest source code
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1315>
2023-08-30 08:05:41 +00:00
Jakub Adam f47c9ce9c6 tutorial/1: fix TOC
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1315>
2023-08-30 08:05:41 +00:00
Sebastian Dröge 146a96686b Update docs for new order of raw video formats
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1308>
2023-08-29 19:45:04 +03:00
Sebastian Dröge b0b63e58f8 ndi: Comment out empty Opus handling and add FIXME comment
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1308>
2023-08-29 12:21:38 +00:00
Sebastian Dröge 8d433761d1 Fix indentation of let-else blocks
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1308>
2023-08-29 12:21:38 +00:00
Taruntej Kanakamalla de6d2e7f40 net/webrtc: rename whipwebrtcsink as whipclientsink
add a deprecation warning in whipsink to indicate it
should be used only for RTP content
add documentation in whipsink code regarding usage and
deprecation

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1282>
2023-08-26 10:53:30 +05:30
Sebastian Dröge 905da44958 Update to AWS SDK 0.30
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1313>
2023-08-25 09:46:52 +03:00
robert c1ac9396ee meson: Fix handling of optional deps
We were requiring the presence of all optional dependencies, such as
gstreamer-check-1.0 and gstreamer-gl-1.0, on the system, regardless of
whether the user actually requires these functionalities.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1305>
2023-08-22 13:48:04 +00:00
L. E. Segovia 7f6421d977 meson: Tell cargo to prefer static libraries
This fixes most, but not all, of the build errors in Windows when using
static libraries.

The ones remaining are:

- redirection of gstreamer-1.0 towards gstreamer-full-1.0
- Cairo not exporting the C++ stdlib requirement when built statically

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1307>
2023-08-21 21:41:07 -03:00
Jakub Adam a06793e25a tutorial/1: update the text to match the latest source code
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1304>
2023-08-21 07:32:49 +00:00
L. E. Segovia 7cf48db2fb meson: Disable plugins and related outputs if features are disabled
Previously, there was no check performed on features of plugins if these
specify GStreamer plugins. This commit adds that, and ensures that the
plugins and pkg-config targets are skipped if no outputs are to be
generated (this is already done for examples).

Closes #369

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1303>
2023-08-18 20:04:32 -03:00
L. E. Segovia 4ff681e0bb meson: Disable plugins and related outputs if features are disabled
Previously, there was no check performed on features of plugins if these
specify GStreamer plugins. This commit adds that, and ensures that the
plugins and pkg-config targets are skipped if no outputs are to be
generated (this is already done for examples).

Closes #369

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1303>
2023-08-18 08:06:07 +00:00
L. E. Segovia 7dea39736b meson: Allow usage of externally overridden pkg-config
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1302>
2023-08-17 22:13:27 -03:00
Sebastian Dröge 1e0621797d threadshare: Update to flume 0.11
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1301>
2023-08-17 09:18:56 +03:00
Guillaume Desmottes f92dc28696 fallbackswitch: protect src pad stream lock using Cond
Should prevent stream and State deadlocks, see https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/202

Fix #202
Hopefully fix #192 as well.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1300>
2023-08-14 14:18:41 +02:00
Guillaume Desmottes d3da30be6d fallbackswitch: prevent deadlocks in chain function
Calling schedule_timeout() may result in handle_timeout() being called right away,
which will need pad state locks which was still hold in chain().

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1300>
2023-08-14 13:16:37 +02:00
Guillaume Desmottes 100333c021 fallbackswitch: ensure strict ordering when taking mutexes
Should prevent deadlocks.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1300>
2023-08-14 13:16:37 +02:00
Mathieu Duponchelle e905299eba generic: expose inter plugin
This new plugin exposes two elements, intersink and intersrc. These act
as wormholes for data in the same process and can be used to forward
data from one pipeline to another.

The implementation makes use of gstreamer-utils' StreamProducer, and
supports dynamically adding and removing consumers, before and after
producers, and changing producer names while PLAYING, both on the sink
and the src.

This initial implementation comes with a small demo, and a few tests.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1257>
2023-08-14 08:13:12 +00:00
Sebastian Dröge 6523a07a9f meson: Check for correct minimum cargo-c version
Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/404
2023-08-14 11:07:57 +03:00
Andoni Morales Alastruey 3c1f05cdc3 webrtcsrc: document how to use the element for remote control
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1281>
2023-08-10 17:43:51 +00:00
Andoni Morales Alastruey 3000b08ec7 webrtcsrc: add support for navigation events
This provides support GstNavigation events handling in webrtcsrc so that
a GStreamer client can be used to control remotely a GStreamer server,
similar to how the web client is capable of controlling a wpesrc.
This is part of a larger set of patches that require more work on the
sinks and sources.
server: d3d11screencapturesrc ! webrtcsink enable-data-channel-navigation=true
client: webrtcsrc enable-data-channel-navigation=true ! d3d11videosink

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1281>
2023-08-10 17:43:51 +00:00
Andoni Morales Alastruey dd005a1e4c threadshare: fix warning for unused variable
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1281>
2023-08-10 17:43:51 +00:00
Loïc Le Page e5e3dc6e19 net/webrtc/signaller: add property to get the connection client ID
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1296>
2023-08-10 17:30:21 +02:00
Loïc Le Page 7af2ff0843 net/webrtc/signaller: advertise running producers in Listener mode
When starting a webrtcsrc-signaller client in Listener mode, only the producers
started after the client connection were advertised. All currently
running producers were ignored unlike the gstwebrtc-api behavior. This
commit now lists all running producers when the client Listener connects
and advertises them through the "producer-added" signal.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1296>
2023-08-10 17:30:21 +02:00
Sebastian Dröge d688aeb184 Update versions to 0.12.0-alpha.1 2023-08-10 17:21:11 +03:00
Sebastian Dröge 473bc94278 Add CHANGELOG.md for 0.11.0 2023-08-10 17:18:18 +03:00
Sebastian Dröge 23e1bfa720 deny: Temporarily allow a duplicated tungstenite dependency
See https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1293
2023-08-09 14:38:52 +03:00
Sebastian Dröge 3b41f206bc Don't generate .def files for plugins
Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/389

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1299>
2023-08-09 13:54:34 +03:00
Sebastian Dröge b3826c108d webrtc: Update to async-tungstenite 0.23
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1299>
2023-08-09 13:18:44 +03:00
Sebastian Dröge 508026d09a Switch to resolver = "2" for the workspace
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1298>
2023-08-09 08:15:08 +00:00
Sebastian Dröge 5ee46a214c webrtc: Use #[repr(C)] to get a C-compatible layout for the Signaller struct
This is required by GObject for class/interface and instance structs and
the reason why implementing the `glib::ObjectInterface` trait is unsafe.

Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/397

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1297>
2023-08-09 10:32:44 +03:00
Sebastian Dröge 045b524bc6 deny: Remove dependencies that are not duplicated anymore
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1295>
2023-08-07 20:04:52 +03:00
Sebastian Dröge cac791a6ca aws/webrtc: Update to AWS SDK 0.56/0.29
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1295>
2023-08-07 20:03:51 +03:00
Sebastian Dröge 2591feb72e Update a couple of dependencies
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1294>
2023-08-07 11:42:32 +03:00
Sanchayan Maity 5b60ecbb18 net: webrtc/webrtchttp: Fix canceller usage
Commit 08b6251a added the check to ensure only one canceller at a time for net/webrtc.

In `whipsink` and since `whipwebrtcsink` picked up the same implementation, there exists a
bug around the use of canceller. `whipsink` calls `wait_async` while passing the canceller
as an argument. The path `send_offer -> do_post -> parse_endpoint_response` results in the
canceller being replaced in each subsequent call to `wait_async`. Since `wait_async` call
does not ensure one canceller, with the async call the use of canceller/abort was subtly
broken. Similarly, for `whepsrc`.

We really don't need to use `wait_async` inside `do_post` for any `await` calls. If the
root future viz. `do_post` with `wait_async` is aborted, the child futures will be taken
care of.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1290>
2023-08-04 10:01:11 +05:30
Nirbheek Chauhan d6616fed3f meson: Don't require Python 3.8 for cargo_wrapper.py
Documentation on gstreamer monorepo is disabled because the image we
use to build the docs only has Python 3.7

https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/2873

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1291>
2023-08-02 13:37:49 +00:00
François Laignel 10902c0485 utils: fix further to glib change ControlFlow -> Propagation
See: https://github.com/gtk-rs/gtk-rs-core/pull/1144
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1292>
2023-08-02 13:19:22 +02:00
Mathieu Duponchelle 9680805bdb webrtcsink: don't forget to setup encoders for discoveries
The "encoder-setup" signal must also be emitted for the encoders
used in discovery pipelines in order for the default settings to
be applied.

This otherwise meant that for instance the x264 encoder would
use a 60 frames latency, greatly delaying startup.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1289>
2023-08-01 00:28:52 +02:00
Mathieu Duponchelle dbeb65da06 webrtc/utils: fix typos
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1289>
2023-08-01 00:28:32 +02:00
Seungha Yang 516c623df5 transcriberbin: Configure audioresample in front of transcriber
Allows any samplerate and make it negotiable. Fixing a scenario
where transcriberbin is configured with passthrough enabled,
(and negotiated samplerate is not supported by transcriber)
and then setting passthrough=false later during playback.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1287>
2023-07-24 22:51:07 +09:00
Sebastian Dröge d4b3827efa webrtcsink: NVIDIA V4L2 encoders always require NVMM memory
And if the input is not like that then a corresponding converter must be
inserted.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1283>
2023-07-24 10:14:59 +00:00
Sebastian Dröge 0e26077722 Update CHANGELOG.md for 0.10.11 2023-07-20 14:45:50 +03:00
Sebastian Dröge d999c1d3ba ci: Directly use the CI images from gstreamer-rs
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1280>
2023-07-20 02:59:51 +03:00
Sebastian Dröge 31b1cb8ca6 Update minimum supported Rust version to 1.70
gtk-rs will update soonish too.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1280>
2023-07-19 09:19:34 +03:00
Sebastian Dröge 5532ea5d2a fmp4mux: Update to dash-mpd 0.12
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1280>
2023-07-19 09:18:50 +03:00
Sebastian Dröge 3661b4f95b fmp4mux: Fix draining in chunk mode if keyframes are too late
We would create another chunk that ends after the fragment end, and
would from then on consider the stream always filled for the chunk
because it starts after the current fragment end (i.e. nothing would go
into this fragment).

This is obviously wrong because the actual fragment end moved further
ahead because of the additional chunk.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1277>
2023-07-18 07:57:20 +00:00
Sebastian Dröge 2dc4ce5da5 ci: Remove omx=disabled from the documentation job 2023-07-17 09:45:21 +03:00
Mathieu Duponchelle 9707bb89e6 webrtcsink: fix pipeline when input caps contain max-framerate
GstVideoInfo uses max-framerate to compute its fps, but this leads
to issues in videorate when framerate is actually 0/1.

Fix this by stripping away max-framerate from input caps

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1276>
2023-07-13 22:18:08 +02:00
Sebastian Dröge 0331522128 webrtcsink: Configure only 4 threads for x264enc
More threads can cause more slices to be created, and Chrome simply falls
apart if there are more than a few slices and fails decoding.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1275>
2023-07-13 16:59:43 +03:00
Sebastian Dröge ca51cf2509 webrtcsink: Translate force-keyunit events to force-IDR action signal for NVIDIA encoders
NVIDIA's v4l2 encoder elements don't handle the force-keyunit events but
instead provide a custom action signal based API for requesting a
keyframe.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1274>
2023-07-12 10:09:32 +00:00
Nirbheek Chauhan 89002b4562 meson: Don't override RUSTFLAGS in the env
Meson does not add RUSTFLAGS to rustc.cmd_array(), so the effect of
this code is to override that value in the env.

This is hacky, since the env has to match during setup and compile
now, and rust_args added in the cross / native file will be ignored.
But at least it fixes this regression:

Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/372

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1237>
2023-07-12 13:44:17 +05:30
Sebastian Dröge bbd3d9ffe0 Remove unnecessary mut everywhere
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1273>
2023-07-11 10:09:35 +03:00
Sebastian Dröge c2201480cf threadshare: Remove unnecessary call to default()
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1273>
2023-07-11 10:09:22 +03:00
Sebastian Dröge ee4aca3010 webrtcsink: Set config-interval=-1 and aggregate-mode=zero-latency on rtph26[45]pay
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1272>
2023-07-10 19:48:37 +03:00
Sebastian Dröge 957a28f239 webrtcsink: Set VP8/VP9 payloader based on payloader element factory name
Instead of checking the encoder's name. There are more VP8/VP9 encoders
than the ones from the vpx plugin.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1272>
2023-07-10 19:45:17 +03:00
Sebastian Dröge 1bb06d775c fmp4: Update to dash-mpd 0.11
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1271>
2023-07-10 08:29:29 +03:00
Sebastian Dröge b6bc7fb6d5 Revert "cargo-deny: Remove bitflags from the list"
This reverts commit 64151790d0.
Some dependencies still use bitflags 1
2023-07-07 09:08:50 +03:00
Mathieu Duponchelle 1dd13c4812 webrtcsink: fix session_id / peer_id confusion
In a few places, for instance parameter names, peer_id was still used
when session_id was actually getting passed.

Go through all instances of peer_id in webrtcsink/imp.rs and address
those mix-ups.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1269>
2023-07-07 05:33:30 +00:00
Bilal Elmoussaoui 0fa2c861d6 Adapt to removal of glib::Inhibit
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1270>
2023-07-06 22:02:31 +02:00
Jan Schmidt 2abc72b606 fallbackswitch: Change the threshold for trailing buffers
Only discard buffers on inactive pads if they are later
than the current output running time, rather than the
later timeout running time. That can mean switching
to a higher priority pad can happen quicker.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1198>
2023-07-07 01:45:52 +10:00
Jan Schmidt 61e282af1a fallbackswitch: Fix pad health calculation and notifies
Change the pad health calculation to consider a pad 'healthy'
if it has received data within the last 'timeout' window. Previously,
inactive pads were constantly flip-flopping between healthy and not
healthy depending on whether they were slightly ahead of or behind
the active pad running_time.

When the health status of a pad changes, make sure to always notify
the property, so that applications that are manually controlling
the active pad can make their switching decisions.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1198>
2023-07-07 01:45:52 +10:00
Bilal Elmoussaoui dd2d7d9215 Use re-exported once_cell
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1268>
2023-07-06 17:50:49 +03:00
Bilal Elmoussaoui 2cc98bf410 Adapt to glib::Continue rename
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1268>
2023-07-06 17:50:49 +03:00
Bilal Elmoussaoui 64151790d0 cargo-deny: Remove bitflags from the list
We now use bitflags 2.x

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1268>
2023-07-06 15:26:13 +02:00
Sebastian Dröge 58adebb325 Fix a couple of typos 2023-07-06 13:50:17 +03:00
Sebastian Dröge 983f990fe9 Update docs after GStreamer update on the CI 2023-07-06 13:48:59 +03:00
Sebastian Dröge 4918bf0ab2 deny: Update 2023-07-06 08:55:14 +03:00
Olivier Crête 08b6251a7a webrtc-utils: Ensure there is only one cancellable call at a time
Since we only have one canceller at a time, panic if one try to
use it twice in parallel.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1262>
2023-07-05 21:43:17 +00:00
Olivier Crête 817b60a758 webrtc: Value.get() is already type checks in the property calls
GObject will have ensured we get a GValue of the right type.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1262>
2023-07-05 21:43:17 +00:00
Olivier Crête 793ee66afa webrtcsink: Add LiveKit WebRTC sink and signaller
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1262>
2023-07-05 21:43:17 +00:00
Sebastian Dröge de6abf1439 Update CHANGELOG.md for 0.10.10 2023-07-05 16:03:42 +03:00
Vivia Nikolaidou 9d7af671c5 togglerecord: Clip segment before calculating timestamp/duration
Clipping happens in buffer time space and data.clip can modify the
buffer timestamp and duration. Move it before we calculate them in order
to make it actually have some effect.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1265>
2023-07-04 09:07:36 +00:00
yatinmaan 1ed9992775 gtk4: Add python example
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1259>
2023-07-02 00:31:32 +00:00
Vivia Nikolaidou 8417efc630 togglerecord: Error out if main stream buffer has no valid running time
We cannot continue with this buffer, because we cannot calculate the
time when the recording stopped or started. We also cannot safely drop
it, because that might break the stream, especially if it's encoded.
Therefore, we return an element error.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1264>
2023-06-30 09:20:42 +00:00
Sebastian Dröge cc26f06289 deny: Update 2023-06-30 11:12:52 +03:00
Seungha Yang 1f0ce101eb awstranscriber: Tone down log message
It's not an ERROR case at all

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1263>
2023-06-28 23:57:54 +09:00
Sebastian Dröge 4555b98aff deny: Update 2023-06-27 10:58:57 +03:00
Sebastian Dröge c350f3c2af webrtcink: Use correct property types for nvvideoconvert
These are enums and not plain integers.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1256>
2023-06-26 14:48:58 +00:00
Vivia Nikolaidou 8366716456 togglerecord: Change test_two_stream_close_open_nonlivein_liveout timeout to 60ms
20ms was not enough for the CI.

Closes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/379

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1258>
2023-06-26 12:33:31 +00:00
Sebastian Dröge effe1bacdf deny: Update
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1260>
2023-06-26 14:24:08 +03:00
Sebastian Dröge bbb88da9e0 videofx: Minimize dependencies of the image crate
Only the basic infrastructure is needed and none of the
decoders/encoders for various image formats.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1260>
2023-06-26 14:21:44 +03:00
Sebastian Dröge f481bb74c4 fmp4: Update to dash-mpd 0.10 for the example
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1260>
2023-06-26 14:19:43 +03:00
Sebastian Dröge 042a297d1a gtk4: Update to windows-sys 0.48
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1260>
2023-06-26 14:19:22 +03:00
Jayson Reis e58abf0705 gtk4: Make winegl code compilable
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1255>
2023-06-23 11:16:40 +03:00
Jayson Reis d3d78846dc gtk4: Fix code to run on current main branch
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1255>
2023-06-22 14:45:28 +02:00
Sebastian Dröge dcb80ac105 gtk4: Add support for GL on Windows
This implements all the workarounds for Windows-specific complications
that the GTK GStreamer mediafile implementation also does.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1255>
2023-06-22 07:43:57 +02:00
Vivia Nikolaidou 2be14b95b3 togglerecord: Fix nonlive inputs when element is started not recording
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1252>
2023-06-21 16:27:00 +03:00
Sebastian Dröge 1119ed6620 livesync: Wait for the end timestamp of the previous buffer before looking at queue
Previously livesync was waiting for the start timestamp of the current
buffer after looking at the queue and right before pushing it
downstream. This meant that it generally looked too early at the queue
and especially that upstream had to provide the next buffer already at
the start timestamp of the previous one.

Instead, now wait before looking at the queue and wait for the end
timestamp of the previous buffer. Once the previous buffer has expired,
a new buffer really needs to be available or otherwise a filler buffer
has to be pushed downstream.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1250>
2023-06-20 13:01:39 +00:00
Jan Alexander Steffens (heftig) 52ded6e8cc livesync: Improve EOS handling
I've looked at the GstQueue code again and tried making livesync behave
better with EOS. This isn't very well tested, though. My goal was to
make this look saner but I think this should be reviewed by someone who
knows the queue code.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1251>
2023-06-20 13:18:17 +02:00
Sebastian Dröge 99fc5f16d2 Update CHANGELOG.md for 0.10.9 2023-06-19 20:48:22 +03:00
François Laignel f85106b86a mp4, fmp4: fix byte order for opus extension
The "Encapsulation of Opus in ISO Base Media File Format" [1] specifications,
§ 4.3.2 Opus Specific Box, indicates that data must be stored as big-endian.

In `write_dops`, `to_le_bytes` variants were used.

Related to [2].

[1] https://opus-codec.org/docs/opus_in_isobmff.html#4.3.2
[2] https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4875

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1247>
2023-06-19 16:32:07 +02:00
Mathieu Duponchelle 84a33ca7b9 webrtcsink: bring in signalling code from whipsink as a signaller
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1168>
2023-06-16 00:32:56 +02:00
Mathieu Duponchelle f00a169081 webrtcsrc: add twcc extension to codec-preferences when present
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1245>
2023-06-15 20:41:53 +00:00
Seungha Yang 02c77d2e44 mccparse: Map timecode to PTS directly without offset
Assumes that caption stream's timeline starts from zero,
and maps timecode time_since_daily_jam() to PTS directly without
subtracting the first seen timecode.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1246>
2023-06-16 01:06:26 +09:00
Stéphane Cerveau 26fd68a37c gitlab: add issue template
Use the same bug template as in gstreamer repository

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1244>
2023-06-15 11:01:15 +00:00
Sebastian Dröge 21df8f8c08 deny: Update
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1243>
2023-06-15 10:18:47 +03:00
Sebastian Dröge 63df653ad2 fmp4mux: Update to quick-xml 0.29
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1243>
2023-06-15 10:15:52 +03:00
Mathieu Duponchelle 1200ae0ee6 webrtcsink: improve debug
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1239>
2023-06-14 22:27:15 +02:00
Mathieu Duponchelle 64056c5527 net/webrtc: improve documentation layout
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1239>
2023-06-14 22:27:15 +02:00
Vivia Nikolaidou 063871a1eb togglerecord: Add support for non-live inputs
Live input + is-live=false:
    While not recording, drop input
    When recording is started, offset to collapse the gap

Live input + is-live=true:
    While not recording, drop input
    Don't modify the offset

Non-live input + is-live=false:
    While not recording, block input
    Don't modify the offset

Non-live input + is-live=true:
    While not recording, block input
    When recording is started, offset to current running time

Co-authored-by: Jan Alexander Steffens (heftig) <jan.steffens@ltnglobal.com>
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1206>
2023-06-14 15:58:04 +03:00
Guillaume Desmottes 4683291c1f fallbackswitch: add 'stop-on-eos' property
Fix the following use case:
- main input of fallbackswitch is finite (a media file)
- fallback input is infinite (videotestsrc)
- main input is done and send eos, which is propagated downstream
- fallbackswitch switches to fallback, sending STREAM_START which reset
  EOS downstream (aggregator does that)
- fallback input keeps pushing buffers forever.

Solve it by adding a 'stop-on-eos' property so fallbackswitch stops
pushing property once the main input is eos.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1242>
2023-06-13 14:49:06 +02:00
Guillaume Desmottes 6ad0db2cdb fallbackswitch: remove unused SinkState::eos
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1242>
2023-06-13 12:43:51 +02:00
Guillaume Desmottes 692d1bfb9e fallbackswitch: log when handling events
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1242>
2023-06-13 12:43:51 +02:00
Sebastian Dröge cdd084bbe8 deny: Update
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1240>
2023-06-09 09:42:10 +03:00
Sebastian Dröge 8a7a1f519c webrtc: Update to fastrand 2
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1240>
2023-06-09 09:36:51 +03:00
Mathieu Duponchelle 81ae675f2d webrtcsink: don't try to use cudaconvert if not present
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1238>
2023-06-08 15:32:49 +02:00
Mathieu Duponchelle 7f78a8428e webrtcsink: dump discovery pipelines on state changes
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1238>
2023-06-08 15:32:49 +02:00
Mathieu Duponchelle 7447d95f1b webrtc/signalling: fix race condition in message ordering
Spawning one task per message to send out instead of sending them out
sequentially from the one task used to poll the handler sometimes
resulted in peers receiving ICE candidates before SDP offers, triggering
hard to understand errors in the browser.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1236>
2023-06-08 13:24:45 +02:00
Mathieu Duponchelle de0f7a08fe gstwebrtc-api: fix firefox errors about more than two stun servers
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1236>
2023-06-08 13:24:45 +02:00
Mathieu Duponchelle cd4b90fef4 webrtcsink/utils: remove unused decoders field in DecodingInfo
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1236>
2023-06-08 01:54:13 +02:00
Mathieu Duponchelle 271b583876 webrtcsink: avoid panic on unprepare from an async tokio context
.. and log an error with advice on how to dispose of elements properly
from a tokio runtime.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1218>
2023-06-07 19:57:19 +00:00
Sebastian Dröge c65b3429ad Use MPL as license specifier for plugins only requiring GStreamer < 1.20
And use MPL-2.0 for all that require GStreamer 1.20 or newer. The new
string is only allowed in 1.20 or newer and using it in older versions
causes failure to load the plugin.

All affected plugins are of course still MPL-2.0 licensed.

Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/374

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1235>
2023-06-07 19:13:55 +03:00
Sebastian Dröge b7e6e5cbc9 Update CHANGELOG.md for 0.10.8 2023-06-07 01:17:34 +03:00
Mathieu Duponchelle fda5aed89f webrtcsink: encoded streams: address last review comments
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1194>
2023-06-06 16:05:28 +02:00
Thibault Saunier ab1ec12698 webrtcsink: Add support for pre encoded streams
This is a first step where we try to replicate encoding conditions from
the input stream into the discovery pipeline. A second patch will
implement using input buffers in the discovery pipelines.

This moves discovery to using input buffers directly. Instead of trying
to replicate buffers that `webrtcsink` is getting as input with testsrc,
directly run discovery based on the real buffers. This way we are sure
we work with the exact right stream type and we don't need encoders to
support encoding streams inputs.

We use the same logic for both encoded and raw input to avoid having
several code paths and makes it all more correct in any case.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1194>
2023-06-06 15:32:40 +02:00
Thibault Saunier 059cdecf7d webrtc: Unify the Codec structure between sink and source
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1194>
2023-06-06 15:31:45 +02:00
Thibault Saunier cf32d9d668 webrtc: Move make_element to the utils
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1194>
2023-06-06 15:31:45 +02:00
Thibault Saunier ce42723ad2 webrtc: Minor documentation enhancement
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1194>
2023-06-06 15:31:45 +02:00
Guillaume Desmottes f4604e1c58 uriplaylistbin: use thiserror
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1232>
2023-06-06 12:46:17 +02:00
Guillaume Desmottes 432de060ea uriplaylistbin: example: display iterations
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1232>
2023-06-05 14:09:41 +02:00
Guillaume Desmottes 97fa20237f uriplaylistbin: prevent deadlock when notifying property changes
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1232>
2023-06-05 14:09:41 +02:00
Guillaume Desmottes 780d9d5b78 uriplaylistbin: example display when leaving because of eos
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1232>
2023-06-05 14:09:41 +02:00
Mathieu Duponchelle 6346d5608e net/aws/transcriber: track discont offset in input stream
and add it up to subsequent transcripts.

This ensures synchronization is maintained even after the input stream
experiences a discontinuity and a gap in its timestamps.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1230>
2023-06-02 08:55:11 +00:00
Sebastian Dröge 2e83107c18 fmp4mux: Don't wait for more data if a stream has no GOP starting before fragment end
Simply don't output anything for this stream and only include it in the
future.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1229>
2023-06-01 19:46:06 +03:00
Sebastian Dröge a5fcd66c95 fmp4mux: Consider a stream filled if the earliest GOP starts after the current chunk
There's not going to be any buffer to output for this stream in the
current chunk.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1229>
2023-06-01 19:25:44 +03:00
Mathieu Duponchelle 80582923bb aws_kvs_signaller: don't force us-east-1 region
Instead use default region provider, with a fallback to us-east-1

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1228>
2023-05-30 16:04:27 +00:00
Sebastian Dröge dfb261ac9a Fix a couple of trivial clippy warnings
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1226>
2023-05-30 10:20:00 +03:00
Edward Hervey 31b06e52ea rtpgccbwe: Improve packet handling
Both the delay-based *and* loss-based estimates should be computed instead of
just one. This ensures faster adaptation.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1179>
2023-05-29 08:20:36 +00:00
François Laignel 4cc2498c24 webrtcsink: use spawn_blocking instead of call_async
In `webrtcsink`, we terminate a session by setting the session's pipeline to
`Null` like this:

```rust
    pipeline.call_async(|pipeline| {
        [...]
        pipeline.set_state(gst::State::Null);
        [...]
        // the following cvar is awaited in unprepare()
        cvar.notify_one();
    });
```

However, `pipeline.call_async` keeps a ref on the pipeline until it's done,
which means the `cvar` is notified before `pipeline` is actually 'disposed',
which happens in a different thread than `unprepare`'s. [`gst_rtp_bin_dispose`]
releases some resources when the pipeline is unrefed. In some cases, those
resources are actually released after the main thread has returned, leading
various issues.

This commit uses tokio runtime's `spawn_blocking` instead, which allows owning
and disposing of the pipeline before the `cvar` is notified.

[`gst_rtp_bin_dispose`]: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/blob/main/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpbin.c#L3108

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1225>
2023-05-26 14:23:03 +02:00
Mathieu Duponchelle a20855dfd9 webrtcsink: expose consumer-pipeline-created signal
This signal is emitted as soon as the pipeline for each consumer
is created, and can be used by applications that require a greater
level of control over webrtcsink's internals.

An example is also provided to demonstrate usage

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1220>
2023-05-25 13:15:52 +02:00
Sebastian Dröge a27be7d054 net: Update to AWS SDK 0.28
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1224>
2023-05-25 13:23:49 +03:00
François Laignel e62e9f5bd4 webrtcsink: adapt commit "abort stats collection before stopping the Signaller"
Adapt a commit [1] that was introduced as part of the forward port of the MR
'add signal "request-encoded-filter"' [2].

The deadlock said commit was fixing doesn't happen on main branch due to
changes in the element design: the Sessions are no longer aborted with the
element `State` held. However, we want to ensure the stats collection task
is terminated when the `webrtcbin` element returns from the Ready to Null
transition, meaning that the related resources are released.

[1]: gstreamer/gst-plugins-rs!1176 (0e6b9df9)
[2]: gstreamer/gst-plugins-rs!1176

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1222>
2023-05-24 21:35:39 +02:00
Sebastian Dröge e3c46b40a0 whipsink: Request pads with webrtcbin's pad templates and not our own
It's invalid to request pads with a pad template that is not part of the
element, and results in a critical warning.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1223>
2023-05-24 14:14:32 +00:00
Mathieu Duponchelle 44a395f134 webrtcsink: further refactor connection to stats signals
- Stop passing webrtcbin around without using it

- Stop using glib::closure as clippy complains when using a unit type
  default-return

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1217>
2023-05-24 13:35:26 +02:00
Mathieu Duponchelle e13124a426 webrtcsink: fix stats_sigid logic
First off, we just created the session, we know stats_sigid is None
at this point.

Second, don't first assign the result of connecting on-new-ssrc to the
field, then the result of connection twcc-stats, that simply doesn't
make sense.

Finally, actually check that stats_sigid *is* None before connecting
twcc-stats, as I understand it this must have been the original
intention / behavior.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1217>
2023-05-24 13:35:26 +02:00
Mathieu Duponchelle ccf076ed1e webrtcsink: don't panic in twcc-stats callback
If webrtcbin was disposed of at this point, simply return

Fixes: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/345
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1217>
2023-05-24 13:35:26 +02:00
François Laignel 9a59763df1 webrtcsink: wait for Sessions to end
`State::finalize_session()` asynchronously sets the Session pipeline to Null.
In some cases, sessions `webrtcbin` could terminate their transition to Null
after `webrtcsink` had reached Null.

This commit adds a set of `finalizing_sessions`. When the finalization process
starts, the session is added to the set. After `webrtcbin` has reached the Null
state, the session is removed from the set and a condvar is notified.

In `unprepare`, `webrtcsink` loops until the `finalizing_sessions` set is
empty, awaiting for the condvar to be notified when it's not.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1221>
2023-05-24 10:18:47 +02:00
François Laignel b68e2a1ed0 webrtcsink: remove unneeded mut
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1221>
2023-05-24 10:18:43 +02:00
Arun Raghavan b05c21680d Revert "fmp4: Return a running time in get_next_time()"
This reverts commit 04bb7b4db0.

As Sebastian points out, the chunk PTS is already in running time, so
this was wrong from the start.

Fixes: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/363
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1219>
2023-05-23 09:27:00 -04:00
Thibault Saunier 04e35e86d6 webrtcsrc: Do not pass raw caps in the transceiver
That was not making sense.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1214>
2023-05-18 18:23:56 +03:00
Thibault Saunier e73d7082a6 webrtcsrc: Fix caps used when creating transceiver
We used to pass all media keys and attributes to the caps which
incorrect. Instead we should be using only the keys from the map
and remove all information related to rtcp which is irrelevant
to create the transceiver.

This also simplifies the code.

New caps look like:

```
Caps(
    application/x-rtp(memory:SystemMemory) {
        media: (gchararray) "video",
        payload: (gint) 96,
        clock-rate: (gint) 90000,
        encoding-name: (gchararray) "VP8",
    },
    application/x-rtp(memory:SystemMemory) {
        media: (gchararray) "video",
        payload: (gint) 102,
        clock-rate: (gint) 90000,
        encoding-name: (gchararray) "H264",
        packetization-mode: (gchararray) "1",
        profile: (gchararray) "baseline",
    },
    application/x-rtp(memory:SystemMemory) {
        media: (gchararray) "video",
        payload: (gint) 104,
        clock-rate: (gint) 90000,
        encoding-name: (gchararray) "H264",
        packetization-mode: (gchararray) "0",
        profile: (gchararray) "baseline",
    },
    application/x-rtp(memory:SystemMemory) {
        media: (gchararray) "video",
        payload: (gint) 106,
        clock-rate: (gint) 90000,
        encoding-name: (gchararray) "H264",
        packetization-mode: (gchararray) "1",
        profile: (gchararray) "constrained-baseline",
    },
    application/x-rtp(memory:SystemMemory) {
        media: (gchararray) "video",
        payload: (gint) 108,
        clock-rate: (gint) 90000,
        encoding-name: (gchararray) "H264",
        packetization-mode: (gchararray) "0",
        profile: (gchararray) "constrained-baseline",
    },
    application/x-rtp(memory:SystemMemory) {
        media: (gchararray) "video",
        payload: (gint) 127,
        clock-rate: (gint) 90000,
        encoding-name: (gchararray) "H264",
        packetization-mode: (gchararray) "1",
        profile: (gchararray) "main",
    },
    application/x-rtp(memory:SystemMemory) {
        media: (gchararray) "video",
        payload: (gint) 39,
        clock-rate: (gint) 90000,
        encoding-name: (gchararray) "H264",
        packetization-mode: (gchararray) "0",
        profile: (gchararray) "main",
    },
    application/x-rtp(memory:SystemMemory) {
        media: (gchararray) "video",
        payload: (gint) 98,
        clock-rate: (gint) 90000,
        encoding-name: (gchararray) "VP9",
        profile-id: (gchararray) "0",
    },
    application/x-rtp(memory:SystemMemory) {
        media: (gchararray) "video",
        payload: (gint) 100,
        clock-rate: (gint) 90000,
        encoding-name: (gchararray) "VP9",
        profile-id: (gchararray) "2",
    },
)
```

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1214>
2023-05-18 18:23:56 +03:00
Seungha Yang 3406e604cd fallbacksrc: Don't apply fallback-audio-caps to the main audio stream
Intended behavior is configuring audio convert/resample elements
only for the fallback stream and also fallback-audio-caps is set.
Video and image stream are doing it as intended already.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1213>
2023-05-17 23:49:09 +09:00
Guillaume Desmottes 7ebf2d7a4f fallbackswitch: document the pad priority ordering
I just wasted lots of time trying to figure out why my higher priority
pad wasn't used...

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1208>
2023-05-15 16:13:20 +02:00
Sanchayan Maity 067d47f0ec videofx: border: Do not advertise I420 for non-zero border radius
In certain cases, roundedcorners would negotiate to I420 even when user
supplied a non-zero border radius.

For example, the below pipeline leads to I420 being negotiated even
though a non-zero border radius was given. Ideally, this pipeline
should have failed at the negotiation stage.

```bash
gst-launch-1.0 -v \
   videotestsrc num-buffers=1000 pattern=white ! \
   video/x-raw,width=320,height=180 ! \
   roundedcorners border-radius-px=10 ! videobox border-alpha=0 top=-10 left=-10 right=-10 bottom=-10 fill=yellow ! \
   compositor name=comp sink_0::xpos=960   sink_0::ypos=0  sink_0::width=320 sink_0::height=180 sink_0::alpha=1.0 sink_1::xpos=960 sink_1::ypos=180  sink_1::width=320 sink_1::height=180 sink_1::alpha=1.0  \
   sink_2::xpos=960 sink_2::ypos=360  sink_2::width=320 sink_2::height=180 sink_2::alpha=1.0 sink_3::xpos=0 sink_3::ypos=0  sink_3::width=960 sink_3::height=720 sink_3::alpha=1.0 ! \
   video/x-raw,width=1280,height=720! x264enc ! mp4mux ! filesink location=test.mp4 \
   videotestsrc num-buffers=1000 pattern=red ! \
   video/x-raw,width=320,height=180 ! roundedcorners border-radius-px=10 ! comp. \
      videotestsrc num-buffers=1000 pattern=blue ! \
   video/x-raw,width=320,height=180 ! roundedcorners border-radius-px=10 ! comp. \
      videotestsrc num-buffers=1000 pattern=green ! \
   video/x-raw,width=960,height=720 ! roundedcorners border-radius-px=10 ! comp.
```

If border radius is non-zero, we should not really allow negotiation
to select I420. Fix this by returning only A420 for border-radius > 0
in `transform_caps` instead of returning both like earlier.

Another example of a simpler pipeline like below which would earlier work

```bash
gst-launch-1.0 videotestsrc pattern=red ! videoconvert ! video/x-raw,width=1923,height=1087,format=I420 ! roundedcorners border-radius-px=40 ! video/x-raw,format=I420 ! videoconvert ! gtksink
```

now fails with

```bash
WARNING: erroneous pipeline: could not link roundedcorners0 to videoconvert1, roundedcorners0 can't handle caps video/x-raw, format=(string)I420
```

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1211>
2023-05-15 12:19:09 +05:30
François Laignel 7ba0073052 use Pad builders for optional name definition
Also, apply auto-naming in the following cases

* When building from a non wildcard-named template, the name of the template is
  automatically assigned to the Pad. User can override with a specific name by
  calling `name()` on the `PadBuilder`.
* When building with a target and no name was provided via the above, the
  GhostPad is named after the target.

See https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/issues/448
Auto-naming discussion: https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/merge_requests/1255#note_1891181

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1197>
2023-05-12 12:55:31 +02:00
François Laignel 8e93d294e5 Update to argumentless {Bin,Pipeline}::new
See https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/issues/449

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1197>
2023-05-12 12:55:31 +02:00
Sebastian Dröge 32d59c31d8 fmp4: examples: Update to dash-mpd 0.9
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1210>
2023-05-12 09:45:40 +03:00
Seungha Yang 773fcd0780 transcriberbin: Add "language-code" property
Proxy the child transcriber element's property so that transcriberbin
can apply the property with required state management

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1205>
2023-05-10 19:12:01 +00:00
Antonio Kevo cf21bfabf2 fmp4: Use updated start_pts when checking stream filled
After calculating the earliest pts, the fragment_start_pts and
chunk_start_pts in State are updated. However, when checking if the
stream is filled, the previous start_pts (set to None) is used instead.
This means that chunk_filled and fragment_filled will be false the first
time aggregate() is called, assuming timeout is false, all_eos is false,
and the sinkpad is not EOS. This requires aggregate() having to be
called a second time before the first fragment is sent.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1207>
2023-05-10 16:09:25 +02:00
Sebastian Dröge 8b2b12e767 Update CHANGELOG.md for 0.10.7 2023-05-09 20:48:43 +03:00
François Laignel 680d5221db net/webrtc: src: add signal "request-encoded-filter"
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1202>
2023-05-09 12:02:15 +02:00
François Laignel 092ae1fec8 net/webrtc: sink: add signal "request-encoded-filter"
The new "request-encoded-filter" signal is emitted when the encoder and related
elements are added to the pipeline. When defined, the element returned by the
signal is inserted between the encoder and the payloader.

The transformation can be reverted using the [insertable streams API] on the
receiver side.

[insertable streams API]: https://developer.mozilla.org/en-US/docs/Web/API/Insertable_Streams_for_MediaStreamTrack_API

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1202>
2023-05-09 11:17:32 +02:00
François Laignel dc5ddd3022 net/webrtc: sink: abort stats collection before stopping the Signaller
In some rare cases, the webrtc-test entered a deadlock while executing
`WebRTCSink::unprepare`. Attaching gdb to a blocked instance showed:

* `gstrswebrtc::signaller:👿:Signaller::stop()` parked, waiting for a
  `Condvar` in `Signaller::stop()`. This was most likely awaiting for the
  receive task to complete while it was locked in `element.end_session()`.
  This code path is triggered from `unprepare` with the `State` `Mutex` locked.
* `webrtcsink:👿:WebRtcSink::process_stats` waiting for a contended `Mutex`,
  which is also the `State` `Mutex`. This prevented completion of the signal
  `gst_webrtc_bin_get_stats`.

This commit aborts the task in charge of periodically collecting stats and
ensures any remaining iteration completes before requesting the Signaller to
stop.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1202>
2023-05-09 10:26:11 +02:00
François Laignel eca269cbf2 net/webrtc: src: don't set stun-server on webrtcbin when our property is None
... otherwise an error occurs about the stun-server address being an empty
string which doesn't comply with the expected address format.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1202>
2023-05-09 10:26:07 +02:00
Sebastian Dröge de1c8ece43 deny: Update 2023-05-08 18:44:12 +03:00
Sebastian Dröge cb5b527d74 Update to AWS SDK 0.27 and async-tungstenite 0.22
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1199>
2023-05-02 15:30:00 +03:00
Guillaume Desmottes 76c8279101 fmp4: define minBufferTime in example mpd
Required to validate the manifest with https://beta.conformance.dashif.org/

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1196>
2023-04-27 14:16:40 +02:00
Sebastian Dröge 05ee55d617 fmp4: Update example to dash-mpd 0.8
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1193>
2023-04-25 08:54:48 +03:00
Nick Steel 3d01c9b363 spotify: check cached creds username before use
If a username was specified, only use cached credentials that match
that username.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1192>
2023-04-24 15:29:22 +01:00
Jan Beich 8d6751c88d gtk4: unbreak wayland, x11egl, x11glx features on non-Linux
As the features are non-default leave the responsibility to filter by
platform to consumers.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1191>
2023-04-22 12:58:29 +00:00
Lily Foster 8e4fd2c167 meson: support rust cross-compiling with cargo wrapper
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1188>
2023-04-21 16:55:37 +00:00
Sebastian Dröge 41ba4b2bc3 deny: Update
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1187>
2023-04-21 10:48:10 +00:00
Sebastian Dröge 5451035215 Update async-tungstenite and AWS SDK dependencies
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1187>
2023-04-21 10:48:10 +00:00
John King 2bd2e501d9 spotify: fix credentials cache
Cache Spotify response instead of username and password.
This should resolve frequent "New login to Spotify" emails.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1183>
2023-04-21 09:12:47 +02:00
Sebastian Dröge cc3646640e Fix a couple of new Rust 1.69 clippy warnings
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1186>
2023-04-20 16:47:45 +03:00
Lily Foster 760e97c7e7 meson: avoid passing the --features flag to wrapper when empty
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1184>
2023-04-18 16:26:11 -04:00
Edward Hervey 721d17e181 rtpgccbwe: Don't process empty lists
The structure parsing could result in an empty vector. Don't do any processing
since the loss code assumes it's non-empty for average estimates which would
result in weird/invalid results.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1181>
2023-04-15 19:35:27 +02:00
Mathieu Duponchelle dbdb9bc164 webrtcsink: fix navigation data channel
At some point, presumably recently, the data channel stopped being
requested in Ready, making webrtcbin refuse to create it.

There was quite a lot of churn recently so I couldn't pinpoint the
breaking commit easily.

Fix by simply restoring the correct behavior of requesting the channel
after going to the Ready state

Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/341

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1180>
2023-04-14 14:26:22 +02:00
Sebastian Dröge 47159ad3c2 Make sure to keep around and drop bus watches after usage in all the examples 2023-04-14 12:46:43 +03:00
Arun Raghavan aabfb61834 ffv1dec: Drop rank for now
We'll keep the rank lower than avdec_ffv1, at least until we're
comfortable with support for the entire range of possible inputs working
well.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1174>
2023-04-13 15:58:49 +00:00
Mathieu Duponchelle f1fd8d84c3 webrtc: extract a BaseWebRTCSink
For documentation purposes, AwsKVSWebRTCSink should not inherit from
another element.

+ Mark base class as plugin API and update plugin cache

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1178>
2023-04-13 15:06:59 +00:00
Guillaume Desmottes 367b98bfcb fmp4: dash_vod example: reformat
Not sure why rustfmt updated those because of my previous change.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1177>
2023-04-13 09:50:15 +02:00
Guillaume Desmottes 371ac83169 fmp4: dash_vod example: use dash-mpd to generate the manifest
Maybe a bit overkill for such simple example but more exemplary for
actual applications.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1177>
2023-04-13 09:50:11 +02:00
Loïc Le Page dba91bceca webrtc: fix documentation after signaller interface changes
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1175>
2023-04-12 20:19:22 +02:00
Thibault Saunier 8f2273328b webrtcsrc: Return bool en 'end-session' as required
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1172>
2023-04-12 12:17:56 +00:00
Sebastian Dröge 5dcdf645d6 net: ndi: Update to libloading 0.8
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1173>
2023-04-12 11:03:05 +03:00
Sebastian Dröge 011f0d5fee deny: Update for miniz_oxide dependency duplication 2023-04-11 11:14:08 +03:00
Mathieu Duponchelle 355f925954 tttocea608: specify raw 608 field
The element can only output field=0 raw 608 data.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1166>
2023-04-11 09:26:24 +10:00
Mathieu Duponchelle f366c20869 awstranscriber: fix what we send over for translations
Prior to this commit, we were sending over words concatenated together
with no separators, for instance "Idon'twanttobeanemperor".

The translation service seems clever enough to translate the contents
anyway, but there is no reason to make its task harder than necessary,
and it didn't re-add separators when the target language was the same as
the source language, which resulted in less than ideal output.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1171>
2023-04-10 20:47:12 +00:00
Mathieu Duponchelle 408fd2030c awstranscriber: slight debug improvement
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1171>
2023-04-10 20:47:12 +00:00
Mathieu Duponchelle 4fcbb6ae61 textwrap: add some logs
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1171>
2023-04-10 20:47:12 +00:00
Guillaume Desmottes 3eca8c60e3 ci: check for typos
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1170>
2023-04-10 13:35:32 +02:00
Guillaume Desmottes 403004a85e fix typos
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1170>
2023-04-10 13:35:32 +02:00
Mathieu Duponchelle a455819871 webrtcsink: fix tracking of signaller state
For the signaller to get stopped, we need to remember that we started it
in the first place.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1167>
2023-04-10 07:58:10 +03:00
Mathieu Duponchelle 3368f55a88 webrtcsink: don't return value from error closure
the signal doesn't expect a return value, which meant we were panicking
as soon as the signaller tried to report an error.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1167>
2023-04-10 07:58:10 +03:00
Mathieu Duponchelle 58c8c0edc7 webrtc: signaller iface: fix session-ended vs end-session confusion
Session ending is bidirectional: the signaller can tell the sink that a
session was ended, and the sink can tell the signaller to end a session.

As such, two signals are needed, before this patch the second case was
not working as in essence the sink was telling itself that a session was
ended, and obviously failing to even find it when trying to end it again.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1167>
2023-04-10 07:58:10 +03:00
Tim-Philipp Müller 0b5cf4e5fd ci: add check for symlinks
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1169>
2023-04-08 23:20:54 +01:00
Tim-Philipp Müller 7c30430320 webrtc-api: replace LICENSE file symlink with copy
As in !1157

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1169>
2023-04-08 17:22:37 +01:00
Seungha Yang 6e36e2ddfd transcriberbin: Allow video with ANY caps features
transcriberbin does not read/write video buffers actually.
Allow ANY caps features in order to avoid unnecessary GPU
upload/download

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1165>
2023-04-08 02:40:49 +09:00
Mathieu Duponchelle c846147275 transcriberbin: require final framerate from cea608mux
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1164>
2023-04-07 17:46:45 +02:00
Matthew Waters c141a82dfb webrtcsink: update docs for property and signal changes
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1141>
2023-04-07 09:58:13 +10:00
Matthew Waters e69b4b7f45 webrtc/signaller/iface: give variables appropriate names
Rather than arg0, arg1, etc.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1141>
2023-04-07 09:58:13 +10:00
Matthew Waters 4f4e5f0d75 webrtcsink/signaller: don't call signals while having state/settings locked
It is a recipe for deadlocks if the signal callback calls back into
webrtcsink in some way.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1141>
2023-04-07 09:58:13 +10:00
Matthew Waters 1c61e46f37 webrtcsink: privatise signalling functions
The functionality is now access through the relevant signals instead.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1141>
2023-04-07 09:58:13 +10:00
Matthew Waters 2ac560975c webrtc/signaller: emit the relevant signals instead of the interface vtable
In order to support the use case of an external user providing their own
signalling mechanism, we want the signals to be used and only if nothing
is connected, fallback to the default handling.  Calling the interface
vtable directly will bypass the signal emission entirely.

Also ensure that the signals are defined properly for this case. i.e.
1. Signals the the application/external code is expected to emit are
   marked as an action signal.
2. Add accumulators to avoid calling the default class handler if
   another signal handler is connected.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1141>
2023-04-07 09:58:13 +10:00
Matthew Waters 343b659755 webrtc/signaller: remove SignallableImplExt
This pattern is used for subclassing and calling parent class/interface functions.
However that is not useful for the signaller object.
1. The signals are the API contract and should instead be used by
   webrtcsrc/sink to ask or provide outside for/with information.
2. The default case (no signal attached)is instead handled by default class
   handlers that call directly using the relevant rust trait.  No parent
   (GObject) vfuncs necessary.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1141>
2023-04-07 09:58:13 +10:00
Matthew Waters b6e78b5f04 webrtcsink: expose signaller as a property
in the process move the signaller field to the settings struct

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1141>
2023-04-07 09:58:13 +10:00
Thibault Saunier 8236f3e5e7 webrtcsink: Port to the 'webrtcsrc' signaller object/interface
With contributions from:
Matthew Waters <matthew@centricular.com>

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1141>
2023-04-07 09:03:47 +10:00
Seungha Yang 538e2e0c9e transcriberbin: Add support for runtime translation-languages update
Allows updating translation-languages at runtime

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1162>
2023-04-06 21:43:04 +09:00
Seungha Yang 65c6117962 transcriberbin: Wrap conversion channel elements into bin
Make dynamic reconfiguration easier

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1162>
2023-04-06 11:49:36 +00:00
Sebastian Dröge 884a8a8b23 meson: Update version 2023-04-06 11:25:33 +03:00
Sebastian Dröge 0bc9718e3b Update CHANGELOG.md for 0.10.6 2023-04-06 11:25:22 +03:00
Seungha Yang 762fb86ce7 awstranscriber: Reset start_time per task
Otherwise wrong start time can be assigned if the element is
reused with state change

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1159>
2023-04-05 18:22:59 +00:00
Sebastian Dröge 9cb211470f ndisrc: Fix copying of raw video frames with different NDI/GStreamer strides
And also don't copy each line twice for single-plane formats.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1158>
2023-04-05 16:45:48 +03:00
Sebastian Dröge e549f5c4a9 deny: Update for older versions of the windows bindings 2023-04-05 12:04:21 +03:00
Matthew Waters a8b46f1bf4 closedcaption: add cea608tocea708 element
Implement an element that can take an input 608 caption stream and
generate a valid 708 caption stream by parsing the 608 data and
generating the equivalent DTVCCPackets and Service blocks.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1112>
2023-04-05 13:00:32 +10:00
Matthew Waters c0dc6eb35c cea608utils: track last channel for characters without channel embedded
If a basicna character is received, it will always have a channel of 0
even if it's directed at a different data channel.  Fix by keeping track
of the last channel from other commands and using that when producing
text in the basicna subset.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1112>
2023-04-05 12:18:15 +10:00
Matthew Waters 9a5e5db271 closedcaption: move 608 utility functions to a separate file
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1112>
2023-04-05 12:18:15 +10:00
Loïc Le Page f17622a1e1 webrtc: Add gstwebrtc-api subproject in net/webrtc plugin
This subproject adds a high-level web API compatible with GStreamer
webrtcsrc and webrtcsink elements and the corresponding signaling
server. It allows a perfect bidirectional communication between HTML5
WebRTC API and native GStreamer.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/946>
2023-04-04 16:29:44 +02:00
Tim-Philipp Müller 8845f6a4c6 git: replace LICENSE file symlinks with copies
Git will de-duplicate the contents for us anyway, and
symlinks can cause problems with some versions of git
and also on Windows.

https://github.com/mesonbuild/meson/issues/11646
https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4326

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1157>
2023-04-04 14:26:37 +01:00
Sebastian Dröge 722dba1203 fallbacksrc: Don't check caps when linking to the fallbackswitch
Downstream might have different caps requirements and linking might
fail. Instead of having linking fail, give upstream an opportunity to
reconfigure and otherwise have a normal negotiation error during data
flow.

Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/334

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1156>
2023-04-04 10:14:06 +00:00
Guillaume Desmottes 138c318be6 uriplaylistbin: example: add queues
Prevent pipeline starvation with some media such as
https://assets.onestream.live/studio/Videos/1080p/osl-interval-1080p-8.mp4

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1064>
2023-04-04 08:24:55 +00:00
Seungha Yang 8576af247b transcriberbin: Set start-time-selection=first to cea608mux
We don't want to modify running time of caption stream

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1155>
2023-04-03 13:32:55 +00:00
Seungha Yang 4000d60305 awstranscriber: Avoid too large initial GAP event
Initialized GstSegment.position is always zero

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1154>
2023-04-03 13:05:15 +00:00
Vivia Nikolaidou c6e1efa0fe livesync: Actually assume zero upstream latency when query fails
The code said "assuming zero" but left latency at None instead of
Some(0), failing to unwrap the value later.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1153>
2023-03-31 17:40:32 +03:00
Mathieu Duponchelle 15e1844956 webrtcsink: fix calculation of fec_ratio with multiple encoders
In this context, the bitrate variable is for all encoders, but the
max_bitrate field is per encoder. To calculate a proper FEC ratio, we
need to scale max_bitrate to the number of encoders.

+ Also clamp the fec-percentage that we set on the transceiver for extra
  safety

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1151>
2023-03-31 12:19:07 +00:00
Sebastian Dröge 23c165dee1 deny: Update for duplicated old dependencies in dependencies
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1152>
2023-03-31 09:12:26 +00:00
Sebastian Dröge 315e53f064 webrtc: Update to AWS SDK 0.55/0.25
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1152>
2023-03-31 09:12:26 +00:00
Sebastian Dröge 6fe806c2b5 aws: Update to AWS SDK 0.55/0.25
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1152>
2023-03-31 09:12:26 +00:00
Mathieu Duponchelle 8cb328b6f2 transcriberbin: add support for translations
With this, if the transcriber element in use supports "translation_src_"
request source pads, the user can now specify what languages to
translate to and how to map them to 608 channels (only CC1 and CC3 are
supported).

For instance, translation-languages="languages, CC3=transcript, CC1=fr"
will cause the original transcript to be muxed into the CC3 channel, and
the French translation to be muxed into the CC1 channel.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1149>
2023-03-29 01:58:37 +02:00
David Revay 002a70a2a4 chore(webrtcsink): fix max-bitrate blurb and nick
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1150>
2023-03-28 16:11:05 +11:00
Vivia Nikolaidou 7a1b2d97d4 webrtcsink: Add ice-transport-policy option
Can be used to force relay ICE candidates, ensuring TURN server is used.
Proxy to the corresponding setting in webrtcbin,

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1143>
2023-03-27 16:12:13 +03:00
Sebastian Dröge 539051c892 deny: Update 2023-03-27 11:19:21 +03:00
Mathieu Duponchelle 002e22510f transcriberbin: fix deadlock on construction error
Don't post an error message on the bus while holding the state lock

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1148>
2023-03-24 23:36:30 +01:00
Mathieu Duponchelle 93f61483b5 tttocea608: fix disappearing text after special character in non-popon
To avoid special characters getting de-duplicated by the decoder, we
insert no-op control commands after those. The no-op command must be
picked according to the mode we're in however, inserting
"resume_caption_loading" commands in roll-up mode caused obvious issues.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1147>
2023-03-24 21:41:21 +01:00
Mathieu Duponchelle 82ccba4267 tttocea608: fix pushing unfixed caps downstream
Allowed downstream caps might hold multiple structures, simply fixating
the first structure is not enough, tttocea608 must also create caps with
a single structure from there (or remove the remaining structures, but
new caps seems cleaner)

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1146>
2023-03-24 17:51:01 +01:00
Lily Foster f18f69809a update-version.sh: Also update versions in Cargo.lock
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1144>
2023-03-23 10:44:18 -04:00
Mathieu Duponchelle 9e3110988c transcriberbin: fix initial transcription bin setup
When passthrough=false at construction and the transcription bin
is linked after receiving video caps (and not on state change),
there could be a race where transcription-bin was linked with
tee but state change of the transcription-bin was not finished.

If upstream pushed a buffer at that point, it got a flushing flow
return and stopped streaming.

This is the same issue and the same fix as 558656deb5
for the initial passthrough=false case.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1142>
2023-03-22 23:39:32 +01:00
Sebastian Dröge ac52ea4d8e Update CHANGELOG.md for 0.10.5 2023-03-19 18:42:26 +02:00
Sebastian Dröge cbc7e16dc0 deny: Update for new syn/bitflags versions 2023-03-19 18:39:02 +02:00
Carlo Cabrera 825fe9a4e2 gtk4: Fix compilation on macOS
Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/332

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1138>
2023-03-18 16:05:30 +02:00
Sebastian Dröge a38e6ca99b threadshare: jitterbuffer: Rename C symbols to avoid conflicts with the same symbols from the rtpmanager plugin
Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/326

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1128>
2023-03-17 16:20:28 +00:00
François Laignel 2b32d00589 net/aws/transcriber: use two queues for sending transcript items
* A queue dedicated to transcript items not intended for translation.
* A queue dedicated to transcript items intended for translation. The items are
  enqueued after a separator is detected or translate-lookahead was reached.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1137>
2023-03-16 20:29:31 +01:00
François Laignel 5a5ca76d9d net/aws/transcriber: desambiguify SrcPad output items queue
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1137>
2023-03-16 12:41:07 +01:00
François Laignel 162db2f3b9 net/aws/transcriber: fix translate lookahead
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1137>
2023-03-16 12:39:15 +01:00
François Laignel d5d6a4daf9 net/aws/transcriber: rename prop transcript-lookahead & TranslationSrcPad
... as translate-lookahead and TranslateSrcPad.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1137>
2023-03-16 12:37:31 +01:00
François Laignel 3b3f0c1a29 net/aws/transcriber: fix transcript-lookahead prop nick
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1136>
2023-03-14 21:11:33 +01:00
François Laignel 299e25ab3c net/aws/transcriber: translate: optional experimental translation tokenization
This commit adds an optional experimental translation tokenization feature.
It can be activated using the `translation_src_%u` pads property
`tokenization-method`. For the moment, the feature is deactivated by default.

The Translate ws accepts '<span></span>' tags in the input and adds matching
tags in the output. When an 'id' is also provided as an attribute of the
'span', the matching output tag also uses this 'id'.

In the context of close captions, the 'id's are of little use. However, we can
take advantage of the spans in the output to identify translation chunks, which
more or less reflect the rythm of the input transcript.

This commit adds simples spans (no 'id') to the input Transcript Items and
parses the resulting spans in the translated output, assigning the timestamps
and durations sequentially from the input Transcript Items. Edge cases such as
absence of spans, nested spans were observed and are handled here. Similarly,
mismatches between the number of input and output items are taken care of by
some sort of reconcialiation.

Note that this is still experimental and requires further testings.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1109>
2023-03-14 13:48:32 +00:00
François Laignel 743e97738f net/aws/transcriber: add translation request src pads
This commit adds an optional transcript translation feature implemented as
request src Pads.

When requesting a src Pad, the user can specify the translation language code
using Pad properties 'language-code'.

The following properties are defined on the Element:

- 'transcribe-latency': formerly 'latency', defines the expected latency for
  the Transcribe webservice.
- 'translate-latency': defines the expected latency for the Translate
  webservice.
- 'transcript-lookahead': maximum transcript duration to send to translation
  when a transcript is hitting its deadline and no punctuation was found.

When the input and output languages are the same, only the 'transcribe-latency'
is used for the Pad. Otherwise, the resulting latency is the addition of
'transcribe-latency' and 'translate-latency'.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1109>
2023-03-14 13:48:32 +00:00
Sebastian Dröge 9a55fda69c Update CHANGELOG.md for 0.10.4 2023-03-14 14:10:11 +02:00
Sebastian Dröge 4eccd30ce2 Revert "aws: Temporarily enable the default features of the test-with crate"
This reverts commit 42116b5bce.
2023-03-14 13:28:28 +02:00
Sebastian Dröge 42116b5bce aws: Temporarily enable the default features of the test-with crate
Version 0.9.4 fails compiling without them enabled.

See https://github.com/yanganto/test-with/pull/57
2023-03-14 09:19:26 +02:00
Josef Kolář 9e00142b40 fmp4mux: fix hls_live example
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1134>
2023-03-12 12:58:17 +01:00
Thibault Saunier f88552ee7f meson: Handle features detection for gst version in a script
Instead of having a big list of features in the meson.build file, we
reuse the information from the Cargo.toml files

This refactors the dependencies to handle that new use case

There were issue in previous handling and only activating the `webrtc`
plugin was failing because the list of features incorrect.

Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/295

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1130>
2023-03-12 09:16:34 +00:00
Sebastian Dröge f7c8940ff2 gtk4: Update for glib::Priority API changes
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1132>
2023-03-12 10:27:16 +02:00
Sebastian Dröge e757212741 deny: Update
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1131>
2023-03-11 09:41:41 +02:00
Sebastian Dröge c1bac30694 webrtc: Update to aws 0.54/0.24
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1131>
2023-03-11 09:37:14 +02:00
Arun Raghavan 04bb7b4db0 fmp4: Return a running time in get_next_time()
We were currently returning a value based on the next chunk PTS, but the
expectation in GstAggregator is that we return a running time. This
resulted in spurious wakeups and warnings like:

0:00:01.501685123 1552995 0x55899715c1e0 WARN                 fmp4mux mux/fmp4/src/fmp4mux/imp.rs:1818:gstfmp4::fmp4mux:👿:FMP4Mux::drain_buffers:<fmp4mux0:sink_1> Don't have a complete GOP for the first stream on timeout in a live pipeline

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1127>
2023-03-10 10:58:38 -05:00
Talha Khan a12a8c566d livesync: Support variable framerate in fallback buffer duration calc
Avoids a divide by zero error

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1123>
2023-03-10 09:18:28 +00:00
Jordan Petridis 9a50f1f318 ci: Update debian jobs to bookworm
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1125>
2023-03-09 22:09:13 +02:00
Mathieu Duponchelle 584392049c net/webrtc: implement AWS KVS signaller
And expose a wrapper webrtcsink variant, aws-kvs-webrtcsink.

This adds support in webrtcsink for processing a consumer offer, instead
of producing one.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1114>
2023-03-09 15:39:09 +00:00
Sebastian Dröge 82f1789589 Fix indentation broken by cargo clippy --fix
... and another clippy warning.
2023-03-09 17:38:41 +02:00
Sebastian Dröge d3b7928b99 Fix a couple of new clippy warnings 2023-03-09 17:31:24 +02:00
Sebastian Dröge b025d068f2 Update for remaining gst::Element::link_many() and related API generalization
Specifically, get rid of now unneeded `&`.
2023-03-09 17:30:57 +02:00
Sebastian Dröge fc5ed15af5 Update for gst::Element::link_many() and related API generalization
Specifically, get rid of now unneeded `&`.
2023-03-09 16:46:52 +02:00
François Laignel b9cd71d8eb net/aws/transcriber: fix eos not being sent
For eos to be sent from the srcpad task loop, we need to go through `dequeue`.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1122>
2023-03-09 13:07:03 +01:00
François Laignel 2ea9f147ab net/aws/transcriber: fix deadlock when the pipeline is interrupted
... also makes sure to abort the taks_iter Future.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1122>
2023-03-09 13:07:03 +01:00
Guillaume Desmottes f7c02cb3b0 uriplaylistbin: reset element when switching back to NULL
Allow us to re-use the element later.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1121>
2023-03-08 14:34:20 +01:00
Sebastian Dröge 3ef8a48ded Fix a few new clippy warnings
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1120>
2023-03-07 08:47:01 +00:00
Guillaume Desmottes 93503c0ca9 spotify: move Settings to common module
Will be used to implement the lyrics source element.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1095>
2023-03-05 14:35:04 +01:00
Sebastian Dröge cd177dee86 Update CHANGELOG.md for 0.10.3 2023-03-02 13:35:47 +02:00
Vivia Nikolaidou cd74d01324 ndisinkcombiner: Properly handle caps changes
We are caching one video buffer, so previously we were changing the src
caps one buffer too early.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1110>
2023-03-01 12:30:54 +00:00
Sebastian Dröge fb528941ea deny: Update to allow socket2 0.4
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1113>
2023-03-01 14:00:26 +02:00
Sebastian Dröge e69f1e0b8c threadshare: Update to socket2 0.5
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1113>
2023-03-01 13:59:53 +02:00
François Laignel 4a988aaeb8 net/aws/transcriber: use a TranscriberLoop struct
This helps gather together the details related to the `TranscriberLoop`.
One difference with previous implementation is that the ws `Client` is
build each time the loop is started instead of being reused. With the new
approach, we don't keep the connection open after EOS and we should be
more resistant in case of a connection failure.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1104>
2023-03-01 08:47:58 +00:00
François Laignel f1a080c94e net/aws/transcriber: own transcription items
So that we can avoid copying the content.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1104>
2023-03-01 08:47:58 +00:00
François Laignel 36ae29d746 net/aws: enqueue transcribed buffers within the ws loop
Instead of sending transcription events to the src pad loop, this commit
enqueues the transcribed buffers immediately in the ws loop, then notifies
the src pad loop. The src pad loop is only in charge of dequeuing the buffers.

This should help with upcoming evolutions.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1104>
2023-03-01 08:47:58 +00:00
François Laignel 00153754bb net/aws: use aws-sdk-transcribestreaming
Switch from manual webservice client impl to `aws-sdk-transcribestreaming`.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1104>
2023-03-01 08:47:58 +00:00
François Laignel 57f365979c net/aws: remove aws_ from the aws_transcribe* folder names
Those folders reside under `aws`, so there's shouldn't be any confusion.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1104>
2023-03-01 08:47:58 +00:00
Thibault Saunier ce3bb2f1d4 Add a webrtcsrc element
Updating the docker image to include:
https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3236

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/932>
2023-02-28 20:50:15 -03:00
Thibault Saunier 0ae637f531 webrtcsink: Move RUNTIME to the crate so it can be reused
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/932>
2023-02-28 17:57:14 -03:00
Thibault Saunier 4ec441560b webrtc: Enhance debug messages when using unknown peer ID
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/932>
2023-02-28 19:28:51 +00:00
Guillaume Desmottes a0f6e84ec2 tracers: queue_levels: add appsrc support
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1111>
2023-02-28 14:38:29 +01:00
Sebastian Dröge ff2f7a8505 livesync: Correctly calculate fallback buffer duration from framerate
Numerator and denominator were switched.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1108>
2023-02-28 12:52:11 +02:00
Matthew Waters 542c7e12b8 webrtcsink: also support nvvidconv in lieu of nvvideoconvert
nvvideoconvert may not exist and nvvidconv might on some Jetson
platforms.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1107>
2023-02-28 10:12:36 +11:00
Sebastian Dröge bca4af0c79 gtk4: Set sync point on the video frame after mapping it
Otherwise it is not always ready for use yet in GTK even after waiting
on the sync point, and a fully transparent texture is rendered instead.

Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/320

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1103>
2023-02-24 11:52:28 +02:00
Sebastian Dröge 6bc72e513c Update CHANGELOG.md for 0.10.2 2023-02-23 10:16:55 +02:00
Jordan Petridis 90455a8111 video/gtk4: Add a flatpak snippet example in the README
Close #155

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1102>
2023-02-22 22:15:40 +02:00
Sebastian Dröge ce1faa6020 gtk4: Attach channel receiver to the default main context from the main thread
It requires acquiring the main context for thread-safety reasons and
that is only possible from the main thread itself.

Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/319

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1099>
2023-02-22 10:02:45 +02:00
Sebastian Dröge f08b65ece1 gtk4: Don't unnecessarily set the sink to READY to retrieve the context
That's not needed and will cause the GL context messages to be not
distributed inside the pipeline.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1099>
2023-02-21 21:36:45 +02:00
Sebastian Dröge 8aa5125d5b gtk4: Refactor and simplify GL context handling
Create a single, global GDK GL context and the corresponding GStreamer
GL display and wrapped GStreamer GL context when initializing the first
sink and continue using that for all further sinks.

Additionally, don't create a full GStreamer GL context inside the sink
but only distribute the wrapped GL context in the pipeline so that
elements that actually need a full GL context can create one that is
sharing with that one. The sink itself does not need a full GStreamer GL
context.

Then inside the sink check that any GL memory that arrives was created
by a GL context that can share with the wrapped GDK GL context and only
then use it.

And lastly, use the correct GL contexts for a) creating a sync point and
b) actually waiting on it.

Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/318

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1099>
2023-02-21 21:36:45 +02:00
Sebastian Dröge 93051dba0e ci: Update image version
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1096>
2023-02-20 13:08:51 +02:00
Sebastian Dröge 143bf7608e ci: Update to cargo-c 0.9.15
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1096>
2023-02-20 13:08:46 +02:00
Sebastian Dröge 53b6efaa6e ci: Update to dav1d 1.1
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1096>
2023-02-20 11:09:21 +02:00
Sebastian Dröge 9fc1404415 Update minimum supported Rust version to 1.66
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1096>
2023-02-20 11:09:01 +02:00
Seungha Yang 59222f7a35 mp4mux: Ignore framerate update
like mp4mux in -good does already

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1094>
2023-02-16 03:43:01 +09:00
Seungha Yang 6b15e772ac fmp4mux: Ignore framerate update
like mp4mux in -good does already

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1094>
2023-02-16 02:23:56 +09:00
Arun Raghavan 487d7fb26b hlssink3: Allow GIOStream signal handlers to return None
If creating a playlist or fragment stream fails (disk is full, the
directory is removed, ...), we will currently crash because the signal
handler expects a non-None GIOStream. The actual callback is allowed to
return None values and we handle this in the caller, so let's not have
this restriction on the signal handler.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1093>
2023-02-14 11:25:44 -05:00
Guillaume Desmottes 77e99e92fb spotifyaudiosrc: use Settings Default to define default props
Makes it easier to change one property's default value.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1074>
2023-02-13 18:04:53 +01:00
Sebastian Dröge 51d61af863 Add mp4 plugin to README.md 2023-02-13 11:56:33 +02:00
Sebastian Dröge b0664b3c85 Update CHANGELOG.md for 0.10.1 2023-02-13 11:54:46 +02:00
Sebastian Dröge 04e101c605 Optimize various error message / debug message formatting
Directly make use of format strings instead of formatting a string
beforehand and then passing it to the macros.
2023-02-13 11:50:57 +02:00
Sebastian Dröge 034c0f0fd8 Add CHANGELOG.md for 0.10.0 release
This is the first one and only lists changes from 0.9.0 to 0.10.0
2023-02-12 13:15:17 +02:00
Arun Raghavan 39e0acb55a hlssink3: Fix case on unspecified playlist type nick for consistency
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1089>
2023-02-10 23:07:12 +00:00
Seungha Yang 6420fe43da rtpav1pay: Fix Leb128Bytes size parsing
There are multiple ways of encoding the value, and don't assume
that bitstream used the way used in this plugin. Instead, count
the number of used bytes.

Fixes: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/312
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1090>
2023-02-10 18:47:52 +00:00
Sebastian Dröge ac8afc4ac0 Update to async-tungstenite 0.20
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1087>
2023-02-10 13:03:07 +02:00
Sebastian Dröge 1e13dbb99c Update versions to 0.11.0-alpha.1 2023-02-10 00:23:56 +02:00
rajneeshksoni 994c79569e awss3sink: Add properties to set content-Type and content-disposition.
for uploaded object default content-type is set to binary/octet-stream,
which is correct.
metadata cannot be used to set content-type and content-disposition as
setting metadata add a prefix x-amz-meta to key
e.g. setting metadate "content-type=video/mp4" actually set value as
x-amz-meta-content-type. So these has to be seaprate property.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1085>
2023-02-09 19:04:07 +00:00
Sebastian Dröge 4d9b6c5472 fmp4mux: Pass one more buffer in test_buffer_multi_stream_short_gops test
This works around non-determinism in aggregator where depending on
timing it can happen that it consumes all buffers from both pads or
waits for another buffer on one pad while the other one already has one.

The effect in this test was that it sometimes timed out. By providing
one more buffer it is guaranteed now that at this point the muxer is
beyond the end of the first fragment.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1081>
2023-02-09 20:36:44 +02:00
Sebastian Dröge 5965ff4364 fmp4mux: Accept more data on already filled streams if the remaining streams need more data for finishing a GOP
In other words, continue queueing buffers in sync from all streams until
all of them are ready for draining instead of stopping to queue buffers
on every stream that is already filled individually.

Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/310

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1081>
2023-02-09 20:36:42 +02:00
Jan Alexander Steffens (heftig) f55c32ed37 livesync: Document State's fields
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1083>
2023-02-09 13:07:33 +01:00
Jan Alexander Steffens (heftig) 953773a314 livesync: Improve formatting
Move some code around to make it a bit more readable. No change in
behavior.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1083>
2023-02-09 13:07:33 +01:00
Jan Alexander Steffens (heftig) c1bfeb4c23 livesync: Fix log message capitalization
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1083>
2023-02-09 13:07:33 +01:00
Jan Alexander Steffens (heftig) 0af7151ae9 livesync: Extract LiveSync::flow_error
And add details so it behaves more like the `GST_ELEMENT_FLOW_ERROR`
macro.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1083>
2023-02-09 13:07:32 +01:00
Jan Alexander Steffens (heftig) f03ee95bf0 livesync: Extract audio_info_from_caps
And adjust it slightly so it never panics.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1083>
2023-02-09 13:07:32 +01:00
Jan Alexander Steffens (heftig) c971c4d1d5 livesync: Move single segment prop
Keep it with the settings, not after the stats.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1083>
2023-02-09 13:07:32 +01:00
Jan Alexander Steffens (heftig) 165b5f8c50 livesync: Fix queueing
The logic of the element requires the next buffer to be available
immediately after we are done pushing the previous, otherwise we insert
a repeat.

Making the src loop handle events and queries broke this, as upstream is
almost guaranteed not to deliver a buffer in time if we allow non-buffer
items to block upstream's push.

To fix this, replace our single-item `Option` with a `VecDeque` that we
allow to hold an unlimited number of events or queries, but only one
buffer at a time.

In addition, the code was confused about the current caps and segment.

This wasn't an issue before making the src loop handle events and
queries, as only the sinkpad cared about the current segment, using it
to buffers received, and only the srcpad cared about the current caps,
sending it just before sending the next received buffer.

Now the sinkpad cares about caps (through `update_fallback_duration`)
and the srcpad cares about the segment (when not in single-segment
mode).

Fix this by
  - making `in_caps` always hold the current caps of the sinkpad,
  - adding `pending_caps`, which is used by the srcpad to store
    caps to be sent with the next received buffer,
  - adding `in_segment`, holding the current segment of the sinkpad,
  - adding `pending_segment`, which is used by the srcpad to store
    the segment to be sent with the next received buffer,
  - adding `out_segment`, holding the current segment of the srcpad.

Maybe a fix for
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/298.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1082>
2023-02-09 12:44:47 +01:00
Simon Himmelbauer 3c31c98d95 spotifyaudiosrc: Support configurable bitrate
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1073>
2023-02-09 00:02:30 +02:00
rajneeshksoni 0f383a6545 hlssink3: Allow setting i-frame-only playlist.
HLS allows manifest where all segments are single ifames.
This manifest requires `EXT-X-I-FRAMES-ONLY` tag in the
manifest.
I-FRAMES-ONLY playlist segments are video only segments.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1070>
2023-02-08 14:04:46 +00:00
Sebastian Dröge 44405e0cd7 dav1ddec: Make sure to call get_picture() twice in a row when draining
The first time might return `EAGAIN` if there are pending frames but
there is no decoded frame available yet. The second time it will
actually wait for frames to become available and only start returning
`EAGAIN` again once no more frames are left.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1080>
2023-02-08 11:26:25 +02:00
Sebastian Dröge 0ed74d0aa4 rtpgccbwe: Don't use clamp() if there's no clear min/max value
Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/305

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1078>
2023-02-06 21:56:46 +02:00
Sebastian Dröge 3a408c0146 fmp4mux: Handle GOPs ending after the desired fragment end correctly
Either create further chunks if enough data is queued or simply start
the new fragment at a later time if the keyframe is later.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1077>
2023-02-06 19:20:34 +02:00
Sebastian Dröge 5c2de6aeb6 gtk4: Update for GLDisplay object lock requirements 2023-02-06 11:10:02 +02:00
Sebastian Dröge 6f26e3bf79 mp4/fmp4: Update docs
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1075>
2023-02-04 16:32:17 +02:00
Sebastian Dröge 5627bd8d7d mp4: Add support for AV1
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1075>
2023-02-04 13:48:37 +00:00
Sebastian Dröge 4c3ae6f8ce fmp4: Add support for AV1
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1075>
2023-02-04 13:48:37 +00:00
Sebastian Dröge cef6fef079 fmp4: Add support for VP8
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1075>
2023-02-04 13:48:37 +00:00
Sebastian Dröge 02ac4b3b04 mp4: Add support for VP8
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1075>
2023-02-04 13:48:37 +00:00
Sebastian Dröge 042a5d0755 deny: Update 2023-02-04 10:38:25 +02:00
Sanchayan Maity 6006a0ba36 aws/s3hlssink: Fix deadlock on EOS
In state change to NULL, we take state lock and call stop. When stop
is called, we will try to upload queued segments in S3 request thread.
That tries to take the state lock again and deadlocks.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1076>
2023-02-03 19:09:18 +05:30
Sanchayan Maity 41aa1e51da aws/s3hlssink: Use factory name when checking name of child element
Commit ad3f1cf fixed the name of hlssink child element to be the same
for hlssink2 and hlssink3. However, we rely on element name to return
boolean in case of hlssink3 or None in case of hlssink2 as the return
value of the delete-fragment closure.

Fix this by using the factory name instead of the element name.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1076>
2023-02-03 19:08:40 +05:30
Sebastian Dröge 5506f8001e rtpav1pay: Add support for tu/frame aligned input
In this case every buffer can be sent out immediately and makes up a
whole frame.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1072>
2023-02-02 20:24:27 +02:00
Sebastian Dröge 194c4e9e9f rtpav1pay: Consider the marker flag to output packets immediately at the end of a frame
Otherwise it is necessary to wait for the beginning of the following
frame, which unnecessarily increases the latency.

Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/255

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1072>
2023-02-02 20:24:27 +02:00
Sebastian Dröge 49350f738f rtpav1depay: Fix depayloading of packets starting with a leading OBU fragment followed by more OBUs
Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/288

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1072>
2023-02-02 20:24:27 +02:00
Sebastian Dröge 1756d7a516 rtpav1depay: Fix error handling
Don't error out immediately on errors anymore but try again with the
next packet.

Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/289

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1072>
2023-02-02 20:24:27 +02:00
Sebastian Dröge ed4e9a50d5 rtpav1depay: Set DISCONT flag on buffers following a corrupted packet
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1072>
2023-02-02 20:24:27 +02:00
Sebastian Dröge d6cb9d72d8 rtpav1depay: Don't output full TUs but just OBUs as they come
Simplifies state tracking and potentially reduces latency as it's not
necessary to wait until all fragments of an OBU are received.

The last OBU of a TU is marked with the marker flag to allow parsers to
detect this without first seeing the beginning of the next TU.

Also use a simple `Vec` for collecting complete OBUs instead of a
`gst_base::Adapter` as this reduces the number of allocations.

And also handle invalid packets a little bit more gracefully.

Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/244

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1072>
2023-02-02 20:24:27 +02:00
Sebastian Dröge 27128a476c deny: Update 2023-02-02 09:24:40 +02:00
Sebastian Dröge ecb26a0b16 fmp4mux: Fix a couple of assertions by handling these cases cleaner
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1071>
2023-02-01 14:57:00 +02:00
Sebastian Dröge 560bdc4cb7 Update for glib API changes 2023-01-31 12:24:07 +02:00
Jan Alexander Steffens (heftig) 33696a8aed livesync: Only resend segment if not in single-segment mode
In single-segment mode, the outgoing segment does not change when the
incoming segment changes. We only need to resend the segment if we got
flushed or deactivated.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1069>
2023-01-30 15:37:00 +00:00
Sebastian Dröge 1998ecab45 fmp4mux: Refactor and clean up code
Split many longer functions into multiple functions and simplify various
parts. Overall this is functionally still the same as before.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1068>
2023-01-30 14:41:33 +00:00
Sebastian Dröge a1cce9b796 aws: Update to AWS SDK 0.54/0.24
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1066>
2023-01-27 22:10:23 +02:00
Sebastian Dröge 2a3d962dc5 fmp4mux: Add support for sub-fragments / chunking
Allow outputting sub-fragments (chunks in CMAF terms) that are shorter
than the fragment duration and don't usually start on a keyframe. By
this the buffering requirements of the element is reduced to one chunk
duration, as is the latency.

This is used for formats like low-latency / LL-HLS and DASH.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1059>
2023-01-27 19:28:27 +00:00
Sebastian Dröge c7209dbd4f Return exit code from gio::Application::run() from main()
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1065>
2023-01-27 18:50:01 +00:00
Sebastian Dröge 62bfc545d3 gtk4: Fix compilation after gst_gl::Display API changes 2023-01-27 20:46:22 +02:00
Guillaume Desmottes abe4efc4a2 fmp4mux: add 'offset-to-zero' property
Add it only to 'isofmp4mux', the onvif variant already does this and
CMAF and DASH are always single-stream so you rely on inter-container
synchronization via the running-time.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1063>
2023-01-25 12:29:30 +00:00
Sebastian Dröge 3b4c48d9f5 Fix various new clippy warnings
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1062>
2023-01-25 10:31:19 +02:00
Arun Raghavan ad3f1cf534 aws: s3hlssink: Fix the name of the hlssink child element
It's easier to set child element properties if the name doesn't depend
on the factory.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1061>
2023-01-24 18:56:46 +00:00
Sebastian Dröge ee8249eec7 fmp4mux: Don't write the first sample flags into any trun but the first
The flags are based on the first sample of this fragment so writing it
into any trun but the first is not very useful.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1060>
2023-01-24 19:54:12 +02:00
Sebastian Dröge 1ceaea844a fmp4mux: Fix decision whether per-sample flags are needed in the trun
Previously it would never use per-sample flags if any later sample
needed different flags than the first two.

Also comment the code a bit better.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1060>
2023-01-24 19:54:11 +02:00
Sebastian Dröge 77d68080e8 meson: Update version to 0.10.0-alpha.1
Should've happened long ago already.
2023-01-24 15:44:54 +02:00
Sebastian Dröge e0e63dd4da dav1d: Don't treat any kind of bitstream error immediately as fatal
Instead use the videodecoder error handling to allow up to max-errors
consecutive decoding errors, i.e. infinite by default in 1.22 and newer.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1057>
2023-01-23 10:46:38 +02:00
Sebastian Dröge 2c386fb792 Update for various deprecated APIs 2023-01-22 20:07:26 +02:00
Sebastian Dröge 037294b077 dav1d: Get rid of some unnecessary unwrap()s
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1055>
2023-01-22 00:32:52 +02:00
Sebastian Dröge f62d07633d dav1d: Remove unnecessary frame dropping loop
After flushing there are no frames left anymore that could be dropped.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1055>
2023-01-22 00:28:15 +02:00
Sebastian Dröge c5a625ae28 dav1d: Don't flush the decoder when draining
This directly discards all frames and it won't be possible to output
them anymore.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1055>
2023-01-22 00:27:22 +02:00
Sebastian Dröge d110977580 dav1d: Only drain at most one decoded frame per input frame unless the decoder requires more before accepting new data
This works around a race condition in dav1d where the decoder deadlocks
if multiple threads are used, and also is generally beneficial as it
allows for proper frame threading.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1055>
2023-01-22 00:25:23 +02:00
Sebastian Dröge 4582ae91ab Move remaining plugins to ParamSpec builders
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1054>
2023-01-21 18:34:55 +02:00
Sebastian Dröge 458b2386ed Update for glib API changes 2023-01-21 18:13:48 +02:00
Sebastian Dröge 7cfd570c15 onvif: Update for allocation query caps API changes 2023-01-19 16:38:06 +02:00
Sebastian Dröge b6af64b970 gtk4: Only provide a buffer pool to upstream if it requested one 2023-01-19 16:37:02 +02:00
Sebastian Dröge d1196c3e28 gtk4: Update for allocation query caps API changes
And make no caps into a non-error.
2023-01-19 16:36:37 +02:00
Sebastian Dröge 03df4f253c gtk4: Asynchronously flush frames from GDK
There is no need to wait until the frames are flushed as the textures
will be kept alive until GDK is finished with them, and doing so can
cause deadlocks.

Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/287

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1052>
2023-01-19 13:53:21 +02:00
Sebastian Dröge b161f56a5c gtk4: Keep GstGLMemory alive as long as it is used inside GDK
Otherwise the texture might be released in the meantime and GDK would
use an invalid GL texture ID.

Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/287

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1052>
2023-01-19 13:51:57 +02:00
Guillaume Desmottes 570eb7463a livesync: fix late-threshold property min value
The code is handling 0 as "always over threshold" but it was not
possible to set the property to 0.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1049>
2023-01-17 10:54:05 +01:00
Sebastian Dröge 812df78b75 webrtcbin: Update for StreamProducer API changes 2023-01-16 16:36:41 +02:00
Sebastian Dröge 4464bf2eaa Update for gtk::Application constructor API changes 2023-01-16 11:51:10 +02:00
Sebastian Dröge 6132788b02 Update for caps/structure-related string API changes
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1048>
2023-01-15 22:58:44 +02:00
Sebastian Dröge 0c954135a3 aws: Update to AWS SDK 0.53/0.23
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1047>
2023-01-14 18:58:30 +02:00
Philippe Normand f5e01b9196 meson: Only enable cargo features when options are enabled (bis)
Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/285 even more.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1043>
2023-01-11 17:08:52 +00:00
Mathieu Duponchelle 1a8abde884 webrtcsink: fix panic on pre-bwe request error
We dispose of consumer pipelines asynchronously, potentially after the
session objects have been disposed of.

As session objects are the owner of the cc element, it is entirely
possible for the bwe-request signal to get emitted after cc has been
disposed of, as the closure only takes a weak reference to it.

Fix by simply checking if cc is None

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1044>
2023-01-11 15:09:45 +00:00
Sebastian Dröge 0201f5a456 deny: Ignore duplicated base64 dependency for now 2023-01-11 10:30:45 +02:00
Nirbheek Chauhan b96d560f0a meson: Only enable cargo features when options are enabled
Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/285

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1041>
2023-01-10 22:50:38 +05:30
Sebastian Dröge bc95a30db6 deny: Remove duplicated windows dependencies 2023-01-10 10:32:37 +02:00
Sebastian Dröge 1a06f5e671 rav1e: Enable threading support
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1039>
2023-01-09 14:04:13 +02:00
Sebastian Dröge 58c21d9868 gtk4: Propagate the GL display to the remainder of the pipeline
This allows sharing it with other parts of the pipeline and avoids
creating different, incompatible displays/contexts in different parts of
the pipeline.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1037>
2023-01-07 12:42:42 +02:00
Sebastian Dröge e9bbf804ba fmp4mux: Remove obsolete comment
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1037>
2023-01-06 14:52:56 +02:00
Sebastian Dröge be72fefb18 reqwest: Update for API changes 2023-01-06 12:52:30 +02:00
Sebastian Dröge d44a1a4245 Fix some clippy warnings
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1035>
2023-01-05 12:42:47 +02:00
Sebastian Dröge 781fd1df9a aws: Update to test-with 0.9
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1035>
2023-01-05 12:35:42 +02:00
Sebastian Dröge 27435ad82e Update for API changes 2023-01-05 12:33:54 +02:00
rajneeshksoni d846f527af awss3hlssink: Add stats property.
application can monitor the progress of hls segment generation
and upload progress.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1022>
2023-01-04 12:36:13 +00:00
Sebastian Dröge de23ea7f29 video: Fix compilation after API changes 2023-01-04 13:39:14 +02:00
Philippe Normand 0fd63ece7d rtpav1depay: Implement srcpad set_caps
Without this auto-pluggers such as decodebin or parsebin will be unable to
process AV1 RTP payloads.

Tested with: `videotestsrc num-buffers=50 ! videoconvert ! av1enc ! av1parse ! rtpav1pay ! queue ! decodebin3 ! videoconvert ! queue ! autovideosink`

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1034>
2023-01-03 19:35:45 +02:00
Sebastian Dröge af9d9c0a5c fmp4: Fix compilation after glib::List API changes 2023-01-02 19:22:51 +02:00
Guillaume Desmottes f59d00b8e6 textahead: fix previous buffers
Actually implement a proper queue.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1033>
2023-01-02 12:04:09 +01:00
Sebastian Dröge 439ada614c gtk4: Rename a variable to make more sense
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1032>
2022-12-29 11:13:25 +02:00
Sebastian Dröge f72540f5c2 gtk4: Handle more GL context creation failures gracefully
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1032>
2022-12-29 11:13:25 +02:00
Sebastian Dröge 9ec06199b1 gtk4: Reset app context and display if GL context creation fails
No need to keep them around and that way we either have all 3 values set
or none of them.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1032>
2022-12-29 11:13:25 +02:00
Sebastian Dröge 4ee70913bd gtk4: Reduce number of unwraps during GL context creation and query handling
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1032>
2022-12-29 11:13:25 +02:00
Jordan Petridis cf0ba40115 video/gtk4: Fix typo in info logs
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1030>
2022-12-29 02:59:26 +00:00
Nirbheek Chauhan 002e3fa171 meson: Enable gstreamer-gl-1.0 features in gtk4 plugin
Basically, if gstreamer-gl-1.0 is built with wayland / x11 / egl, use
those features in the gtk4 plugin.

MacOS always uses CGL, and it's always available. Windows version does
not use GL yet.

Requires https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3654

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1031>
2022-12-29 06:51:17 +05:30
Nirbheek Chauhan f94e422b61 cargo_wrapper: Write to log with line-buffering
So we get log output while cargo is running, not just when it completes

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1031>
2022-12-29 06:51:17 +05:30
Nirbheek Chauhan 9ee7118bf6 gtk4: Remove 'gst' prefix from another debug category
Missed it last time. Caught all of them this time. Continuation from:

https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1029

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1025>
2022-12-28 23:55:10 +05:30
Nirbheek Chauhan 155d621262 meson: Require gstreamer-gl-1.0 for gtkpaintablesink
This is required on macOS, and is also highly recommended on Linux.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1025>
2022-12-28 23:55:10 +05:30
Nirbheek Chauhan 06123d74ba gtk4: Use GL implicitly without the gst_gl feature on macOS
We already require gstreamer-gl as a dependency on macOS, so reflect
that in the code too.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1025>
2022-12-28 23:55:10 +05:30
Sebastian Dröge 4fe0786bbd gtk4: Add support for GL on macOS
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1025>
2022-12-28 23:55:10 +05:30
Nirbheek Chauhan 5f0ff8348f meson: Add an option to build examples
Required renaming threadshare/benchmark to threadshare/ts-benchmark
because 'benchmark' as a target name is reserved for meson's
`benchmark` target.

Disabled by default because cargo decides that it has to rebuild
everything, and is really slow because of that.

Also required adding --features for setting features required by the
examples.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1028>
2022-12-28 22:30:11 +05:30
Nirbheek Chauhan a3d405f670 meson: Add options for all plugins
Required a slight rework of the build file, and how options are passed
to cargo_wrapper.py

Necessitated a bump of the required gstreamer version to 1.20, which
should be fine for the meson build since its primary function is to be
built as part of the gstreamer monorepo build to get a dev env.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1028>
2022-12-28 22:30:11 +05:30
Nirbheek Chauhan 851c82df85 cargo_wrapper: Fix setting of PKG_CONFIG_PATH and CARGO_TARGET_DIR
Don't need to use an env var for the latter.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1028>
2022-12-28 15:52:52 +00:00
Nirbheek Chauhan 72fa5fa922 meson: Require tomllib / tomli python modules explicitly
These are required by dependencies.py

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1028>
2022-12-28 15:52:52 +00:00
Nirbheek Chauhan ae9ac872c0 gtk4: Remove 'gst' from gtksink debug category name
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1029>
2022-12-28 19:38:57 +05:30
Zhao, Gang 9fa838e366 webrtc: Fix rustfmt errors
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1019>
2022-12-27 11:12:54 +02:00
Zhao, Gang 877a9bd7f3 webrtc: Share runtime between webrtcsink and signaller crates
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1019>
2022-12-26 23:10:40 +00:00
Zhao, Gang 1ffeb4d44d webrtc: Move from async-std to tokio
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1019>
2022-12-26 23:10:40 +00:00
Zhao, Gang 2bc29c1fd3 webrtc: examples: Update package-lock.json
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1019>
2022-12-26 23:10:40 +00:00
Sebastian Dröge ca17c9bc4f gtk4: Release GStreamer GL context and display when going back to NULL state
And acquire it again next time when going to READY state.

Also clean up the whole GL context initialization.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1024>
2022-12-22 22:56:48 +00:00
Sebastian Dröge 1026949b2b gtk4: Use glib::ThreadGuard instead of the fragile crate
Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/272

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1024>
2022-12-22 22:56:48 +00:00
Sebastian Dröge 52764e140e gtk4: Don't try to use GL mapped video frames as raw RGB memory
This will fail badly because the memory pointers are actually GL texture
IDs, however this case can't really happen in practice so simply assert
on this.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1024>
2022-12-22 22:56:48 +00:00
Sebastian Dröge 30e501e7b0 gtk4: Don't error out when the main context channel does not exist anymore when rendering
But instead return flushing to shut down silently.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1024>
2022-12-22 22:56:48 +00:00
Sebastian Dröge 0c8e69ed7c gtk4: Flush frames from the paintable when shutting down the sink
Otherwise it will continue showing the last frames forever and keep
around the frames forever instead of rendering black.

Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/281

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1024>
2022-12-22 22:56:48 +00:00
Johan Bjäreholt 71c268da14 fmp4mux: Only push fragment_offset if write_mfra is true
This is done so that the fragment_offset vector does not infinitely
build up when write_mfra is disabled.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1023>
2022-12-22 10:31:27 +01:00
Nirbheek Chauhan 6607a63159 meson: Disable webp plugin on Windows and macOS
Known to be broken, should be kept disabled till the fix is in
a release: https://github.com/qnighy/libwebp-sys2-rs/pull/13

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1021>
2022-12-19 11:21:57 +00:00
Nirbheek Chauhan 639997d67f meson: Handle windows path separator correctly
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1021>
2022-12-19 11:21:57 +00:00
Nirbheek Chauhan 0530b324c1 cargo_wrapper: Handle windows paths for depfiles
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1021>
2022-12-19 11:21:57 +00:00
Sebastian Dröge cb45ef2c03 deny: Update 2022-12-19 09:54:50 +02:00
Sebastian Dröge 4e444a066c aws: Update to AWS SDK 0.52/0.22
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1020>
2022-12-18 07:54:30 +00:00
Nirbheek Chauhan a507f24694 meson: Fix pkgconfig detection when specified in machine file
When pkgconfig and pkg_config_path are specified in the machine file,
we need to parse those and pass them on to the cargo_wrapper.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1018>
2022-12-18 04:56:46 +00:00
Nirbheek Chauhan 985e3e85d6 meson: Do not serialize env, use env: kwarg
This is simpler, and more correct.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1018>
2022-12-18 04:56:46 +00:00
Sebastian Dröge 620ba6e185 livesync: Fix version 2022-12-16 18:53:37 +02:00
Sebastian Dröge 13b6f8fad4 fmp4mux: Skip gap buffers earlier to consider them for the sample durations and fragment start durations
Otherwise dropping the gap buffers would offset the timestamps of
following samples.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1016>
2022-12-16 17:43:44 +02:00
Sebastian Dröge e344585d99 mp4mux: Adjust durations and possibly stream start time on encountering a gap buffer
If there was a previous sample in this stream then its duration needs to
be extended by the gap position, and if there was none then the start
time of the whole stream has to be shifted by the duration.

Not doing so causes timestamps to be offset wrongly by the duration of
the gap.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1015>
2022-12-16 13:24:21 +02:00
Sebastian Dröge 9307acf7fa mp4mux: Fix edit list shift for streams with initial DTS smaller earliest PTS but initial DTS positive
This would be a stream where the initial DTS is negative if the initial
PTS was zero, but it is offset so the initial DTS became positive now.
The edit list shift has to happen exactly the same way though.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1014>
2022-12-15 18:52:47 +02:00
Sebastian Dröge ed429d570e mp4mux: Don't write gap edit lists if their duration would be zero
The track might start later than the earliest track by less than one
timescale units, in which case writing an empty gap edit list would be
useless and confusing.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1014>
2022-12-15 18:45:19 +02:00
Sebastian Dröge f8024f072f mp4mux: Don't write empty chunks at the end if the last buffer of a stream started a new chunk and happened to be a from a gap event
Empty chunks are not valid in MP4.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1014>
2022-12-15 17:44:03 +02:00
Jan Alexander Steffens (heftig) 42385c81be Add livesync plugin
It attempts to produce a (nearly) gapless live stream by synchronizing
its output to the running time and forwarding the next input buffer if
its start is (nearly) flush with the end of the last output buffer.

If the input buffer is missing or too far in the future, it duplicates
the last output buffer with adjusted timestamps. If it is operating on a
raw audio stream, it will fill duplicate buffers with silence.

If an input buffer arrives too late, it is thrown away. If the last
input buffer was accepted too long ago (according to `late-threshold`),
a late input buffer is accepted anyway, but immediately considered a
duplicate. Due to the silence-filling, this has no effect on audio, but
video gets a "slideshow" effect instead of freezing completely.

The "many-repeats" property will be notified when this element has
recently duplicated a lot of buffers or recovered from such a state.

Co-authored-by: Vivia Nikolaidou <vivia@ahiru.eu>
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/708>
2022-12-14 18:51:36 +02:00
Arun Raghavan 473e7d951b audiofx: Derive from AudioFilter where possible
Saves a little bit of code.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1013>
2022-12-14 10:35:28 -05:00
Michiel Konstapel 3a8536b45e audiornnoise: Add debug output for voice activity to help you choose a threshold
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1010>
2022-12-14 10:00:28 +00:00
Mathieu Duponchelle e5360ff431 webrtc/README: update command to run the signalling server
Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/277

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1012>
2022-12-13 12:47:26 +01:00
Sebastian Dröge 3f904553ea Fix various new clippy warnings
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1011>
2022-12-13 11:43:16 +02:00
Sebastian Dröge 289e8a08c3 webrtchttp: Remove unnecessary clippy warning override
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1009>
2022-12-12 14:32:12 +02:00
Sebastian Dröge 65efdc8c81 gtk4: Only require GTK 4.6 if GL support is enabled
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1007>
2022-12-12 13:49:14 +02:00
Michiel Konstapel 54741b7cc4 audiornnoise: add voice detection threshold
Add a property "voice-activity-threshold". Frames where the voice
detection score from the RNN is below the threshold will be completely
muted.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1004>
2022-12-12 11:55:38 +02:00
Sebastian Dröge a077ecba85 gtk4: Deactivate application GL context again after fill_info()
It does not need to be activate anymore, and keeping it active can cause
problems.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1001>
2022-12-12 10:51:15 +02:00
Jordan Petridis 37b0dab0e8 gtk4: Deactivate the context if we fail to fill_info
Avoid leaving the context activated if we end up erroring out.

Similar to https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3492

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1001>
2022-12-12 10:51:09 +02:00
Guillaume Desmottes d9de2d3d7b textahead: add settings to display previous buffers
I'll use this in Karapulse to keep displaying the few previous lyrics
rather than having them disappear right away.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1006>
2022-12-12 08:31:57 +01:00
Sebastian Dröge fb42cd8a0f net: Update to async-tungstenite 0.19
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1005>
2022-12-11 12:54:24 +02:00
Sebastian Dröge 1ffadbc270 audiorrnoise: Use correct value range for the samples
The nnnoiseless crate wants all samples in the range [-32767,32767]
instead of the [-1,1] range we're using for floating point samples.

Scale before/after processing while (de)interleaving the samples.

Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/276

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1003>
2022-12-10 21:03:28 +02:00
Sebastian Dröge 08c716d110 tttocea608: Don't fail if a gap event contains no duration
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1002>
2022-12-07 14:04:54 +00:00
Sebastian Dröge 99a1e30ab0 webrtchttp: Fix documentation JSON
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/949>
2022-12-05 12:47:04 +02:00
Sebastian Dröge 9b964db4c9 whipsink: Handle offer creation errors more gracefully
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/949>
2022-12-05 12:15:55 +02:00
Sebastian Dröge 8452cd9efa webrtchttp: Fix missing import for docs build
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/949>
2022-12-05 12:10:53 +02:00
Sebastian Dröge 9c31344bbc webrtchttp: Don't use let-else for now
We still support Rust 1.63.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/949>
2022-12-05 12:08:57 +02:00
Sebastian Dröge 5dc52975ff webrtchttp: Fix formatting
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/949>
2022-12-05 12:07:09 +02:00
Sanchayan Maity 40680a47ab webrtchttp: Use tokio runtime for spawning thread used for candidate offer
While at it, we had a bug in whepsrc where for redirect we were
incorrectly calling initial_post_request instead of do_post. Fix
that.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/949>
2022-12-05 12:27:07 +05:30
Sanchayan Maity d18761892e webrtchttp: Use a proper Rust type name for ICE transport policy
We don't need to namespace here but can just use the Rust namespaces.
Only the GType name has to stay like it is.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/949>
2022-12-05 11:04:45 +05:30
Sanchayan Maity 2eba3b321e webrtchttp: Do not import element_imp_error
element_imp_error and such macros should not be imported but rather
only be accessed via gst namespace.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/949>
2022-12-05 11:04:45 +05:30
Sanchayan Maity 0b1b8b91b9 webrtchttp: Do not block webrtcbin signal handlers for sending candidates
While at it, drop the OPTIONS request in WHIP sink. This was not really
required. See section 4.4 of the spec
https://www.ietf.org/archive/id/draft-ietf-wish-whip-01.html#name-stun-turn-server-configurat

Also introduce a new error type and distinguish between a future being
aborted or returning an error.

We call abort only during shutdown and hence except for the DELETE
resource request being aborted, other waits on future should not
be fatal.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/949>
2022-12-05 11:04:45 +05:30
Alba Mendez db39370701 webrtchttp: whipsink: construct TURN URL correctly
Right now the code manually pieces together the components
in a String for efficiency. When credentials contain special
characters this can result in invalid URLs, so do it the proper
way (with Url::parse + format) to make sure components are escaped
as needed.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/949>
2022-12-05 11:04:45 +05:30
Sanchayan Maity 9fb058d5bc webrtchttp: Drop unused dependencies
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/949>
2022-12-05 11:04:45 +05:30
Sanchayan Maity b5daa92c9d webrtchttp: Implement timeout for waiting on futures
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/949>
2022-12-05 11:04:45 +05:30
Sanchayan Maity cc7419308b webrtchttp: whipsink: Add candidates when sending the offer
WHIP endpoint providers like Cloudflare do not support Trickle ICE
and need candidates to be send along with the initial offer. Instead
of sending the offer in create-offer promise, send it once the ICE
candidates have been gathered.

While at it add properties to set STUN and TURN server along with the
ICE transport policy as at least when testing the Cloudflare WHIP
endpoint seems unreachable without it. This has also been observed
with Cloudflare provided demos.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/949>
2022-12-05 11:04:45 +05:30
Sanchayan Maity b992596236 webrtchttp: whipsink: Miscellaneous clean up
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/949>
2022-12-05 11:04:45 +05:30
Sanchayan Maity b427cb6a3d webrtchttp: Factor out the common bits for WHIP and WHEP
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/949>
2022-12-05 11:04:45 +05:30
Sanchayan Maity 6be5796888 Add a WebRTC WHEP source element
This implements WHEP specification based on
https://datatracker.ietf.org/doc/html/draft-murillo-whep-00

and has been tested with Cloudflare.

Server offers are likely to be removed from the WHEP specification
in upcoming revisions, to avoid compatibility issues. None of the
commercial services implementing WHEP support server initiated offers.
So we only support client side initiated offers.

Follows session setup and tear down as covered in Figure 1, Section 3
of the specification.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/949>
2022-12-05 11:04:45 +05:30
Sebastian Dröge 3172bcd095 fmp4mux: Crank clock for the first fragment in more tests
Due to how aggregator works, it depends on how buffers are pulled
whether aggregate() is called again or it is waiting for a timeout or EOS:

works:
  - pad 1: 4 buffers, pad 2: 4 buffers
  - aggregate ready: take all 4/4 buffers
  - pad 1: 1 buffers, pad 2: 1 buffer
  - aggregate ready: take all 1/1 buffers

waits:
  - pad 1: 5 buffers, pad 2: 4 buffers
  - aggregate ready: take all 5/4 buffers
  - pad 1: 0 buffers, pad 2: 1 buffer
  - aggregate not ready: waiting for timeout or EOS

Also don't manually set the clock time as that's unnecessary.

Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/274

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/998>
2022-12-03 18:21:19 +00:00
Sebastian Dröge e6fa7c0b2b ci: Disable gst-build job for now
See https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/262

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/998>
2022-12-03 18:21:19 +00:00
Raphael Dürscheid aa2abc50bf webrtcsink: Support nvv4l2vp9enc
Naive support for nvv4l2vp9enc by assuming configuration is equivalent
to existing nvv4l2vp8enc. Validated to have relevant properties.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/983>
2022-12-02 10:18:27 +00:00
Sebastian Dröge 4604a6368c deny: Remove another dependency that is not duplicated anymore 2022-12-02 11:09:43 +02:00
Seungha Yang 1c145e2ba9 dav1ddec: Lower rank to primary
The rank of AOM av1dec was demoted as secondary, and thus
primary rank is sufficient.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/996>
2022-12-01 17:03:31 +00:00
Sebastian Dröge f9e5a68156 deny: Remove dependencies that are not duplicated anymore 2022-12-01 17:35:09 +02:00
Sebastian Dröge 25b0b15989 rav1e: Update to rav1e 0.6
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/997>
2022-12-01 15:59:44 +02:00
Sebastian Dröge 8c457cfa04 gtk4: example: Use a bin with a videoconvert in the non-GL case
The sink only supports RGB formats in that case, which decoders rarely
would output.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/995>
2022-11-30 11:59:53 +02:00
Sebastian Dröge 599d3a4d8a gtk4: Make GL support fully optional
Don't depend on gstreamer-gl if it's not enabled, and don't try doing
anything with the GDK GL context at all.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/995>
2022-11-30 11:59:53 +02:00
Jordan Petridis 975f0141be video/gtk4: Implement support for GLTextures when possible.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/588>
2022-11-29 21:18:46 +02:00
Jordan Petridis 51c34267a9 video/gtk4: Restrict visibility of struct related to the Frame
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/588>
2022-11-29 21:06:12 +02:00
Jordan Petridis ea6c59e5e9 video/gtk4: Rename Object types and struct to something simpler
Avoid the confusion caused by SinkPaintable and PaintableSink,
and instead refer to the objects as Paintable for the GdkPaintable
subclass or PaintalbeSink for the gst element.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/588>
2022-11-29 21:06:12 +02:00
Jordan Petridis a84eeeb240 mux/{mp4, fmp4}: Hard depend on feature v1_18
Else --no-default-features was failing to compile.

v1_18 is needed to for the aggregator code.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/588>
2022-11-29 21:06:12 +02:00
Jordan Petridis 821c23e202 net/ndi: fix build with --no-default-features
doc_show_default() is only available with gst/v1_18

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/588>
2022-11-29 21:06:12 +02:00
Jordan Petridis b75483e597 meson: Fix build of static plugins
While we were correctly skipping the plugins that couldn't be
built statically, we were still adding their names to the list
and the .pc list causing them to still get built.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/994>
2022-11-29 20:04:25 +02:00
Jordan Petridis 12c058bc49 meson: Fix build of static plugins
While we were correctly skipping the plugins that couldn't be
built statically, we were still adding their names to the list
and the .pc list causing them to still get built.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/994>
2022-11-29 20:03:29 +02:00
Sebastian Dröge 76eeaffbb2 textwrap: Don't panic on empty buffers
Simply don't calculate with any duration per word for this buffer.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/990>
2022-11-29 12:18:25 +00:00
Vivia Nikolaidou 5bbe0eab25 ndisrc: Use actual number of channels in positions_from_mask
Otherwise it fails for mono and stereo

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/991>
2022-11-29 12:19:45 +02:00
Vivia Nikolaidou 73ce616bd9 ndisrc: Use default channel mask for audio output
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/988>
2022-11-28 17:06:07 +02:00
Sebastian Dröge 72f616fa14 deny: Update 2022-11-28 10:58:03 +02:00
Sebastian Dröge fceacf7081 Update for gst::Array / gst::List API improvements
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/985>
2022-11-27 01:12:46 +02:00
Sebastian Dröge 0e2a00cbc8 aws: Update to env_logger 0.10 for the tests
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/984>
2022-11-25 11:08:19 +02:00
Sebastian Dröge 1fcbc346bc fmp4mux: examples: Avoid unnecessary caps copies 2022-11-22 10:39:47 +02:00
Sebastian Dröge 45fa946e8b tracer: buffer-lateness: Fix compilation after minor API change 2022-11-22 10:39:32 +02:00
Sebastian Dröge 79972f8305 deny: Update 2022-11-20 11:52:32 +02:00
Sebastian Dröge 6b3bb2c747 fmp4mux: Handle EOS correctly if it happens before a fragment start time was determined
Whatever earliest time we have at that point is going to be the start
time.

Also handle the case correctly where all inputs are EOS before any
buffers were received at all.

Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/270

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/982>
2022-11-19 19:24:43 +02:00
Sebastian Dröge e3f645af19 fmp4mux: Don't overflow negative composition offset calculation
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/982>
2022-11-19 19:24:04 +02:00
Sebastian Dröge ae4b49c668 mp4mux: For video with N/1001 framerates use N as timescale
See https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3049

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/981>
2022-11-18 16:10:10 +02:00
Sebastian Dröge fd910cb828 fmp4mux: For video with N/1001 framerates use N as timescale
See https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3049

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/981>
2022-11-18 16:07:11 +02:00
Sebastian Dröge c553ac7402 fmp4mux: Re-work buffer dequeueing and calculations of timestamps
Especially simplify calculation of ONVIF UTC times. As a side-effect
this reduces the number of times the running times of a buffer are
calculated, and also causes streams to be interleaved correctly in ONVIF
mode if there is a non-constant UTC-to-running-time difference.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/979>
2022-11-18 15:00:00 +02:00
Sebastian Dröge 3003987c3a mp4mux: Make use of i64::TryFrom<gst::Signed<u64>> impl
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/979>
2022-11-18 12:26:18 +02:00
Sebastian Dröge 9903d536b5 mp4mux: Factor out running time to UTC time calculation into a function
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/979>
2022-11-18 12:21:25 +02:00
Sebastian Dröge aa7fd34097 mp4mux: Remove unnecessary error case of negative PTS when doing the ONVIF UTC time calculations
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/979>
2022-11-18 12:21:25 +02:00
Sebastian Dröge 02fc343642 gif: Update to gif 0.12
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/980>
2022-11-18 09:03:21 +00:00
Sebastian Dröge 456fb276d6 Revert "Update for pango API changes"
This reverts commit 6e54d3cea9.

The change was wrong and the pango bindings work the same as before
again.
2022-11-18 10:58:41 +02:00
Sebastian Dröge 6e54d3cea9 Update for pango API changes
pango::Language::from_string() can fail and also can accept None as
argument.
2022-11-18 09:46:50 +02:00
Sebastian Dröge 1981ffbea0 Provide explicit type to Iterator::sum() calls to avoid ambiguity 2022-11-17 10:16:26 +02:00
Thibault Saunier 6b11284e8a webrtcsink: Make the turn-server prop a turn-servers list
So that we can simply specify several turn servers at once

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/973>
2022-11-16 14:48:16 +00:00
Guillaume Desmottes 2642410702 spotify: fix "start a runtime from within a runtime" with static link
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/976>
2022-11-16 13:20:38 +01:00
Arun Raghavan 3abd13e57b aws: s3sink: Treat stopping without EOS as an error for multipart upload
This allows us to try to clean up based on configuration (abort /
complete / do nothing) if the pipeline is shut down without an EOS.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/970>
2022-11-15 02:28:35 +00:00
Sebastian Dröge bf9f7a747e closedcaption: Update for deprecated chrono functions
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/978>
2022-11-12 18:41:08 +02:00
Sebastian Dröge 3094bd96df version-helper: Update for deprecated chrono functions
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/978>
2022-11-12 18:24:48 +02:00
Guillaume Desmottes 37cb636140 webrtc: README: fix couple of links
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/975>
2022-11-11 14:51:46 +01:00
Mathieu Duponchelle 66e7b314f7 webrtcsink: improve debug
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/972>
2022-11-10 15:00:19 +00:00
Sebastian Dröge 4d310434ab mp4mux: Skip gap buffers instead of writing empty samples
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/974>
2022-11-10 12:59:53 +02:00
Sebastian Dröge 2b4fd40d62 mp4: Add ONVIF non-fragmented MP4 muxer
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/974>
2022-11-10 12:59:53 +02:00
Sebastian Dröge 97bb327b2a mp4: Remove unneeded cast in tests
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/974>
2022-11-10 12:44:46 +02:00
Tim-Philipp Müller 8d1c7cef3e ci: add trigger job and only run documentation job post-merge
- require manual trigger to run pipeline on branches and MRs
- require manual trigger to run pipeline post-merge (excl. docs)

https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/issues/417

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/965>
2022-11-09 20:47:22 +02:00
Tim-Philipp Müller cc8d84330c ci: add integration stage and move documentation job to that
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/965>
2022-11-09 20:37:43 +02:00
François Laignel e1afa43aa3 ts/udpsink: handle items in the PadSinkHandler
... instead of forwarding them to a Task via a channel.

This improves CPU usage by 5% according to `udpsrc-benchmark-sender`
with the `tuning` feature using default audio test buffers and
400 streams on the same ts-context.

It is expected to improve latency significantly. This is inferred
from `ts-standalone`: latency shrinks from around 5ms to 1.5µs
using the `task` sink compared to the `async-mutex` sink.

The async Mutex is mandatory here as we need to hold the lock
across await points.
2022-11-09 07:55:04 +00:00
François Laignel 29a490f6dc ts: introduce ts-audiotestsrc
This makes it easy to generate "listenable" signals and to evaluate
discontinuities.

When the `tuning` feature is activated and the `main-elem` property
is set, the element can log the parked duration in %, which is an
image of the CPU usage for the ts-context.

This commit adds a test mode to `udpsrc-benchmark-sender` which
generates default audio buffers from `ts-audiotestsrc`. The `rtp`
mode is modified so that it uses `ts-audiotestsrc`.
2022-11-09 07:55:04 +00:00
François Laignel 9b96cfc452 ts/standalone: add new Sinks
Contrary to the existing Task Sink, the Async and Sync Mutex Sinks
handle buffers in the `PadSinkHandler` directly. The Async Mutex
Sink uses an async Mutex for the `PadSinkHandlerInner` while the
Sync Mutex Sink uses... a sync Mutex.

All Sinks share the same settings and stats manager.

Use the `--sink` command line option to select the sink (default is
`sync-mutex` since it allows evaluating the framework with as little
overhead as possible.

Also apply various fixes:

- Only keep the segment start instead of the full `Segment`. This
  helps with cache locality (`Segment` is a plain struct with many
  fields) and avoids downcasting the generic `Segment` upon each
  buffer handling.
- Box the `Stat`s. This should improve cache locality a bit.
- Fix EOS handling which took ages for no benefits in this
  particular use case.
- Use a macro to raise log level in the main element.
- Move error handling during item processing in `handle_loop_error`.
  This function was precisely designed for this and it should reduce
  the `handle_item`'s Future size.
2022-11-09 07:55:04 +00:00
François Laignel 4616f0a4a4 ts/standalone: move current sink under task_sink 2022-11-09 07:55:04 +00:00
Sebastian Dröge f22be3a586 deny: Update 2022-11-09 09:15:55 +02:00
Sebastian Dröge 10d8cc21e6 mp4: Update to url 2 2022-11-09 09:15:50 +02:00
Sebastian Dröge 360e4275ed threadshare: Update to concurrent-queue 2 2022-11-09 09:15:38 +02:00
Sebastian Dröge c2f403f998 gst-plugin-mp4: Add new MP4 plugin with a non-fragmented MP4 muxer 2022-11-08 19:08:47 +02:00
Sebastian Dröge a5f3197651 Add missing doc features to WebRTC plugins 2022-11-07 18:06:29 +00:00
Sebastian Dröge f062b7cf0d fmp4mux: Make media/trak timescales configurable
And refactor a bit of code for easier extensibility.
2022-11-07 18:06:29 +00:00
Sebastian Dröge e87251c7d9 ci: Update to cargo-c 0.9.14 2022-11-05 16:26:23 +00:00
Jan Beich d01779dc6c meson: optionalize pango dependency used by net/onvif
Similar to -Dpango=<auto|enabled|disabled> in gst-plugins-base.
2022-11-05 08:19:12 +00:00
Jan Beich 9aeaac5a96 ndi: provide Unix fallback after 3fe9e4a207
error[E0425]: cannot find value `LIBRARY_NAME` in this scope
   --> net/ndi/src/ndisys.rs:336:23
    |
336 |             path.push(LIBRARY_NAME);
    |                       ^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find value `LIBRARY_NAME` in this scope
   --> net/ndi/src/ndisys.rs:339:33
    |
339 |             path::PathBuf::from(LIBRARY_NAME)
    |                                 ^^^^^^^^^^^^ not found in this scope
2022-11-05 02:51:28 +00:00
Sebastian Dröge 7ac29827d2 fmp4mux: Don't allow VP9 for CMAF
This would require setting the correct compatible band for VP9 in CMAF,
which is not implemented yet.
2022-11-03 16:53:01 +02:00
Sebastian Dröge 6706f3a4b4 fmp4mux: Add initial Opus support
Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/239
2022-11-03 16:53:01 +02:00
Sebastian Dröge 9504e4d540 docs: Remove some stale entries of renamed elements 2022-11-03 15:09:20 +02:00
Arun Raghavan 54c84a7211 aws: Skip s3 test on Windows until we figure out why it times out 2022-11-02 13:14:08 -04:00
Sebastian Dröge ba20fc735e ci: Only warn about unknown lints instead of denying 2022-11-01 11:27:01 +02:00
Sebastian Dröge a8250abbf1 Fix various new clippy warnings 2022-11-01 10:27:48 +02:00
Sebastian Dröge 31d4ba2eae fmp4mux: For VP9, write resolution into the tkhd and include a stss box to signal that not all frames are sync samples
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/957>
2022-10-31 15:20:19 +02:00
Sebastian Dröge 976ae5707e webrtc: Update to human_bytes 0.4 2022-10-31 14:11:29 +02:00
Sebastian Dröge 6ceeadc0f0 aws: Update to aws 0.21/0.51 2022-10-31 14:11:29 +02:00
Sebastian Dröge 7106b0484d fmp4mux: Remove unused uuid dependency 2022-10-28 12:45:42 +03:00
Sebastian Dröge 938f4e4f1c fmp4mux: Clip negative PTS to zero/last PTS instead of erroring out
This can happen at the beginning of a stream if upstream is
rtpjitterbuffer and it has problems figuring out timestamps in the
beginning due to resetting / skew.
2022-10-27 14:47:16 +03:00
Sebastian Dröge 627bf756b1 fmp4mux: Send force-keyunit events for now if the ideal position has already passed 2022-10-27 12:53:09 +03:00
Sebastian Dröge a56435801d fmp4mux: Add debug log when writing the mfra box 2022-10-26 17:22:20 +00:00
Sebastian Dröge 27fac33c44 fmp4mux: Reset timing infos to None if a stream only contained gap events for a whole fragment 2022-10-26 17:22:20 +00:00
Sebastian Dröge cab4cd3b8c fmp4mux: If a stream is longer than the main stream at EOS, simply include all of its buffers in the last fragment nonetheless 2022-10-26 17:22:20 +00:00
Sebastian Dröge ce166b4d8f whipsink: Add object to debug logs 2022-10-26 16:20:26 +03:00
Matthew Waters d067fb2ec8 fmp4mux: don't require dts for predictive-only formats like vp9 2022-10-26 11:42:13 +00:00
Guillaume Desmottes d46857d3b1 aws: fix title in README
The title was not matching the actual plugin name which was confusing.
2022-10-26 11:13:47 +02:00
Sebastian Dröge 4c7dfceb9a deny: Update 2022-10-25 11:03:32 +03:00
Matthew Waters 8c8384c711 fmp4: add support for muxing VP9 streams in cmaf, dash and iso fmp4
As specified in https://www.webmproject.org/vp9/mp4/
2022-10-25 18:33:42 +11:00
Sebastian Dröge bf6bdab80c webrtc: Remove version requirement from internal crate dependencies 2022-10-24 19:50:24 +03:00
Sebastian Dröge f2223cf2cb Update versions to 0.10.0-alpha.1 2022-10-24 19:31:19 +03:00
686 changed files with 98805 additions and 26609 deletions

4
.gitignore vendored
View file

@ -1,7 +1,7 @@
Cargo.lock
target
*~
*.bk
*.swp
.vscode
builddir
builddir
.meson-subproject-wrap-hash.txt

View file

@ -1,4 +1,4 @@
.templates_sha: &templates_sha 567700e483aabed992d0a4fea84994a0472deff6
.templates_sha: &templates_sha fddab8aa63e89a8e65214f59860d9c0f030360c9
include:
- project: 'freedesktop/ci-templates'
@ -6,7 +6,7 @@ include:
file: '/templates/debian.yml'
- project: 'gstreamer/gstreamer-rs'
ref: '0.19'
ref: main
file: '/ci/images_template.yml'
- project: 'gstreamer/gstreamer'
@ -14,12 +14,14 @@ include:
file: '/.gitlab-image-tags.yml'
variables:
FDO_UPSTREAM_REPO: gstreamer/gst-plugins-rs
FDO_UPSTREAM_REPO: gstreamer/gstreamer-rs
# We use GStreamer image to build the documentation as it is the simplest way
# to ensure that we are testing against the same thing as GStreamer itself.
# The tag name is included above from the main repo.
GSTREAMER_DOC_IMAGE: "registry.freedesktop.org/gstreamer/gstreamer/amd64/fedora:$FEDORA_TAG-main"
# Use the gstreamer image to trigger the cerbero job, same as the monorepo
CERBERO_TRIGGER_IMAGE: "registry.freedesktop.org/gstreamer/gstreamer/amd64/fedora:$FEDORA_TAG-main"
WINDOWS_BASE: "registry.freedesktop.org/gstreamer/gstreamer-rs/windows"
WINDOWS_RUST_MINIMUM_IMAGE: "$WINDOWS_BASE:$GST_RS_IMG_TAG-main-$GST_RS_MSRV"
WINDOWS_RUST_STABLE_IMAGE: "$WINDOWS_BASE:$GST_RS_IMG_TAG-main-$GST_RS_STABLE"
@ -39,7 +41,6 @@ default:
stages:
- "trigger"
- "prep"
- "lint"
- "test"
- "extras"
@ -51,6 +52,7 @@ trigger:
stage: 'trigger'
variables:
GIT_STRATEGY: none
tags: [ 'placeholder-job' ]
script:
- echo "Trigger job done, now running the pipeline."
rules:
@ -66,121 +68,26 @@ trigger:
when: 'manual'
allow_failure: false
.debian:11:
variables:
FDO_DISTRIBUTION_VERSION: 'bullseye-slim'
before_script:
- source ./ci/env.sh
- mkdir .cargo && echo -e "[net]\ngit-fetch-with-cli = true" > .cargo/config
.debian:11-stable:
extends: .debian:11
variables:
FDO_DISTRIBUTION_TAG: '$GST_RS_STABLE-${GST_RS_IMG_TAG}_2022-11-05.0'
FDO_BASE_IMAGE: "registry.freedesktop.org/gstreamer/gstreamer-rs/debian/bullseye-slim:$GST_RS_STABLE-$GST_RS_IMG_TAG"
.debian:11-msrv:
extends: .debian:11
variables:
FDO_DISTRIBUTION_TAG: '$GST_RS_MSRV-${GST_RS_IMG_TAG}_2022-11-05.0'
FDO_BASE_IMAGE: "registry.freedesktop.org/gstreamer/gstreamer-rs/debian/bullseye-slim:$GST_RS_MSRV-$GST_RS_IMG_TAG"
.debian:11-nightly:
extends: .debian:11
variables:
FDO_DISTRIBUTION_TAG: 'nightly-${GST_RS_IMG_TAG}_2022-11-05.0'
FDO_BASE_IMAGE: "registry.freedesktop.org/gstreamer/gstreamer-rs/debian/bullseye-slim:nightly-$GST_RS_IMG_TAG"
.build-debian-container:
extends:
- .fdo.container-build@debian
stage: prep
variables:
FDO_DISTRIBUTION_PACKAGES: "libcsound64-dev llvm clang nasm libsodium-dev libwebp-dev python3-pip"
FDO_DISTRIBUTION_EXEC: >-
bash ci/install-dav1d.sh &&
apt clean &&
bash ./ci/install-rust-ext.sh &&
pip install tomli
needs:
- "trigger"
rules:
- if: '$UPDATE_IMG == null'
build-stable:
extends:
- .build-debian-container
- .debian:11-stable
build-msrv:
extends:
- .build-debian-container
- .debian:11-msrv
build-nightly:
extends:
- .build-debian-container
- .debian:11-nightly
# Those jobs are triggered by gstreamer-rs when updating its images
update-stable:
extends: build-stable
rules:
- if: '$UPDATE_IMG == "stable"'
variables:
FDO_FORCE_REBUILD: 1
update-msrv:
extends: build-msrv
rules:
- if: '$UPDATE_IMG == "msrv"'
variables:
FDO_FORCE_REBUILD: 1
update-nightly:
extends: build-nightly
rules:
- if: '$UPDATE_IMG == "nightly"'
variables:
FDO_FORCE_REBUILD: 1
.dist-debian-container:
extends:
- .fdo.distribution-image@debian
.debian:12:
variables:
SODIUM_USE_PKG_CONFIG: "true"
after_script:
- rm -rf target
before_script:
- source ./ci/env.sh
- mkdir .cargo && echo -e "[net]\ngit-fetch-with-cli = true" > .cargo/config
.img-stable:
extends:
- .dist-debian-container
- .debian:11-stable
needs:
- job: 'build-stable'
optional: true
- job: 'update-stable'
optional: true
.debian:12-stable:
extends: .debian:12
image: "registry.freedesktop.org/gstreamer/gstreamer-rs/debian/bookworm-slim:$GST_RS_STABLE-$GST_RS_IMG_TAG"
.img-msrv:
extends:
- .dist-debian-container
- .debian:11-msrv
needs:
- job: 'build-msrv'
optional: true
- job: 'update-msrv'
optional: true
.debian:12-msrv:
extends: .debian:12
image: "registry.freedesktop.org/gstreamer/gstreamer-rs/debian/bookworm-slim:$GST_RS_MSRV-$GST_RS_IMG_TAG"
.img-nightly:
extends:
- .dist-debian-container
- .debian:11-nightly
needs:
- job: 'build-nightly'
optional: true
- job: 'update-nightly'
optional: true
.debian:12-nightly:
extends: .debian:12
image: "registry.freedesktop.org/gstreamer/gstreamer-rs/debian/bookworm-slim:nightly-$GST_RS_IMG_TAG"
.cargo test:
stage: "test"
@ -193,47 +100,43 @@ update-nightly:
- cargo build --locked --color=always --workspace --all-targets
- G_DEBUG=fatal_warnings cargo test --locked --color=always --workspace --all-targets
- cargo build --locked --color=always --workspace --all-targets --all-features
- G_DEBUG=fatal_warnings cargo test --locked --color=always --workspace --all-targets --all-features
- cargo build --locked --color=always --workspace --all-targets --all-features --exclude gst-plugin-gtk4
- G_DEBUG=fatal_warnings cargo test --locked --color=always --workspace --all-targets --all-features --exclude gst-plugin-gtk4
- cargo build --locked --color=always --workspace --all-targets --no-default-features
- G_DEBUG=fatal_warnings cargo test --locked --color=always --workspace --all-targets --no-default-features
test msrv:
extends:
- '.cargo test'
- .img-msrv
rules:
- if: '$UPDATE_IMG == null || $UPDATE_IMG == "msrv"'
- '.debian:12-msrv'
needs: [ "trigger" ]
test stable:
extends:
- '.cargo test'
- .img-stable
rules:
- if: '$UPDATE_IMG == null || $UPDATE_IMG == "stable"'
- '.debian:12-stable'
needs: [ "trigger" ]
test nightly:
allow_failure: true
extends:
- '.cargo test'
- .img-nightly
rules:
- if: '$UPDATE_IMG == null || $UPDATE_IMG == "nightly"'
- '.debian:12-nightly'
needs: [ "trigger" ]
.meson:
extends: .img-stable
rules:
- if: '$UPDATE_IMG == null || $UPDATE_IMG == "stable"'
extends: .debian:12-stable
variables:
# csound-sys only looks at /usr/lib and /usr/local top levels
CSOUND_LIB_DIR: '/usr/lib/x86_64-linux-gnu/'
meson shared:
extends: .meson
needs: [ "trigger" ]
variables:
CI_ARTIFACTS_URL: "${CI_PROJECT_URL}/-/jobs/${CI_JOB_ID}/artifacts/raw/"
script:
- meson build --default-library=shared --prefix=$(pwd)/install
- meson build --default-library=shared --prefix=$(pwd)/install --fatal-meson-warnings
- ninja -C build install
- ./ci/check-installed.py install
- ninja -C build docs/gst_plugins_cache.json
@ -247,6 +150,7 @@ meson shared:
meson static:
extends: .meson
needs: [ "trigger" ]
script:
- meson build --default-library=static --prefix=$(pwd)/install -Dsodium-source=built-in
- ninja -C build install
@ -384,64 +288,97 @@ test windows stable:
image: "$WINDOWS_RUST_STABLE_IMAGE"
rustfmt:
extends: .img-stable
extends: '.debian:12-stable'
stage: "lint"
rules:
- when: 'always'
tags: [ 'placeholder-job' ]
needs: []
script:
- cargo fmt --version
- cargo fmt -- --color=always --check
check commits:
extends: .img-stable
typos:
extends: '.debian:12-stable'
stage: "lint"
rules:
- when: 'always'
tags: [ 'placeholder-job' ]
needs: []
script:
- typos
gstwebrtc-api lint:
image: node:lts
stage: "lint"
tags: [ 'placeholder-job' ]
needs: []
script:
- cd net/webrtc/gstwebrtc-api
- npm install
- npm run check
check commits:
extends: '.debian:12-stable'
stage: "lint"
tags: [ 'placeholder-job' ]
needs: []
script:
- ci-fairy check-commits --textwidth 0 --no-signed-off-by
- ci/check-for-symlinks.sh
- ci/check-meson-version.sh
clippy:
extends: .img-stable
extends: '.debian:12-stable'
needs:
- "trigger"
- "test stable"
stage: 'extras'
variables:
# csound-sys only looks at /usr/lib and /usr/local top levels
CSOUND_LIB_DIR: '/usr/lib/x86_64-linux-gnu/'
rules:
- when: 'always'
script:
- cargo clippy --locked --color=always --all --all-features --all-targets -- -D warnings
- cargo clippy --locked --color=always --all --all-targets -- -D warnings -A unknown-lints
- cargo clippy --locked --color=always --all --all-features --all-targets --exclude gst-plugin-gtk4 -- -D warnings -A unknown-lints
- cargo clippy --locked --color=always --all --all-targets --no-default-features -- -D warnings -A unknown-lints
deny:
extends: .img-stable
extends: .debian:12-stable
stage: 'extras'
needs:
- "trigger"
- "test stable"
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'
script:
- cargo deny check
- cargo update --color=always
- cargo deny --color=always --workspace --all-features check all
outdated:
extends: .img-stable
extends: '.debian:12-stable'
allow_failure: true
needs:
- "trigger"
- "test stable"
stage: 'extras'
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'
script:
- cargo outdated --root-deps-only --exit-code 1 -v
- cargo update --color=always
# env_logger is ignored because it requires Rust >= 1.71
- cargo outdated --color=always --root-deps-only --ignore env_logger --exit-code 1 -v
coverage:
allow_failure: true
extends:
- .img-stable
- '.debian:12-stable'
needs:
- "trigger"
- "test stable"
stage: 'extras'
rules:
- when: 'always'
variables:
RUSTFLAGS: "-Cinstrument-coverage"
LLVM_PROFILE_FILE: "gst-plugins-rs-%p-%m.profraw"
# csound-sys only looks at /usr/lib and /usr/local top levels
CSOUND_LIB_DIR: '/usr/lib/x86_64-linux-gnu/'
script:
- cargo test --locked --color=always --all --all-features
- cargo test --locked --color=always --all --all-features --exclude gst-plugin-gtk4
# generate html report
- grcov . --binary-path ./target/debug/ -s . -t html --branch --ignore-not-existing --ignore "*target*" --ignore "*/build.rs" -o ./coverage/
# generate cobertura report for gitlab integration
@ -456,3 +393,34 @@ coverage:
coverage_report:
coverage_format: cobertura
path: coverage.xml
cerbero trigger:
image: $CERBERO_TRIGGER_IMAGE
needs: [ "trigger" ]
variables:
# We will build this cerbero branch in the cerbero trigger CI
CERBERO_UPSTREAM_BRANCH: 'main'
script:
- ci/cerbero/trigger_cerbero_pipeline.py
rules:
# Never run post merge
- if: '$CI_PROJECT_NAMESPACE == "gstreamer"'
when: never
# Don't run if the only changes are files that cargo-c does not read
- if:
changes:
- "CHANGELOG.md"
- "README.md"
- "deny.toml"
- "rustfmt.toml"
- "typos.toml"
- "*.py"
- "*.sh"
- "Makefile"
- "meson.build"
- "meson_options.txt"
- "**/meson.build"
- "ci/*.sh"
- "ci/*.py"
when: never
- when: always

View file

@ -0,0 +1,33 @@
### Describe your issue
<!-- a clear and concise summary of the bug. -->
<!-- For any GStreamer usage question, please contact the community using the #gstreamer channel on IRC https://www.oftc.net/ or the mailing list on https://gstreamer.freedesktop.org/lists/ -->
#### Expected Behavior
<!-- What did you expect to happen -->
#### Observed Behavior
<!-- What actually happened -->
#### Setup
- **Operating System:**
- **Device:** Computer / Tablet / Mobile / Virtual Machine <!-- Delete as appropriate !-->
- **gst-plugins-rs Version:**
- **GStreamer Version:**
- **Command line:**
### Steps to reproduce the bug
<!-- please fill in exact steps which reproduce the bug on your system, for example: -->
1. open terminal
2. type `command`
### How reproducible is the bug?
<!-- The reproducibility of the bug is Always/Intermittent/Only once after doing a very specific set of steps-->
### Screenshots if relevant
### Solutions you have tried
### Related non-duplicate issues
### Additional Information
<!-- Any other information such as logs. Make use of <details> for long output -->

457
CHANGELOG.md Normal file
View file

@ -0,0 +1,457 @@
# Changelog
All notable changes to this project will be documented in this file.
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.12.6] - 2024-05-23
### Fixed
- Various Rust 1.78 clippy warnings.
- gtk4paintablesink: Fix plugin description.
### Added
- fmp4mux / mp4mux: Add support for adding AV1 header OBUs into the MP4
headers.
- fmp4mux / mp4mux: Take track language from the tags if provided.
- gtk4paintablesink: Add GST_GTK4_WINDOW_FULLSCREEN environment variable to
create a fullscreen window for debugging purposes.
- gtk4paintablesink: Also create a window automatically when called from
gst-play-1.0.
- webrtc: Add support for insecure TLS connections.
- webrtcsink: Add VP9 parser after the encoder.
### Changed
- webrtcsink: Improve error when no discovery pipeline runs.
- rtpgccbwe: Improve debug output in various places.
## [0.12.5] - 2024-04-29
### Fixed
- hrtfrender: Use a bitmask instead of an int in the caps for the channel-mask.
- rtpgccbwe: Don't log an error when pushing a buffer list fails while stopping.
- webrtcsink: Don't panic in bitrate handling with unsupported encoders.
- webrtcsink: Don't panic if unsupported input caps are used.
- webrtcsrc: Allow a `None` producer-id in `request-encoded-filter` signal.
### Added
- aws: New property to support path-style addressing.
- fmp4mux / mp4mux: Support FLAC instead (f)MP4.
- gtk4: Support directly importing dmabufs with GTK 4.14.
- gtk4: Add force-aspect-ratio property similar to other video sinks.
## [0.12.4] - 2024-04-08
### Fixed
- aws: Use fixed behaviour version to ensure that updates to the AWS SDK don't
change any defaults configurations in unexpected ways.
- onvifmetadataparse: Fix possible deadlock on shutdown.
- webrtcsink: Set `perfect-timestamp=true` on audio encoders to work around
bugs in Chrome's audio decoders.
- Various clippy warnings.
### Changed
- reqwest: Update to reqwest 0.12.
- webrtchttp: Update to reqwest 0.12.
## [0.12.3] - 2024-03-21
### Fixed
- gtk4paintablesink: Fix scaling of texture position.
- janusvrwebrtcsink: Handle 64 bit numerical room ids.
- janusvrwebrtcsink: Don't include deprecated audio/video fields in publish
messages.
- janusvrwebrtcsink: Handle various other messages to avoid printing errors.
- livekitwebrtc: Fix shutdown behaviour.
- rtpgccbwe: Don't forward buffer lists with buffers from different SSRCs to
avoid breaking assumptions in rtpsession.
- sccparse: Ignore invalid timecodes during seeking.
- webrtcsink: Don't try parsing audio caps as video caps.
### Changed
- webrtc: Allow resolution and framerate changes.
- webrtcsrc: Make produce-peer-id optional.
### Added
- livekitwebrtcsrc: Add new LiveKit source element.
- regex: Add support for configuring regex behaviour.
- spotifyaudiosrc: Document how to use with non-Facebook accounts.
- webrtcsrc: Add `do-retransmission` property.
## [0.12.2] - 2024-02-26
### Fixed
- rtpgccbwe: Don't reset PTS/DTS to `None` as otherwise `rtpsession` won't be
able to generate valid RTCP.
- webrtcsink: Fix usage with 1.22.
### Added
- janusvrwebrtcsink: Add `secret-key` property.
- janusvrwebrtcsink: Allow for string room ids and add `string-ids` property.
- textwrap: Don't split on all whitespaces, especially not on non-breaking
whitespace.
## [0.12.1] - 2024-02-13
### Added
- gtk4: Create a window for testing purposes when running in `gst-launch-1.0`
or if `GST_GTK4_WINDOW=1` is set.
- webrtcsink: Add `msid` property.
## [0.12.0] - 2024-02-08
### Changed
- ndi: `ndisrc` passes received data downstream without an additional copy, if
possible.
- webrtc: Cleanups to webrtcsrc/sink default signalling protocol, JavaScript
implementation and server implementation.
- webrtc: `whipwebrtcsink` is renamed to `whipclientsink` and deprecate old
`whipsink`.
### Fixed
- gtk4: Fix Windows build when using EGL.
- gtk4: Fix ARGB pre-multiplication with GTK 4.14. This requires building with
the `gtk_v4_10` or even better `gtk_v4_14` feature.
- gtk4: Fix segfault if GTK3 is used in the same process.
- gtk4: Always draw background behind the video frame and not only when
borders have to be added to avoid glitches.
- livekitwebrtcsink: Add high-quality layer for video streams.
- webrtc: Fix potential hang and fd leak in signalling server.
- webrtc: Fix closing of WebSockets.
- webrtchttp: Allow setting `None` for audio/video caps for WHEP.
### Added
- New `awss3putobjectsink` that works similar to `awss3sink` but with a
different upload strategy.
- New `hlscmafsink` element for writing HLS streams with CMAF/ISOBMFF
fragments.
- New `inter` plugin with `intersink` / `intersrc` elements that allow to
connect different pipelines in the same process.
- New `janusvrwebrtcsink` element for the Janus VideoRoom API.
- New `rtspsrc2` element.
- New `whipserversrc` element.
- gtk4: New `background-color` property for setting the color of the
background of the frame and the borders, if any.
- gtk4: New `scale-filter` property for defining how to scale the frames.
- livesync: Add support for image formats.
- ndi: Closed Caption support in `ndisrc` / `ndisink`.
- textwrap: Add support for gaps.
- tracers: Optionally only show late buffers in `buffer-lateness` tracer.
- webrtc: Add support for custom headers.
- webrtcsink: New `payloader-setup` signal to configure payloader elements.
- webrtcsrc: Support for navigation events.
## [0.11.3] - 2023-12-18
### Fixed
- ndi: Mark a private type as such and remove a wrong `Clone` impl of internal types.
- uriplaylistbin: Fix a minor clippy warning.
- fallbacksrc: Fix error during badly timed timeout scheduling.
- webrtcsink: Fail gracefully if webrtcbin pads can't be requested instead of
panicking.
- threadshare: Fix deadlock in `ts-udpsrc` `notify::used-socket` signal
emission.
### Changed
- Update to AWS SDK 1.0.
- Update to windows-sys 0.52.
- Update to async-tungstenite 0.24.
- Update to bitstream-io 2.0.
- tttocea608: De-duplicate some functions.
- gtk4: Use async-channel instead of deprecated GLib main context channel.
## [0.11.2] - 2023-11-11
### Fixed
- filesink / s3sink: Set `sync=false` to allow processing faster than
real-time.
- hlssink3: Various minor bugfixes and cleanups.
- livesync: Various minor bugfixes and cleanups that should make the element
work more reliable.
- s3sink: Fix handling of non-ASCII characters in URIs and keys.
- sccparse: Parse SCC files that are incorrectly created by CCExtractor.
- ndisrc: Assume > 8 channels are unpositioned.
- rtpav1depay: Skip unexpected leading fragments instead of repeatedly warning
about the stream possibly being corrupted.
- rtpav1depay: Don't push stale temporal delimiters downstream but wait until
a complete OBU is collected.
- whipwebrtcsink: Use correct URL during redirects.
- webrtcsink: Make sure to not miss any ICE candidates.
- webrtcsink: Fix deadlock when calling `set-local-description`.
- webrtcsrc: Fix reference cycles that prevented the element from being freed.
- webrtcsrc: Define signaller property as `CONSTRUCT_ONLY` to make it actually
possible to set different signallers.
- webrtc: Update livekit signaller to livekit 0.2.
- meson: Various fixes to the meson-based build system.
### Added
- audiornnoise: Attach audio level meta to output buffers.
- hlssink3: Allow adding `EXT-X-PROGRAM-DATE-TIME` tag to the manifest.
- webrtcsrc: Add `turn-servers` property.
### Changed
- aws/webrtc: Update to AWS SDK 0.57/0.35.
## [0.11.1] - 2023-10-04
### Fixed
- fallbackswitch: Fix various deadlocks.
- webrtcsink: Gracefully fail if adding the TWCC RTP header extension fails.
- webrtcsink: Fix codec selection discovery.
- webrtcsink: Add support for D3D11 memory and qsvh264enc.
- onvifmetadataparse: Skip metadata frames with unrepresentable UTC times.
- gtk4paintablesink: Pre-multiply alpha when creating GL textures with alpha.
- gtk4paintablesink: Only support RGBA/RGB in the GL code path.
- webrtchttp: Respect HTTP redirects.
- fmp4mux: Specify unit of fragment-duration property.
### Changed
- threadshare: Port to polling 3.1.
## [0.11.0] - 2023-08-10
### Changed
- Updated MSRV to 1.70.
- Compatible with gtk-rs 0.18 and gstreamer-rs 0.21.
- awstranscriber: Move to HTTP2-based API via the aws-sdk-transcribestreaming
crate instead of our own implementation around the WebSocket API.
### Added
- webrtcsink: Add AWS KVS signaller and corresponding aws-kvs-webrtcsink
element.
- awstranscriber / transcriberbin: Add support for translations and outputting
transcriptions from a single audio stream in multiple languages at once.
- gstwebrtc-api: JavaScript API for interacting with the default signalling
protocol used by webrtcsink / webrtcsrc.
- cea608to708: New element for converting CEA608 to CEA708 closed captions.
- webrtcsink: Expose the signaller as property and allow implementing a
custom signaller by connecting signal handlers to the default signaller.
- webrtcsink: Add support for pre-encoded streams.
- togglerecord: Add support for non-live input streams.
- webrtcsink: New whipwebrtcsink that implements WHIP around webrtcsink.
The existing whipsink still exists but will sooner or later be deprecated.
- webrtcsink: Add LiveKit signaller and corresponding livekitwebrtcsink
element.
## [0.10.11] - 2023-07-20
### Fixed
- fallbackswitch: Fix pad health calculation and notifies.
- fallbackswitch: Change the threshold for trailing buffers.
- webrtcsink: Fix pipeline when input caps contain a max-framerate field.
- webrtcsink: Set VP8/VP9 payloader properties based on payloader element
factory name.
- webrtcsink: Set config-interval=-1 and aggregate-mode=zero-latency for
H264/5 payloaders.
- webrtcsink: Translate force-keyunit events to custom force-IDR API of NVIDIA
encoders.
- webrtcsink: Configure only 4 threads instead of 12 for x264enc for Chrome
compatibility.
- fmp4mux: Fix draining in chunk mode if keyframes are after the desired
fragment end.
## [0.10.10] - 2023-07-05
### Fixed
- livesync: Improve EOS handling to be in sync with `queue`'s behaviour.
- livesync: Wait for the end timestamp of the previous buffer before looking
at queue to actually make use of the available latency.
- webrtcsink: Avoid panic on unprepare from an async tokio context.
- webrtc/signalling: Fix race condition in message ordering.
- webrtcsink: Use the correct property types when configuring `nvvideoconvert`.
- videofx: Minimize dependencies of the image crate.
- togglerecord: Fix segment clipping to actually work as intended.
### Added
- gtk4paintablesink: Support for WGL/EGL on Windows.
- gtk4paintablesink: Add Python example application to the repository.
## [0.10.9] - 2023-06-19
### Fixed
- mp4mux/fmp4mux: Fix byte order in Opus extension box.
- webrtcsrc: Add twcc extension to the codec-preferences when present.
- webrtcsink: Don't try using cudaconvert if it is not present.
- mccparse: Don't offset the first timecode to a zero PTS.
- Correctly use MPL as license specifier instead of MPL-2 for plugins that
compile with GStreamer < 1.20.
### Added
- fallbackswitch: Add `stop-on-eos` property.
## [0.10.8] - 2023-06-07
### Fixed
- fmp4mux: Use updated start PTS when checking if a stream is filled instead
of a stale one.
- fmp4mux: Fix various issues with stream gaps, especially in the beginning.
- fmp4mux: Fix waiting in live pipelines.
- uriplaylistbin: Prevent deadlocks during property notifications.
- webrtcsink: Fix panics during `twcc-stats` callback and related issues.
- awstranscriber: Handle stream disconts correctly.
- roundedcorners: Fix caps negotiation to not use I420 if a border radius is
configured.
- whipsink: Use the correct pad template to request pads from the internal
webrtcbin.
- fallbacksrc: Don't apply fallback audio caps to the main stream.
- webrtcsrc: Fix caps handling during transceiver creation.
### Changed
- rtpgccbwe: Improve packet handling.
## [0.10.7] - 2023-05-09
### Fixed
- ffv1dec: Drop rank until the implementation is feature-complete.
- spotifyaudiosrc: Check cached credentials before use and fix usage of
credentials cache.
- tttocea608: Specify raw CEA608 field.
- gtk4paintablesink: Fix compilation on non-Linux UNIX systems.
- webrtcsrc: Don't set stun-server to the empty string if none was set.
- webrtcsink: Abort statistics collection before stopping the signaller.
- rtpgccbwe: Don't process empty lists.
### Changed
- ndi: Update to libloading 0.8.
- aws: Update to AWS SDK 0.55/0.27.
- webrtcsink: Order pads by serial number.
- Update to async-tungstenite 0.22.
### Added
- webrtcsink/webrtcsrc: Add `request-encoded-filter` signal to add support for
inserting custom filters between encoder/payloader or depayloader/decoder.
This allows interacting with the "insertable streams" API from Chrome.
## [0.10.6] - 2023-04-06
### Fixed
- webrtcsink: Fix max/min-bitrate property blurb/nick.
- uriplaylistbin: Add missing queues to example.
- tttocea608: Fix pushing of caps events that sometimes contained unfixed caps.
- tttocea608: Fix disappearing text after special character in non-popon mode.
- transcriberbin: Fix deadlock on construction.
- transcriberbin: Fix initial bin setup.
- fallbacksrc: Handle incompatible downstream caps without panicking.
- ndisrc: Fix copying of raw video frames with different NDI/GStreamer strides.
- livesync: Correctly assume zero upstream latency if latency query fails.
### Added
- webrtcsink: Add `ice-transport-policy` property that proxies the same
`webrtcbin` property.
## [0.10.5] - 2023-03-19
### Fixed
- gtk4: Fix build with OpenGL support on macOS.
- threadshare: Fix symbol conflicts when statically linking the plugin.
## [0.10.4] - 2023-03-14
### Fixed
- fmp4mux: Return a running time from `AggregatorImpl::next_time()` to fix
waiting in live pipelines.
- fmp4mux: Fix `hls_live` example to set properties on the right element.
- uriplaylistbin: Reset element when switching back to `NULL` state.
- livesync: Handle variable framerates correctly in fallback buffer duration
calculation.
- meson: Fix GStreamer version feature detection.
### Added
- webrtc: New `webrtc` element.
## [0.10.3] - 2023-03-02
### Added
- tracers: `queue_levels` tracer now also supports printing the `appsrc` levels.
- webrtc: `webrtcsink` can use `nvvidconv` if `nvvideoconvert` does not exist
on an NVIDIA platform.
### Fixed
- gtk4: Set the sync point on the video frame after mapping it as otherwise
the frame might not be ready yet for further usage.
- livesync: Correctly calculate the fallback buffer duration from the video
framerate.
- ndi: Handle caps changes correctly in `ndisinkcombiner`.
### Changed
- webrtc: Minor cleanup.
## [0.10.2] - 2023-02-23
### Fixed
- hlssink3: Allow signal handlers to return `None`
- gtk4: Make GL context sharing more reliable in pipelines with multiple
`gtk4paintablesinks`
- gtk4: Attach channel receiver to the main context from the correct thread to
make it possible to start the sink from a different thread than the main
thread without having retrieved the paintable from the main thread before.
- fmp4mux/mp4mux: Ignore caps changes if only the framerate changes.
### Changed
- gtk4: Simplify and refactor GL context sharing. Apart from being more
reliable this reduces GL resource usage.
## [0.10.1] - 2023-02-13
### Fixed
- rtpav1pay: Fix calculation of Leb128 size size to work correctly with
streams from certain encoders.
## [0.10.0] - 2023-02-10
### Fixed
- audiornnoise: Use correct value range for the samples
- awss3sink: Treat stopping without EOS as an error for multipart upload
- awss3hlssink: Fix the name of the hlssink child element
- awss3hlssink: Fix deadlock on EOS
- dav1d: Various fixes to improve performance, to handle decoding errors more
gracefully and to make sure all frames are output in the end
- fmp4mux: Various fixes to fragment splitting behaviour, output formatting
and header generation
- gtk4: Various stability and rendering fixes
- meson: Various fixes and improvements to the meson-based build system
- ndi: provide non-Linux/macOS UNIX fallback for the soname
- ndisrc: Use default channel mask for audio output to allow >2 channels to
work better
- rav1e: Correctly enable threading support
- rtpav1: Various fixes to the payloader and depayloader to handle streams
more correctly and to handle errors more cleanly
- rtpav1depay: Set caps on the source pad
- spotify: fix "start a runtime from within a runtime" with static link
- textahead: fix previous buffers
- textwrap: Don't panic on empty buffers
- tttocea608: Don't fail if a GAP event contains no duration
- webrtchttp: whipsink: construct TURN URL correctly
- webrtcsink: fix panic on pre-bwe request error
- whipsink: Send ICE candidates together with the offer
- whipsink: Various cleanups and minor fixes
### Added
- audiornnoise: Add voice detection threshold property
- awss3hlssink: Add `stats` property
- awss3sink: Add properties to set Content-Type and Content-Disposition
- fmp4mux: add 'offset-to-zero' property
- fmp4mux/mp4mux: add support for muxing Opus, VP8, VP9 and AV1 streams
- fmp4mux/mp4mux: Make media/track timescales configurable
- fmp4mux: Add support for CMAF-style chunking, e.g. low-latency / LL HLS and DASH
- gtk4: Support for rendering GL textures on X11/EGL, X11/GLX, Wayland and macOS
- hlssink3: Allow generating i-frame-only playlist
- livesync: New element that allows maintaining a contiguous live stream
without gaps from a potentially unstable source.
- mp4mux: New non-fragmented MP4 muxer element
- spotifyaudiosrc: Support configurable bitrate
- textahead: add settings to display previous buffers
- threadshare: Introduce new ts-audiotestsrc
- webrtcsink: Support nvv4l2vp9enc
- whepsource: Add a WebRTC WHEP source element
### Changed
- audiofx: Derive from AudioFilter where possible
- dav1ddec: Lower rank to primary to allow usage of hardware decoders with
higher ranks
- fmp4mux: Only push `fragment_offset` if `write-mfra` is true to reduce memory usage
- webrtcsink: Make the `turn-server` property a `turn-servers` list
- webrtcsink: Move from async-std to tokio
[Unreleased]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.12.6...HEAD
[0.12.6]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.12.5...0.12.6
[0.12.5]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.12.4...0.12.5
[0.12.4]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.12.3...0.12.4
[0.12.3]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.12.2...0.12.3
[0.12.2]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.12.1...0.12.2
[0.12.1]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.12.0...0.12.1
[0.12.0]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.11.3...0.12.0
[0.11.3]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.11.2...0.11.3
[0.11.2]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.11.1...0.11.2
[0.11.1]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.11.0...0.11.1
[0.11.0]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.10.11...0.11.0
[0.10.11]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.10.10...0.10.11
[0.10.10]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.10.9...0.10.10
[0.10.9]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.10.8...0.10.9
[0.10.8]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.10.7...0.10.8
[0.10.7]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.10.6...0.10.7
[0.10.6]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.10.5...0.10.6
[0.10.5]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.10.4...0.10.5
[0.10.4]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.10.3...0.10.4
[0.10.3]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.10.2...0.10.3
[0.10.2]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.10.1...0.10.2
[0.10.1]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.10.0...0.10.1
[0.10.0]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.9.0...0.10.0

4047
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,5 @@
[workspace]
resolver = "2"
members = [
"tutorial",
@ -11,8 +12,11 @@ members = [
"audio/spotify",
"generic/file",
"generic/originalbuffer",
"generic/sodium",
"generic/threadshare",
"generic/inter",
"generic/gopbuffer",
"mux/flavors",
"mux/fmp4",
@ -25,10 +29,12 @@ members = [
"net/raptorq",
"net/reqwest",
"net/rtp",
"net/rtsp",
"net/webrtchttp",
"net/webrtc",
"net/webrtc/protocol",
"net/webrtc/signalling",
"net/quinn",
"text/ahead",
"text/json",
@ -62,7 +68,10 @@ default-members = [
"audio/claxon",
"audio/lewton",
"generic/originalbuffer",
"generic/threadshare",
"generic/inter",
"generic/gopbuffer",
"mux/fmp4",
"mux/mp4",
@ -73,11 +82,13 @@ default-members = [
"net/raptorq",
"net/reqwest",
"net/rtp",
"net/rtsp",
"net/webrtchttp",
"net/webrtc",
"net/webrtc/protocol",
"net/webrtc/signalling",
"net/ndi",
"net/quinn",
"text/ahead",
"text/json",
@ -106,3 +117,39 @@ panic = 'unwind'
[profile.dev]
opt-level = 1
[workspace.package]
version = "0.13.0-alpha.1"
repository = "https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs"
edition = "2021"
rust-version = "1.70"
[workspace.dependencies]
once_cell = "1"
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "master" }
gio = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "master" }
cairo-rs = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "master", features=["use_glib"] }
pango = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "master" }
pangocairo = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "master" }
gtk = { package = "gtk4", git = "https://github.com/gtk-rs/gtk4-rs", branch = "master"}
gdk-wayland = { package = "gdk4-wayland", git = "https://github.com/gtk-rs/gtk4-rs", branch = "master"}
gdk-x11 = { package = "gdk4-x11", git = "https://github.com/gtk-rs/gtk4-rs", branch = "master"}
gdk-win32 = { package = "gdk4-win32", git = "https://github.com/gtk-rs/gtk4-rs", branch = "master"}
gst = { package = "gstreamer", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "main" }
gst-allocators = { package = "gstreamer-allocators", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "main" }
gst-app = { package = "gstreamer-app", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "main" }
gst-audio = { package = "gstreamer-audio", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "main" }
gst-base = { package = "gstreamer-base", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "main" }
gst-check = { package = "gstreamer-check", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "main" }
gst-gl = { package = "gstreamer-gl", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "main" }
gst-gl-egl = { package = "gstreamer-gl-egl", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "main" }
gst-gl-wayland = { package = "gstreamer-gl-wayland", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "main" }
gst-gl-x11 = { package = "gstreamer-gl-x11", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "main" }
gst-net = { package = "gstreamer-net", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "main" }
gst-pbutils = { package = "gstreamer-pbutils", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "main" }
gst-plugin-version-helper = { path="./version-helper" }
gst-rtp = { package = "gstreamer-rtp", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "main" }
gst-sdp = { package = "gstreamer-sdp", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "main" }
gst-utils = { package = "gstreamer-utils", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "main" }
gst-video = { package = "gstreamer-video", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "main" }
gst-webrtc = { package = "gstreamer-webrtc", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "main" }

View file

@ -33,6 +33,9 @@ You will find the following plugins in this repository:
- `onvif`: Various elements for parsing, RTP (de)payloading, overlaying of ONVIF timed metadata.
- `quinn`: Transfer data over the network using QUIC
- `quinnquicsink`/`quinnquicsrc`: Send and receive data using QUIC
- `raptorq`: Encoder/decoder element for RaptorQ RTP FEC mechanism.
- `reqwest`: An HTTP source element based on the [reqwest](https://github.com/seanmonstar/reqwest) library.

View file

@ -1,27 +1,27 @@
[package]
name = "gst-plugin-audiofx"
version = "0.9.13"
version.workspace = true
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
repository = "https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs"
repository.workspace = true
license = "MPL-2.0"
description = "GStreamer Rust Audio Effects Plugin"
edition = "2021"
rust-version = "1.63"
edition.workspace = true
rust-version.workspace = true
[dependencies]
gst = { package = "gstreamer", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "0.19", version = "0.19.1", features = ["v1_16"] }
gst-base = { package = "gstreamer-base", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "0.19", version = "0.19", features = ["v1_16"] }
gst-audio = { package = "gstreamer-audio", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "0.19", version = "0.19", features = ["v1_16"] }
gst = { workspace = true, features = ["v1_20"] }
gst-base = { workspace = true, features = ["v1_20"] }
gst-audio = { workspace = true, features = ["v1_20"] }
anyhow = "1"
byte-slice-cast = "1.0"
num-traits = "0.2"
once_cell = "1.0"
ebur128 = "0.1"
hrtf = "0.8"
nnnoiseless = { version = "0.5", default-features = false }
smallvec = "1"
atomic_refcell = "0.1"
rayon = "1.5"
once_cell.workspace = true
[lib]
name = "gstrsaudiofx"
@ -29,11 +29,11 @@ crate-type = ["cdylib", "rlib"]
path = "src/lib.rs"
[dev-dependencies]
gst-check = { package = "gstreamer-check", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "0.19", version = "0.19", features = ["v1_18"] }
gst-app = { package = "gstreamer-app", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "0.19", version = "0.19" }
gst-check = { workspace = true, features = ["v1_18"] }
gst-app.workspace = true
[build-dependencies]
gst-plugin-version-helper = { version = "0.7", path="../../version-helper" }
gst-plugin-version-helper.workspace = true
[features]
static = []
@ -41,7 +41,7 @@ capi = []
doc = ["gst/v1_18"]
[package.metadata.capi]
min_version = "0.8.0"
min_version = "0.9.21"
[package.metadata.capi.header]
enabled = false
@ -49,6 +49,7 @@ enabled = false
[package.metadata.capi.library]
install_subdir = "gstreamer-1.0"
versioning = false
import_library = false
[package.metadata.capi.pkg_config]
requires_private = "gstreamer-1.0, gstreamer-base-1.0, gstreamer-audio-1.0, gobject-2.0, glib-2.0, gmodule-2.0"

View file

@ -36,10 +36,9 @@ fn run() -> Result<(), Error> {
let uri = &args[1];
let hrir = &args[2];
let pipeline = gst::parse_launch(&format!(
"uridecodebin uri={} ! audioconvert ! audio/x-raw,channels=1 !
hrtfrender hrir-file={} name=hrtf ! audioresample ! autoaudiosink",
uri, hrir
let pipeline = gst::parse::launch(&format!(
"uridecodebin uri={uri} ! audioconvert ! audio/x-raw,channels=1 !
hrtfrender hrir-file={hrir} name=hrtf ! audioresample ! autoaudiosink"
))?
.downcast::<gst::Pipeline>()
.expect("type error");
@ -110,7 +109,7 @@ fn run() -> Result<(), Error> {
match msg.view() {
MessageView::StateChanged(state_changed) => {
if state_changed.src().map(|s| s == pipeline).unwrap_or(false)
if state_changed.src().map(|s| s == &pipeline).unwrap_or(false)
&& state_changed.current() == gst::State::Playing
{
let (lock, cvar) = &*state_cond;
@ -142,6 +141,6 @@ fn run() -> Result<(), Error> {
fn main() {
match run() {
Ok(r) => r,
Err(e) => eprintln!("Error! {}", e),
Err(e) => eprintln!("Error! {e}"),
}
}

View file

@ -9,7 +9,7 @@
use gst::glib;
use gst::prelude::*;
use gst::subclass::prelude::*;
use gst_base::subclass::prelude::*;
use gst_audio::subclass::prelude::*;
use std::sync::Mutex;
use std::{cmp, u64};
@ -20,7 +20,7 @@ use num_traits::cast::{FromPrimitive, ToPrimitive};
use num_traits::float::Float;
use once_cell::sync::Lazy;
static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
static _CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
gst::DebugCategory::new(
"rsaudioecho",
gst::DebugColorFlags::empty(),
@ -89,7 +89,7 @@ impl AudioEcho {
impl ObjectSubclass for AudioEcho {
const NAME: &'static str = "GstRsAudioEcho";
type Type = super::AudioEcho;
type ParentType = gst_base::BaseTransform;
type ParentType = gst_audio::AudioFilter;
}
impl ObjectImpl for AudioEcho {
@ -194,32 +194,6 @@ impl ElementImpl for AudioEcho {
Some(&*ELEMENT_METADATA)
}
fn pad_templates() -> &'static [gst::PadTemplate] {
static PAD_TEMPLATES: Lazy<Vec<gst::PadTemplate>> = Lazy::new(|| {
let caps = gst_audio::AudioCapsBuilder::new_interleaved()
.format_list([gst_audio::AUDIO_FORMAT_F32, gst_audio::AUDIO_FORMAT_F64])
.build();
let src_pad_template = gst::PadTemplate::new(
"src",
gst::PadDirection::Src,
gst::PadPresence::Always,
&caps,
)
.unwrap();
let sink_pad_template = gst::PadTemplate::new(
"sink",
gst::PadDirection::Sink,
gst::PadPresence::Always,
&caps,
)
.unwrap();
vec![src_pad_template, sink_pad_template]
});
PAD_TEMPLATES.as_ref()
}
}
impl BaseTransformImpl for AudioEcho {
@ -252,28 +226,6 @@ impl BaseTransformImpl for AudioEcho {
Ok(gst::FlowSuccess::Ok)
}
fn set_caps(&self, incaps: &gst::Caps, outcaps: &gst::Caps) -> Result<(), gst::LoggableError> {
if incaps != outcaps {
return Err(gst::loggable_error!(
CAT,
"Input and output caps are not the same"
));
}
let info = gst_audio::AudioInfo::from_caps(incaps)
.map_err(|_| gst::loggable_error!(CAT, "Failed to parse input caps"))?;
let max_delay = self.settings.lock().unwrap().max_delay;
let size = (max_delay * (info.rate() as u64)).seconds() as usize;
let buffer_size = size * (info.channels() as usize);
*self.state.lock().unwrap() = Some(State {
info,
buffer: RingBuffer::new(buffer_size),
});
Ok(())
}
fn stop(&self) -> Result<(), gst::ErrorMessage> {
// Drop state
let _ = self.state.lock().unwrap().take();
@ -281,3 +233,28 @@ impl BaseTransformImpl for AudioEcho {
Ok(())
}
}
impl AudioFilterImpl for AudioEcho {
fn allowed_caps() -> &'static gst::Caps {
static CAPS: Lazy<gst::Caps> = Lazy::new(|| {
gst_audio::AudioCapsBuilder::new_interleaved()
.format_list([gst_audio::AUDIO_FORMAT_F32, gst_audio::AUDIO_FORMAT_F64])
.build()
});
&CAPS
}
fn setup(&self, info: &gst_audio::AudioInfo) -> Result<(), gst::LoggableError> {
let max_delay = self.settings.lock().unwrap().max_delay;
let size = (max_delay * (info.rate() as u64)).seconds() as usize;
let buffer_size = size * (info.channels() as usize);
*self.state.lock().unwrap() = Some(State {
info: info.clone(),
buffer: RingBuffer::new(buffer_size),
});
Ok(())
}
}

View file

@ -20,7 +20,7 @@ pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
gst::Element::register(
Some(plugin),
"rsaudioecho",
gst::Rank::None,
gst::Rank::NONE,
AudioEcho::static_type(),
)
}

View file

@ -348,9 +348,9 @@ impl State {
true_peak
);
// Difference between targetted and calculated LUFS loudness as a linear scalefactor.
// Difference between targeted and calculated LUFS loudness as a linear scalefactor.
let offset = f64::powf(10., (self.target_i - global) / 20.);
// What the new peak would be after adjusting for the targetted loudness.
// What the new peak would be after adjusting for the targeted loudness.
let offset_tp = true_peak * offset;
// If the new peak would be more quiet than targeted one, take it. Otherwise only go as
@ -705,7 +705,7 @@ impl State {
self.process_fill_final_frame(imp, num_samples, FRAME_SIZE);
}
// Now repeatadly run the limiter, output the output gain, update the gains, copy further
// Now repeatedly run the limiter, output the output gain, update the gains, copy further
// data from the buf to limiter_buf until we have output everything.
//
// At this point we have to output 3s - (FRAME_SIZE - num_samples)
@ -782,8 +782,8 @@ impl State {
self.offset
);
let mut outbuf = gst::Buffer::with_size(src.len() * mem::size_of::<f64>())
.map_err(|_| gst::FlowError::Error)?;
let mut outbuf =
gst::Buffer::with_size(mem::size_of_val(src)).map_err(|_| gst::FlowError::Error)?;
{
let outbuf = outbuf.get_mut().unwrap();
let mut dst = outbuf.map_writable().map_err(|_| gst::FlowError::Error)?;
@ -855,15 +855,15 @@ impl State {
smp_cnt += LIMITER_LOOKAHEAD + peak_delta - LIMITER_ATTACK_WINDOW;
gst::debug!(
CAT,
imp: imp,
"Found peak {} at sample {}, going to attack state at sample {} (gain reduction {}-{})",
peak_value,
smp_cnt + LIMITER_ATTACK_WINDOW,
smp_cnt,
self.gain_reduction[0],
self.gain_reduction[1]
);
CAT,
imp: imp,
"Found peak {} at sample {}, going to attack state at sample {} (gain reduction {}-{})",
peak_value,
smp_cnt + LIMITER_ATTACK_WINDOW,
smp_cnt,
self.gain_reduction[0],
self.gain_reduction[1]
);
} else {
// Process all samples, no peak found
smp_cnt = nb_samples;
@ -992,15 +992,15 @@ impl State {
self.sustain_cnt = None;
gst::debug!(
CAT,
imp: imp,
"Found new peak {} at sample {}, restarting attack state at sample {} (gain reduction {}-{})",
peak_value,
smp_cnt + LIMITER_ATTACK_WINDOW,
smp_cnt,
self.gain_reduction[0],
self.gain_reduction[1],
);
CAT,
imp: imp,
"Found new peak {} at sample {}, restarting attack state at sample {} (gain reduction {}-{})",
peak_value,
smp_cnt + LIMITER_ATTACK_WINDOW,
smp_cnt,
self.gain_reduction[0],
self.gain_reduction[1],
);
} else {
// If the slope is lower we can't simply reduce the slope as we would
// then have a lower gain reduction than needed at the previous peak.
@ -1041,15 +1041,15 @@ impl State {
self.sustain_cnt = Some(self.env_cnt);
gst::debug!(
CAT,
imp: imp,
"Found new peak {} at sample {}, adjusting attack state at sample {} (gain reduction {}-{})",
peak_value,
smp_cnt + LIMITER_ATTACK_WINDOW,
smp_cnt,
self.gain_reduction[0],
self.gain_reduction[1],
);
CAT,
imp: imp,
"Found new peak {} at sample {}, adjusting attack state at sample {} (gain reduction {}-{})",
peak_value,
smp_cnt + LIMITER_ATTACK_WINDOW,
smp_cnt,
self.gain_reduction[0],
self.gain_reduction[1],
);
}
return smp_cnt;
} else {
@ -1151,25 +1151,25 @@ impl State {
self.gain_reduction[1] = gain_reduction;
gst::debug!(
CAT,
imp: imp,
"Found new peak {} at sample {}, going back to attack state at sample {} (gain reduction {}-{})",
peak_value,
smp_cnt + LIMITER_ATTACK_WINDOW,
smp_cnt,
self.gain_reduction[0],
self.gain_reduction[1],
);
CAT,
imp: imp,
"Found new peak {} at sample {}, going back to attack state at sample {} (gain reduction {}-{})",
peak_value,
smp_cnt + LIMITER_ATTACK_WINDOW,
smp_cnt,
self.gain_reduction[0],
self.gain_reduction[1],
);
} else {
gst::debug!(
CAT,
imp: imp,
"Found new peak {} at sample {}, going sustain further at sample {} (gain reduction {})",
peak_value,
smp_cnt + LIMITER_ATTACK_WINDOW,
smp_cnt,
self.gain_reduction[1],
);
CAT,
imp: imp,
"Found new peak {} at sample {}, going sustain further at sample {} (gain reduction {})",
peak_value,
smp_cnt + LIMITER_ATTACK_WINDOW,
smp_cnt,
self.gain_reduction[1],
);
// We need to sustain until the peak at least
self.sustain_cnt = Some(LIMITER_LOOKAHEAD);
}
@ -1259,26 +1259,26 @@ impl State {
self.gain_reduction[1] = gain_reduction;
gst::debug!(
CAT,
imp: imp,
"Found new peak {} at sample {}, going back to attack state at sample {} (gain reduction {}-{})",
peak_value,
smp_cnt + LIMITER_ATTACK_WINDOW,
smp_cnt,
self.gain_reduction[0],
self.gain_reduction[1],
);
CAT,
imp: imp,
"Found new peak {} at sample {}, going back to attack state at sample {} (gain reduction {}-{})",
peak_value,
smp_cnt + LIMITER_ATTACK_WINDOW,
smp_cnt,
self.gain_reduction[0],
self.gain_reduction[1],
);
} else {
self.gain_reduction[1] = current_gain_reduction;
gst::debug!(
CAT,
imp: imp,
"Going from release to sustain state at sample {} because of low peak {} at sample {} (gain reduction {})",
smp_cnt,
peak_value,
smp_cnt + LIMITER_ATTACK_WINDOW,
self.gain_reduction[1]
);
CAT,
imp: imp,
"Going from release to sustain state at sample {} because of low peak {} at sample {} (gain reduction {})",
smp_cnt,
peak_value,
smp_cnt + LIMITER_ATTACK_WINDOW,
self.gain_reduction[1]
);
self.limiter_state = LimiterState::Sustain;
}
@ -1690,7 +1690,7 @@ impl ObjectSubclass for AudioLoudNorm {
fn with_class(klass: &Self::Class) -> Self {
let templ = klass.pad_template("sink").unwrap();
let sinkpad = gst::Pad::builder_with_template(&templ, Some("sink"))
let sinkpad = gst::Pad::builder_from_template(&templ)
.chain_function(|pad, parent, buffer| {
Self::catch_panic_pad_function(
parent,
@ -1705,7 +1705,7 @@ impl ObjectSubclass for AudioLoudNorm {
.build();
let templ = klass.pad_template("src").unwrap();
let srcpad = gst::Pad::builder_with_template(&templ, Some("src"))
let srcpad = gst::Pad::builder_from_template(&templ)
.query_function(|pad, parent, query| {
Self::catch_panic_pad_function(parent, || false, |this| this.src_query(pad, query))
})

View file

@ -19,7 +19,7 @@ pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
gst::Element::register(
Some(plugin),
"audioloudnorm",
gst::Rank::None,
gst::Rank::NONE,
AudioLoudNorm::static_type(),
)
}

View file

@ -12,10 +12,10 @@ use std::sync::Mutex;
use gst::glib;
use gst::prelude::*;
use gst::subclass::prelude::*;
use gst_audio::subclass::prelude::*;
use gst_base::prelude::*;
use gst_base::subclass::base_transform::BaseTransformImplExt;
use gst_base::subclass::base_transform::GenerateOutputSuccess;
use gst_base::subclass::prelude::*;
use nnnoiseless::DenoiseState;
@ -129,10 +129,13 @@ impl AudioRNNoise {
buffer.set_duration(duration);
buffer.set_pts(pts);
let mut out_map = buffer.map_writable().map_err(|_| gst::FlowError::Error)?;
let out_data = out_map.as_mut_slice_of::<f32>().unwrap();
let (level, has_voice) = {
let mut out_map = buffer.map_writable().map_err(|_| gst::FlowError::Error)?;
let out_data = out_map.as_mut_slice_of::<f32>().unwrap();
self.process(state, &settings, in_data, out_data)
};
self.process(state, &settings, in_data, out_data);
gst_audio::AudioLevelMeta::add(buffer, level, has_voice);
}
self.obj().src_pad().push(buffer)
@ -160,10 +163,13 @@ impl AudioRNNoise {
buffer.set_duration(duration);
buffer.set_pts(pts);
let mut out_map = buffer.map_writable().map_err(|_| gst::FlowError::Error)?;
let out_data = out_map.as_mut_slice_of::<f32>().unwrap();
let (level, has_voice) = {
let mut out_map = buffer.map_writable().map_err(|_| gst::FlowError::Error)?;
let out_data = out_map.as_mut_slice_of::<f32>().unwrap();
self.process(state, &settings, in_data, out_data)
};
self.process(state, &settings, in_data, out_data);
gst_audio::AudioLevelMeta::add(buffer, level, has_voice);
}
Ok(GenerateOutputSuccess::Buffer(buffer))
@ -175,9 +181,10 @@ impl AudioRNNoise {
settings: &Settings,
input_plane: &[f32],
output_plane: &mut [f32],
) {
) -> (u8, bool) {
let channels = state.in_info.channels() as usize;
let size = FRAME_SIZE * channels;
let mut has_voice = false;
for (out_frame, in_frame) in output_plane.chunks_mut(size).zip(input_plane.chunks(size)) {
for (index, item) in in_frame.iter().enumerate() {
@ -207,11 +214,15 @@ impl AudioRNNoise {
);
}
gst::debug!(CAT, imp: self, "Voice activity: {}", vad);
gst::trace!(CAT, imp: self, "Voice activity: {}", vad);
if vad < settings.vad_threshold {
out_frame.fill(0.0);
} else {
// Upon voice activity nnoiseless never really reports a 1.0
// VAD, so we use a hardcoded value close to 1.0 here.
if vad >= 0.98 {
has_voice = true;
}
for (index, item) in out_frame.iter_mut().enumerate() {
let channel_index = index % channels;
let channel_denoiser = &state.denoisers[channel_index];
@ -220,6 +231,19 @@ impl AudioRNNoise {
}
}
}
let rms = output_plane.iter().copied().map(|x| x * x).sum::<f32>();
let level = (20.0 * f32::log10(rms + f32::EPSILON)) as u8;
gst::trace!(
CAT,
imp: self,
"rms: {}, level: {}, has_voice : {} ", rms,
level,
has_voice
);
(level, has_voice)
}
}
@ -227,7 +251,7 @@ impl AudioRNNoise {
impl ObjectSubclass for AudioRNNoise {
const NAME: &'static str = "GstAudioRNNoise";
type Type = super::AudioRNNoise;
type ParentType = gst_base::BaseTransform;
type ParentType = gst_audio::AudioFilter;
}
impl ObjectImpl for AudioRNNoise {
@ -282,34 +306,6 @@ impl ElementImpl for AudioRNNoise {
Some(&*ELEMENT_METADATA)
}
fn pad_templates() -> &'static [gst::PadTemplate] {
static PAD_TEMPLATES: Lazy<Vec<gst::PadTemplate>> = Lazy::new(|| {
let caps = gst_audio::AudioCapsBuilder::new_interleaved()
.format(gst_audio::AUDIO_FORMAT_F32)
.rate(48000)
.build();
let src_pad_template = gst::PadTemplate::new(
"src",
gst::PadDirection::Src,
gst::PadPresence::Always,
&caps,
)
.unwrap();
let sink_pad_template = gst::PadTemplate::new(
"sink",
gst::PadDirection::Sink,
gst::PadPresence::Always,
&caps,
)
.unwrap();
vec![src_pad_template, sink_pad_template]
});
PAD_TEMPLATES.as_ref()
}
}
impl BaseTransformImpl for AudioRNNoise {
@ -318,44 +314,6 @@ impl BaseTransformImpl for AudioRNNoise {
const PASSTHROUGH_ON_SAME_CAPS: bool = false;
const TRANSFORM_IP_ON_PASSTHROUGH: bool = false;
fn set_caps(&self, incaps: &gst::Caps, outcaps: &gst::Caps) -> Result<(), gst::LoggableError> {
// Flush previous state
if self.state.borrow_mut().is_some() {
self.drain().map_err(|e| {
gst::loggable_error!(CAT, "Error flushing previous state data {:?}", e)
})?;
}
if incaps != outcaps {
return Err(gst::loggable_error!(
CAT,
"Input and output caps are not the same"
));
}
gst::debug!(CAT, imp: self, "Set caps to {}", incaps);
let in_info = gst_audio::AudioInfo::from_caps(incaps)
.map_err(|e| gst::loggable_error!(CAT, "Failed to parse input caps {:?}", e))?;
let mut denoisers = vec![];
for _i in 0..in_info.channels() {
denoisers.push(ChannelDenoiser {
denoiser: DenoiseState::new(),
frame_chunk: Box::new([0.0; FRAME_SIZE]),
out_chunk: Box::new([0.0; FRAME_SIZE]),
})
}
let mut state_lock = self.state.borrow_mut();
*state_lock = Some(State {
in_info,
denoisers,
adapter: gst_base::UniqueAdapter::new(),
});
Ok(())
}
fn generate_output(&self) -> Result<GenerateOutputSuccess, gst::FlowError> {
// Check if there are enough data in the queued buffer and adapter,
// if it is not the case, just notify the parent class to not generate
@ -427,3 +385,45 @@ impl BaseTransformImpl for AudioRNNoise {
Ok(())
}
}
impl AudioFilterImpl for AudioRNNoise {
fn allowed_caps() -> &'static gst::Caps {
static CAPS: Lazy<gst::Caps> = Lazy::new(|| {
gst_audio::AudioCapsBuilder::new_interleaved()
.format(gst_audio::AUDIO_FORMAT_F32)
.rate(48000)
.build()
});
&CAPS
}
fn setup(&self, info: &gst_audio::AudioInfo) -> Result<(), gst::LoggableError> {
// Flush previous state
if self.state.borrow_mut().is_some() {
self.drain().map_err(|e| {
gst::loggable_error!(CAT, "Error flushing previous state data {:?}", e)
})?;
}
gst::debug!(CAT, imp: self, "Set caps to {:?}", info);
let mut denoisers = vec![];
for _i in 0..info.channels() {
denoisers.push(ChannelDenoiser {
denoiser: DenoiseState::new(),
frame_chunk: Box::new([0.0; FRAME_SIZE]),
out_chunk: Box::new([0.0; FRAME_SIZE]),
})
}
let mut state_lock = self.state.borrow_mut();
*state_lock = Some(State {
in_info: info.clone(),
denoisers,
adapter: gst_base::UniqueAdapter::new(),
});
Ok(())
}
}

View file

@ -20,7 +20,7 @@ pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
gst::Element::register(
Some(plugin),
"audiornnoise",
gst::Rank::None,
gst::Rank::NONE,
AudioRNNoise::static_type(),
)
}

View file

@ -9,8 +9,8 @@
use gst::glib;
use gst::prelude::*;
use gst::subclass::prelude::*;
use gst_audio::subclass::prelude::*;
use gst_base::prelude::*;
use gst_base::subclass::prelude::*;
use std::i32;
use std::sync::atomic;
@ -118,7 +118,7 @@ pub struct EbuR128Level {
impl ObjectSubclass for EbuR128Level {
const NAME: &'static str = "GstEbuR128Level";
type Type = super::EbuR128Level;
type ParentType = gst_base::BaseTransform;
type ParentType = gst_audio::AudioFilter;
}
impl ObjectImpl for EbuR128Level {
@ -283,113 +283,6 @@ impl BaseTransformImpl for EbuR128Level {
const PASSTHROUGH_ON_SAME_CAPS: bool = true;
const TRANSFORM_IP_ON_PASSTHROUGH: bool = true;
fn set_caps(&self, incaps: &gst::Caps, _outcaps: &gst::Caps) -> Result<(), gst::LoggableError> {
let info = match gst_audio::AudioInfo::from_caps(incaps) {
Err(_) => return Err(gst::loggable_error!(CAT, "Failed to parse input caps")),
Ok(info) => info,
};
gst::debug!(CAT, imp: self, "Configured for caps {}", incaps,);
let settings = *self.settings.lock().unwrap();
let mut ebur128 = ebur128::EbuR128::new(info.channels(), info.rate(), settings.mode.into())
.map_err(|err| gst::loggable_error!(CAT, "Failed to create EBU R128: {}", err))?;
// Map channel positions if we can to give correct weighting
if let Some(positions) = info.positions() {
let channel_map = positions
.iter()
.map(|p| {
match p {
gst_audio::AudioChannelPosition::Mono => ebur128::Channel::DualMono,
gst_audio::AudioChannelPosition::FrontLeft => ebur128::Channel::Left,
gst_audio::AudioChannelPosition::FrontRight => ebur128::Channel::Right,
gst_audio::AudioChannelPosition::FrontCenter => ebur128::Channel::Center,
gst_audio::AudioChannelPosition::Lfe1
| gst_audio::AudioChannelPosition::Lfe2 => ebur128::Channel::Unused,
gst_audio::AudioChannelPosition::RearLeft => ebur128::Channel::Mp135,
gst_audio::AudioChannelPosition::RearRight => ebur128::Channel::Mm135,
gst_audio::AudioChannelPosition::FrontLeftOfCenter => {
ebur128::Channel::MpSC
}
gst_audio::AudioChannelPosition::FrontRightOfCenter => {
ebur128::Channel::MmSC
}
gst_audio::AudioChannelPosition::RearCenter => ebur128::Channel::Mp180,
gst_audio::AudioChannelPosition::SideLeft => ebur128::Channel::Mp090,
gst_audio::AudioChannelPosition::SideRight => ebur128::Channel::Mm090,
gst_audio::AudioChannelPosition::TopFrontLeft => ebur128::Channel::Up030,
gst_audio::AudioChannelPosition::TopFrontRight => ebur128::Channel::Um030,
gst_audio::AudioChannelPosition::TopFrontCenter => ebur128::Channel::Up000,
gst_audio::AudioChannelPosition::TopCenter => ebur128::Channel::Tp000,
gst_audio::AudioChannelPosition::TopRearLeft => ebur128::Channel::Up135,
gst_audio::AudioChannelPosition::TopRearRight => ebur128::Channel::Um135,
gst_audio::AudioChannelPosition::TopSideLeft => ebur128::Channel::Up090,
gst_audio::AudioChannelPosition::TopSideRight => ebur128::Channel::Um090,
gst_audio::AudioChannelPosition::TopRearCenter => ebur128::Channel::Up180,
gst_audio::AudioChannelPosition::BottomFrontCenter => {
ebur128::Channel::Bp000
}
gst_audio::AudioChannelPosition::BottomFrontLeft => ebur128::Channel::Bp045,
gst_audio::AudioChannelPosition::BottomFrontRight => {
ebur128::Channel::Bm045
}
gst_audio::AudioChannelPosition::WideLeft => {
ebur128::Channel::Mp135 // Mp110?
}
gst_audio::AudioChannelPosition::WideRight => {
ebur128::Channel::Mm135 // Mm110?
}
gst_audio::AudioChannelPosition::SurroundLeft => {
ebur128::Channel::Mp135 // Mp110?
}
gst_audio::AudioChannelPosition::SurroundRight => {
ebur128::Channel::Mm135 // Mm110?
}
gst_audio::AudioChannelPosition::Invalid
| gst_audio::AudioChannelPosition::None => ebur128::Channel::Unused,
val => {
gst::debug!(
CAT,
imp: self,
"Unknown channel position {:?}, ignoring channel",
val
);
ebur128::Channel::Unused
}
}
})
.collect::<Vec<_>>();
ebur128
.set_channel_map(&channel_map)
.map_err(|err| gst::loggable_error!(CAT, "Failed to set channel map: {}", err))?;
} else {
// Weight all channels equally if we have no channel map
let channel_map = std::iter::repeat(ebur128::Channel::Center)
.take(info.channels() as usize)
.collect::<Vec<_>>();
ebur128
.set_channel_map(&channel_map)
.map_err(|err| gst::loggable_error!(CAT, "Failed to set channel map: {}", err))?;
}
let interval_frames = settings
.interval
.mul_div_floor(info.rate() as u64, *gst::ClockTime::SECOND)
.unwrap();
*self.state.borrow_mut() = Some(State {
info,
ebur128,
num_frames: 0,
interval_frames,
interval_frames_remaining: interval_frames,
});
Ok(())
}
fn stop(&self) -> Result<(), gst::ErrorMessage> {
// Drop state
let _ = self.state.borrow_mut().take();
@ -538,10 +431,10 @@ impl BaseTransformImpl for EbuR128Level {
if state.ebur128.mode().contains(ebur128::Mode::SAMPLE_PEAK) {
let peaks = (0..state.info.channels())
.map(|c| state.ebur128.sample_peak(c).map(|p| p.to_send_value()))
.collect::<Result<Vec<_>, _>>();
.collect::<Result<gst::Array, _>>();
match peaks {
Ok(peaks) => s.set("sample-peak", gst::Array::from(peaks)),
Ok(peaks) => s.set("sample-peak", peaks),
Err(err) => {
gst::error!(CAT, imp: self, "Failed to get sample peaks: {}", err)
}
@ -551,10 +444,10 @@ impl BaseTransformImpl for EbuR128Level {
if state.ebur128.mode().contains(ebur128::Mode::TRUE_PEAK) {
let peaks = (0..state.info.channels())
.map(|c| state.ebur128.true_peak(c).map(|p| p.to_send_value()))
.collect::<Result<Vec<_>, _>>();
.collect::<Result<gst::Array, _>>();
match peaks {
Ok(peaks) => s.set("true-peak", gst::Array::from(peaks)),
Ok(peaks) => s.set("true-peak", peaks),
Err(err) => {
gst::error!(CAT, imp: self, "Failed to get true peaks: {}", err)
}
@ -587,6 +480,133 @@ impl BaseTransformImpl for EbuR128Level {
}
}
impl AudioFilterImpl for EbuR128Level {
fn allowed_caps() -> &'static gst::Caps {
static CAPS: Lazy<gst::Caps> = Lazy::new(|| {
gst_audio::AudioCapsBuilder::new()
.format_list([
gst_audio::AUDIO_FORMAT_S16,
gst_audio::AUDIO_FORMAT_S32,
gst_audio::AUDIO_FORMAT_F32,
gst_audio::AUDIO_FORMAT_F64,
])
// Limit from ebur128
.rate_range(1..2_822_400)
// Limit from ebur128
.channels_range(1..64)
.layout_list([
gst_audio::AudioLayout::Interleaved,
gst_audio::AudioLayout::NonInterleaved,
])
.build()
});
&CAPS
}
fn setup(&self, info: &gst_audio::AudioInfo) -> Result<(), gst::LoggableError> {
gst::debug!(CAT, imp: self, "Configured for caps {:?}", info);
let settings = *self.settings.lock().unwrap();
let mut ebur128 = ebur128::EbuR128::new(info.channels(), info.rate(), settings.mode.into())
.map_err(|err| gst::loggable_error!(CAT, "Failed to create EBU R128: {}", err))?;
// Map channel positions if we can to give correct weighting
if let Some(positions) = info.positions() {
let channel_map = positions
.iter()
.map(|p| {
match p {
gst_audio::AudioChannelPosition::Mono => ebur128::Channel::DualMono,
gst_audio::AudioChannelPosition::FrontLeft => ebur128::Channel::Left,
gst_audio::AudioChannelPosition::FrontRight => ebur128::Channel::Right,
gst_audio::AudioChannelPosition::FrontCenter => ebur128::Channel::Center,
gst_audio::AudioChannelPosition::Lfe1
| gst_audio::AudioChannelPosition::Lfe2 => ebur128::Channel::Unused,
gst_audio::AudioChannelPosition::RearLeft => ebur128::Channel::Mp135,
gst_audio::AudioChannelPosition::RearRight => ebur128::Channel::Mm135,
gst_audio::AudioChannelPosition::FrontLeftOfCenter => {
ebur128::Channel::MpSC
}
gst_audio::AudioChannelPosition::FrontRightOfCenter => {
ebur128::Channel::MmSC
}
gst_audio::AudioChannelPosition::RearCenter => ebur128::Channel::Mp180,
gst_audio::AudioChannelPosition::SideLeft => ebur128::Channel::Mp090,
gst_audio::AudioChannelPosition::SideRight => ebur128::Channel::Mm090,
gst_audio::AudioChannelPosition::TopFrontLeft => ebur128::Channel::Up030,
gst_audio::AudioChannelPosition::TopFrontRight => ebur128::Channel::Um030,
gst_audio::AudioChannelPosition::TopFrontCenter => ebur128::Channel::Up000,
gst_audio::AudioChannelPosition::TopCenter => ebur128::Channel::Tp000,
gst_audio::AudioChannelPosition::TopRearLeft => ebur128::Channel::Up135,
gst_audio::AudioChannelPosition::TopRearRight => ebur128::Channel::Um135,
gst_audio::AudioChannelPosition::TopSideLeft => ebur128::Channel::Up090,
gst_audio::AudioChannelPosition::TopSideRight => ebur128::Channel::Um090,
gst_audio::AudioChannelPosition::TopRearCenter => ebur128::Channel::Up180,
gst_audio::AudioChannelPosition::BottomFrontCenter => {
ebur128::Channel::Bp000
}
gst_audio::AudioChannelPosition::BottomFrontLeft => ebur128::Channel::Bp045,
gst_audio::AudioChannelPosition::BottomFrontRight => {
ebur128::Channel::Bm045
}
gst_audio::AudioChannelPosition::WideLeft => {
ebur128::Channel::Mp135 // Mp110?
}
gst_audio::AudioChannelPosition::WideRight => {
ebur128::Channel::Mm135 // Mm110?
}
gst_audio::AudioChannelPosition::SurroundLeft => {
ebur128::Channel::Mp135 // Mp110?
}
gst_audio::AudioChannelPosition::SurroundRight => {
ebur128::Channel::Mm135 // Mm110?
}
gst_audio::AudioChannelPosition::Invalid
| gst_audio::AudioChannelPosition::None => ebur128::Channel::Unused,
val => {
gst::debug!(
CAT,
imp: self,
"Unknown channel position {:?}, ignoring channel",
val
);
ebur128::Channel::Unused
}
}
})
.collect::<Vec<_>>();
ebur128
.set_channel_map(&channel_map)
.map_err(|err| gst::loggable_error!(CAT, "Failed to set channel map: {}", err))?;
} else {
// Weight all channels equally if we have no channel map
let channel_map = std::iter::repeat(ebur128::Channel::Center)
.take(info.channels() as usize)
.collect::<Vec<_>>();
ebur128
.set_channel_map(&channel_map)
.map_err(|err| gst::loggable_error!(CAT, "Failed to set channel map: {}", err))?;
}
let interval_frames = settings
.interval
.mul_div_floor(info.rate() as u64, *gst::ClockTime::SECOND)
.unwrap();
*self.state.borrow_mut() = Some(State {
info: info.clone(),
ebur128,
num_frames: 0,
interval_frames,
interval_frames_remaining: interval_frames,
});
Ok(())
}
}
/// Helper struct to handle the different sample formats and layouts generically.
enum Frames<'a> {
S16(&'a [i16], usize),
@ -759,8 +779,8 @@ fn non_interleaved_channel_data_into_slices<'a, T: FromByteSlice>(
/// Split a vector of slices into a tuple of slices with each slice split at `split_at`.
#[allow(clippy::type_complexity)]
fn split_vec<'a, 'b, T: Copy>(
vec: &'b SmallVec<[&'a [T]; 64]>,
fn split_vec<'a, T: Copy>(
vec: &SmallVec<[&'a [T]; 64]>,
split_at: usize,
) -> (SmallVec<[&'a [T]; 64]>, SmallVec<[&'a [T]; 64]>) {
let VecPair(first, second) = vec

View file

@ -22,7 +22,7 @@ pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
gst::Element::register(
Some(plugin),
"ebur128level",
gst::Rank::None,
gst::Rank::NONE,
EbuR128Level::static_type(),
)
}

View file

@ -514,15 +514,15 @@ impl ObjectImpl for HrtfRender {
}
"spatial-objects" => {
let settings = self.settings.lock().unwrap();
let spatial_objects = settings
settings
.spatial_objects
.as_ref()
.unwrap_or(&Vec::new())
.iter()
.map(|x| gst::Structure::from(*x).to_send_value())
.collect::<Vec<_>>();
gst::Array::from(spatial_objects).to_value()
.collect::<gst::Array>()
.to_value()
}
_ => unimplemented!(),
}
@ -649,7 +649,7 @@ impl BaseTransformImpl for HrtfRender {
if direction == gst::PadDirection::Sink {
s.set("channels", 2);
s.set("channel-mask", 0x3);
s.set("channel-mask", gst::Bitmask(0x3));
} else {
let settings = self.settings.lock().unwrap();
if let Some(objs) = &settings.spatial_objects {

View file

@ -19,7 +19,7 @@ pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
gst::Element::register(
Some(plugin),
"hrtfrender",
gst::Rank::None,
gst::Rank::NONE,
HrtfRender::static_type(),
)
}

View file

@ -33,13 +33,13 @@ fn run_test(
init();
let format = if cfg!(target_endian = "little") {
format!("audio/x-raw,format=F64LE,rate=192000,channels={}", channels)
format!("audio/x-raw,format=F64LE,rate=192000,channels={channels}")
} else {
format!("audio/x-raw,format=F64BE,rate=192000,channels={}", channels)
format!("audio/x-raw,format=F64BE,rate=192000,channels={channels}")
};
let pipeline = if let Some(second_input) = second_input {
gst::parse_launch(&format!(
gst::parse::launch(&format!(
"audiotestsrc {first_input} num-buffers={num_buffers} samplesperbuffer={samples_per_buffer} ! {format} ! audiomixer name=mixer output-buffer-duration={output_buffer_duration} ! {format} ! audioloudnorm ! appsink name=sink audiotestsrc {second_input} num-buffers={num_buffers} samplesperbuffer={samples_per_buffer} ! {format} ! mixer.",
first_input = first_input,
second_input = second_input,
@ -49,12 +49,8 @@ fn run_test(
format = format,
))
} else {
gst::parse_launch(&format!(
gst::parse::launch(&format!(
"audiotestsrc {first_input} num-buffers={num_buffers} samplesperbuffer={samples_per_buffer} ! {format} ! audioloudnorm ! appsink name=sink",
first_input = first_input,
num_buffers = num_buffers,
samples_per_buffer = samples_per_buffer,
format = format,
))
}
.unwrap()
@ -129,17 +125,13 @@ fn run_test(
Ordering::Greater => {
assert!(
ts - expected_ts <= gst::ClockTime::NSECOND,
"TS is {} instead of {}",
ts,
expected_ts
"TS is {ts} instead of {expected_ts}"
);
}
Ordering::Less => {
assert!(
expected_ts - ts <= gst::ClockTime::NSECOND,
"TS is {} instead of {}",
ts,
expected_ts
"TS is {ts} instead of {expected_ts}"
);
}
Ordering::Equal => (),
@ -164,27 +156,18 @@ fn run_test(
if expected_loudness.classify() == std::num::FpCategory::Infinite && expected_loudness < 0.0 {
assert!(
loudness.classify() == std::num::FpCategory::Infinite && loudness < 0.0,
"Loudness is {} instead of {}",
loudness,
expected_loudness,
"Loudness is {loudness} instead of {expected_loudness}",
);
} else {
assert!(
f64::abs(loudness - expected_loudness) < 1.0,
"Loudness is {} instead of {}",
loudness,
expected_loudness,
"Loudness is {loudness} instead of {expected_loudness}",
);
}
for c in 0..channels {
let peak = 20.0 * f64::log10(r128.sample_peak(c).unwrap());
assert!(
peak <= -2.0,
"Peak {} for channel {} is above -2.0",
c,
peak,
);
assert!(peak <= -2.0, "Peak {c} for channel {peak} is above -2.0",);
}
}

View file

@ -156,7 +156,7 @@ fn test_hrtfrender_explicit_spatial_objects() {
}
#[test]
// Caps negotation should fail if we have mismatch between input channels and
// Caps negotiation should fail if we have mismatch between input channels and
// of objects that we set via property. In this test case input has 6 channels
// but the number of spatial objects set is 2.
fn test_hrtfrender_caps_negotiation_fail() {

View file

@ -1,23 +1,23 @@
[package]
name = "gst-plugin-claxon"
version = "0.9.13"
version.workspace = true
authors = ["Ruben Gonzalez <rgonzalez@fluendo.com>"]
repository = "https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs"
repository.workspace = true
license = "MIT OR Apache-2.0"
description = "GStreamer Claxon FLAC Decoder Plugin"
edition = "2021"
rust-version = "1.63"
edition.workspace = true
rust-version.workspace = true
[dependencies]
gst = { package = "gstreamer", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "0.19", version = "0.19.1" }
gst-audio = { package = "gstreamer-audio", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "0.19", version = "0.19" }
gst.workspace = true
gst-audio.workspace = true
claxon = { version = "0.4" }
byte-slice-cast = "1.0"
atomic_refcell = "0.1"
once_cell = "1"
once_cell.workspace = true
[dev-dependencies]
gst-check = { package = "gstreamer-check", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "0.19", version = "0.19" }
gst-check.workspace = true
[lib]
name = "gstclaxon"
@ -25,7 +25,7 @@ crate-type = ["cdylib", "rlib"]
path = "src/lib.rs"
[build-dependencies]
gst-plugin-version-helper = { version = "0.7", path="../../version-helper" }
gst-plugin-version-helper.workspace = true
[features]
static = []
@ -33,7 +33,7 @@ capi = []
doc = ["gst/v1_18"]
[package.metadata.capi]
min_version = "0.8.0"
min_version = "0.9.21"
[package.metadata.capi.header]
enabled = false
@ -41,6 +41,7 @@ enabled = false
[package.metadata.capi.library]
install_subdir = "gstreamer-1.0"
versioning = false
import_library = false
[package.metadata.capi.pkg_config]
requires_private = "gstreamer-1.0, gstreamer-audio-1.0, gobject-2.0, glib-2.0, gmodule-2.0"

View file

@ -209,12 +209,12 @@ impl ClaxonDec {
indata: &[u8],
) -> Result<gst::FlowSuccess, gst::FlowError> {
let streaminfo = claxon_streaminfo(indata).map_err(|e| {
gst::element_imp_error!(self, gst::StreamError::Decode, [e]);
gst::element_imp_error!(self, gst::StreamError::Decode, ["{e}"]);
gst::FlowError::Error
})?;
let audio_info = gstaudioinfo(&streaminfo).map_err(|e| {
gst::element_imp_error!(self, gst::StreamError::Decode, [&e]);
gst::element_imp_error!(self, gst::StreamError::Decode, ["{e}"]);
gst::FlowError::Error
})?;
@ -392,7 +392,7 @@ fn gstaudioinfo(streaminfo: &claxon::metadata::StreamInfo) -> Result<gst_audio::
let audio_info = info_builder
.build()
.map_err(|e| format!("failed to build audio info: {}", e))?;
.map_err(|e| format!("failed to build audio info: {e}"))?;
Ok(audio_info)
}

View file

@ -21,7 +21,7 @@ pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
gst::Element::register(
Some(plugin),
"claxondec",
gst::Rank::Marginal,
gst::Rank::MARGINAL,
ClaxonDec::static_type(),
)
}

View file

@ -1,23 +1,23 @@
[package]
name = "gst-plugin-csound"
version = "0.9.13"
version.workspace = true
authors = ["Natanael Mojica <neithanmo@gmail.com>"]
repository = "https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs"
repository.workspace = true
license = "MPL-2.0"
edition = "2021"
rust-version = "1.63"
edition.workspace = true
rust-version.workspace = true
description = "GStreamer Audio Filter plugin based on Csound"
[dependencies]
gst = { package = "gstreamer", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "0.19", version = "0.19.1" }
gst-base = { package = "gstreamer-base", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "0.19", version = "0.19" }
gst-audio = { package = "gstreamer-audio", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "0.19", version = "0.19" }
gst.workspace = true
gst-base.workspace = true
gst-audio.workspace = true
csound = "0.1.8"
once_cell = "1.0"
byte-slice-cast = "1.0"
once_cell.workspace = true
[dev-dependencies]
gst-check = { package = "gstreamer-check", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "0.19", version = "0.19" }
gst-check.workspace = true
[lib]
name = "gstcsound"
@ -29,7 +29,7 @@ name = "csound-effect"
path = "examples/effect_example.rs"
[build-dependencies]
gst-plugin-version-helper = { version = "0.7", path = "../../version-helper" }
gst-plugin-version-helper.workspace = true
[features]
static = []
@ -37,7 +37,7 @@ capi = []
doc = ["gst/v1_18"]
[package.metadata.capi]
min_version = "0.8.0"
min_version = "0.9.21"
[package.metadata.capi.header]
enabled = false
@ -45,6 +45,7 @@ enabled = false
[package.metadata.capi.library]
install_subdir = "gstreamer-1.0"
versioning = false
import_library = false
[package.metadata.capi.pkg_config]
requires_private = "gstreamer-1.0, gstreamer-base-1.0, gstreamer-audio-1.0, gobject-2.0, glib-2.0, gmodule-2.0, csound"

View file

@ -19,7 +19,7 @@ const AUDIO_SINK: &str = "audioconvert ! autoaudiosink";
// from the global accumulator(gasig), then reads these buffers at a fixed delay time, creating the adelL, adelM and adelR buffers,
// also, It multiplies the audio samples in the right channel by 0.5 * kdel, being kdel a line of values starting at 0.5 at increments of 0.001.
// Finally, those buffers are mixed with the accumulator, and an audio envelop is applied(aseg) to them.
// The result is similar to an audio echo in which the buffered samples are read at different delay times and also modified in frecuency(right channel),
// The result is similar to an audio echo in which the buffered samples are read at different delay times and also modified in frequency(right channel),
// this creates an space effect using just one channel audio input.
const CSD: &str = "
<CsoundSynthesizer>
@ -75,16 +75,16 @@ const CSD: &str = "
fn create_pipeline() -> Result<gst::Pipeline, Box<dyn Error>> {
let pipeline = gst::Pipeline::default();
let audio_src = gst::parse_bin_from_description(AUDIO_SRC, true)?.upcast();
let audio_src = gst::parse::bin_from_description(AUDIO_SRC, true)?.upcast();
let audio_sink = gst::parse_bin_from_description(AUDIO_SINK, true)?.upcast();
let audio_sink = gst::parse::bin_from_description(AUDIO_SINK, true)?.upcast();
let csoundfilter = gst::ElementFactory::make("csoundfilter")
.property("csd-text", CSD)
.build()
.unwrap();
pipeline.add_many(&[&audio_src, &csoundfilter, &audio_sink])?;
pipeline.add_many([&audio_src, &csoundfilter, &audio_sink])?;
audio_src.link_pads(Some("src"), &csoundfilter, Some("sink"))?;
csoundfilter.link_pads(Some("src"), &audio_sink, Some("sink"))?;

View file

@ -127,9 +127,9 @@ impl CsoundFilter {
let spout = csound.get_spout().unwrap();
let in_chunks = idata.chunks_exact(spin.len());
let out_chuncks = odata.chunks_exact_mut(spout.len());
let out_chunks = odata.chunks_exact_mut(spout.len());
let mut end_score = false;
for (ichunk, ochunk) in in_chunks.zip(out_chuncks) {
for (ichunk, ochunk) in in_chunks.zip(out_chunks) {
spin.copy_from_slice(ichunk);
end_score = csound.perform_ksmps();
spout.copy_to_slice(ochunk);
@ -144,11 +144,11 @@ impl CsoundFilter {
if let Some(ref location) = settings.location {
csound
.compile_csd(location)
.map_err(|e| error_msg!(gst::LibraryError::Failed, [e]))?;
.map_err(|e| error_msg!(gst::LibraryError::Failed, ["{e}"]))?;
} else if let Some(ref text) = settings.csd_text {
csound
.compile_csd_text(text)
.map_err(|e| error_msg!(gst::LibraryError::Failed, [e]))?;
.map_err(|e| error_msg!(gst::LibraryError::Failed, ["{e}"]))?;
} else {
return Err(error_msg!(
gst::LibraryError::Failed,
@ -254,7 +254,7 @@ impl CsoundFilter {
);
// Get the required amount of bytes to be read from
// the adapter to fill an ouput buffer of size output_size
// the adapter to fill an output buffer of size output_size
let bytes_to_read = state.bytes_to_read(output_size);
let indata = state
@ -470,7 +470,7 @@ impl BaseTransformImpl for CsoundFilter {
csound.set_score_offset_seconds(settings.offset);
if let Err(e) = csound.start() {
return Err(error_msg!(gst::LibraryError::Failed, [e]));
return Err(error_msg!(gst::LibraryError::Failed, ["{e}"]));
}
Ok(())
@ -554,7 +554,7 @@ impl BaseTransformImpl for CsoundFilter {
// Flush previous state
if self.state.lock().unwrap().is_some() {
self.drain()
.map_err(|e| loggable_error!(CAT, "Error flusing previous state data {:?}", e))?;
.map_err(|e| loggable_error!(CAT, "Error flushing previous state data {:?}", e))?;
}
let in_info = gst_audio::AudioInfo::from_caps(incaps)

View file

@ -19,7 +19,7 @@ pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
gst::Element::register(
Some(plugin),
"csoundfilter",
gst::Rank::None,
gst::Rank::NONE,
CsoundFilter::static_type(),
)
}

View file

@ -1,23 +1,23 @@
[package]
name = "gst-plugin-lewton"
version = "0.9.13"
version.workspace = true
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
repository = "https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs"
repository.workspace = true
license = "MIT OR Apache-2.0"
description = "GStreamer lewton Vorbis Decoder Plugin"
edition = "2021"
rust-version = "1.63"
edition.workspace = true
rust-version.workspace = true
[dependencies]
gst = { package = "gstreamer", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "0.19", version = "0.19.1" }
gst-audio = { package = "gstreamer-audio", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "0.19", version = "0.19" }
gst.workspace = true
gst-audio.workspace = true
lewton = { version = "0.10", default-features = false }
byte-slice-cast = "1.0"
atomic_refcell = "0.1"
once_cell = "1.0"
once_cell.workspace = true
[dev-dependencies]
gst-check = { package = "gstreamer-check", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "0.19", version = "0.19" }
gst-check.workspace = true
[lib]
name = "gstlewton"
@ -25,7 +25,7 @@ crate-type = ["cdylib", "rlib"]
path = "src/lib.rs"
[build-dependencies]
gst-plugin-version-helper = { version = "0.7", path="../../version-helper" }
gst-plugin-version-helper.workspace = true
[features]
static = []
@ -33,7 +33,7 @@ capi = []
doc = ["gst/v1_18"]
[package.metadata.capi]
min_version = "0.8.0"
min_version = "0.9.21"
[package.metadata.capi.header]
enabled = false
@ -41,6 +41,7 @@ enabled = false
[package.metadata.capi.library]
install_subdir = "gstreamer-1.0"
versioning = false
import_library = false
[package.metadata.capi.pkg_config]
requires_private = "gstreamer-1.0, gstreamer-audio-1.0, gobject-2.0, glib-2.0, gmodule-2.0"

View file

@ -132,7 +132,7 @@ impl AudioDecoderImpl for LewtonDec {
reorder_map: None,
});
let mut state = state_guard.as_mut().unwrap();
let state = state_guard.as_mut().unwrap();
let s = caps.structure(0).unwrap();
if let Ok(Some(streamheaders)) = s.get_optional::<gst::ArrayRef>("streamheader") {

View file

@ -21,7 +21,7 @@ pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
gst::Element::register(
Some(plugin),
"lewtondec",
gst::Rank::Marginal,
gst::Rank::MARGINAL,
LewtonDec::static_type(),
)
}

View file

@ -1,22 +1,22 @@
[package]
name = "gst-plugin-spotify"
version = "0.9.13"
version.workspace = true
authors = ["Guillaume Desmottes <guillaume@desmottes.be>"]
repository = "https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs"
repository.workspace = true
license = "MPL-2.0"
description = "GStreamer Spotify Plugin"
edition = "2021"
rust-version = "1.63"
edition.workspace = true
rust-version.workspace = true
[dependencies]
gst = { package = "gstreamer", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "0.19", version = "0.19.1" }
gst-base = { package = "gstreamer-base", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "0.19", version = "0.19" }
once_cell = "1.0"
gst.workspace = true
gst-base.workspace = true
librespot = { version = "0.4", default-features = false }
tokio = "1.0"
futures = "0.3"
anyhow = "1.0"
url = "2.3"
once_cell.workspace = true
[lib]
name = "gstspotify"
@ -24,7 +24,7 @@ crate-type = ["cdylib", "rlib"]
path = "src/lib.rs"
[build-dependencies]
gst-plugin-version-helper = { version = "0.7", path="../../version-helper" }
gst-plugin-version-helper.workspace = true
[features]
static = []
@ -32,7 +32,7 @@ capi = []
doc = ["gst/v1_18"]
[package.metadata.capi]
min_version = "0.8.0"
min_version = "0.9.21"
[package.metadata.capi.header]
enabled = false
@ -40,6 +40,7 @@ enabled = false
[package.metadata.capi.library]
install_subdir = "gstreamer-1.0"
versioning = false
import_library = false
[package.metadata.capi.pkg_config]
requires_private = "gstreamer-1.0, gstreamer-base-1.0, gobject-2.0, glib-2.0, gmodule-2.0"

View file

@ -8,10 +8,11 @@ to respect their legal/licensing restrictions.
## Spotify Credentials
This plugin requires a [Spotify Premium](https://www.spotify.com/premium/) account configured
with a [device password](https://www.spotify.com/us/account/set-device-password/).
This plugin requires a [Spotify Premium](https://www.spotify.com/premium/) account.
If your account is linked with Facebook, you'll need to setup
a [device username and password](https://www.spotify.com/us/account/set-device-password/).
You can then set the device username and password using the `username` and `password` properties.
Those username and password are then set using the `username` and `password` properties.
You may also want to cache credentials and downloaded files, see the `cache-` properties on the element.

194
audio/spotify/src/common.rs Normal file
View file

@ -0,0 +1,194 @@
// Copyright (C) 2021 Guillaume Desmottes <guillaume@desmottes.be>
//
// This Source Code Form is subject to the terms of the Mozilla Public License, v2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at
// <https://mozilla.org/MPL/2.0/>.
//
// SPDX-License-Identifier: MPL-2.0
use anyhow::bail;
use gst::glib;
use gst::prelude::*;
use librespot::core::{
cache::Cache, config::SessionConfig, session::Session, spotify_id::SpotifyId,
};
use librespot::discovery::Credentials;
#[derive(Default, Debug, Clone)]
pub struct Settings {
username: String,
password: String,
cache_credentials: String,
cache_files: String,
cache_max_size: u64,
pub track: String,
}
impl Settings {
pub fn properties() -> Vec<glib::ParamSpec> {
vec![glib::ParamSpecString::builder("username")
.nick("Username")
.blurb("Spotify username, Facebook accounts need a device username from https://www.spotify.com/us/account/set-device-password/")
.default_value(Some(""))
.mutable_ready()
.build(),
glib::ParamSpecString::builder("password")
.nick("Password")
.blurb("Spotify password, Facebook accounts need a device password from https://www.spotify.com/us/account/set-device-password/")
.default_value(Some(""))
.mutable_ready()
.build(),
glib::ParamSpecString::builder("cache-credentials")
.nick("Credentials cache")
.blurb("Directory where to cache Spotify credentials")
.default_value(Some(""))
.mutable_ready()
.build(),
glib::ParamSpecString::builder("cache-files")
.nick("Files cache")
.blurb("Directory where to cache downloaded files from Spotify")
.default_value(Some(""))
.mutable_ready()
.build(),
glib::ParamSpecUInt64::builder("cache-max-size")
.nick("Cache max size")
.blurb("The max allowed size of the cache, in bytes, or 0 to disable the cache limit")
.default_value(0)
.mutable_ready()
.build(),
glib::ParamSpecString::builder("track")
.nick("Spotify URI")
.blurb("Spotify track URI, in the form 'spotify:track:$SPOTIFY_ID'")
.default_value(Some(""))
.mutable_ready()
.build(),
]
}
pub fn set_property(&mut self, value: &glib::Value, pspec: &glib::ParamSpec) {
match pspec.name() {
"username" => {
self.username = value.get().expect("type checked upstream");
}
"password" => {
self.password = value.get().expect("type checked upstream");
}
"cache-credentials" => {
self.cache_credentials = value.get().expect("type checked upstream");
}
"cache-files" => {
self.cache_files = value.get().expect("type checked upstream");
}
"cache-max-size" => {
self.cache_max_size = value.get().expect("type checked upstream");
}
"track" => {
self.track = value.get().expect("type checked upstream");
}
_ => unimplemented!(),
}
}
pub fn property(&self, pspec: &glib::ParamSpec) -> glib::Value {
match pspec.name() {
"username" => self.username.to_value(),
"password" => self.password.to_value(),
"cache-credentials" => self.cache_credentials.to_value(),
"cache-files" => self.cache_files.to_value(),
"cache-max-size" => self.cache_max_size.to_value(),
"track" => self.track.to_value(),
_ => unimplemented!(),
}
}
pub async fn connect_session<T>(
&self,
src: T,
cat: &gst::DebugCategory,
) -> anyhow::Result<Session>
where
T: IsA<glib::Object>,
{
let credentials_cache = if self.cache_credentials.is_empty() {
None
} else {
Some(&self.cache_credentials)
};
let files_cache = if self.cache_files.is_empty() {
None
} else {
Some(&self.cache_files)
};
let max_size = if self.cache_max_size != 0 {
Some(self.cache_max_size)
} else {
None
};
let cache = Cache::new(credentials_cache, None, files_cache, max_size)?;
if let Some(cached_cred) = cache.credentials() {
if !self.username.is_empty() && self.username != cached_cred.username {
gst::debug!(
cat,
obj: &src,
"ignore cached credentials for user {} which mismatch user {}",
cached_cred.username,
self.username
);
} else {
gst::debug!(
cat,
obj: &src,
"reuse cached credentials for user {}",
cached_cred.username
);
if let Ok((session, _credentials)) = Session::connect(
SessionConfig::default(),
cached_cred,
Some(cache.clone()),
true,
)
.await
{
return Ok(session);
}
}
}
gst::debug!(
cat,
obj: &src,
"credentials not in cache or cached credentials invalid",
);
if self.username.is_empty() {
bail!("username is not set and credentials are not in cache");
}
if self.password.is_empty() {
bail!("password is not set and credentials are not in cache");
}
let cred = Credentials::with_password(&self.username, &self.password);
let (session, _credentials) =
Session::connect(SessionConfig::default(), cred, Some(cache), true).await?;
Ok(session)
}
pub fn track_id(&self) -> anyhow::Result<SpotifyId> {
if self.track.is_empty() {
bail!("track is not set");
}
let track = SpotifyId::from_uri(&self.track).map_err(|_| {
anyhow::anyhow!("failed to create Spotify URI from track {}", self.track)
})?;
Ok(track)
}
}

View file

@ -14,6 +14,7 @@
*/
use gst::glib;
mod common;
mod spotifyaudiosrc;
fn plugin_init(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {

View file

@ -8,7 +8,6 @@
use std::sync::{mpsc, Arc, Mutex, MutexGuard};
use anyhow::bail;
use futures::future::{AbortHandle, Abortable, Aborted};
use once_cell::sync::Lazy;
use tokio::{runtime, task::JoinHandle};
@ -18,10 +17,6 @@ use gst::prelude::*;
use gst::subclass::prelude::*;
use gst_base::subclass::{base_src::CreateSuccess, prelude::*};
use librespot::core::{
cache::Cache, config::SessionConfig, session::Session, spotify_id::SpotifyId,
};
use librespot::discovery::Credentials;
use librespot::playback::{
audio_backend::{Sink, SinkResult},
config::PlayerConfig,
@ -67,12 +62,7 @@ struct State {
#[derive(Default)]
struct Settings {
username: String,
password: String,
cache_credentials: String,
cache_files: String,
cache_max_size: u64,
track: String,
common: crate::common::Settings,
bitrate: Bitrate,
}
@ -99,118 +89,39 @@ impl ObjectSubclass for SpotifyAudioSrc {
impl ObjectImpl for SpotifyAudioSrc {
fn properties() -> &'static [glib::ParamSpec] {
static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
vec![glib::ParamSpecString::builder("username")
.nick("Username")
.blurb("Spotify device username from https://www.spotify.com/us/account/set-device-password/")
.default_value(Some(""))
let mut props = crate::common::Settings::properties();
let default = Settings::default();
props.push(
glib::ParamSpecEnum::builder_with_default::<Bitrate>("bitrate", default.bitrate)
.nick("Spotify bitrate")
.blurb("Spotify audio bitrate in kbit/s")
.mutable_ready()
.build(),
glib::ParamSpecString::builder("password")
.nick("Password")
.blurb("Spotify device password from https://www.spotify.com/us/account/set-device-password/")
.default_value(Some(""))
.mutable_ready()
.build(),
glib::ParamSpecString::builder("cache-credentials")
.nick("Credentials cache")
.blurb("Directory where to cache Spotify credentials")
.default_value(Some(""))
.mutable_ready()
.build(),
glib::ParamSpecString::builder("cache-files")
.nick("Files cache")
.blurb("Directory where to cache downloaded files from Spotify")
.default_value(Some(""))
.mutable_ready()
.build(),
glib::ParamSpecUInt64::builder("cache-max-size")
.nick("Cache max size")
.blurb("The max allowed size of the cache, in bytes, or 0 to disable the cache limit")
.default_value(0)
.mutable_ready()
.build(),
glib::ParamSpecString::builder("track")
.nick("Spotify URI")
.blurb("Spotify track URI, in the form 'spotify:track:$SPOTIFY_ID'")
.default_value(Some(""))
.mutable_ready()
.build(),
glib::ParamSpecEnum::builder("bitrate", Bitrate::default())
.nick("Spotify bitrate")
.blurb("Spotify audio bitrate in kbit/s")
.mutable_ready()
.build()
]
);
props
});
PROPERTIES.as_ref()
}
fn set_property(&self, _id: usize, value: &glib::Value, pspec: &glib::ParamSpec) {
let mut settings = self.settings.lock().unwrap();
match pspec.name() {
"username" => {
let mut settings = self.settings.lock().unwrap();
settings.username = value.get().expect("type checked upstream");
}
"password" => {
let mut settings = self.settings.lock().unwrap();
settings.password = value.get().expect("type checked upstream");
}
"cache-credentials" => {
let mut settings = self.settings.lock().unwrap();
settings.cache_credentials = value.get().expect("type checked upstream");
}
"cache-files" => {
let mut settings = self.settings.lock().unwrap();
settings.cache_files = value.get().expect("type checked upstream");
}
"cache-max-size" => {
let mut settings = self.settings.lock().unwrap();
settings.cache_max_size = value.get().expect("type checked upstream");
}
"track" => {
let mut settings = self.settings.lock().unwrap();
settings.track = value.get().expect("type checked upstream");
}
"bitrate" => {
let mut settings = self.settings.lock().unwrap();
settings.bitrate = value.get().expect("type checked upstream");
}
_ => unimplemented!(),
_ => settings.common.set_property(value, pspec),
}
}
fn property(&self, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
let settings = self.settings.lock().unwrap();
match pspec.name() {
"username" => {
let settings = self.settings.lock().unwrap();
settings.username.to_value()
}
"password" => {
let settings = self.settings.lock().unwrap();
settings.password.to_value()
}
"cache-credentials" => {
let settings = self.settings.lock().unwrap();
settings.cache_credentials.to_value()
}
"cache-files" => {
let settings = self.settings.lock().unwrap();
settings.cache_files.to_value()
}
"cache-max-size" => {
let settings = self.settings.lock().unwrap();
settings.cache_max_size.to_value()
}
"track" => {
let settings = self.settings.lock().unwrap();
settings.track.to_value()
}
"bitrate" => {
let settings = self.settings.lock().unwrap();
settings.bitrate.to_value()
}
_ => unimplemented!(),
"bitrate" => settings.bitrate.to_value(),
_ => settings.common.property(pspec),
}
}
}
@ -324,9 +235,8 @@ impl PushSrcImpl for SpotifyAudioSrc {
return Err(gst::FlowError::Flushing);
}
Ok(Err(err)) => {
let details = format!("{:?}", err);
gst::error!(CAT, imp: self, "failed to start: {}", details);
gst::element_imp_error!(self, gst::ResourceError::Settings, [&details]);
gst::error!(CAT, imp: self, "failed to start: {err:?}");
gst::element_imp_error!(self, gst::ResourceError::Settings, ["{err:?}"]);
return Err(gst::FlowError::Error);
}
Ok(Ok(_)) => {}
@ -388,10 +298,10 @@ impl URIHandlerImpl for SpotifyAudioSrc {
fn uri(&self) -> Option<String> {
let settings = self.settings.lock().unwrap();
if settings.track.is_empty() {
if settings.common.track.is_empty() {
None
} else {
Some(settings.track.clone())
Some(settings.common.track.clone())
}
}
@ -399,7 +309,7 @@ impl URIHandlerImpl for SpotifyAudioSrc {
gst::debug!(CAT, imp: self, "set URI: {}", uri);
let url = url::Url::parse(uri)
.map_err(|e| glib::Error::new(gst::URIError::BadUri, &format!("{:?}", e)))?;
.map_err(|e| glib::Error::new(gst::URIError::BadUri, &format!("{e:?}")))?;
// allow to configure auth and cache settings from the URI
for (key, value) in url.query_pairs() {
@ -450,64 +360,23 @@ impl SpotifyAudioSrc {
}
}
let (credentials, cache, track, bitrate) = {
let settings = self.settings.lock().unwrap();
let src = self.obj();
let credentials_cache = if settings.cache_credentials.is_empty() {
None
} else {
Some(&settings.cache_credentials)
let (session, track, bitrate) = {
let (common, bitrate) = {
let settings = self.settings.lock().unwrap();
let bitrate = settings.bitrate.into();
(settings.common.clone(), bitrate)
};
let files_cache = if settings.cache_files.is_empty() {
None
} else {
Some(&settings.cache_files)
};
let max_size = if settings.cache_max_size != 0 {
Some(settings.cache_max_size)
} else {
None
};
let cache = Cache::new(credentials_cache, None, files_cache, max_size)?;
let credentials = match cache.credentials() {
Some(cached_cred)
if settings.username.is_empty()
|| settings.username == cached_cred.username =>
{
gst::debug!(CAT, imp: self, "reuse credentials from cache",);
cached_cred
}
_ => {
gst::debug!(CAT, imp: self, "credentials not in cache",);
if settings.username.is_empty() {
bail!("username is not set and credentials are not in cache");
}
if settings.password.is_empty() {
bail!("password is not set and credentials are not in cache");
}
Credentials::with_password(&settings.username, &settings.password)
}
};
if settings.track.is_empty() {
bail!("track is not set")
}
let bitrate = settings.bitrate.into();
let session = common.connect_session(src.clone(), &CAT).await?;
let track = common.track_id()?;
gst::debug!(CAT, imp: self, "Requesting bitrate {:?}", bitrate);
(credentials, cache, settings.track.clone(), bitrate)
(session, track, bitrate)
};
let (session, _credentials) =
Session::connect(SessionConfig::default(), credentials, Some(cache), true).await?;
let player_config = PlayerConfig {
passthrough: true,
bitrate,
@ -523,11 +392,6 @@ impl SpotifyAudioSrc {
Box::new(BufferSink { sender })
});
let track = match SpotifyId::from_uri(&track) {
Ok(track) => track,
Err(_) => bail!("Failed to create Spotify URI from track"),
};
player.load(track, true, 0);
let player_channel_handle = RUNTIME.spawn(async move {

View file

@ -50,7 +50,7 @@ pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
gst::Element::register(
Some(plugin),
"spotifyaudiosrc",
gst::Rank::Primary,
gst::Rank::PRIMARY,
SpotifyAudioSrc::static_type(),
)
}

View file

@ -0,0 +1,103 @@
#!/usr/bin/python3
#
# Copied from gstreamer.git/ci/gitlab/trigger_cerbero_pipeline.py
import time
import os
import sys
import gitlab
CERBERO_PROJECT = 'gstreamer/cerbero'
class Status:
FAILED = 'failed'
MANUAL = 'manual'
CANCELED = 'canceled'
SUCCESS = 'success'
SKIPPED = 'skipped'
CREATED = 'created'
@classmethod
def is_finished(cls, state):
return state in [
cls.FAILED,
cls.MANUAL,
cls.CANCELED,
cls.SUCCESS,
cls.SKIPPED,
]
def fprint(msg):
print(msg, end="")
sys.stdout.flush()
if __name__ == "__main__":
server = os.environ['CI_SERVER_URL']
gl = gitlab.Gitlab(server,
private_token=os.environ.get('GITLAB_API_TOKEN'),
job_token=os.environ.get('CI_JOB_TOKEN'))
def get_matching_user_project(project, branch):
cerbero = gl.projects.get(project)
# Search for matching branches, return only if the branch name matches
# exactly
for b in cerbero.branches.list(search=cerbero_branch, iterator=True):
if branch == b.name:
return cerbero
return None
cerbero = None
# We do not want to run on (often out of date) user upstream branch
if os.environ["CI_COMMIT_REF_NAME"] != os.environ['CERBERO_UPSTREAM_BRANCH']:
try:
cerbero_name = f'{os.environ["CI_PROJECT_NAMESPACE"]}/cerbero'
cerbero_branch = os.environ["CI_COMMIT_REF_NAME"]
cerbero = get_matching_user_project(cerbero_name, cerbero_branch)
except gitlab.exceptions.GitlabGetError:
pass
if cerbero is None:
cerbero_name = CERBERO_PROJECT
cerbero_branch = os.environ["CERBERO_UPSTREAM_BRANCH"]
cerbero = gl.projects.get(cerbero_name)
fprint(f"-> Triggering on branch {cerbero_branch} in {cerbero_name}\n")
# CI_PROJECT_URL is not necessarily the project where the branch we need to
# build resides, for instance merge request pipelines can be run on
# 'gstreamer' namespace. Fetch the branch name in the same way, just in
# case it breaks in the future.
if 'CI_MERGE_REQUEST_SOURCE_PROJECT_URL' in os.environ:
project_url = os.environ['CI_MERGE_REQUEST_SOURCE_PROJECT_URL']
project_branch = os.environ['CI_MERGE_REQUEST_SOURCE_BRANCH_NAME']
else:
project_url = os.environ['CI_PROJECT_URL']
project_branch = os.environ['CI_COMMIT_REF_NAME']
variables = {
"CI_GST_PLUGINS_RS_URL": project_url,
"CI_GST_PLUGINS_RS_REF_NAME": project_branch,
# This tells cerbero CI that this is a pipeline started via the
# trigger API, which means it can use a deps cache instead of
# building from scratch.
"CI_GSTREAMER_TRIGGERED": "true",
}
pipe = cerbero.trigger_pipeline(
token=os.environ['CI_JOB_TOKEN'],
ref=cerbero_branch,
variables=variables,
)
fprint(f'Cerbero pipeline running at {pipe.web_url} ')
while True:
time.sleep(15)
pipe.refresh()
if Status.is_finished(pipe.status):
fprint(f": {pipe.status}\n")
sys.exit(0 if pipe.status == Status.SUCCESS else 1)
else:
fprint(".")

12
ci/check-for-symlinks.sh Executable file
View file

@ -0,0 +1,12 @@
#!/bin/bash
LINKS=`find -type l`
if test -z $LINKS; then
echo "No symlinks found."
else
echo "===> FOUND SYMLINKS!"
echo
echo "$LINKS"
echo
echo "Please replace these with actual files."
exit 1;
fi

14
ci/check-meson-version.sh Executable file
View file

@ -0,0 +1,14 @@
#!/bin/bash
MESON_VERSION=`head -n5 meson.build | grep ' version\s*:' | sed -e "s/.*version\s*:\s*'//" -e "s/',.*//"`
CARGO_VERSION=`cat Cargo.toml | grep -A1 workspace.package | grep ^version | sed -e 's/^version = "\(.*\)"/\1/'`
echo "gst-plugins-rs version (meson.build) : $MESON_VERSION"
echo "gst-plugins-rs version (Cargo.toml) : $CARGO_VERSION"
if test "x$MESON_VERSION" != "x$CARGO_VERSION"; then
echo
echo "===> Version mismatch between meson.build and Cargo.toml! <==="
echo
exit 1;
fi

View file

@ -1,6 +1,6 @@
set -e
RELEASE=1.0.0
RELEASE=1.1.0
git clone https://code.videolan.org/videolan/dav1d.git --branch $RELEASE
cd dav1d

View file

@ -3,4 +3,4 @@ source ./ci/env.sh
set -e
export CARGO_HOME='/usr/local/cargo'
cargo install cargo-c --version 0.9.14+cargo-0.66
cargo install cargo-c --version 0.9.15+cargo-0.67

View file

@ -22,6 +22,8 @@ RS_PREFIXED = [
'png',
'tracers',
'rtp',
'rtsp',
'inter',
]
OVERRIDE = {

238
deny.toml
View file

@ -10,8 +10,6 @@ ignore = [
"RUSTSEC-2021-0060",
"RUSTSEC-2021-0061",
"RUSTSEC-2021-0145",
# https://github.com/chronotope/chrono/issues/499
"RUSTSEC-2020-0071",
# sodiumoxide is deprecated
"RUSTSEC-2021-0137",
]
@ -19,16 +17,10 @@ ignore = [
[licenses]
unlicensed = "deny"
allow = [
"Apache-2.0",
"MPL-2.0",
]
deny = [
"GPL-1.0",
"GPL-2.0",
"GPL-3.0",
"AGPL-1.0",
"AGPL-3.0",
]
copyleft = "allow"
default = "deny"
copyleft = "deny"
allow-osi-fsf-free = "either"
confidence-threshold = 0.8
@ -40,30 +32,22 @@ license-files = [
{ path = "LICENSE", hash = 0xbd0eed23 }
]
# Allow AGPL3 from dssim-core, which is optionally used in gst-plugin-videofx
[[licenses.exceptions]]
allow = ["AGPL-3.0"]
name = "dssim-core"
version = "3.2"
# Allow LGPL 2.1 for the threadshare plugin as it includes some LGPL code
[[licenses.exceptions]]
allow = ["LGPL-2.1"]
name = "gst-plugin-threadshare"
[bans]
multiple-versions = "deny"
highlight = "all"
wildcards = "allow"
# ignore duplicated deps because of chrono, cookie, cookie_store, hyper,
# hyperx, reqwest depending on old time
# https://github.com/chronotope/chrono/issues/400
# https://github.com/pfernie/cookie_store/issues/11
# https://github.com/hyperium/hyper/pull/2139
# https://github.com/dekellum/hyperx/issues/21
# https://github.com/seanmonstar/reqwest/issues/934
[[bans.skip]]
name = "time"
version = "0.1"
# ignore duplicated rustc_version dependency because rav1e depends on an old version
[[bans.skip]]
name = "rustc_version"
version = "0.3"
[[bans.skip]]
name = "semver"
version = "0.11"
# ignore duplicated crc dependency because ffv1 depends on an old version
# https://github.com/rust-av/ffv1/issues/21
[[bans.skip]]
@ -86,22 +70,15 @@ version = "0.9"
[[bans.skip]]
name = "hmac"
version = "0.11"
# ignore duplicated wasi dependency because various crates depends on an old version
[[bans.skip]]
name = "wasi"
version = "0.10"
# ignore duplicated spin dependency because various crates depend on an old version
name = "zerocopy"
version = "0.6"
[[bans.skip]]
name = "spin"
version = "0.5"
# cookie_store depends on older idna
# https://github.com/pfernie/cookie_store/commit/b9c710f45550c5c8997f18a83e6fcc5998cf1726
name = "multimap"
version = "0.8"
[[bans.skip]]
name = "idna"
version = "0.2"
name = "nix"
version = "0.23"
# field-offset and nix depend on an older memoffset
# https://github.com/Diggsey/rust-field-offset/pull/23
@ -114,72 +91,159 @@ version = "0.6"
[[bans.skip]]
name = "hermit-abi"
version = "0.1"
[[bans.skip]]
name = "hermit-abi"
version = "0.2"
# Various crates depend on an older version of base64
[[bans.skip]]
name = "base64"
version = "0.13"
# Various crates depend on an older version of windows-sys
[[bans.skip]]
name = "windows-sys"
version = "0.42"
[[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"
name = "base64"
version = "0.21"
# Various crates depend on an older version of socket2
[[bans.skip]]
name = "socket2"
version = "0.4"
# Various crates depend on an older version of syn
[[bans.skip]]
name = "syn"
version = "1.0"
# Various crates depend on an older version of bitflags
[[bans.skip]]
name = "bitflags"
version = "1.0"
# cargo-lock depends on an old version of the toml crate
# https://github.com/rustsec/rustsec/pull/805
# tracing-subscriber depends on an older version of regex-syntax
[[bans.skip]]
name = "toml"
name = "regex-syntax"
version = "0.6"
# publicsuffix depends on an older version of idna
# https://github.com/rushmorem/publicsuffix/pull/39
[[bans.skip]]
name = "idna"
version = "0.3"
# Various crates depend on an older version of indexmap / hashbrown
[[bans.skip]]
name = "indexmap"
version = "1.0"
[[bans.skip]]
name = "hashbrown"
version = "0.12"
# various livekit dependencies depend on an old version of itertools
[[bans.skip]]
name = "itertools"
version = "0.11"
# various rav1e / dssim-core depend on an old version of itertools
[[bans.skip]]
name = "itertools"
version = "0.12"
# matchers depends on an old version of regex-automata
[[bans.skip]]
name = "regex-automata"
version = "0.1"
# Various crates depend on old versions of the windows crates
[[bans.skip]]
name = "windows_x86_64_msvc"
version = "0.48"
[[bans.skip]]
name = "windows_x86_64_gnullvm"
version = "0.48"
[[bans.skip]]
name = "windows_x86_64_gnu"
version = "0.48"
[[bans.skip]]
name = "windows_i686_msvc"
version = "0.48"
[[bans.skip]]
name = "windows_i686_gnu"
version = "0.48"
[[bans.skip]]
name = "windows_aarch64_msvc"
version = "0.48"
[[bans.skip]]
name = "windows_aarch64_gnullvm"
version = "0.48"
[[bans.skip]]
name = "windows-targets"
version = "0.48"
[[bans.skip]]
name = "windows-sys"
version = "0.48"
# Various crates depend on an older version of crypto-bigint
[[bans.skip]]
name = "crypto-bigint"
version = "0.4"
# livekit-api depends on an older version of tokio-tungstenite
[[bans.skip]]
name = "tokio-tungstenite"
version = "0.20"
[[bans.skip]]
name = "tungstenite"
version = "0.20"
# Various crates depend on an older version of http
[[bans.skip]]
name = "http"
version = "0.2"
# proc-macro-crate depends on an older version of toml_edit
# https://github.com/bkchr/proc-macro-crate/pull/50
[[bans.skip]]
name = "toml_edit"
version = "0.21"
[[bans.skip]]
name = "winnow"
version = "0.5"
# Various crates depend on an older version of redox_syscall
# Various crates depend on an older version of heck
[[bans.skip]]
name = "redox_syscall"
name = "heck"
version = "0.4"
# Various crates depend on an older version of hyper / reqwest / headers / etc
[[bans.skip]]
name = "hyper"
version = "0.14"
[[bans.skip]]
name = "hyper-tls"
version = "0.5"
[[bans.skip]]
name = "http-body"
version = "0.4"
[[bans.skip]]
name = "headers-core"
version = "0.2"
[[bans.skip]]
name = "headers"
version = "0.3"
[[bans.skip]]
name = "h2"
version = "0.3"
[[bans.skip]]
name = "reqwest"
version = "0.11"
[[bans.skip]]
name = "rustls-pemfile"
version = "1.0"
[[bans.skip]]
name = "winreg"
version = "0.50"
# The AWS SDK uses old versions of rustls and related crates
[[bans.skip]]
name = "rustls"
version = "0.21"
[[bans.skip]]
name = "rustls-native-certs"
version = "0.6"
[[bans.skip]]
name = "rustls-webpki"
version = "0.101"
[sources]
unknown-registry = "deny"

View file

@ -29,6 +29,7 @@ RENAMES = {
'rsfile': 'file',
'rsflv': 'flavors',
'rsrtp': 'rtp',
'rsrtsp': 'rtsp',
'rswebp': 'webp',
'rsonvif': 'onvif',
'rstracers': 'tracers',
@ -36,6 +37,7 @@ RENAMES = {
'rswebrtc': 'webrtc',
'rspng': 'png',
'rsvideofx': 'videofx',
'rsinter': 'inter',
'textahead': 'ahead',
'textwrap': 'wrap',
}

View file

@ -1,5 +1,9 @@
build_hotdoc = false
if get_option('doc').disabled()
subdir_done()
endif
if meson.is_cross_build()
if get_option('doc').enabled()
error('Documentation enabled but building the doc while cross building is not supported yet.')

File diff suppressed because it is too large Load diff

View file

@ -1,18 +1,18 @@
[package]
name = "gst-plugin-file"
version = "0.9.13"
version.workspace = true
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
repository = "https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs"
repository.workspace = true
license = "MIT OR Apache-2.0"
description = "GStreamer Rust File Source/Sink Plugin"
edition = "2021"
rust-version = "1.63"
edition.workspace = true
rust-version.workspace = true
[dependencies]
url = "2"
gst = { package = "gstreamer", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "0.19", version = "0.19.1" }
gst-base = { package = "gstreamer-base", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "0.19", version = "0.19" }
once_cell = "1.0"
gst.workspace = true
gst-base.workspace = true
once_cell.workspace = true
[lib]
name = "gstrsfile"
@ -20,7 +20,7 @@ crate-type = ["cdylib", "rlib"]
path = "src/lib.rs"
[build-dependencies]
gst-plugin-version-helper = { version = "0.7", path="../../version-helper" }
gst-plugin-version-helper.workspace = true
[features]
static = []
@ -28,7 +28,7 @@ capi = []
doc = ["gst/v1_18"]
[package.metadata.capi]
min_version = "0.8.0"
min_version = "0.9.21"
[package.metadata.capi.header]
enabled = false
@ -36,6 +36,7 @@ enabled = false
[package.metadata.capi.library]
install_subdir = "gstreamer-1.0"
versioning = false
import_library = false
[package.metadata.capi.pkg_config]
requires_private = "gstreamer-1.0, gstreamer-base-1.0, gobject-2.0, glib-2.0, gmodule-2.0"

View file

@ -33,14 +33,14 @@ impl FileLocation {
if url.scheme() != "file" {
return Err(glib::Error::new(
gst::URIError::UnsupportedProtocol,
format!("Unsupported URI {}", uri_str).as_str(),
format!("Unsupported URI {uri_str}").as_str(),
));
}
let path = url.to_file_path().map_err(|_| {
glib::Error::new(
gst::URIError::BadUri,
format!("Unsupported URI {}", uri_str).as_str(),
format!("Unsupported URI {uri_str}").as_str(),
)
})?;
@ -48,7 +48,7 @@ impl FileLocation {
}
Err(err) => Err(glib::Error::new(
gst::URIError::BadUri,
format!("Couldn't parse URI {}: {}", uri_str, err).as_str(),
format!("Couldn't parse URI {uri_str}: {err}").as_str(),
)),
}
}
@ -57,14 +57,14 @@ impl FileLocation {
let location_str = location.to_str().ok_or_else(|| {
glib::Error::new(
gst::URIError::BadReference,
format!("Invalid path {:?}", location).as_str(),
format!("Invalid path {location:?}").as_str(),
)
})?;
let file_name = location.file_name().ok_or_else(|| {
glib::Error::new(
gst::URIError::BadReference,
format!("Expected a path with a filename, got {}", location_str,).as_str(),
format!("Expected a path with a filename, got {location_str}",).as_str(),
)
})?;
@ -83,7 +83,7 @@ impl FileLocation {
let parent_canonical = parent_dir.canonicalize().map_err(|err| {
glib::Error::new(
gst::URIError::BadReference,
format!("Could not resolve path {}: {}", location_str, err,).as_str(),
format!("Could not resolve path {location_str}: {err}",).as_str(),
)
})?;
@ -109,7 +109,7 @@ impl FileLocation {
.map_err(|_| {
glib::Error::new(
gst::URIError::BadReference,
format!("Could not resolve path to URL {}", location_str).as_str(),
format!("Could not resolve path to URL {location_str}").as_str(),
)
})
.map(|_| FileLocation(location_canonical))

View file

@ -39,15 +39,14 @@ impl Default for Settings {
}
}
#[derive(Default)]
enum State {
#[default]
Stopped,
Started { file: File, position: u64 },
}
impl Default for State {
fn default() -> State {
State::Stopped
}
Started {
file: File,
position: u64,
},
}
#[derive(Default)]

View file

@ -23,7 +23,7 @@ pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
gst::Element::register(
Some(plugin),
"rsfilesink",
gst::Rank::None,
gst::Rank::NONE,
FileSink::static_type(),
)
}

View file

@ -38,15 +38,14 @@ impl Default for Settings {
}
}
#[derive(Default)]
enum State {
#[default]
Stopped,
Started { file: File, position: u64 },
}
impl Default for State {
fn default() -> State {
State::Stopped
}
Started {
file: File,
position: u64,
},
}
#[derive(Default)]
@ -80,14 +79,14 @@ impl FileSrc {
if !location.exists() {
return Err(glib::Error::new(
gst::URIError::BadReference,
format!("{} doesn't exist", location).as_str(),
format!("{location} doesn't exist").as_str(),
));
}
if !location.is_file() {
return Err(glib::Error::new(
gst::URIError::BadReference,
format!("{} is not a file", location).as_str(),
format!("{location} is not a file").as_str(),
));
}

View file

@ -22,7 +22,7 @@ pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
gst::Element::register(
Some(plugin),
"rsfilesrc",
gst::Rank::None,
gst::Rank::NONE,
FileSrc::static_type(),
)
}

View file

@ -0,0 +1,44 @@
[package]
name = "gst-plugin-gopbuffer"
version.workspace = true
authors = ["Matthew Waters <matthew@centricular.com>"]
license = "MPL-2.0"
description = "Store complete groups of pictures at a time"
repository.workspace = true
edition.workspace = true
rust-version.workspace = true
[dependencies]
anyhow = "1"
gst = { workspace = true, features = ["v1_18"] }
gst-video = { workspace = true, features = ["v1_18"] }
once_cell.workspace = true
[lib]
name = "gstgopbuffer"
crate-type = ["cdylib", "rlib"]
path = "src/lib.rs"
[dev-dependencies]
gst-app = { workspace = true, features = ["v1_18"] }
gst-check = { workspace = true, features = ["v1_18"] }
[build-dependencies]
gst-plugin-version-helper = { path="../../version-helper" }
[features]
static = []
capi = []
[package.metadata.capi]
min_version = "0.8.0"
[package.metadata.capi.header]
enabled = false
[package.metadata.capi.library]
install_subdir = "gstreamer-1.0"
versioning = false
[package.metadata.capi.pkg_config]
requires_private = "gstreamer-1.0, gstreamer-base-1.0, gstreamer-audio-1.0, gstreamer-video-1.0, gobject-2.0, glib-2.0, gmodule-2.0"

View file

@ -0,0 +1,373 @@
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.

View file

@ -0,0 +1,3 @@
fn main() {
gst_plugin_version_helper::info()
}

View file

@ -0,0 +1,880 @@
// Copyright (C) 2023 Matthew Waters <matthew@centricular.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License, v2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at
// <https://mozilla.org/MPL/2.0/>.
//
// SPDX-License-Identifier: MPL-2.0
/**
* SECTION:element-gopbuffer
*
* #gopbuffer is an element that can be used to store a minimum duration of data delimited by
* discrete GOPs (Group of Picture). It does this in by differentiation on the DELTA_UNIT
* flag on each input buffer.
*
* One example of the usefulness of #gopbuffer is its ability to store a backlog of data starting
* on a key frame boundary if say the previous 10s seconds of a stream would like to be recorded to
* disk.
*
* ## Example pipeline
*
* |[
* gst-launch videotestsrc ! vp8enc ! gopbuffer minimum-duration=10000000000 ! fakesink
* ]|
*
* Since: plugins-rs-0.13.0
*/
use gst::glib;
use gst::prelude::*;
use gst::subclass::prelude::*;
use std::collections::VecDeque;
use std::sync::Mutex;
use once_cell::sync::Lazy;
static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
gst::DebugCategory::new(
"gopbuffer",
gst::DebugColorFlags::empty(),
Some("GopBuffer Element"),
)
});
const DEFAULT_MIN_TIME: gst::ClockTime = gst::ClockTime::from_seconds(1);
const DEFAULT_MAX_TIME: Option<gst::ClockTime> = None;
#[derive(Debug, Clone)]
struct Settings {
min_time: gst::ClockTime,
max_time: Option<gst::ClockTime>,
}
impl Default for Settings {
fn default() -> Self {
Settings {
min_time: DEFAULT_MIN_TIME,
max_time: DEFAULT_MAX_TIME,
}
}
}
#[derive(Debug, Copy, Clone)]
pub(crate) enum DeltaFrames {
/// Only single completely decodable frames
IntraOnly,
/// Frames may depend on past frames
PredictiveOnly,
/// Frames may depend on past or future frames
Bidirectional,
}
impl DeltaFrames {
/// Whether dts is required to order buffers differently from presentation order
pub(crate) fn requires_dts(&self) -> bool {
matches!(self, Self::Bidirectional)
}
/// Whether this coding structure does not allow delta flags on buffers
pub(crate) fn intra_only(&self) -> bool {
matches!(self, Self::IntraOnly)
}
pub(crate) fn from_caps(caps: &gst::CapsRef) -> Option<Self> {
let s = caps.structure(0)?;
Some(match s.name().as_str() {
"video/x-h264" | "video/x-h265" => DeltaFrames::Bidirectional,
"video/x-vp8" | "video/x-vp9" | "video/x-av1" => DeltaFrames::PredictiveOnly,
"image/jpeg" | "image/png" | "video/x-raw" => DeltaFrames::IntraOnly,
_ => return None,
})
}
}
// TODO: add buffer list support
#[derive(Debug)]
enum GopItem {
Buffer(gst::Buffer),
Event(gst::Event),
}
struct Gop {
// all times are in running time
start_pts: gst::ClockTime,
start_dts: Option<gst::Signed<gst::ClockTime>>,
earliest_pts: gst::ClockTime,
final_earliest_pts: bool,
end_pts: gst::ClockTime,
end_dts: Option<gst::Signed<gst::ClockTime>>,
final_end_pts: bool,
// Buffer or event
data: VecDeque<GopItem>,
}
impl Gop {
fn push_on_pad(mut self, pad: &gst::Pad) -> Result<gst::FlowSuccess, gst::FlowError> {
let mut iter = self.data.iter().filter_map(|item| match item {
GopItem::Buffer(buffer) => buffer.pts(),
_ => None,
});
let first_pts = iter.next();
let last_pts = iter.last();
gst::debug!(
CAT,
"pushing gop with start pts {} end pts {}",
first_pts.display(),
last_pts.display(),
);
for item in self.data.drain(..) {
match item {
GopItem::Buffer(buffer) => {
pad.push(buffer)?;
}
GopItem::Event(event) => {
pad.push_event(event);
}
}
}
Ok(gst::FlowSuccess::Ok)
}
}
struct Stream {
sinkpad: gst::Pad,
srcpad: gst::Pad,
sink_segment: Option<gst::FormattedSegment<gst::ClockTime>>,
delta_frames: DeltaFrames,
queued_gops: VecDeque<Gop>,
}
impl Stream {
fn queue_buffer(
&mut self,
buffer: gst::Buffer,
segment: &gst::FormattedSegment<gst::ClockTime>,
) -> Result<gst::FlowSuccess, gst::FlowError> {
let pts_position = buffer.pts().unwrap();
let end_pts_position = pts_position
.opt_add(buffer.duration())
.unwrap_or(pts_position);
let pts = segment
.to_running_time_full(pts_position)
.ok_or_else(|| {
gst::error!(CAT, obj: self.sinkpad, "Couldn't convert PTS to running time");
gst::FlowError::Error
})?
.positive()
.unwrap_or_else(|| {
gst::warning!(CAT, obj: self.sinkpad, "Negative PTSs are not supported");
gst::ClockTime::ZERO
});
let end_pts = segment
.to_running_time_full(end_pts_position)
.ok_or_else(|| {
gst::error!(
CAT,
obj: self.sinkpad,
"Couldn't convert end PTS to running time"
);
gst::FlowError::Error
})?
.positive()
.unwrap_or_else(|| {
gst::warning!(CAT, obj: self.sinkpad, "Negative PTSs are not supported");
gst::ClockTime::ZERO
});
let (dts, end_dts) = if !self.delta_frames.requires_dts() {
(None, None)
} else {
let dts_position = buffer.dts().expect("No dts");
let end_dts_position = buffer
.duration()
.opt_add(dts_position)
.unwrap_or(dts_position);
let dts = segment.to_running_time_full(dts_position).ok_or_else(|| {
gst::error!(CAT, obj: self.sinkpad, "Couldn't convert DTS to running time");
gst::FlowError::Error
})?;
let end_dts = segment
.to_running_time_full(end_dts_position)
.ok_or_else(|| {
gst::error!(
CAT,
obj: self.sinkpad,
"Couldn't convert end DTS to running time"
);
gst::FlowError::Error
})?;
let end_dts = std::cmp::max(end_dts, dts);
(Some(dts), Some(end_dts))
};
if !buffer.flags().contains(gst::BufferFlags::DELTA_UNIT) {
gst::debug!(
CAT,
"New GOP detected with buffer pts {} dts {}",
buffer.pts().display(),
buffer.dts().display()
);
let gop = Gop {
start_pts: pts,
start_dts: dts,
earliest_pts: pts,
final_earliest_pts: false,
end_pts: pts,
end_dts,
final_end_pts: false,
data: VecDeque::from([GopItem::Buffer(buffer)]),
};
self.queued_gops.push_front(gop);
if let Some(prev_gop) = self.queued_gops.get_mut(1) {
gst::debug!(
CAT,
obj: self.sinkpad,
"Updating previous GOP starting at PTS {} to end PTS {}",
prev_gop.earliest_pts,
pts,
);
prev_gop.end_pts = std::cmp::max(prev_gop.end_pts, pts);
prev_gop.end_dts = std::cmp::max(prev_gop.end_dts, dts);
if !self.delta_frames.requires_dts() {
prev_gop.final_end_pts = true;
}
if !prev_gop.final_earliest_pts {
// Don't bother logging this for intra-only streams as it would be for every
// single buffer.
if self.delta_frames.requires_dts() {
gst::debug!(
CAT,
obj: self.sinkpad,
"Previous GOP has final earliest PTS at {}",
prev_gop.earliest_pts
);
}
prev_gop.final_earliest_pts = true;
if let Some(prev_prev_gop) = self.queued_gops.get_mut(2) {
prev_prev_gop.final_end_pts = true;
}
}
}
} else if let Some(gop) = self.queued_gops.front_mut() {
gop.end_pts = std::cmp::max(gop.end_pts, end_pts);
gop.end_dts = gop.end_dts.opt_max(end_dts);
gop.data.push_back(GopItem::Buffer(buffer));
if self.delta_frames.requires_dts() {
let dts = dts.unwrap();
if gop.earliest_pts > pts && !gop.final_earliest_pts {
gst::debug!(
CAT,
obj: self.sinkpad,
"Updating current GOP earliest PTS from {} to {}",
gop.earliest_pts,
pts
);
gop.earliest_pts = pts;
if let Some(prev_gop) = self.queued_gops.get_mut(1) {
if prev_gop.end_pts < pts {
gst::debug!(
CAT,
obj: self.sinkpad,
"Updating previous GOP starting PTS {} end time from {} to {}",
pts,
prev_gop.end_pts,
pts
);
prev_gop.end_pts = pts;
}
}
}
let gop = self.queued_gops.front_mut().unwrap();
// The earliest PTS is known when the current DTS is bigger or equal to the first
// PTS that was observed in this GOP. If there was another frame later that had a
// lower PTS then it wouldn't be possible to display it in time anymore, i.e. the
// stream would be invalid.
if gop.start_pts <= dts && !gop.final_earliest_pts {
gst::debug!(
CAT,
obj: self.sinkpad,
"GOP has final earliest PTS at {}",
gop.earliest_pts
);
gop.final_earliest_pts = true;
if let Some(prev_gop) = self.queued_gops.get_mut(1) {
prev_gop.final_end_pts = true;
}
}
}
} else {
gst::debug!(
CAT,
"dropping buffer before first GOP with pts {} dts {}",
buffer.pts().display(),
buffer.dts().display()
);
}
if let Some((prev_gop, first_gop)) = Option::zip(
self.queued_gops.iter().find(|gop| gop.final_end_pts),
self.queued_gops.back(),
) {
gst::debug!(
CAT,
obj: self.sinkpad,
"Queued full GOPs duration updated to {}",
prev_gop.end_pts.saturating_sub(first_gop.earliest_pts),
);
}
gst::debug!(
CAT,
obj: self.sinkpad,
"Queued duration updated to {}",
Option::zip(self.queued_gops.front(), self.queued_gops.back())
.map(|(end, start)| end.end_pts.saturating_sub(start.start_pts))
.unwrap_or(gst::ClockTime::ZERO)
);
Ok(gst::FlowSuccess::Ok)
}
fn oldest_gop(&mut self) -> Option<Gop> {
self.queued_gops.pop_back()
}
fn peek_oldest_gop(&self) -> Option<&Gop> {
self.queued_gops.back()
}
fn peek_second_oldest_gop(&self) -> Option<&Gop> {
if self.queued_gops.len() <= 1 {
return None;
}
self.queued_gops.get(self.queued_gops.len() - 2)
}
fn drain_all(&mut self) -> impl Iterator<Item = Gop> + '_ {
self.queued_gops.drain(..)
}
fn flush(&mut self) {
self.queued_gops.clear();
}
}
#[derive(Default)]
struct State {
streams: Vec<Stream>,
}
impl State {
fn stream_from_sink_pad(&self, pad: &gst::Pad) -> Option<&Stream> {
self.streams.iter().find(|stream| &stream.sinkpad == pad)
}
fn stream_from_sink_pad_mut(&mut self, pad: &gst::Pad) -> Option<&mut Stream> {
self.streams
.iter_mut()
.find(|stream| &stream.sinkpad == pad)
}
fn stream_from_src_pad(&self, pad: &gst::Pad) -> Option<&Stream> {
self.streams.iter().find(|stream| &stream.srcpad == pad)
}
}
#[derive(Default)]
pub(crate) struct GopBuffer {
state: Mutex<State>,
settings: Mutex<Settings>,
}
impl GopBuffer {
fn sink_chain(
&self,
pad: &gst::Pad,
buffer: gst::Buffer,
) -> Result<gst::FlowSuccess, gst::FlowError> {
let obj = self.obj();
if buffer.pts().is_none() {
gst::error!(CAT, obj: obj, "Require timestamped buffers!");
return Err(gst::FlowError::Error);
}
let settings = self.settings.lock().unwrap().clone();
let mut state = self.state.lock().unwrap();
let stream = state
.stream_from_sink_pad_mut(pad)
.expect("pad without an internal Stream");
let Some(segment) = stream.sink_segment.clone() else {
gst::element_imp_error!(self, gst::CoreError::Clock, ["Got buffer before segment"]);
return Err(gst::FlowError::Error);
};
if stream.delta_frames.intra_only() && buffer.flags().contains(gst::BufferFlags::DELTA_UNIT)
{
gst::error!(CAT, obj: pad, "Intra-only stream with delta units");
return Err(gst::FlowError::Error);
}
if stream.delta_frames.requires_dts() && buffer.dts().is_none() {
gst::error!(CAT, obj: pad, "Require DTS for video streams");
return Err(gst::FlowError::Error);
}
let srcpad = stream.srcpad.clone();
stream.queue_buffer(buffer, &segment)?;
let mut gops_to_push = vec![];
let Some(newest_gop) = stream.queued_gops.front() else {
return Ok(gst::FlowSuccess::Ok);
};
// we are looking for the latest pts value here (which should be the largest)
let newest_ts = if stream.delta_frames.requires_dts() {
newest_gop.end_dts.unwrap()
} else {
gst::Signed::Positive(newest_gop.end_pts)
};
loop {
// check stored times as though the oldest GOP doesn't exist.
let Some(second_oldest_gop) = stream.peek_second_oldest_gop() else {
break;
};
// we are looking for the oldest pts here (with the largest value). This is our potentially
// new end time.
let oldest_ts = if stream.delta_frames.requires_dts() {
second_oldest_gop.start_dts.unwrap()
} else {
gst::Signed::Positive(second_oldest_gop.start_pts)
};
let stored_duration_without_oldest = newest_ts.saturating_sub(oldest_ts);
gst::trace!(
CAT,
obj: obj,
"newest_pts {}, second oldest_pts {}, stored_duration_without_oldest_gop {}, min-time {}",
newest_ts.display(),
oldest_ts.display(),
stored_duration_without_oldest.display(),
settings.min_time.display()
);
if stored_duration_without_oldest < settings.min_time {
break;
}
gops_to_push.push(stream.oldest_gop().unwrap());
}
if let Some(max_time) = settings.max_time {
while let Some(oldest_gop) = stream.peek_oldest_gop() {
let oldest_ts = oldest_gop.data.iter().rev().find_map(|item| match item {
GopItem::Buffer(buffer) => {
if stream.delta_frames.requires_dts() {
Some(gst::Signed::Positive(buffer.dts().unwrap()))
} else {
Some(gst::Signed::Positive(buffer.pts().unwrap()))
}
}
_ => None,
});
if newest_ts
.opt_saturating_sub(oldest_ts)
.map_or(false, |diff| diff > gst::Signed::Positive(max_time))
{
gst::warning!(CAT, obj: obj, "Stored data has overflowed the maximum allowed stored time {}, pushing oldest GOP", max_time.display());
gops_to_push.push(stream.oldest_gop().unwrap());
} else {
break;
}
}
}
drop(state);
for gop in gops_to_push.into_iter() {
gop.push_on_pad(&srcpad)?;
}
Ok(gst::FlowSuccess::Ok)
}
fn sink_event(&self, pad: &gst::Pad, event: gst::Event) -> bool {
let obj = self.obj();
let mut state = self.state.lock().unwrap();
let stream = state
.stream_from_sink_pad_mut(pad)
.expect("pad without an internal Stream!");
match event.view() {
gst::EventView::Caps(caps) => {
let Some(delta_frames) = DeltaFrames::from_caps(caps.caps()) else {
return false;
};
stream.delta_frames = delta_frames;
}
gst::EventView::FlushStop(_flush) => {
gst::debug!(CAT, obj: obj, "flushing stored data");
stream.flush();
}
gst::EventView::Eos(_eos) => {
gst::debug!(CAT, obj: obj, "draining data at EOS");
let gops = stream.drain_all().collect::<Vec<_>>();
let srcpad = stream.srcpad.clone();
drop(state);
for gop in gops.into_iter() {
let _ = gop.push_on_pad(&srcpad);
}
// once we've pushed all the data, we can push the corresponding eos
gst::Pad::event_default(pad, Some(&*obj), event);
return true;
}
gst::EventView::Segment(segment) => {
let Ok(segment) = segment.segment().clone().downcast::<gst::ClockTime>() else {
gst::error!(CAT, "Non TIME segments are not supported");
return false;
};
stream.sink_segment = Some(segment);
}
_ => (),
};
if event.is_serialized() {
if stream.peek_oldest_gop().is_none() {
// if there is nothing queued, the event can go straight through
gst::trace!(CAT, obj: obj, "nothing queued, event {:?} passthrough", event.structure().map(|s| s.name().as_str()));
drop(state);
return gst::Pad::event_default(pad, Some(&*obj), event);
}
let gop = stream.queued_gops.front_mut().unwrap();
gop.data.push_back(GopItem::Event(event));
true
} else {
// non-serialized events can be pushed directly
drop(state);
gst::Pad::event_default(pad, Some(&*obj), event)
}
}
fn sink_query(&self, pad: &gst::Pad, query: &mut gst::QueryRef) -> bool {
let obj = self.obj();
if query.is_serialized() {
// TODO: serialized queries somehow?
gst::warning!(CAT, obj: pad, "Serialized queries are currently not supported");
return false;
}
gst::Pad::query_default(pad, Some(&*obj), query)
}
fn src_query(&self, pad: &gst::Pad, query: &mut gst::QueryRef) -> bool {
let obj = self.obj();
match query.view_mut() {
gst::QueryViewMut::Latency(latency) => {
let mut upstream_query = gst::query::Latency::new();
let otherpad = {
let state = self.state.lock().unwrap();
let Some(stream) = state.stream_from_src_pad(pad) else {
return false;
};
stream.sinkpad.clone()
};
let ret = otherpad.peer_query(&mut upstream_query);
if ret {
let (live, mut min, mut max) = upstream_query.result();
let settings = self.settings.lock().unwrap();
min += settings.max_time.unwrap_or(settings.min_time);
max = max.opt_max(settings.max_time);
latency.set(live, min, max);
gst::debug!(
CAT,
obj: pad,
"Latency query response: live {} min {} max {}",
live,
min,
max.display()
);
}
ret
}
_ => gst::Pad::query_default(pad, Some(&*obj), query),
}
}
fn iterate_internal_links(&self, pad: &gst::Pad) -> gst::Iterator<gst::Pad> {
let state = self.state.lock().unwrap();
let otherpad = match pad.direction() {
gst::PadDirection::Src => state
.stream_from_src_pad(pad)
.map(|stream| stream.sinkpad.clone()),
gst::PadDirection::Sink => state
.stream_from_sink_pad(pad)
.map(|stream| stream.srcpad.clone()),
_ => unreachable!(),
};
if let Some(otherpad) = otherpad {
gst::Iterator::from_vec(vec![otherpad])
} else {
gst::Iterator::from_vec(vec![])
}
}
}
#[glib::object_subclass]
impl ObjectSubclass for GopBuffer {
const NAME: &'static str = "GstGopBuffer";
type Type = super::GopBuffer;
type ParentType = gst::Element;
}
impl ObjectImpl for GopBuffer {
fn properties() -> &'static [glib::ParamSpec] {
static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
vec![
glib::ParamSpecUInt64::builder("minimum-duration")
.nick("Minimum Duration")
.blurb("The minimum duration to store")
.default_value(DEFAULT_MIN_TIME.nseconds())
.mutable_ready()
.build(),
glib::ParamSpecUInt64::builder("max-size-time")
.nick("Maximum Duration")
.blurb("The maximum duration to store (0=disable)")
.default_value(0)
.mutable_ready()
.build(),
]
});
&PROPERTIES
}
fn set_property(&self, _id: usize, value: &glib::Value, pspec: &glib::ParamSpec) {
match pspec.name() {
"minimum-duration" => {
let mut settings = self.settings.lock().unwrap();
let min_time = value.get().expect("type checked upstream");
if settings.min_time != min_time {
settings.min_time = min_time;
drop(settings);
self.post_message(gst::message::Latency::builder().src(&*self.obj()).build());
}
}
"max-size-time" => {
let mut settings = self.settings.lock().unwrap();
let max_time = value
.get::<Option<gst::ClockTime>>()
.expect("type checked upstream");
let max_time = if matches!(max_time, Some(gst::ClockTime::ZERO) | None) {
None
} else {
max_time
};
if settings.max_time != max_time {
settings.max_time = max_time;
drop(settings);
self.post_message(gst::message::Latency::builder().src(&*self.obj()).build());
}
}
_ => unimplemented!(),
}
}
fn property(&self, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
match pspec.name() {
"minimum-duration" => {
let settings = self.settings.lock().unwrap();
settings.min_time.to_value()
}
"max-size-time" => {
let settings = self.settings.lock().unwrap();
settings.max_time.unwrap_or(gst::ClockTime::ZERO).to_value()
}
_ => unimplemented!(),
}
}
fn constructed(&self) {
self.parent_constructed();
let obj = self.obj();
let class = obj.class();
let templ = class.pad_template("video_sink").unwrap();
let sinkpad = gst::Pad::builder_from_template(&templ)
.name("video_sink")
.chain_function(|pad, parent, buffer| {
GopBuffer::catch_panic_pad_function(
parent,
|| Err(gst::FlowError::Error),
|gopbuffer| gopbuffer.sink_chain(pad, buffer),
)
})
.event_function(|pad, parent, event| {
GopBuffer::catch_panic_pad_function(
parent,
|| false,
|gopbuffer| gopbuffer.sink_event(pad, event),
)
})
.query_function(|pad, parent, query| {
GopBuffer::catch_panic_pad_function(
parent,
|| false,
|gopbuffer| gopbuffer.sink_query(pad, query),
)
})
.iterate_internal_links_function(|pad, parent| {
GopBuffer::catch_panic_pad_function(
parent,
|| gst::Pad::iterate_internal_links_default(pad, parent),
|gopbuffer| gopbuffer.iterate_internal_links(pad),
)
})
.flags(gst::PadFlags::PROXY_CAPS)
.build();
obj.add_pad(&sinkpad).unwrap();
let templ = class.pad_template("video_src").unwrap();
let srcpad = gst::Pad::builder_from_template(&templ)
.name("video_src")
.query_function(|pad, parent, query| {
GopBuffer::catch_panic_pad_function(
parent,
|| false,
|gopbuffer| gopbuffer.src_query(pad, query),
)
})
.iterate_internal_links_function(|pad, parent| {
GopBuffer::catch_panic_pad_function(
parent,
|| gst::Pad::iterate_internal_links_default(pad, parent),
|gopbuffer| gopbuffer.iterate_internal_links(pad),
)
})
.build();
obj.add_pad(&srcpad).unwrap();
let mut state = self.state.lock().unwrap();
state.streams.push(Stream {
sinkpad,
srcpad,
sink_segment: None,
delta_frames: DeltaFrames::IntraOnly,
queued_gops: VecDeque::new(),
});
}
}
impl GstObjectImpl for GopBuffer {}
impl ElementImpl for GopBuffer {
fn metadata() -> Option<&'static gst::subclass::ElementMetadata> {
static ELEMENT_METADATA: Lazy<gst::subclass::ElementMetadata> = Lazy::new(|| {
gst::subclass::ElementMetadata::new(
"GopBuffer",
"Video",
"GOP Buffer",
"Matthew Waters <matthew@centricular.com>",
)
});
Some(&*ELEMENT_METADATA)
}
fn pad_templates() -> &'static [gst::PadTemplate] {
static PAD_TEMPLATES: Lazy<Vec<gst::PadTemplate>> = Lazy::new(|| {
// This element is designed to implement multiple streams but it has not been
// implemented.
//
// The things missing for multiple (audio or video) streams are:
// 1. More pad templates
// 2. Choosing a main stream to drive the timestamp logic between all input streams
// 3. Allowing either the main stream to cause other streams to push data
// regardless of it's GOP state, or allow each stream to be individually delimited
// by GOP but all still within the minimum duration.
let video_caps = [
gst::Structure::builder("video/x-h264")
.field("stream-format", gst::List::new(["avc", "avc3"]))
.field("alignment", "au")
.build(),
gst::Structure::builder("video/x-h265")
.field("stream-format", gst::List::new(["hvc1", "hev1"]))
.field("alignment", "au")
.build(),
gst::Structure::builder("video/x-vp8").build(),
gst::Structure::builder("video/x-vp9").build(),
gst::Structure::builder("video/x-av1")
.field("stream-format", "obu-stream")
.field("alignment", "tu")
.build(),
]
.into_iter()
.collect::<gst::Caps>();
let src_pad_template = gst::PadTemplate::new(
"video_src",
gst::PadDirection::Src,
gst::PadPresence::Always,
&video_caps,
)
.unwrap();
let sink_pad_template = gst::PadTemplate::new(
"video_sink",
gst::PadDirection::Sink,
gst::PadPresence::Always,
&video_caps,
)
.unwrap();
vec![src_pad_template, sink_pad_template]
});
PAD_TEMPLATES.as_ref()
}
fn change_state(
&self,
transition: gst::StateChange,
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
#[allow(clippy::single_match)]
match transition {
gst::StateChange::NullToReady => {
let settings = self.settings.lock().unwrap();
if let Some(max_time) = settings.max_time {
if max_time < settings.min_time {
gst::element_imp_error!(
self,
gst::CoreError::StateChange,
["Configured maximum time is less than the minimum time"]
);
return Err(gst::StateChangeError);
}
}
}
_ => (),
}
self.parent_change_state(transition)?;
Ok(gst::StateChangeSuccess::Success)
}
}

View file

@ -0,0 +1,27 @@
// Copyright (C) 2022 Matthew Waters <matthew@centricular.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License, v2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at
// <https://mozilla.org/MPL/2.0/>.
//
// SPDX-License-Identifier: MPL-2.0
use gst::glib;
use gst::prelude::*;
mod imp;
glib::wrapper! {
pub(crate) struct GopBuffer(ObjectSubclass<imp::GopBuffer>) @extends gst::Element, gst::Object;
}
pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
gst::Element::register(
Some(plugin),
"gopbuffer",
gst::Rank::PRIMARY,
GopBuffer::static_type(),
)?;
Ok(())
}

View file

@ -0,0 +1,34 @@
// Copyright (C) 2022 Matthew Waters <matthew@centricular.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License, v2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at
// <https://mozilla.org/MPL/2.0/>.
//
// SPDX-License-Identifier: MPL-2.0
#![allow(clippy::non_send_fields_in_send_ty, unused_doc_comments)]
/**
* plugin-gopbuffer:
*
* Since: plugins-rs-0.13.0
*/
use gst::glib;
mod gopbuffer;
fn plugin_init(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
gopbuffer::register(plugin)
}
gst::plugin_define!(
gopbuffer,
env!("CARGO_PKG_DESCRIPTION"),
plugin_init,
concat!(env!("CARGO_PKG_VERSION"), "-", env!("COMMIT_ID")),
// FIXME: MPL-2.0 is only allowed since 1.18.3 (as unknown) and 1.20 (as known)
"MPL",
env!("CARGO_PKG_NAME"),
env!("CARGO_PKG_NAME"),
env!("CARGO_PKG_REPOSITORY"),
env!("BUILD_REL_DATE")
);

View file

@ -0,0 +1,128 @@
//
// This Source Code Form is subject to the terms of the Mozilla Public License, v2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at
// <https://mozilla.org/MPL/2.0/>.
//
// SPDX-License-Identifier: MPL-2.0
//
use gst::prelude::*;
fn init() {
use std::sync::Once;
static INIT: Once = Once::new();
INIT.call_once(|| {
gst::init().unwrap();
gstgopbuffer::plugin_register_static().unwrap();
});
}
macro_rules! check_buffer {
($buf1:expr, $buf2:expr) => {
assert_eq!($buf1.pts(), $buf2.pts());
assert_eq!($buf1.dts(), $buf2.dts());
assert_eq!($buf1.flags(), $buf2.flags());
};
}
#[test]
fn test_min_one_gop_held() {
const OFFSET: gst::ClockTime = gst::ClockTime::from_seconds(10);
init();
let mut h =
gst_check::Harness::with_padnames("gopbuffer", Some("video_sink"), Some("video_src"));
// 200ms min buffer time
let element = h.element().unwrap();
element.set_property("minimum-duration", gst::ClockTime::from_mseconds(200));
h.set_src_caps(
gst::Caps::builder("video/x-h264")
.field("width", 320i32)
.field("height", 240i32)
.field("framerate", gst::Fraction::new(10, 1))
.field("stream-format", "avc")
.field("alignment", "au")
.field("codec_data", gst::Buffer::with_size(1).unwrap())
.build(),
);
let mut in_segment = gst::Segment::new();
in_segment.set_format(gst::Format::Time);
in_segment.set_base(10.seconds());
assert!(h.push_event(gst::event::Segment::builder(&in_segment).build()));
h.play();
// Push 10 buffers of 100ms each, 2nd and 5th buffer without DELTA_UNIT flag
let in_buffers: Vec<_> = (0..6)
.map(|i| {
let mut buffer = gst::Buffer::with_size(1).unwrap();
{
let buffer = buffer.get_mut().unwrap();
buffer.set_pts(OFFSET + gst::ClockTime::from_mseconds(i * 100));
buffer.set_dts(OFFSET + gst::ClockTime::from_mseconds(i * 100));
buffer.set_duration(gst::ClockTime::from_mseconds(100));
if i != 1 && i != 4 {
buffer.set_flags(gst::BufferFlags::DELTA_UNIT);
}
}
assert_eq!(h.push(buffer.clone()), Ok(gst::FlowSuccess::Ok));
buffer
})
.collect();
// pull mandatory events
let ev = h.pull_event().unwrap();
assert_eq!(ev.type_(), gst::EventType::StreamStart);
let ev = h.pull_event().unwrap();
assert_eq!(ev.type_(), gst::EventType::Caps);
// GstHarness pushes its own segment event that we need to eat
let ev = h.pull_event().unwrap();
assert_eq!(ev.type_(), gst::EventType::Segment);
let ev = h.pull_event().unwrap();
let gst::event::EventView::Segment(recv_segment) = ev.view() else {
unreachable!()
};
let recv_segment = recv_segment.segment();
assert_eq!(recv_segment, &in_segment);
// check that at least the first GOP has been output already as it exceeds the minimum-time
// value
let mut in_iter = in_buffers.iter();
// the first buffer is dropped because it was not preceded by a keyframe
let _buffer = in_iter.next().unwrap();
// a keyframe
let out = h.pull().unwrap();
let buffer = in_iter.next().unwrap();
check_buffer!(buffer, out);
// not a keyframe
let out = h.pull().unwrap();
let buffer = in_iter.next().unwrap();
check_buffer!(buffer, out);
// not a keyframe
let out = h.pull().unwrap();
let buffer = in_iter.next().unwrap();
check_buffer!(buffer, out);
// no more buffers
assert_eq!(h.buffers_in_queue(), 0);
// push eos to drain out the rest of the data
assert!(h.push_event(gst::event::Eos::new()));
for buffer in in_iter {
let out = h.pull().unwrap();
check_buffer!(buffer, out);
}
// no more buffers
assert_eq!(h.buffers_in_queue(), 0);
let ev = h.pull_event().unwrap();
assert_eq!(ev.type_(), gst::EventType::Eos);
}

53
generic/inter/Cargo.toml Normal file
View file

@ -0,0 +1,53 @@
[package]
name = "gst-plugin-inter"
version.workspace = true
authors = ["Mathieu Duponchelle <mathieu@centricular.com>"]
license = "MPL-2.0"
description = "GStreamer Inter Plugin"
repository.workspace = true
edition.workspace = true
rust-version.workspace = true
[dependencies]
anyhow = "1"
gst = { workspace = true, features = ["v1_18"] }
gst-utils.workspace = true
gst-app.workspace = true
once_cell = "1.0"
[dev-dependencies]
pretty_assertions = "1"
gst-check.workspace = true
futures = "0.3"
tokio = { version = "1", features = ["fs", "macros", "rt-multi-thread", "time"] }
tokio-stream = "0.1.11"
serial_test = "3"
[lib]
name = "gstrsinter"
crate-type = ["cdylib", "rlib"]
path = "src/lib.rs"
[build-dependencies]
gst-plugin-version-helper.workspace = true
[features]
static = []
capi = []
doc = ["gst/v1_18"]
[package.metadata.capi]
min_version = "0.8.0"
[package.metadata.capi.header]
enabled = false
[package.metadata.capi.library]
install_subdir = "gstreamer-1.0"
versioning = false
[package.metadata.capi.pkg_config]
requires_private = "gstreamer-1.0, gobject-2.0, glib-2.0, gmodule-2.0"
[[example]]
name = "plug-and-play"

5
generic/inter/build.rs Normal file
View file

@ -0,0 +1,5 @@
// SPDX-License-Identifier: MPL-2.0
fn main() {
gst_plugin_version_helper::info()
}

View file

@ -0,0 +1,74 @@
use anyhow::Error;
use futures::prelude::*;
use futures::stream::select_all;
use gst::prelude::*;
fn toplevel(obj: &gst::Object) -> gst::Object {
if let Some(parent) = obj.parent() {
toplevel(&parent)
} else {
obj.clone()
}
}
#[tokio::main]
async fn main() -> Result<(), Error> {
gst::init()?;
let src_pipeline = gst::parse::launch("videotestsrc is-live=true ! intersink")?;
let sink_pipeline = gst::parse::launch("intersrc ! videoconvert ! autovideosink")?;
let mut stream = select_all([
src_pipeline.bus().unwrap().stream(),
sink_pipeline.bus().unwrap().stream(),
]);
let base_time = gst::SystemClock::obtain().time().unwrap();
src_pipeline.set_clock(Some(&gst::SystemClock::obtain()))?;
src_pipeline.set_start_time(gst::ClockTime::NONE);
src_pipeline.set_base_time(base_time);
sink_pipeline.set_clock(Some(&gst::SystemClock::obtain()))?;
sink_pipeline.set_start_time(gst::ClockTime::NONE);
sink_pipeline.set_base_time(base_time);
src_pipeline.set_state(gst::State::Playing)?;
sink_pipeline.set_state(gst::State::Playing)?;
while let Some(msg) = stream.next().await {
use gst::MessageView;
match msg.view() {
MessageView::Latency(..) => {
if let Some(o) = msg.src() {
if let Ok(pipeline) = toplevel(o).downcast::<gst::Pipeline>() {
eprintln!("Recalculating latency {:?}", pipeline);
let _ = pipeline.recalculate_latency();
}
}
}
MessageView::Eos(..) => {
eprintln!("Unexpected EOS");
break;
}
MessageView::Error(err) => {
eprintln!(
"Got error from {}: {} ({})",
msg.src()
.map(|s| String::from(s.path_string()))
.unwrap_or_else(|| "None".into()),
err.error(),
err.debug().unwrap_or_else(|| "".into()),
);
break;
}
_ => (),
}
}
src_pipeline.set_state(gst::State::Null)?;
sink_pipeline.set_state(gst::State::Null)?;
Ok(())
}

View file

@ -0,0 +1,324 @@
use anyhow::Error;
use futures::prelude::*;
use gst::prelude::*;
use std::collections::HashMap;
use std::io::prelude::*;
use tokio::task;
struct Producer {
pipeline: gst::Pipeline,
sink: gst::Element,
overlay: gst::Element,
}
struct Consumer {
pipeline: gst::Pipeline,
src: gst::Element,
}
fn create_sink_pipeline(producer_name: &str) -> Result<Producer, Error> {
let pipeline = gst::Pipeline::builder()
.name(format!("producer-{producer_name}"))
.build();
let videotestsrc = gst::ElementFactory::make("videotestsrc")
.property_from_str("pattern", "ball")
.property("is-live", true)
.build()?;
let capsfilter = gst::ElementFactory::make("capsfilter")
.property(
"caps",
gst::Caps::builder("video/x-raw")
.field("framerate", gst::Fraction::new(50, 1))
.build(),
)
.build()?;
let queue = gst::ElementFactory::make("queue").build()?;
let overlay = gst::ElementFactory::make("textoverlay")
.property("font-desc", "Sans 30")
.property("text", format!("Producer: {producer_name}"))
.property_from_str("valignment", "top")
.build()?;
let timeoverlay = gst::ElementFactory::make("timeoverlay")
.property("font-desc", "Sans 30")
.property_from_str("valignment", "center")
.property_from_str("halignment", "center")
.build()?;
let sink = gst::ElementFactory::make("intersink")
.property("producer-name", producer_name)
.build()?;
pipeline.add_many([
&videotestsrc,
&capsfilter,
&queue,
&overlay,
&timeoverlay,
&sink,
])?;
gst::Element::link_many([
&videotestsrc,
&capsfilter,
&queue,
&overlay,
&timeoverlay,
&sink,
])?;
Ok(Producer {
pipeline,
sink,
overlay,
})
}
fn create_src_pipeline(producer_name: &str, consumer_name: &str) -> Result<Consumer, Error> {
let pipeline = gst::Pipeline::builder()
.name(format!("consumer-{consumer_name}"))
.build();
let src = gst::ElementFactory::make("intersrc")
.property("producer-name", producer_name)
.build()?;
let queue = gst::ElementFactory::make("queue").build()?;
let vconv = gst::ElementFactory::make("videoconvert").build()?;
let overlay = gst::ElementFactory::make("textoverlay")
.property("font-desc", "Sans 30")
.property("text", format!("Consumer: {consumer_name}"))
.property_from_str("valignment", "bottom")
.build()?;
let vconv2 = gst::ElementFactory::make("videoconvert").build()?;
let sink = gst::ElementFactory::make("autovideosink").build()?;
pipeline.add_many([&src, &queue, &vconv, &overlay, &vconv2, &sink])?;
gst::Element::link_many([&src, &queue, &vconv, &overlay, &vconv2, &sink])?;
Ok(Consumer { pipeline, src })
}
fn prompt_on() {
print!("$ ");
let _ = std::io::stdout().flush();
}
fn monitor_pipeline(pipeline: &gst::Pipeline, base_time: gst::ClockTime) -> Result<(), Error> {
pipeline.set_clock(Some(&gst::SystemClock::obtain()))?;
pipeline.set_start_time(gst::ClockTime::NONE);
pipeline.set_base_time(base_time);
pipeline.set_state(gst::State::Playing)?;
let mut bus_stream = pipeline.bus().expect("Pipeline should have a bus").stream();
let pipeline_clone = pipeline.downgrade();
task::spawn(async move {
while let Some(msg) = bus_stream.next().await {
use gst::MessageView;
if let Some(pipeline) = pipeline_clone.upgrade() {
match msg.view() {
MessageView::Latency(..) => {
let _ = pipeline.recalculate_latency();
}
MessageView::Eos(..) => {
println!(
"EOS from {}",
msg.src()
.map(|s| String::from(s.path_string()))
.unwrap_or_else(|| "None".into())
);
prompt_on();
break;
}
MessageView::Error(err) => {
let _ = pipeline.set_state(gst::State::Null);
println!(
"Got error from {}: {} ({})",
msg.src()
.map(|s| String::from(s.path_string()))
.unwrap_or_else(|| "None".into()),
err.error(),
err.debug().unwrap_or_else(|| "".into()),
);
prompt_on();
break;
}
MessageView::StateChanged(sc) => {
if msg.src() == Some(pipeline.upcast_ref()) {
pipeline.debug_to_dot_file(
gst::DebugGraphDetails::all(),
format!("{}-{:?}-{:?}", pipeline.name(), sc.old(), sc.current()),
);
}
}
_ => (),
}
} else {
break;
}
}
});
Ok(())
}
#[tokio::main]
async fn main() -> Result<(), Error> {
gst::init()?;
println!("h for help");
let base_time = gst::SystemClock::obtain().time().unwrap();
let mut producers: HashMap<String, Producer> = HashMap::new();
let mut consumers: HashMap<String, Consumer> = HashMap::new();
let mut stdin = std::io::stdin().lock();
loop {
let mut buf = String::new();
prompt_on();
match stdin.read_line(&mut buf)? {
0 => {
eprintln!("EOF!");
break;
}
_ => {
let command: Vec<_> = buf.split_whitespace().collect();
match command.first() {
Some(&"ap") => {
if command.len() != 2 {
println!("ap <producer_name>: Add a producer");
} else {
let producer_name = command.get(1).unwrap().to_string();
if producers.contains_key(&producer_name) {
println!("Producer with name {producer_name} already exists!");
continue;
}
let producer = create_sink_pipeline(&producer_name)?;
monitor_pipeline(&producer.pipeline, base_time)?;
println!("Added producer with name {producer_name}");
producers.insert(producer_name, producer);
}
}
Some(&"ac") => {
if command.len() != 3 {
println!("ac <consumer_name> <producer_name>: Add a consumer");
} else {
let consumer_name = command.get(1).unwrap().to_string();
let producer_name = command.get(2).unwrap().to_string();
if consumers.contains_key(&consumer_name) {
println!("Consumer with name {consumer_name} already exists!");
continue;
}
let consumer = create_src_pipeline(&producer_name, &consumer_name)?;
monitor_pipeline(&consumer.pipeline, base_time)?;
println!("Added consumer with name {consumer_name} and producer name {producer_name}");
consumers.insert(consumer_name, consumer);
}
}
Some(&"rp") => {
if command.len() != 2 {
println!("rp <producer_name>: Remove a producer");
} else {
let producer_name = command.get(1).unwrap().to_string();
if let Some(producer) = producers.remove(&producer_name) {
let _ = producer.pipeline.set_state(gst::State::Null);
println!("Removed producer with name {producer_name}");
} else {
println!("No producer with name {producer_name}");
}
}
}
Some(&"rc") => {
if command.len() != 2 {
println!("rc <consumer_name>: Remove a consumer");
} else {
let consumer_name = command.get(1).unwrap().to_string();
if let Some(consumer) = consumers.remove(&consumer_name) {
let _ = consumer.pipeline.set_state(gst::State::Null);
println!("Removed consumer with name {consumer_name}");
} else {
println!("No consumer with name {consumer_name}");
}
}
}
Some(&"cnp") => {
if command.len() != 3 {
println!("cnp <old_producer_name> <new_producer_name>: Change the name of a producer");
} else {
let old_producer_name = command.get(1).unwrap().to_string();
let producer_name = command.get(2).unwrap().to_string();
if producers.contains_key(&producer_name) {
println!("Producer with name {producer_name} already exists!");
continue;
}
if let Some(producer) = producers.remove(&old_producer_name) {
producer.sink.set_property("producer-name", &producer_name);
producer
.overlay
.set_property("text", format!("Producer: {producer_name}"));
println!(
"Changed producer name {old_producer_name} -> {producer_name}"
);
producers.insert(producer_name, producer);
} else {
println!("No producer with name {old_producer_name}");
}
}
}
Some(&"cpn") => {
if command.len() != 3 {
println!("cpn <consumer_name> <new_producer_name>: Change the producer name for a consumer");
} else {
let consumer_name = command.get(1).unwrap().to_string();
let producer_name = command.get(2).unwrap().to_string();
if let Some(consumer) = consumers.get_mut(&consumer_name) {
consumer.src.set_property("producer-name", &producer_name);
println!("Changed producer name for consumer {consumer_name} to {producer_name}");
} else {
println!("No consumer with name {consumer_name}");
}
}
}
Some(&"h") => {
println!("h: show this help");
println!("ap <producer_name>: Add a producer");
println!("ac <consumer_name> <producer_name>: Add a consumer");
println!("rp <producer_name>: Remove a producer");
println!("rc <consumer_name>: Remove a consumer");
println!("cnp <old_producer_name> <new_producer_name>: Change the name of a producer");
println!("cpn <consumer_name> <new_producer_name>: Change the producer name for a consumer");
}
_ => {
println!("Unknown command");
}
}
}
}
buf.clear();
}
for (_, producer) in producers {
let _ = producer.pipeline.set_state(gst::State::Null);
}
for (_, consumer) in consumers {
let _ = consumer.pipeline.set_state(gst::State::Null);
}
Ok(())
}

44
generic/inter/src/lib.rs Normal file
View file

@ -0,0 +1,44 @@
// Copyright (C) 2023 Mathieu Duponchelle <mathieu@centricular.com>
//
// Take a look at the license at the top of the repository in the LICENSE file.
#![allow(unused_doc_comments)]
//! GStreamer elements for connecting pipelines in the same process
mod sink;
mod src;
mod streamproducer;
/**
* plugin-rsinter:
* @title: Rust inter elements
* @short_description: A set of elements for transferring data between pipelines
*
* This plugin exposes two elements, `intersink` and `intersrc`, that can be
* used to transfer data from one pipeline to multiple others in the same
* process.
*
* The elements are implemented using the `StreamProducer` API from
* gstreamer-utils.
*
* Since: plugins-rs-0.11.0
*/
use gst::glib;
fn plugin_init(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
sink::register(plugin)?;
src::register(plugin)?;
Ok(())
}
gst::plugin_define!(
rsinter,
env!("CARGO_PKG_DESCRIPTION"),
plugin_init,
concat!(env!("CARGO_PKG_VERSION"), "-", env!("COMMIT_ID")),
"MPL-2.0",
env!("CARGO_PKG_NAME"),
env!("CARGO_PKG_NAME"),
env!("CARGO_PKG_REPOSITORY"),
env!("BUILD_REL_DATE")
);

View file

@ -0,0 +1,217 @@
// SPDX-License-Identifier: MPL-2.0
use crate::streamproducer::InterStreamProducer;
use anyhow::Error;
use gst::glib;
use gst::prelude::*;
use gst::subclass::prelude::*;
use std::sync::Mutex;
use once_cell::sync::Lazy;
const DEFAULT_PRODUCER_NAME: &str = "default";
#[derive(Debug)]
struct Settings {
producer_name: String,
}
impl Default for Settings {
fn default() -> Self {
Settings {
producer_name: DEFAULT_PRODUCER_NAME.to_string(),
}
}
}
struct State {
appsink: gst_app::AppSink,
sinkpad: gst::GhostPad,
}
/* Locking order is field order */
pub struct InterSink {
settings: Mutex<Settings>,
state: Mutex<State>,
}
impl InterSink {
fn prepare(&self) -> Result<(), Error> {
let settings = self.settings.lock().unwrap();
let state = self.state.lock().unwrap();
InterStreamProducer::acquire(&settings.producer_name, &state.appsink)?;
Ok(())
}
fn unprepare(&self) {
let settings = self.settings.lock().unwrap();
InterStreamProducer::release(&settings.producer_name);
}
}
static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
gst::DebugCategory::new(
"intersink",
gst::DebugColorFlags::empty(),
Some("Inter Sink"),
)
});
#[glib::object_subclass]
impl ObjectSubclass for InterSink {
const NAME: &'static str = "GstInterSink";
type Type = super::InterSink;
type ParentType = gst::Bin;
fn with_class(klass: &Self::Class) -> Self {
let templ = klass.pad_template("sink").unwrap();
let sinkpad = gst::GhostPad::from_template(&templ);
Self {
settings: Mutex::new(Default::default()),
state: Mutex::new(State {
appsink: gst_app::AppSink::builder().name("appsink").build(),
sinkpad: sinkpad.upcast(),
}),
}
}
}
impl ObjectImpl for InterSink {
fn properties() -> &'static [glib::ParamSpec] {
static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
vec![glib::ParamSpecString::builder("producer-name")
.nick("Producer Name")
.blurb("Producer Name to use")
.doc_show_default()
.mutable_playing()
.build()]
});
PROPERTIES.as_ref()
}
fn set_property(&self, _id: usize, value: &glib::Value, pspec: &glib::ParamSpec) {
match pspec.name() {
"producer-name" => {
let mut settings = self.settings.lock().unwrap();
let old_producer_name = settings.producer_name.clone();
settings.producer_name = value
.get::<String>()
.unwrap_or_else(|_| DEFAULT_PRODUCER_NAME.to_string());
if let Some(appsink) = InterStreamProducer::release(&old_producer_name) {
if let Err(err) =
InterStreamProducer::acquire(&settings.producer_name, &appsink)
{
drop(settings);
gst::error!(CAT, imp: self, "{err}");
self.post_error_message(gst::error_msg!(
gst::StreamError::Failed,
["{err}"]
))
} else {
drop(settings);
// This is required because StreamProducer obtains the latency
// it needs to forward from Latency events, and we need to let the
// application know it should recalculate latency to get the event
// to travel upstream again
self.post_message(gst::message::Latency::new());
}
}
}
_ => unimplemented!(),
};
}
fn property(&self, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
match pspec.name() {
"producer-name" => {
let settings = self.settings.lock().unwrap();
settings.producer_name.to_value()
}
_ => unimplemented!(),
}
}
fn constructed(&self) {
self.parent_constructed();
let obj = self.obj();
obj.set_suppressed_flags(gst::ElementFlags::SINK | gst::ElementFlags::SOURCE);
obj.set_element_flags(gst::ElementFlags::SINK);
let state = self.state.lock().unwrap();
obj.add(&state.appsink).unwrap();
obj.add_pad(&state.sinkpad).unwrap();
state
.sinkpad
.set_target(Some(&state.appsink.static_pad("sink").unwrap()))
.unwrap();
}
}
impl GstObjectImpl for InterSink {}
impl ElementImpl for InterSink {
fn metadata() -> Option<&'static gst::subclass::ElementMetadata> {
static ELEMENT_METADATA: Lazy<gst::subclass::ElementMetadata> = Lazy::new(|| {
gst::subclass::ElementMetadata::new(
"Inter Sink",
"Generic/Sink",
"Inter Sink",
"Mathieu Duponchelle <mathieu@centricular.com>",
)
});
Some(&*ELEMENT_METADATA)
}
fn pad_templates() -> &'static [gst::PadTemplate] {
static PAD_TEMPLATES: Lazy<Vec<gst::PadTemplate>> = Lazy::new(|| {
let caps = gst::Caps::new_any();
let sink_pad_template = gst::PadTemplate::new(
"sink",
gst::PadDirection::Sink,
gst::PadPresence::Always,
&caps,
)
.unwrap();
vec![sink_pad_template]
});
PAD_TEMPLATES.as_ref()
}
fn change_state(
&self,
transition: gst::StateChange,
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
gst::trace!(CAT, imp: self, "Changing state {:?}", transition);
if transition == gst::StateChange::ReadyToPaused {
if let Err(err) = self.prepare() {
gst::element_error!(
self.obj(),
gst::StreamError::Failed,
["Failed to prepare: {}", err]
);
return Err(gst::StateChangeError);
}
}
let ret = self.parent_change_state(transition)?;
if transition == gst::StateChange::PausedToReady {
self.unprepare();
}
Ok(ret)
}
}
impl BinImpl for InterSink {}

View file

@ -0,0 +1,35 @@
// SPDX-License-Identifier: MPL-2.0
use glib::prelude::*;
use gst::glib;
mod imp;
/**
* SECTION:element-intersink
*
* #intersink is an element that can be used to produce data for
* multiple #intersrc elements to consume.
*
* You can access the underlying appsink element through the static name
* "appsink".
*
* #intersink should not reside in the same pipeline as the #intersrc
* that consumes from it, here is an example of how to use those elements
* in separate pipelines:
*
* {{ generic/inter/examples/basic.rs }}
*/
glib::wrapper! {
pub struct InterSink(ObjectSubclass<imp::InterSink>) @extends gst::Bin, gst::Element, gst::Object;
}
pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
gst::Element::register(
Some(plugin),
"intersink",
gst::Rank::NONE,
InterSink::static_type(),
)
}

View file

@ -0,0 +1,203 @@
// SPDX-License-Identifier: MPL-2.0
use crate::streamproducer::InterStreamProducer;
use anyhow::Error;
use gst::glib;
use gst::prelude::*;
use gst::subclass::prelude::*;
use std::sync::Mutex;
use once_cell::sync::Lazy;
const DEFAULT_PRODUCER_NAME: &str = "default";
#[derive(Debug)]
struct Settings {
producer_name: String,
}
impl Default for Settings {
fn default() -> Self {
Settings {
producer_name: DEFAULT_PRODUCER_NAME.to_string(),
}
}
}
struct State {
srcpad: gst::GhostPad,
appsrc: gst_app::AppSrc,
}
/* Locking order is field order */
pub struct InterSrc {
settings: Mutex<Settings>,
state: Mutex<State>,
}
impl InterSrc {
fn prepare(&self) -> Result<(), Error> {
let settings = self.settings.lock().unwrap();
let state = self.state.lock().unwrap();
InterStreamProducer::subscribe(&settings.producer_name, &state.appsrc);
Ok(())
}
fn unprepare(&self) {
let settings = self.settings.lock().unwrap();
let state = self.state.lock().unwrap();
InterStreamProducer::unsubscribe(&settings.producer_name, &state.appsrc);
}
}
static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
gst::DebugCategory::new("intersrc", gst::DebugColorFlags::empty(), Some("Inter Src"))
});
#[glib::object_subclass]
impl ObjectSubclass for InterSrc {
const NAME: &'static str = "GstInterSrc";
type Type = super::InterSrc;
type ParentType = gst::Bin;
fn with_class(klass: &Self::Class) -> Self {
let templ = klass.pad_template("src").unwrap();
let srcpad = gst::GhostPad::from_template(&templ);
Self {
settings: Mutex::new(Default::default()),
state: Mutex::new(State {
srcpad: srcpad.upcast(),
appsrc: gst_app::AppSrc::builder().name("appsrc").build(),
}),
}
}
}
impl ObjectImpl for InterSrc {
fn properties() -> &'static [glib::ParamSpec] {
static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
vec![glib::ParamSpecString::builder("producer-name")
.nick("Producer Name")
.blurb("Producer Name to consume from")
.doc_show_default()
.mutable_playing()
.build()]
});
PROPERTIES.as_ref()
}
fn set_property(&self, _id: usize, value: &glib::Value, pspec: &glib::ParamSpec) {
match pspec.name() {
"producer-name" => {
let mut settings = self.settings.lock().unwrap();
let old_producer_name = settings.producer_name.clone();
settings.producer_name = value
.get::<String>()
.unwrap_or_else(|_| DEFAULT_PRODUCER_NAME.to_string());
let state = self.state.lock().unwrap();
if InterStreamProducer::unsubscribe(&old_producer_name, &state.appsrc) {
InterStreamProducer::subscribe(&settings.producer_name, &state.appsrc);
}
}
_ => unimplemented!(),
};
}
fn property(&self, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
match pspec.name() {
"producer-name" => {
let settings = self.settings.lock().unwrap();
settings.producer_name.to_value()
}
_ => unimplemented!(),
}
}
fn constructed(&self) {
self.parent_constructed();
let obj = self.obj();
obj.set_suppressed_flags(gst::ElementFlags::SINK | gst::ElementFlags::SOURCE);
obj.set_element_flags(gst::ElementFlags::SOURCE);
let state = self.state.lock().unwrap();
gst_utils::StreamProducer::configure_consumer(&state.appsrc);
obj.add(&state.appsrc).unwrap();
obj.add_pad(&state.srcpad).unwrap();
state
.srcpad
.set_target(Some(&state.appsrc.static_pad("src").unwrap()))
.unwrap();
}
}
impl GstObjectImpl for InterSrc {}
impl ElementImpl for InterSrc {
fn metadata() -> Option<&'static gst::subclass::ElementMetadata> {
static ELEMENT_METADATA: Lazy<gst::subclass::ElementMetadata> = Lazy::new(|| {
gst::subclass::ElementMetadata::new(
"Inter Src",
"Generic/Src",
"Inter Src",
"Mathieu Duponchelle <mathieu@centricular.com>",
)
});
Some(&*ELEMENT_METADATA)
}
fn pad_templates() -> &'static [gst::PadTemplate] {
static PAD_TEMPLATES: Lazy<Vec<gst::PadTemplate>> = Lazy::new(|| {
let caps = gst::Caps::new_any();
let src_pad_template = gst::PadTemplate::new(
"src",
gst::PadDirection::Src,
gst::PadPresence::Always,
&caps,
)
.unwrap();
vec![src_pad_template]
});
PAD_TEMPLATES.as_ref()
}
fn change_state(
&self,
transition: gst::StateChange,
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
gst::trace!(CAT, imp: self, "Changing state {:?}", transition);
if transition == gst::StateChange::ReadyToPaused {
if let Err(err) = self.prepare() {
gst::element_error!(
self.obj(),
gst::StreamError::Failed,
["Failed to prepare: {}", err]
);
return Err(gst::StateChangeError);
}
}
let ret = self.parent_change_state(transition)?;
if transition == gst::StateChange::PausedToReady {
self.unprepare();
}
Ok(ret)
}
}
impl BinImpl for InterSrc {}

View file

@ -0,0 +1,34 @@
// SPDX-License-Identifier: MPL-2.0
use glib::prelude::*;
use gst::glib;
mod imp;
/**
* SECTION:element-intersrc
*
* #intersrc is an element that can be used to consume data from an #intersink.
*
* You can access the underlying appsrc element through the static name
* "appsrc".
*
* #intersrc should not reside in the same pipeline as the #intersink
* that it consumes from, here is an example of how to use those elements
* in separate pipelines:
*
* {{ generic/inter/examples/basic.rs }}
*/
glib::wrapper! {
pub struct InterSrc(ObjectSubclass<imp::InterSrc>) @extends gst::Bin, gst::Element, gst::Object;
}
pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
gst::Element::register(
Some(plugin),
"intersrc",
gst::Rank::NONE,
InterSrc::static_type(),
)
}

View file

@ -0,0 +1,159 @@
use gst::prelude::*;
use std::collections::{HashMap, HashSet};
use std::sync::Mutex;
use anyhow::{anyhow, Error};
use once_cell::sync::Lazy;
pub enum InterStreamProducer {
Pending {
consumers: HashSet<gst_app::AppSrc>,
},
Active {
producer: gst_utils::StreamProducer,
links: HashMap<gst_app::AppSrc, gst_utils::ConsumptionLink>,
},
}
static PRODUCERS: Lazy<Mutex<HashMap<String, InterStreamProducer>>> =
Lazy::new(|| Mutex::new(HashMap::new()));
fn toplevel(obj: &gst::Object) -> gst::Object {
if let Some(parent) = obj.parent() {
toplevel(&parent)
} else {
obj.clone()
}
}
fn ensure_different_toplevel(producer: &gst_app::AppSink, consumer: &gst_app::AppSrc) {
let top_a = toplevel(producer.upcast_ref());
let top_b = toplevel(consumer.upcast_ref());
if top_a == top_b {
gst::glib::g_critical!(
"gstrsinter",
"Intersink with appsink {} should not share the same toplevel bin \
as intersrc with appsrc {}, this results in loops in latency calculation",
producer.name(),
consumer.name()
);
}
}
impl InterStreamProducer {
pub fn acquire(
name: &str,
appsink: &gst_app::AppSink,
) -> Result<gst_utils::StreamProducer, Error> {
let mut producers = PRODUCERS.lock().unwrap();
if let Some(producer) = producers.remove(name) {
match producer {
InterStreamProducer::Pending { consumers } => {
let producer = gst_utils::StreamProducer::from(appsink);
let mut links = HashMap::new();
for consumer in consumers {
ensure_different_toplevel(appsink, &consumer);
let link = producer
.add_consumer(&consumer)
.expect("consumer should not have already been added");
links.insert(consumer, link);
}
producers.insert(
name.to_string(),
InterStreamProducer::Active {
producer: producer.clone(),
links,
},
);
Ok(producer)
}
InterStreamProducer::Active { .. } => {
producers.insert(name.to_string(), producer);
Err(anyhow!(
"An active producer already exists with name {}",
name
))
}
}
} else {
let producer = gst_utils::StreamProducer::from(appsink);
producers.insert(
name.to_string(),
InterStreamProducer::Active {
producer: producer.clone(),
links: HashMap::new(),
},
);
Ok(producer)
}
}
pub fn release(name: &str) -> Option<gst_app::AppSink> {
let mut producers = PRODUCERS.lock().unwrap();
if let Some(producer) = producers.remove(name) {
match producer {
InterStreamProducer::Pending { .. } => None,
InterStreamProducer::Active { links, producer } => {
producers.insert(
name.to_string(),
InterStreamProducer::Pending {
consumers: links.into_keys().collect(),
},
);
Some(producer.appsink().clone())
}
}
} else {
None
}
}
pub fn subscribe(name: &str, consumer: &gst_app::AppSrc) {
let mut producers = PRODUCERS.lock().unwrap();
if let Some(producer) = producers.get_mut(name) {
match producer {
InterStreamProducer::Pending { consumers } => {
consumers.insert(consumer.clone());
}
InterStreamProducer::Active { producer, links } => {
ensure_different_toplevel(producer.appsink(), consumer);
let link = producer
.add_consumer(consumer)
.expect("consumer should not already have been added");
links.insert(consumer.clone(), link);
}
}
} else {
let producer = InterStreamProducer::Pending {
consumers: [consumer.clone()].into(),
};
producers.insert(name.to_string(), producer);
}
}
pub fn unsubscribe(name: &str, consumer: &gst_app::AppSrc) -> bool {
let mut producers = PRODUCERS.lock().unwrap();
if let Some(producer) = producers.get_mut(name) {
match producer {
InterStreamProducer::Pending { consumers } => consumers.remove(consumer),
InterStreamProducer::Active { links, .. } => links.remove(consumer).is_some(),
}
} else {
false
}
}
}

View file

@ -0,0 +1,138 @@
// SPDX-License-Identifier: MPL-2.0
use gst::prelude::*;
use serial_test::serial;
use pretty_assertions::assert_eq;
fn init() {
use std::sync::Once;
static INIT: Once = Once::new();
INIT.call_once(|| {
gst::init().unwrap();
gstrsinter::plugin_register_static().unwrap();
});
}
fn start_consumer(producer_name: &str) -> gst_check::Harness {
let mut hc = gst_check::Harness::new("intersrc");
hc.element()
.unwrap()
.set_property("producer-name", producer_name);
hc.play();
hc
}
fn start_producer(producer_name: &str) -> (gst::Pad, gst::Element) {
let element = gst::ElementFactory::make("intersink").build().unwrap();
element.set_property("producer-name", producer_name);
element.set_state(gst::State::Playing).unwrap();
let sinkpad = element.static_pad("sink").unwrap();
let srcpad = gst::Pad::new(gst::PadDirection::Src);
srcpad.set_active(true).unwrap();
srcpad.link(&sinkpad).unwrap();
srcpad.push_event(gst::event::StreamStart::builder("foo").build());
srcpad
.push_event(gst::event::Caps::builder(&gst::Caps::builder("video/x-raw").build()).build());
srcpad.push_event(
gst::event::Segment::builder(&gst::FormattedSegment::<gst::format::Time>::new()).build(),
);
(srcpad, element)
}
fn push_one(srcpad: &gst::Pad, pts: gst::ClockTime) {
let mut inbuf = gst::Buffer::with_size(1).unwrap();
{
let buf = inbuf.get_mut().unwrap();
buf.set_pts(pts);
}
srcpad.push(inbuf).unwrap();
}
#[test]
#[serial]
fn test_forward_one_buffer() {
init();
let mut hc = start_consumer("p1");
let (srcpad, element) = start_producer("p1");
push_one(&srcpad, gst::ClockTime::from_nseconds(1));
let outbuf = hc.pull().unwrap();
assert_eq!(outbuf.pts(), Some(gst::ClockTime::from_nseconds(1)));
element.set_state(gst::State::Null).unwrap();
}
#[test]
#[serial]
fn test_change_name_of_producer() {
init();
let mut hc1 = start_consumer("p1");
let mut hc2 = start_consumer("p2");
let (srcpad, element) = start_producer("p1");
/* Once this returns, the buffer should have been dispatched only to hc1 */
push_one(&srcpad, gst::ClockTime::from_nseconds(1));
let outbuf = hc1.pull().unwrap();
assert_eq!(outbuf.pts(), Some(gst::ClockTime::from_nseconds(1)));
element.set_property("producer-name", "p2");
/* This should only get dispatched to hc2, and it should be its first buffer */
push_one(&srcpad, gst::ClockTime::from_nseconds(2));
let outbuf = hc2.pull().unwrap();
assert_eq!(outbuf.pts(), Some(gst::ClockTime::from_nseconds(2)));
element.set_property("producer-name", "p1");
/* Back to hc1, which should not see the buffer we pushed in the previous step */
push_one(&srcpad, gst::ClockTime::from_nseconds(3));
let outbuf = hc1.pull().unwrap();
assert_eq!(outbuf.pts(), Some(gst::ClockTime::from_nseconds(3)));
element.set_state(gst::State::Null).unwrap();
}
#[test]
#[serial]
fn test_change_producer_name() {
init();
let mut hc = start_consumer("p1");
let (srcpad1, element1) = start_producer("p1");
let (srcpad2, element2) = start_producer("p2");
/* This buffer should be dispatched to no consumer */
push_one(&srcpad2, gst::ClockTime::from_nseconds(1));
/* This one should be dispatched to hc, and it should be its first buffer */
push_one(&srcpad1, gst::ClockTime::from_nseconds(2));
let outbuf = hc.pull().unwrap();
assert_eq!(outbuf.pts(), Some(gst::ClockTime::from_nseconds(2)));
hc.element().unwrap().set_property("producer-name", "p2");
/* This buffer should be dispatched to no consumer */
push_one(&srcpad1, gst::ClockTime::from_nseconds(3));
/* This one should be dispatched to hc, and it should be its next buffer */
push_one(&srcpad2, gst::ClockTime::from_nseconds(4));
let outbuf = hc.pull().unwrap();
assert_eq!(outbuf.pts(), Some(gst::ClockTime::from_nseconds(4)));
element1.set_state(gst::State::Null).unwrap();
element2.set_state(gst::State::Null).unwrap();
}

View file

@ -0,0 +1,43 @@
[package]
name = "gst-plugin-originalbuffer"
version.workspace = true
authors = ["Olivier Crête <olivier.crete@collabora.com>"]
repository.workspace = true
license = "MPL-2.0"
description = "GStreamer Origin buffer meta Plugin"
edition.workspace = true
rust-version.workspace = true
[dependencies]
glib.workspace = true
gst.workspace = true
gst-video.workspace = true
atomic_refcell = "0.1"
once_cell.workspace = true
[lib]
name = "gstoriginalbuffer"
crate-type = ["cdylib", "rlib"]
path = "src/lib.rs"
[build-dependencies]
gst-plugin-version-helper.workspace = true
[features]
static = []
capi = []
doc = ["gst/v1_16"]
[package.metadata.capi]
min_version = "0.9.21"
[package.metadata.capi.header]
enabled = false
[package.metadata.capi.library]
install_subdir = "gstreamer-1.0"
versioning = false
import_library = false
[package.metadata.capi.pkg_config]
requires_private = "gstreamer-1.0, gstreamer-base-1.0, gobject-2.0, glib-2.0, gmodule-2.0"

View file

@ -0,0 +1,3 @@
fn main() {
gst_plugin_version_helper::info()
}

View file

@ -0,0 +1,38 @@
// Copyright (C) 2024 Collabora Ltd
// @author: Olivier Crête <olivier.crete@collabora.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License, v2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at
// <https://mozilla.org/MPL/2.0/>.
//
// SPDX-License-Identifier: MPL-2.0
#![allow(clippy::non_send_fields_in_send_ty, unused_doc_comments)]
/**
* plugin-originalbuffer:
*
* Since: plugins-rs-0.12 */
use gst::glib;
mod originalbuffermeta;
mod originalbufferrestore;
mod originalbuffersave;
fn plugin_init(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
originalbuffersave::register(plugin)?;
originalbufferrestore::register(plugin)?;
Ok(())
}
gst::plugin_define!(
originalbuffer,
env!("CARGO_PKG_DESCRIPTION"),
plugin_init,
concat!(env!("CARGO_PKG_VERSION"), "-", env!("COMMIT_ID")),
"MPL",
env!("CARGO_PKG_NAME"),
env!("CARGO_PKG_NAME"),
env!("CARGO_PKG_REPOSITORY"),
env!("BUILD_REL_DATE")
);

View file

@ -0,0 +1,199 @@
// Copyright (C) 2024 Collabora Ltd
// @author: Olivier Crête <olivier.crete@collabora.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License, v2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at
// <https://mozilla.org/MPL/2.0/>.
//
// SPDX-License-Identifier: MPL-2.0
use gst::prelude::*;
use std::fmt;
use std::mem;
#[repr(transparent)]
pub struct OriginalBufferMeta(imp::OriginalBufferMeta);
unsafe impl Send for OriginalBufferMeta {}
unsafe impl Sync for OriginalBufferMeta {}
impl OriginalBufferMeta {
pub fn add(
buffer: &mut gst::BufferRef,
original: gst::Buffer,
caps: Option<gst::Caps>,
) -> gst::MetaRefMut<'_, Self, gst::meta::Standalone> {
unsafe {
// Manually dropping because gst_buffer_add_meta() takes ownership of the
// content of the struct
let mut params =
mem::ManuallyDrop::new(imp::OriginalBufferMetaParams { original, caps });
let meta = gst::ffi::gst_buffer_add_meta(
buffer.as_mut_ptr(),
imp::original_buffer_meta_get_info(),
&mut *params as *mut imp::OriginalBufferMetaParams as gst::glib::ffi::gpointer,
) as *mut imp::OriginalBufferMeta;
Self::from_mut_ptr(buffer, meta)
}
}
pub fn replace(&mut self, original: gst::Buffer, caps: Option<gst::Caps>) {
self.0.original = Some(original);
self.0.caps = caps;
}
pub fn original(&self) -> &gst::Buffer {
self.0.original.as_ref().unwrap()
}
pub fn caps(&self) -> &gst::Caps {
self.0.caps.as_ref().unwrap()
}
}
unsafe impl MetaAPI for OriginalBufferMeta {
type GstType = imp::OriginalBufferMeta;
fn meta_api() -> gst::glib::Type {
imp::original_buffer_meta_api_get_type()
}
}
impl fmt::Debug for OriginalBufferMeta {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("OriginalBufferMeta")
.field("buffer", &self.original())
.finish()
}
}
mod imp {
use gst::glib::translate::*;
use once_cell::sync::Lazy;
use std::mem;
use std::ptr;
pub(super) struct OriginalBufferMetaParams {
pub original: gst::Buffer,
pub caps: Option<gst::Caps>,
}
#[repr(C)]
pub struct OriginalBufferMeta {
parent: gst::ffi::GstMeta,
pub(super) original: Option<gst::Buffer>,
pub(super) caps: Option<gst::Caps>,
}
pub(super) fn original_buffer_meta_api_get_type() -> glib::Type {
static TYPE: Lazy<glib::Type> = Lazy::new(|| unsafe {
let t = from_glib(gst::ffi::gst_meta_api_type_register(
b"GstOriginalBufferMetaAPI\0".as_ptr() as *const _,
[ptr::null::<std::os::raw::c_char>()].as_ptr() as *mut *const _,
));
assert_ne!(t, glib::Type::INVALID);
t
});
*TYPE
}
unsafe extern "C" fn original_buffer_meta_init(
meta: *mut gst::ffi::GstMeta,
params: glib::ffi::gpointer,
_buffer: *mut gst::ffi::GstBuffer,
) -> glib::ffi::gboolean {
assert!(!params.is_null());
let meta = &mut *(meta as *mut OriginalBufferMeta);
let params = ptr::read(params as *const OriginalBufferMetaParams);
let OriginalBufferMetaParams { original, caps } = params;
ptr::write(&mut meta.original, Some(original));
ptr::write(&mut meta.caps, caps);
true.into_glib()
}
unsafe extern "C" fn original_buffer_meta_free(
meta: *mut gst::ffi::GstMeta,
_buffer: *mut gst::ffi::GstBuffer,
) {
let meta = &mut *(meta as *mut OriginalBufferMeta);
meta.original = None;
meta.caps = None;
}
unsafe extern "C" fn original_buffer_meta_transform(
dest: *mut gst::ffi::GstBuffer,
meta: *mut gst::ffi::GstMeta,
_buffer: *mut gst::ffi::GstBuffer,
_type_: glib::ffi::GQuark,
_data: glib::ffi::gpointer,
) -> glib::ffi::gboolean {
let dest = gst::BufferRef::from_mut_ptr(dest);
let meta = &*(meta as *const OriginalBufferMeta);
if dest.meta::<super::OriginalBufferMeta>().is_some() {
return true.into_glib();
}
// We don't store a ref in the meta if it's self-refencing, but we add it
// when copying the meta to another buffer.
super::OriginalBufferMeta::add(
dest,
meta.original.as_ref().unwrap().clone(),
meta.caps.clone(),
);
true.into_glib()
}
pub(super) fn original_buffer_meta_get_info() -> *const gst::ffi::GstMetaInfo {
struct MetaInfo(ptr::NonNull<gst::ffi::GstMetaInfo>);
unsafe impl Send for MetaInfo {}
unsafe impl Sync for MetaInfo {}
static META_INFO: Lazy<MetaInfo> = Lazy::new(|| unsafe {
MetaInfo(
ptr::NonNull::new(gst::ffi::gst_meta_register(
original_buffer_meta_api_get_type().into_glib(),
b"OriginalBufferMeta\0".as_ptr() as *const _,
mem::size_of::<OriginalBufferMeta>(),
Some(original_buffer_meta_init),
Some(original_buffer_meta_free),
Some(original_buffer_meta_transform),
) as *mut gst::ffi::GstMetaInfo)
.expect("Failed to register meta API"),
)
});
META_INFO.0.as_ptr()
}
}
#[test]
fn test() {
gst::init().unwrap();
let mut b = gst::Buffer::with_size(10).unwrap();
let caps = gst::Caps::new_empty_simple("video/x-raw");
let copy = b.copy();
let m = OriginalBufferMeta::add(b.make_mut(), copy, Some(caps.clone()));
assert_eq!(m.caps(), caps.as_ref());
assert_eq!(m.original().clone(), b);
let b2: gst::Buffer = b.copy_deep().unwrap();
let m = b.meta::<OriginalBufferMeta>().unwrap();
assert_eq!(m.caps(), caps.as_ref());
assert_eq!(m.original(), &b);
let m = b2.meta::<OriginalBufferMeta>().unwrap();
assert_eq!(m.caps(), caps.as_ref());
assert_eq!(m.original(), &b);
let b3: gst::Buffer = b2.copy_deep().unwrap();
drop(b2);
let m = b3.meta::<OriginalBufferMeta>().unwrap();
assert_eq!(m.caps(), caps.as_ref());
assert_eq!(m.original(), &b);
}

View file

@ -0,0 +1,315 @@
// Copyright (C) 2024 Collabora Ltd
// @author: Olivier Crête <olivier.crete@collabora.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License, v2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at
// <https://mozilla.org/MPL/2.0/>.
//
// SPDX-License-Identifier: MPL-2.0
use gst::glib;
use gst::subclass::prelude::*;
use gst_video::prelude::*;
use atomic_refcell::AtomicRefCell;
use crate::originalbuffermeta;
use crate::originalbuffermeta::OriginalBufferMeta;
struct CapsState {
caps: gst::Caps,
vinfo: Option<gst_video::VideoInfo>,
}
impl Default for CapsState {
fn default() -> Self {
CapsState {
caps: gst::Caps::new_empty(),
vinfo: None,
}
}
}
#[derive(Default)]
struct State {
sinkpad_caps: CapsState,
meta_caps: CapsState,
sinkpad_segment: Option<gst::Event>,
}
pub struct OriginalBufferRestore {
state: AtomicRefCell<State>,
src_pad: gst::Pad,
sink_pad: gst::Pad,
}
use once_cell::sync::Lazy;
#[cfg(unused_code)]
static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
gst::DebugCategory::new(
"originalbufferrestore",
gst::DebugColorFlags::empty(),
Some("Restore Original buffer as meta"),
)
});
#[glib::object_subclass]
impl ObjectSubclass for OriginalBufferRestore {
const NAME: &'static str = "GstOriginalBufferRestore";
type Type = super::OriginalBufferRestore;
type ParentType = gst::Element;
fn with_class(klass: &Self::Class) -> Self {
let sink_templ = klass.pad_template("sink").unwrap();
let src_templ = klass.pad_template("src").unwrap();
let sink_pad = gst::Pad::builder_from_template(&sink_templ)
.chain_function(|pad, parent, buffer| {
OriginalBufferRestore::catch_panic_pad_function(
parent,
|| Err(gst::FlowError::Error),
|obj| obj.sink_chain(pad, buffer),
)
})
.event_function(|pad, parent, event| {
OriginalBufferRestore::catch_panic_pad_function(
parent,
|| false,
|obj| obj.sink_event(pad, parent, event),
)
})
.query_function(|pad, parent, query| {
OriginalBufferRestore::catch_panic_pad_function(
parent,
|| false,
|obj| obj.sink_query(pad, parent, query),
)
})
.build();
let src_pad = gst::Pad::builder_from_template(&src_templ)
.event_function(|pad, parent, event| {
OriginalBufferRestore::catch_panic_pad_function(
parent,
|| false,
|obj| obj.src_event(pad, parent, event),
)
})
.build();
Self {
src_pad,
sink_pad,
state: Default::default(),
}
}
}
impl ObjectImpl for OriginalBufferRestore {
fn constructed(&self) {
self.parent_constructed();
let obj = self.obj();
obj.add_pad(&self.sink_pad).unwrap();
obj.add_pad(&self.src_pad).unwrap();
}
}
impl GstObjectImpl for OriginalBufferRestore {}
impl ElementImpl for OriginalBufferRestore {
fn metadata() -> Option<&'static gst::subclass::ElementMetadata> {
static ELEMENT_METADATA: Lazy<gst::subclass::ElementMetadata> = Lazy::new(|| {
gst::subclass::ElementMetadata::new(
"Original Buffer Restore",
"Generic",
"Restores a reference to the buffer in a meta",
"Olivier Crête <olivier.crete@collabora.com>",
)
});
Some(&*ELEMENT_METADATA)
}
fn pad_templates() -> &'static [gst::PadTemplate] {
static PAD_TEMPLATES: Lazy<Vec<gst::PadTemplate>> = Lazy::new(|| {
let caps = gst::Caps::new_any();
let src_pad_template = gst::PadTemplate::new(
"src",
gst::PadDirection::Src,
gst::PadPresence::Always,
&caps,
)
.unwrap();
let sink_pad_template = gst::PadTemplate::new(
"sink",
gst::PadDirection::Sink,
gst::PadPresence::Always,
&caps,
)
.unwrap();
vec![src_pad_template, sink_pad_template]
});
PAD_TEMPLATES.as_ref()
}
fn change_state(
&self,
transition: gst::StateChange,
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
let ret = self.parent_change_state(transition)?;
if transition == gst::StateChange::PausedToReady {
let mut state = self.state.borrow_mut();
*state = State::default();
}
Ok(ret)
}
}
impl OriginalBufferRestore {
fn sink_event(
&self,
pad: &gst::Pad,
parent: Option<&impl IsA<gst::Object>>,
event: gst::Event,
) -> bool {
match event.view() {
gst::EventView::Caps(e) => {
let mut state = self.state.borrow_mut();
let caps = e.caps_owned();
let vinfo = gst_video::VideoInfo::from_caps(&caps).ok();
state.sinkpad_caps = CapsState { caps, vinfo };
true
}
gst::EventView::Segment(_) => {
let mut state = self.state.borrow_mut();
state.sinkpad_segment = Some(event);
true
}
_ => gst::Pad::event_default(pad, parent, event),
}
}
fn src_event(
&self,
pad: &gst::Pad,
parent: Option<&impl IsA<gst::Object>>,
event: gst::Event,
) -> bool {
if event.type_() == gst::EventType::Reconfigure
|| event.has_name("gst-original-buffer-forward-upstream-event")
{
let s = gst::Structure::builder("gst-original-buffer-forward-upstream-event")
.field("event", event)
.build();
let event = gst::event::CustomUpstream::new(s);
self.sink_pad.push_event(event)
} else {
gst::Pad::event_default(pad, parent, event)
}
}
fn sink_query(
&self,
pad: &gst::Pad,
parent: Option<&impl IsA<gst::Object>>,
query: &mut gst::QueryRef,
) -> bool {
if let gst::QueryViewMut::Custom(_) = query.view_mut() {
let s = query.structure_mut();
if s.has_name("gst-original-buffer-forward-query") {
if let Ok(mut q) = s.get::<gst::Query>("query") {
s.remove_field("query");
assert!(q.is_writable());
let res = self.src_pad.peer_query(q.get_mut().unwrap());
s.set("query", q);
s.set("result", res);
return true;
}
}
}
gst::Pad::query_default(pad, parent, query)
}
fn sink_chain(
&self,
_pad: &gst::Pad,
inbuf: gst::Buffer,
) -> Result<gst::FlowSuccess, gst::FlowError> {
let Some(ometa) = inbuf.meta::<OriginalBufferMeta>() else {
//gst::element_warning!(self, gst::StreamError::Failed, ["Buffer {} is missing the GstOriginalBufferMeta, put originalbuffersave upstream in your pipeline", buffer]);
return Ok(gst::FlowSuccess::Ok);
};
let mut state = self.state.borrow_mut();
let meta_caps = &mut state.meta_caps;
if &meta_caps.caps != ometa.caps() {
if !self.src_pad.push_event(gst::event::Caps::new(ometa.caps())) {
return Err(gst::FlowError::NotNegotiated);
}
meta_caps.caps = ometa.caps().clone();
meta_caps.vinfo = gst_video::VideoInfo::from_caps(&meta_caps.caps).ok();
}
let mut outbuf = ometa.original().copy();
inbuf
.copy_into(
outbuf.make_mut(),
gst::BufferCopyFlags::TIMESTAMPS | gst::BufferCopyFlags::FLAGS,
..,
)
.unwrap();
for meta in inbuf.iter_meta::<gst::Meta>() {
if meta.api() == originalbuffermeta::OriginalBufferMeta::meta_api() {
continue;
}
if meta.has_tag::<gst::meta::tags::Memory>()
|| meta.has_tag::<gst::meta::tags::MemoryReference>()
{
continue;
}
if meta.has_tag::<gst_video::video_meta::tags::Size>() {
if let (Some(ref meta_vinfo), Some(ref sink_vinfo)) =
(&state.meta_caps.vinfo, &state.sinkpad_caps.vinfo)
{
if (meta_vinfo.width() != sink_vinfo.width()
|| meta_vinfo.height() != sink_vinfo.height())
&& meta
.transform(
outbuf.make_mut(),
&gst_video::video_meta::VideoMetaTransformScale::new(
sink_vinfo, meta_vinfo,
),
)
.is_ok()
{
continue;
}
}
}
let _ = meta.transform(
outbuf.make_mut(),
&gst::meta::MetaTransformCopy::new(false, ..),
);
}
if let Some(event) = state.sinkpad_segment.take() {
if !self.src_pad.push_event(event) {
return Err(gst::FlowError::Error);
}
}
self.src_pad.push(outbuf)
}
}

View file

@ -0,0 +1,31 @@
// Copyright (C) 2024 Collabora Ltd
// @author: Olivier Crête <olivier.crete@collabora.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License, v2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at
// <https://mozilla.org/MPL/2.0/>.
//
// SPDX-License-Identifier: MPL-2.0
/**
* SECTION:element-originalbufferrestore
*
* See originalbuffersave for details
*/
use gst::glib;
use gst::prelude::*;
mod imp;
glib::wrapper! {
pub struct OriginalBufferRestore(ObjectSubclass<imp::OriginalBufferRestore>) @extends gst::Element, gst::Object;
}
pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
gst::Element::register(
Some(plugin),
"originalbufferrestore",
gst::Rank::NONE,
OriginalBufferRestore::static_type(),
)
}

View file

@ -0,0 +1,205 @@
// Copyright (C) 2024 Collabora Ltd
// @author: Olivier Crête <olivier.crete@collabora.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License, v2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at
// <https://mozilla.org/MPL/2.0/>.
//
// SPDX-License-Identifier: MPL-2.0
use gst::glib;
use gst::prelude::*;
use gst::subclass::prelude::*;
use crate::originalbuffermeta::OriginalBufferMeta;
pub struct OriginalBufferSave {
src_pad: gst::Pad,
sink_pad: gst::Pad,
}
use once_cell::sync::Lazy;
#[cfg(unused_code)]
static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
gst::DebugCategory::new(
"originalbuffersave",
gst::DebugColorFlags::empty(),
Some("Save Original buffer as meta"),
)
});
#[glib::object_subclass]
impl ObjectSubclass for OriginalBufferSave {
const NAME: &'static str = "GstOriginalBufferSave";
type Type = super::OriginalBufferSave;
type ParentType = gst::Element;
fn with_class(klass: &Self::Class) -> Self {
let sink_templ = klass.pad_template("sink").unwrap();
let src_templ = klass.pad_template("src").unwrap();
let sink_pad = gst::Pad::builder_from_template(&sink_templ)
.chain_function(|pad, parent, buffer| {
OriginalBufferSave::catch_panic_pad_function(
parent,
|| Err(gst::FlowError::Error),
|obj| obj.sink_chain(pad, buffer),
)
})
.query_function(|pad, parent, query| {
OriginalBufferSave::catch_panic_pad_function(
parent,
|| false,
|obj| obj.sink_query(pad, parent, query),
)
})
.flags(gst::PadFlags::PROXY_CAPS | gst::PadFlags::PROXY_ALLOCATION)
.build();
let src_pad = gst::Pad::builder_from_template(&src_templ)
.event_function(|pad, parent, event| {
OriginalBufferSave::catch_panic_pad_function(
parent,
|| false,
|obj| obj.src_event(pad, parent, event),
)
})
.build();
Self { src_pad, sink_pad }
}
}
impl ObjectImpl for OriginalBufferSave {
fn constructed(&self) {
self.parent_constructed();
let obj = self.obj();
obj.add_pad(&self.sink_pad).unwrap();
obj.add_pad(&self.src_pad).unwrap();
}
}
impl GstObjectImpl for OriginalBufferSave {}
impl ElementImpl for OriginalBufferSave {
fn metadata() -> Option<&'static gst::subclass::ElementMetadata> {
static ELEMENT_METADATA: Lazy<gst::subclass::ElementMetadata> = Lazy::new(|| {
gst::subclass::ElementMetadata::new(
"Original Buffer Save",
"Generic",
"Saves a reference to the buffer in a meta",
"Olivier Crête <olivier.crete@collabora.com>",
)
});
Some(&*ELEMENT_METADATA)
}
fn pad_templates() -> &'static [gst::PadTemplate] {
static PAD_TEMPLATES: Lazy<Vec<gst::PadTemplate>> = Lazy::new(|| {
let caps = gst::Caps::new_any();
let src_pad_template = gst::PadTemplate::new(
"src",
gst::PadDirection::Src,
gst::PadPresence::Always,
&caps,
)
.unwrap();
let sink_pad_template = gst::PadTemplate::new(
"sink",
gst::PadDirection::Sink,
gst::PadPresence::Always,
&caps,
)
.unwrap();
vec![src_pad_template, sink_pad_template]
});
PAD_TEMPLATES.as_ref()
}
}
impl OriginalBufferSave {
fn forward_query(&self, query: gst::Query) -> Option<gst::Query> {
let mut s = gst::Structure::new_empty("gst-original-buffer-forward-query");
s.set("query", query);
let mut query = gst::query::Custom::new(s);
if self.src_pad.peer_query(&mut query) {
let s = query.structure_mut();
if let (Ok(true), Ok(q)) = (s.get("result"), s.get::<gst::Query>("query")) {
Some(q)
} else {
None
}
} else {
None
}
}
fn sink_chain(
&self,
pad: &gst::Pad,
inbuf: gst::Buffer,
) -> Result<gst::FlowSuccess, gst::FlowError> {
let mut buf = inbuf.copy();
let caps = pad.current_caps();
if let Some(mut meta) = buf.make_mut().meta_mut::<OriginalBufferMeta>() {
meta.replace(inbuf, caps);
} else {
OriginalBufferMeta::add(buf.make_mut(), inbuf, caps);
}
self.src_pad.push(buf)
}
fn sink_query(
&self,
pad: &gst::Pad,
parent: Option<&impl IsA<gst::Object>>,
query: &mut gst::QueryRef,
) -> bool {
let ret = gst::Pad::query_default(pad, parent, query);
if !ret {
return ret;
}
if let gst::QueryViewMut::Caps(q) = query.view_mut() {
if let Some(caps) = q.result_owned() {
let forwarding_q = gst::query::Caps::new(Some(&caps)).into();
if let Some(forwarding_q) = self.forward_query(forwarding_q) {
if let gst::QueryView::Caps(c) = forwarding_q.view() {
let res = c
.result_owned()
.map(|c| c.intersect_with_mode(&caps, gst::CapsIntersectMode::First));
q.set_result(&res);
}
}
}
}
// We should also do allocation queries, but that requires supporting the same
// intersection semantics as gsttee, which should be in a helper function.
true
}
fn src_event(
&self,
pad: &gst::Pad,
parent: Option<&impl IsA<gst::Object>>,
event: gst::Event,
) -> bool {
let event = if event.has_name("gst-original-buffer-forward-upstream-event") {
event.structure().unwrap().get("event").unwrap()
} else {
event
};
gst::Pad::event_default(pad, parent, event)
}
}

View file

@ -0,0 +1,41 @@
// Copyright (C) 2024 Collabora Ltd
// @author: Olivier Crête <olivier.crete@collabora.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License, v2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at
// <https://mozilla.org/MPL/2.0/>.
//
// SPDX-License-Identifier: MPL-2.0
/**
* SECTION:element-originalbuffersave
*
* GStreamer elements to store the original buffer and restore it later
*
* In many analysis scenario (for example machine learning), it is desirable to
* use a pre-processed buffer, for example by lowering the resolution, but we may
* want to take the output of this analysis, and apply it to the original buffer.
*
* These elements do just this, the typical usage would be a pipeline like:
*
* `... ! originalbuffersave ! videoconvertscale ! video/x-raw, width=100, height=100 ! analysiselement ! originalbufferrestore ! ...`
*
* The originalbufferrestore element will "restore" the buffer that was entered to the "save" element, but will keep any metadata that was added later.
*/
use gst::glib;
use gst::prelude::*;
mod imp;
glib::wrapper! {
pub struct OriginalBufferSave(ObjectSubclass<imp::OriginalBufferSave>) @extends gst::Element, gst::Object;
}
pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
gst::Element::register(
Some(plugin),
"originalbuffersave",
gst::Rank::NONE,
OriginalBufferSave::static_type(),
)
}

View file

@ -1,16 +1,16 @@
[package]
name = "gst-plugin-sodium"
version = "0.9.13"
version.workspace = true
authors = ["Jordan Petridis <jordan@centricular.com>"]
repository = "https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs"
repository.workspace = true
description = "GStreamer plugin for libsodium-based file encryption and decryption"
license = "MIT"
edition = "2021"
rust-version = "1.63"
edition.workspace = true
rust-version.workspace = true
[dependencies]
gst = { package="gstreamer", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "0.19", version = "0.19" }
gst-base = { package = "gstreamer-base", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "0.19", version = "0.19" }
gst.workspace = true
gst-base.workspace = true
sodiumoxide = "0.2.1"
once_cell = "1.3.0"
hex = "0.4"
@ -24,18 +24,8 @@ serde_json = { version = "1.0", optional = true }
[dev-dependencies]
pretty_assertions = "1"
rand = "0.8"
[dev-dependencies.gst-check]
git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
branch = "0.19"
version = "0.19"
package="gstreamer-check"
[dev-dependencies.gst-app]
git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"
branch = "0.19"
version = "0.19"
package="gstreamer-app"
gst-check.workspace = true
gst-app.workspace = true
[lib]
name = "gstsodium"
@ -58,7 +48,7 @@ path = "examples/decrypt_example.rs"
required-features = ["serde", "serde_json", "clap"]
[build-dependencies]
gst-plugin-version-helper = { version = "0.7", path="../../version-helper" }
gst-plugin-version-helper.workspace = true
[features]
static = []
@ -66,7 +56,7 @@ capi = []
doc = ["gst/v1_18"]
[package.metadata.capi]
min_version = "0.8.0"
min_version = "0.9.21"
[package.metadata.capi.header]
enabled = false
@ -74,6 +64,7 @@ enabled = false
[package.metadata.capi.library]
install_subdir = "gstreamer-1.0"
versioning = false
import_library = false
[package.metadata.capi.pkg_config]
requires_private = "gstreamer-1.0, gstreamer-base-1.0, gobject-2.0, glib-2.0, gmodule-2.0, libsodium"

View file

@ -100,11 +100,11 @@ fn main() -> Result<(), Box<dyn Error>> {
.build()
.unwrap();
let pipeline = gst::Pipeline::builder().name("test-pipeline").build();
let pipeline = gst::Pipeline::with_name("test-pipeline");
pipeline
.add_many(&[&filesrc, &decrypter, &typefind, &filesink])
.add_many([&filesrc, &decrypter, &typefind, &filesink])
.expect("failed to add elements to the pipeline");
gst::Element::link_many(&[&filesrc, &decrypter, &typefind, &filesink])
gst::Element::link_many([&filesrc, &decrypter, &typefind, &filesink])
.expect("failed to link the elements");
pipeline

View file

@ -103,11 +103,11 @@ fn main() -> Result<(), Box<dyn Error>> {
.build()
.unwrap();
let pipeline = gst::Pipeline::builder().name("test-pipeline").build();
let pipeline = gst::Pipeline::with_name("test-pipeline");
pipeline
.add_many(&[&filesrc, &encrypter, &filesink])
.add_many([&filesrc, &encrypter, &filesink])
.expect("failed to add elements to the pipeline");
gst::Element::link_many(&[&filesrc, &encrypter, &filesink])
gst::Element::link_many([&filesrc, &encrypter, &filesink])
.expect("failed to link the elements");
pipeline.set_state(gst::State::Playing)?;

View file

@ -61,11 +61,10 @@ impl State {
.ok_or_else(|| {
gst::error_msg!(
gst::ResourceError::NotFound,
[format!(
[
"Failed to set Sender's Key from property: {:?}",
props.sender_key
)
.as_ref()]
]
)
})?;
@ -76,11 +75,10 @@ impl State {
.ok_or_else(|| {
gst::error_msg!(
gst::ResourceError::NotFound,
[format!(
[
"Failed to set Receiver's Key from property: {:?}",
props.receiver_key
)
.as_ref()]
]
)
})?;
@ -488,7 +486,7 @@ impl Decrypter {
let block_size = {
let mut mutex_state = self.state.lock().unwrap();
// This will only be run after READY state,
// and will be guaranted to be initialized
// and will be guaranteed to be initialized
let state = mutex_state.as_mut().unwrap();
// Cleanup the adapter
state.adapter.clear();
@ -510,7 +508,7 @@ impl Decrypter {
let mut state = self.state.lock().unwrap();
// This will only be run after READY state,
// and will be guaranted to be initialized
// and will be guaranteed to be initialized
let state = state.as_mut().unwrap();
state.decrypt_into_adapter(self, &self.srcpad, &pulled_buffer, chunk_index)?;
@ -528,10 +526,10 @@ impl ObjectSubclass for Decrypter {
fn with_class(klass: &Self::Class) -> Self {
let templ = klass.pad_template("sink").unwrap();
let sinkpad = gst::Pad::from_template(&templ, Some("sink"));
let sinkpad = gst::Pad::from_template(&templ);
let templ = klass.pad_template("src").unwrap();
let srcpad = gst::Pad::builder_with_template(&templ, Some("src"))
let srcpad = gst::Pad::builder_from_template(&templ)
.getrange_function(|pad, parent, offset, buffer, size| {
Decrypter::catch_panic_pad_function(
parent,

View file

@ -35,7 +35,7 @@ pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
gst::Element::register(
Some(plugin),
"sodiumdecrypter",
gst::Rank::None,
gst::Rank::NONE,
Decrypter::static_type(),
)
}

View file

@ -76,11 +76,10 @@ impl State {
.ok_or_else(|| {
gst::error_msg!(
gst::ResourceError::NotFound,
[format!(
[
"Failed to set Sender's Key from property: {:?}",
props.sender_key
)
.as_ref()]
]
)
})?;
@ -91,16 +90,15 @@ impl State {
.ok_or_else(|| {
gst::error_msg!(
gst::ResourceError::NotFound,
[format!(
[
"Failed to set Receiver's Key from property: {:?}",
props.receiver_key
)
.as_ref()]
]
)
})?;
// This env variable is only meant to bypass nonce regeneration during
// tests to get determinisic results. It should never be used outside
// tests to get deterministic results. It should never be used outside
// of testing environments.
let nonce = if let Ok(val) = std::env::var("GST_SODIUM_ENCRYPT_NONCE") {
let bytes = hex::decode(val).expect("Failed to decode hex variable");
@ -218,7 +216,7 @@ impl Encrypter {
let mut state_mutex = self.state.lock().unwrap();
let mut buffers = BufferVec::new();
// This will only be run after READY state,
// and will be guaranted to be initialized
// and will be guaranteed to be initialized
let state = state_mutex.as_mut().unwrap();
// Now that all the full size blocks are pushed, drain the
@ -331,7 +329,7 @@ impl ObjectSubclass for Encrypter {
fn with_class(klass: &Self::Class) -> Self {
let templ = klass.pad_template("sink").unwrap();
let sinkpad = gst::Pad::builder_with_template(&templ, Some("sink"))
let sinkpad = gst::Pad::builder_from_template(&templ)
.chain_function(|pad, parent, buffer| {
Encrypter::catch_panic_pad_function(
parent,
@ -349,7 +347,7 @@ impl ObjectSubclass for Encrypter {
.build();
let templ = klass.pad_template("src").unwrap();
let srcpad = gst::Pad::builder_with_template(&templ, Some("src"))
let srcpad = gst::Pad::builder_from_template(&templ)
.query_function(|pad, parent, query| {
Encrypter::catch_panic_pad_function(
parent,

View file

@ -35,7 +35,7 @@ pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
gst::Element::register(
Some(plugin),
"sodiumencrypter",
gst::Rank::None,
gst::Rank::NONE,
Encrypter::static_type(),
)
}

View file

@ -46,7 +46,7 @@ fn typefind_register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
TypeFind::register(
Some(plugin),
"sodium_encrypted_typefind",
gst::Rank::None,
gst::Rank::NONE,
None,
Some(&Caps::builder("application/x-sodium-encrypted").build()),
|typefind| {

View file

@ -91,9 +91,9 @@ fn test_pipeline() {
let sink = gst_app::AppSink::builder().build();
pipeline
.add_many(&[&filesrc, &dec, &typefind, sink.upcast_ref()])
.add_many([&filesrc, &dec, &typefind, sink.upcast_ref()])
.expect("failed to add elements to the pipeline");
gst::Element::link_many(&[&filesrc, &dec, &typefind, sink.upcast_ref()])
gst::Element::link_many([&filesrc, &dec, &typefind, sink.upcast_ref()])
.expect("failed to link the elements");
let adapter = Arc::new(Mutex::new(gst_base::UniqueAdapter::new()));
@ -179,9 +179,9 @@ fn test_pull_range() {
.unwrap();
pipeline
.add_many(&[&filesrc, &dec])
.add_many([&filesrc, &dec])
.expect("failed to add elements to the pipeline");
gst::Element::link_many(&[&filesrc, &dec]).expect("failed to link the elements");
gst::Element::link_many([&filesrc, &dec]).expect("failed to link the elements");
// Activate in the pad in pull mode
pipeline

View file

@ -1,28 +1,29 @@
[package]
name = "gst-plugin-threadshare"
version = "0.9.13"
version.workspace = true
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
license = "LGPL-2.1-or-later"
description = "GStreamer Threadshare Plugin"
repository = "https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs"
edition = "2021"
rust-version = "1.63"
repository.workspace = true
edition.workspace = true
rust-version.workspace = true
[dependencies]
async-task = "4.3.0"
concurrent-queue = "2"
flume = "0.10.13"
futures = "0.3.21"
libc = "0.2"
gio = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.16", version = "0.16" }
gst = { package = "gstreamer", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "0.19", version = "0.19.1" }
gst-audio = { package = "gstreamer-audio", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "0.19", version = "0.19" }
gst-net = { package = "gstreamer-net", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "0.19", version = "0.19" }
gst-rtp = { package = "gstreamer-rtp", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "0.19", version = "0.19" }
once_cell = "1"
cfg-if = "1"
concurrent-queue = "2.2.0"
flume = "0.11"
futures = "0.3.28"
gio.workspace = true
gst.workspace = true
gst-audio.workspace = true
gst-net.workspace = true
gst-rtp.workspace = true
once_cell.workspace = true
pin-project-lite = "0.2.0"
polling = "2.2.0"
polling = "3.1.0"
rand = "0.8"
rustix = { version = "0.38.2", default-features = false, features = ["std", "fs", "net"] }
slab = "0.4.7"
socket2 = {features = ["all"], version = "0.5"}
waker-fn = "1.1"
@ -34,8 +35,8 @@ clap = { version = "4", features = ["derive"], optional = true }
winapi = { version = "0.3.9", features = ["winsock2", "processthreadsapi"] }
[dev-dependencies]
gst-check = { package = "gstreamer-check", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "0.19", version = "0.19" }
gst-app = { package = "gstreamer-app", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "0.19", version = "0.19" }
gst-check.workspace = true
gst-app.workspace = true
[lib]
name = "gstthreadshare"
@ -59,7 +60,7 @@ name = "ts-standalone"
path = "examples/standalone/main.rs"
[build-dependencies]
gst-plugin-version-helper = { version = "0.7", path="../../version-helper" }
gst-plugin-version-helper.workspace = true
cc = "1.0.38"
pkg-config = "0.3.15"
@ -71,7 +72,7 @@ tuning = []
doc = ["gst/v1_18"]
[package.metadata.capi]
min_version = "0.8.0"
min_version = "0.9.21"
[package.metadata.capi.header]
enabled = false
@ -79,6 +80,7 @@ enabled = false
[package.metadata.capi.library]
install_subdir = "gstreamer-1.0"
versioning = false
import_library = false
[package.metadata.capi.pkg_config]
requires_private = "gstreamer-1.0, gstreamer-net-1.0, gstreamer-rtp-1.0, gobject-2.0, glib-2.0, gmodule-2.0"

View file

@ -78,7 +78,7 @@ fn main() {
let build_context = || format!("context-{}", (i as u32) % n_groups);
let sink = gst::ElementFactory::make("fakesink")
.name(format!("sink-{}", i).as_str())
.name(format!("sink-{i}").as_str())
.property("sync", false)
.property("async", false)
.property("signal-handoffs", true)
@ -96,7 +96,7 @@ fn main() {
let (source, context) = match source.as_str() {
"udpsrc" => {
let source = gst::ElementFactory::make("udpsrc")
.name(format!("source-{}", i).as_str())
.name(format!("source-{i}").as_str())
.property("port", 5004i32 + i as i32)
.property("retrieve-sender-address", false)
.build()
@ -107,7 +107,7 @@ fn main() {
"ts-udpsrc" => {
let context = build_context();
let source = gst::ElementFactory::make("ts-udpsrc")
.name(format!("source-{}", i).as_str())
.name(format!("source-{i}").as_str())
.property("port", 5004i32 + i as i32)
.property("context", &context)
.property("context-wait", wait)
@ -122,7 +122,7 @@ fn main() {
}
"tcpclientsrc" => {
let source = gst::ElementFactory::make("tcpclientsrc")
.name(format!("source-{}", i).as_str())
.name(format!("source-{i}").as_str())
.property("host", "127.0.0.1")
.property("port", 40000i32)
.build()
@ -133,7 +133,7 @@ fn main() {
"ts-tcpclientsrc" => {
let context = build_context();
let source = gst::ElementFactory::make("ts-tcpclientsrc")
.name(format!("source-{}", i).as_str())
.name(format!("source-{i}").as_str())
.property("host", "127.0.0.1")
.property("port", 40000i32)
.property("context", &context)
@ -145,7 +145,7 @@ fn main() {
}
"tonegeneratesrc" => {
let source = gst::ElementFactory::make("tonegeneratesrc")
.name(format!("source-{}", i).as_str())
.name(format!("source-{i}").as_str())
.property("samplesperbuffer", (wait as i32) * 8000 / 1000)
.build()
.unwrap();
@ -157,7 +157,7 @@ fn main() {
"ts-tonesrc" => {
let context = build_context();
let source = gst::ElementFactory::make("ts-tonesrc")
.name(format!("source-{}", i).as_str())
.name(format!("source-{i}").as_str())
.property("samples-per-buffer", wait * 8000 / 1000)
.property("context", &context)
.property("context-wait", wait)
@ -171,7 +171,7 @@ fn main() {
if is_rtp {
let jb = gst::ElementFactory::make("ts-jitterbuffer")
.name(format!("jb-{}", i).as_str())
.name(format!("jb-{i}").as_str())
.property("context-wait", wait)
.property("latency", wait)
.build()
@ -192,27 +192,28 @@ fn main() {
let bus = pipeline.bus().unwrap();
let l_clone = l.clone();
bus.add_watch(move |_, msg| {
use gst::MessageView;
let _bus_watch = bus
.add_watch(move |_, msg| {
use gst::MessageView;
match msg.view() {
MessageView::Eos(..) => l_clone.quit(),
MessageView::Error(err) => {
gst::error!(
CAT,
"Error from {:?}: {} ({:?})",
err.src().map(|s| s.path_string()),
err.error(),
err.debug()
);
l_clone.quit();
}
_ => (),
};
match msg.view() {
MessageView::Eos(..) => l_clone.quit(),
MessageView::Error(err) => {
gst::error!(
CAT,
"Error from {:?}: {} ({:?})",
err.src().map(|s| s.path_string()),
err.error(),
err.debug()
);
l_clone.quit();
}
_ => (),
};
glib::Continue(true)
})
.expect("Failed to add bus watch");
glib::ControlFlow::Continue
})
.expect("Failed to add bus watch");
pipeline.set_state(gst::State::Playing).unwrap();

View file

@ -106,47 +106,47 @@ fn main() {
let bus = pipeline.bus().unwrap();
let terminated_count = Arc::new(AtomicU32::new(0));
let pipeline_clone = pipeline.clone();
let l_clone = l.clone();
bus.add_watch(move |_, msg| {
use gst::MessageView;
match msg.view() {
MessageView::Eos(_) => {
// Actually, we don't post EOS (see sinks impl).
gst::info!(CAT, "Received eos");
l_clone.quit();
let _bus_watch = bus
.add_watch(move |_, msg| {
use gst::MessageView;
match msg.view() {
MessageView::Eos(_) => {
// Actually, we don't post EOS (see sinks impl).
gst::info!(CAT, "Received eos");
l_clone.quit();
glib::Continue(false)
}
MessageView::Error(msg) => {
if let gst::MessageView::Error(msg) = msg.message().view() {
if msg.error().matches(gst::LibraryError::Shutdown) {
if terminated_count.fetch_add(1, Ordering::SeqCst) == args.streams - 1 {
gst::info!(CAT, "Received all shutdown requests");
l_clone.quit();
glib::ControlFlow::Break
}
MessageView::Error(msg) => {
if let gst::MessageView::Error(msg) = msg.message().view() {
if msg.error().matches(gst::LibraryError::Shutdown) {
if terminated_count.fetch_add(1, Ordering::SeqCst) == args.streams - 1 {
gst::info!(CAT, "Received all shutdown requests");
l_clone.quit();
return glib::Continue(false);
} else {
return glib::Continue(true);
return glib::ControlFlow::Break;
} else {
return glib::ControlFlow::Continue;
}
}
}
gst::error!(
CAT,
"Error from {:?}: {} ({:?})",
msg.src().map(|s| s.path_string()),
msg.error(),
msg.debug()
);
l_clone.quit();
glib::ControlFlow::Break
}
gst::error!(
CAT,
"Error from {:?}: {} ({:?})",
msg.src().map(|s| s.path_string()),
msg.error(),
msg.debug()
);
l_clone.quit();
glib::Continue(false)
_ => glib::ControlFlow::Continue,
}
_ => glib::Continue(true),
}
})
.expect("Failed to add bus watch");
})
.expect("Failed to add bus watch");
gst::info!(CAT, "Switching to Ready");
let start = Instant::now();
@ -162,11 +162,11 @@ fn main() {
gst::info!(CAT, "Switching to Ready");
let stop = Instant::now();
pipeline_clone.set_state(gst::State::Ready).unwrap();
pipeline.set_state(gst::State::Ready).unwrap();
gst::info!(CAT, "Switching to Ready took {:.2?}", stop.elapsed());
gst::info!(CAT, "Shutting down");
let stop = Instant::now();
pipeline_clone.set_state(gst::State::Null).unwrap();
pipeline.set_state(gst::State::Null).unwrap();
gst::info!(CAT, "Shutting down took {:.2?}", stop.elapsed());
}

View file

@ -241,7 +241,7 @@ impl ObjectSubclass for AsyncMutexSink {
let sink_pad_handler = AsyncPadSinkHandler::default();
Self {
sink_pad: PadSink::new(
gst::Pad::from_template(&klass.pad_template("sink").unwrap(), Some("sink")),
gst::Pad::from_template(&klass.pad_template("sink").unwrap()),
sink_pad_handler.clone(),
),
sink_pad_handler,

View file

@ -11,7 +11,7 @@ pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
gst::Element::register(
Some(plugin),
super::ASYNC_MUTEX_ELEMENT_NAME,
gst::Rank::None,
gst::Rank::NONE,
AsyncMutexSink::static_type(),
)
}

View file

@ -234,7 +234,7 @@ impl ObjectSubclass for DirectSink {
let sink_pad_handler = SyncPadSinkHandler::default();
Self {
sink_pad: PadSink::new(
gst::Pad::from_template(&klass.pad_template("sink").unwrap(), Some("sink")),
gst::Pad::from_template(&klass.pad_template("sink").unwrap()),
sink_pad_handler.clone(),
),
sink_pad_handler,

View file

@ -11,7 +11,7 @@ pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
gst::Element::register(
Some(plugin),
super::SYNC_MUTEX_ELEMENT_NAME,
gst::Rank::None,
gst::Rank::NONE,
DirectSink::static_type(),
)
}

View file

@ -305,7 +305,7 @@ impl ObjectSubclass for TaskSink {
fn with_class(klass: &Self::Class) -> Self {
Self {
sink_pad: PadSink::new(
gst::Pad::from_template(&klass.pad_template("sink").unwrap(), Some("sink")),
gst::Pad::from_template(&klass.pad_template("sink").unwrap()),
TaskPadSinkHandler,
),
task: Task::default(),

View file

@ -11,7 +11,7 @@ pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
gst::Element::register(
Some(plugin),
super::TASK_ELEMENT_NAME,
gst::Rank::None,
gst::Rank::NONE,
TaskSink::static_type(),
)
}

View file

@ -266,7 +266,7 @@ impl TestSrc {
drop(settings);
self.task
.prepare(SrcTask::new(self.instance().clone()), ts_ctx)
.prepare(SrcTask::new(self.obj().clone()), ts_ctx)
.block_on()?;
debug_or_trace!(CAT, is_main_elem, imp: self, "Prepared");
@ -318,7 +318,7 @@ impl ObjectSubclass for TestSrc {
fn with_class(klass: &Self::Class) -> Self {
Self {
src_pad: PadSrc::new(
gst::Pad::from_template(&klass.pad_template("src").unwrap(), Some("src")),
gst::Pad::from_template(&klass.pad_template("src").unwrap()),
TestSrcPadHandler,
),
task: Task::default(),

View file

@ -13,7 +13,7 @@ pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
gst::Element::register(
Some(plugin),
"ts-standalone-src",
gst::Rank::None,
gst::Rank::NONE,
TestSrc::static_type(),
)
}

View file

@ -90,7 +90,7 @@ fn send_test_buffers(n_streams: u16, num_buffers: Option<i32>) {
let pipeline = gst::Pipeline::default();
for i in 0..n_streams {
let src = gst::ElementFactory::make("ts-audiotestsrc")
.name(format!("ts-audiotestsrc-{}", i).as_str())
.name(format!("ts-audiotestsrc-{i}").as_str())
.property("context-wait", 20u32)
.property("is-live", true)
.property("do-timestamp", true)
@ -107,7 +107,7 @@ fn send_test_buffers(n_streams: u16, num_buffers: Option<i32>) {
}
let sink = gst::ElementFactory::make("ts-udpsink")
.name(format!("udpsink-{}", i).as_str())
.name(format!("udpsink-{i}").as_str())
.property("clients", format!("127.0.0.1:{}", i + 5004))
.property("context-wait", 20u32)
.build()
@ -125,7 +125,7 @@ fn send_rtp_buffers(n_streams: u16, num_buffers: Option<i32>) {
let pipeline = gst::Pipeline::default();
for i in 0..n_streams {
let src = gst::ElementFactory::make("ts-audiotestsrc")
.name(format!("ts-audiotestsrc-{}", i).as_str())
.name(format!("ts-audiotestsrc-{i}").as_str())
.property("context-wait", 20u32)
.property("is-live", true)
.property("do-timestamp", true)
@ -142,16 +142,16 @@ fn send_rtp_buffers(n_streams: u16, num_buffers: Option<i32>) {
}
let enc = gst::ElementFactory::make("alawenc")
.name(format!("alawenc-{}", i).as_str())
.name(format!("alawenc-{i}").as_str())
.build()
.unwrap();
let pay = gst::ElementFactory::make("rtppcmapay")
.name(format!("rtppcmapay-{}", i).as_str())
.name(format!("rtppcmapay-{i}").as_str())
.build()
.unwrap();
let sink = gst::ElementFactory::make("ts-udpsink")
.name(format!("udpsink-{}", i).as_str())
.name(format!("udpsink-{i}").as_str())
.property("context-wait", 20u32)
.property("clients", format!("127.0.0.1:{}", i + 5004))
.build()
@ -170,31 +170,32 @@ fn run(pipeline: gst::Pipeline) {
let bus = pipeline.bus().unwrap();
let l_clone = l.clone();
bus.add_watch(move |_, msg| {
use gst::MessageView;
match msg.view() {
MessageView::Eos(_) => {
gst::info!(CAT, "Received eos");
l_clone.quit();
let _bus_watch = bus
.add_watch(move |_, msg| {
use gst::MessageView;
match msg.view() {
MessageView::Eos(_) => {
gst::info!(CAT, "Received eos");
l_clone.quit();
glib::Continue(false)
}
MessageView::Error(msg) => {
gst::error!(
CAT,
"Error from {:?}: {} ({:?})",
msg.src().map(|s| s.path_string()),
msg.error(),
msg.debug()
);
l_clone.quit();
glib::ControlFlow::Break
}
MessageView::Error(msg) => {
gst::error!(
CAT,
"Error from {:?}: {} ({:?})",
msg.src().map(|s| s.path_string()),
msg.error(),
msg.debug()
);
l_clone.quit();
glib::Continue(false)
glib::ControlFlow::Break
}
_ => glib::ControlFlow::Continue,
}
_ => glib::Continue(true),
}
})
.expect("Failed to add bus watch");
})
.expect("Failed to add bus watch");
pipeline.set_state(gst::State::Playing).unwrap();
l.run();

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