Projects
Essentials
gstreamer-plugins-bad-codecs
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 46
View file
gstreamer-plugins-bad-codecs.changes
Changed
@@ -1,4 +1,9 @@ ------------------------------------------------------------------- +Thu Apr 16 08:36:58 UTC 2026 - Bjørn Lie <zaitor@opensuse.org> + +- Update to version 1.28.2 + +------------------------------------------------------------------- Mon Mar 2 13:15:57 UTC 2026 - Bjørn Lie <zaitor@opensuse.org> - Update to version 1.28.1
View file
gstreamer-plugins-bad-codecs.spec
Changed
@@ -7,7 +7,7 @@ %define _version 1.28.0 Name: gstreamer-plugins-bad-codecs -Version: 1.28.1 +Version: 1.28.2 Release: 0 Summary: Codecs/plugins for gstreamer-plugins-bad License: LGPL-2.1-or-later
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/ChangeLog -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/ChangeLog
Changed
@@ -1,3 +1,628 @@ +=== release 1.28.2 === + +2026-04-07 20:02:23 +0100 Tim-Philipp Müller <tim@centricular.com> + + * gst-plugins-bad.doap: + * meson.build: + Release 1.28.2 + +2026-04-07 16:36:27 +0900 Seungmin Lee <seungmin.lee.cpp@navercorp.com> + + * gst/vmnc/vmncdec.c: + vmncdec: Set cursormask to NULL to prevent double free + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11264> + +2026-03-26 19:26:54 +0200 Sebastian Dröge <sebastian@centricular.com> + + * gst-libs/gst/codecparsers/gstav1parser.c: + * gst/videoparsers/gstav1parse.c: + av1parse: Correctly reject LEB128 values where the 8th byte has the high bit set + This is invalid according to the specification. + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11259> + +2026-03-26 19:18:33 +0200 Sebastian Dröge <sebastian@centricular.com> + + * gst-libs/gst/codecparsers/gstav1parser.c: + * gst/videoparsers/gstav1parse.c: + av1parse: Allow G_MAXUINT32 as LEB128 encoded value + The spec states that any value less than or equal to (1<<32) - 1 should be + accepted but we were rejecting (1<<32) - 1. + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11259> + +2026-03-26 18:52:48 +0200 Sebastian Dröge <sebastian@centricular.com> + + * gst/videoparsers/gstav1parse.c: + av1parse: Be more explicit about available data when parsing LEB128 values + The caller already checks that at least 8 bytes are available, which is the + maximum this function is going to parse anyway, but better to not hardcode this + assumption and instead actually check for it. + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11259> + +2026-03-26 18:45:11 +0200 Sebastian Dröge <sebastian@centricular.com> + + * gst-libs/gst/codecparsers/gstav1parser.c: + * gst/videoparsers/gstav1parse.c: + av1parse: Avoid signed 32 bit integer overflow when parsing LEB128 values + Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/work_items/4994 + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11259> + +2026-03-12 11:14:11 +0200 Sebastian Dröge <sebastian@centricular.com> + + * gst-libs/gst/codecparsers/gsth266parser.c: + h266parser: Avoid integer overflow when parsing profile / tier / level + And as a result also avoid a stack overflow. + Thanks to Nicholas Soh for finding and analyzing the issue, and suggesting this fix. + Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/4958 + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11257> + +2026-03-26 18:37:50 +0200 Sebastian Dröge <sebastian@centricular.com> + + * gst-libs/gst/codecparsers/gsth264parser.c: + h264parse: Avoid NULL pointer dereferences when freeing partially parsed SPS/MVC data + Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/work_items/4992 + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11251> + +2026-03-26 18:31:05 +0200 Sebastian Dröge <sebastian@centricular.com> + + * gst-libs/gst/codecparsers/gsth264parser.c: + h264parse: Remove pointless allocation failure handling + g_new0() already aborts the process on allocation failure. + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11251> + +2026-03-30 16:29:27 +0300 Sebastian Dröge <sebastian@centricular.com> + + * gst/jp2kdecimator/jp2kcodestream.c: + jp2kdecimator: Avoid integer overflows and divisions by zero on invalid tile configurations + Thanks to Sebastian Alba Vives for reporting the issue and suggesting the fix. + Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/work_items/5008 + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11239> + +2026-03-30 16:29:01 +0300 Sebastian Dröge <sebastian@centricular.com> + + * gst/jp2kdecimator/jp2kcodestream.c: + jp2kdecimator: Fix some possible integer overflows in size checks + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11239> + +2026-03-18 18:58:54 +0530 Nirbheek Chauhan <nirbheek@centricular.com> + + * gst-libs/gst/vulkan/cocoa/gstvkwindow_cocoa.m: + macos: Set activation policy in vulkansink (MoltenVK) + Upon creating a window, vulkansink now sets the policy to + NSApplicationActivationPolicyRegular, which lets us show an icon in + the Dock for convenience and appear in the top menu bar like other + apps. + This matches the behaviour of glimagesink and osxvideosink from commit + 5e45a1b1bd0ec4355346c60ef40c14fa91aa9b6c + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11138> + +2026-03-18 11:41:18 +0530 Nirbheek Chauhan <nirbheek@centricular.com> + + * sys/applemedia/vtdec.c: + vtdec: Invert order of output caps to match our preference + We want Vulkan > GL > sysmem + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11138> + +2026-02-13 03:33:34 +0530 Nirbheek Chauhan <nirbheek@centricular.com> + + * sys/applemedia/vtdec.c: + vtdec: Fix incorrect setting of bitfield / flag + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11138> + +2026-02-13 03:30:24 +0530 Nirbheek Chauhan <nirbheek@centricular.com> + + * sys/applemedia/vtdec.c: + vtdec: Don't leak RGBA64_LE caps during class init + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11138> + +2025-10-29 11:08:00 +0000 Thibault Saunier <tsaunier@igalia.com> + + * gst-libs/gst/cuda/cuda-gst.h: + * gst-libs/gst/cuda/gstcudacontext.cpp: + * gst-libs/gst/cuda/gstcudacontext.h: + * gst-libs/gst/cuda/gstcudaloader.cpp: + * gst-libs/gst/cuda/stub/cuda.h: + * gst-libs/gst/hip/stub/cuda.h: + * sys/nvcodec/gstnvav1encoder.cpp: + * sys/nvcodec/gstnvav1encoder.h: + * sys/nvcodec/gstnvdecoder.cpp: + * sys/nvcodec/gstnvdecoder.h: + * sys/nvcodec/gstnvencoder.h: + * sys/nvcodec/gstnvh264encoder.cpp: + * sys/nvcodec/gstnvh264encoder.h: + * sys/nvcodec/gstnvh265encoder.cpp: + * sys/nvcodec/gstnvh265encoder.h: + * sys/nvcodec/gstnvjpegenc.cpp: + * sys/nvcodec/gstnvjpegenc.h: + * sys/nvcodec/plugin.c: + nvcodec: Add capability caching to speed up plugin initialization + Probing encoder/decoder capabilities requires opening NVENC/NVDEC + sessions which adds significant overhead to plugin loading. This + change caches the discovered capabilities in GstPlugin cache data + and reloads them on subsequent runs. + The cache is keyed by device UUID and validated against the CUDA + driver API version, ensuring it's invalidated when + the hardware configuration changes or the driver is updated. + Plugin initialization time: 1.64s -> 0.14s (~11x faster) + The remaining time is basically spent in CuInit. + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10767> + +2026-03-28 15:22:35 -0400 Nicolas Dufresne <nicolas.dufresne@collabora.com> + + * ext/gtk/gstgtkwaylandsink.c: + * ext/wayland/gstwaylandsink.c: + waylandsink: Properly reset the tag orientation + Reset the tag orientation to identity if a new tag list is received without + the orientation in it, or if a new stream starts, as it may not contain a + tag list. + Fixes #3661 + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11216> + +2026-03-24 18:46:33 +0530 Nirbheek Chauhan <nirbheek@centricular.com> + + * sys/applemedia/vtdec.c: + * sys/applemedia/vtdec.h: + vtdec: Also reset session when output_callback gets a kVTVideoDecoderMalfunctionErr + We still reset the session only in handle_frame, because the reset + will block. We merely set a flag in output_callback(). + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11233> + +2025-01-14 19:43:16 +0100 Vadym Markov <markov.vadym@gmail.com> + + * sys/applemedia/vtenc.c: + vtenc: restart even if VTCompressionSessionCompleteFrames fails + Co-Authored-By: Nirbheek Chauhan <nirbheek@centricular.com> + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11233> + +2025-08-21 18:39:22 +0200 Havard Graff <havard@pexip.com> + + * sys/applemedia/vtenc.c: + applemedia/vtenc: make sure to NULL terminate the level string + Without this, passing in level="4", will cause undetermined behavior. + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11233> + +2024-05-23 18:36:29 +0200 Tulio Beloqui <tulio@pexip.com> + + * sys/applemedia/vtdec.c: + applemedia/vtdec: handle decoder error status for iOS + If VTDecompressionSessionDecodeFrame returns kVTInvalidSessionErr or + kVTVideoDecoderMalfunctionErr we need to reset the decoder session and + request an intra frame. + This change allows the decoder to continue decoding after the + application switches between foreground and background modes. + Co-Authored-by: Nirbheek Chauhan <nirbheek@centricular.com> + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11233> + +2026-04-01 09:25:57 +0200 Emil Ljungdahl <emillj@axis.com> + + * ext/sctp/sctpassociation.c: + sctp: Set number of outgoing & incoming streams to the same value + usrsctp has its own default number of streams. For outgoing streams the + default is 10, while for incoming streams the default is 2048. In + sctpassociation.c the default number of outgoing streams is changed to + 1024. + This means that when initializing an SCTP session, the INIT message will + announce 1024 as number of outbound streams, and 2048 as number of + inbound streams. That is not incorrect itself, but it becomes weird when + it comes to WebRTC where a datachannel requires one stream in each + direction. + If a WebRTC peer tries to open a datachannel with ID 1024, it won't be + rejected with a proper error message, but you rather get a fatal error + originating from a sanity check in sctp_output.c:13873. + If there is a risk there are other of sctp than WebRTC we might consider + changing the DEFAULT_NUMBER_OF_SCTP_STREAMS define to 2048 instead to + avoid changed default behavior. On the other hand, that will affect + resource utilization for a session... + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11209> + +2026-03-31 14:33:26 +0900 Seungha Yang <seungha@centricular.com> + + * sys/wasapi2/gstwasapi2rbuf.cpp: + wasapi2: Log target device information + Log device ID and requested mode information + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11202> + +2026-03-30 16:40:02 +0300 Sebastian Dröge <sebastian@centricular.com> + + * gst/sdp/gstsdpdemux.c: + gst: Fix a couple of const correctness bugs around strchr() usage + `assignment discards ‘const’ qualifier from pointer target type` + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11186> + +2026-03-11 16:25:47 +0900 Hou Qi <qi.hou@nxp.com> + + * gst-libs/gst/wayland/gstwldisplay.c: + wayland: display: Add protection when replacing wl_output + Some legacy platforms are still using older weston version, where wl_output + version number is 3. This results in wl_output name being empty, leading + to a segment fault when replacing wl_output according to name. + In order to avoid above issue, need to add protection when replacing wl_output. + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11086> + +2026-03-24 02:28:58 +0200 Pavel Guzenfeld <pavelguzenfeld@gmail.com> + + * sys/shm/gstshmsink.c: + * tests/check/elements/shm.c: + shm: fix shmsink exit code 1 on clean shutdown + gst_shm_sink_stop() calls gst_poll_set_flushing() which makes + gst_poll_wait() return -1 with errno=EBUSY. The poll thread + treated this as a fatal error instead of a clean shutdown. + Check self->stop before posting GST_ELEMENT_ERROR. + Fixes #4487 + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11163> + +2026-03-26 16:45:05 +0100 Piotr Brzeziński <piotr@centricular.com> + + * gst-libs/gst/vulkan/gstvkswapper.c: + vkswapper/vksink: Don't advertise unsupported formats + vulkansink's template caps are limited to + GST_VULKAN_SWAPPER_VIDEO_FORMATS, but get_supported_caps() did not + respect that and would advertise more formats if the HW supported them. + vulkanswapper doesn't know how to handle those incorrect formats, + resulting in a wrong image being displayed, or even crashes (on macOS + with MoltenVK). + This change just makes sure to filter out formats not correctly handled + by our code before we return the caps. + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11160> + +2026-01-28 10:27:43 -0500 Dominique Leroux <dominique.p.leroux@gmail.com> + + * sys/applemedia/vtdec.c: + * sys/applemedia/vtutil.c: + * sys/applemedia/vtutil.h: + vtdec: Supplemental VideoToolbox decoders now registered via vtutil helper + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11146> + +2026-03-25 17:35:28 +0900 Haihua Hu <jared.hu@nxp.com> + + * gst-libs/gst/wayland/gstwlwindow.c: + wlwindow: fix viewport source outside buffer when play resolution change stream + when playing resolution change stream, there is chance that video crop meta + is not updated, only video info changed. eg. when use libav decoder. + Need always update crop w/h based on priv->video_width/video_height. + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11142> + +2026-03-25 15:18:43 +0900 Haihua Hu <jared.hu@nxp.com> + + * ext/wayland/gstwaylandsink.c: + waylandsink: fix waylandsink crash when call window flush + Need check if window is created when call gst_wl_window_flush + otherwise it will crash when receive event but window is not created + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11137> + +2026-03-24 16:49:53 +0100 François Laignel <francois@centricular.com> + + * gst/mxf/mxfdemux.c: + mxfdemux: add reversed temporal offset bound check + In `find_entry_for_offset()`, `position` is checked against the segment bounds, + which should match `reverse_temporal_offsets` size considering how it is built + in `collect_index_table_segments`. However, it doesn't check the actual size of + `collect_index_table_segments` which seems a bit fragile. Besides, all other + parts of the code explicitely check the `reverse_temporal_offsets` size before + accessing it. + This commit: + * ensures `position` is valid before accessing `reverse_temporal_offsets`, + similarly to what was intended to be done for `find_edit_entry()`. + * actually acts upon the check result for both. + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11127> + +2026-03-24 16:23:25 +0100 François Laignel <francois@centricular.com> + + * gst/mxf/mxfdemux.c: + mxfdemux: reject corrupted index entry + A corrupted index could lead to computing an incorrect edit entry size which + would exceed MAX `guint32` and would lead to pulling less bytes than was + computed due to the size being casted to `guint32` in the next pull range call. + Looking for the next entry would most likely fail due to the excessive previous + computed size: + > Couldn't find matching partition for stream offset 4294968000 + This commit detects this situation, logs the problem so as to ease root cause + identification and prevents the caller from pulling the entry with incorrect + size. + See https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/4974 + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11127> + +2026-03-24 14:20:39 +0900 Seungha Yang <seungha@centricular.com> + + * sys/wasapi2/gstwasapi2rbuf.cpp: + wasapi2sink: Ignore device errors from default device + Temporary device-invalidated errors from an automatic + stream-routing-aware default device are expected. Ignore + them, as we do in the read path + Fixes: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/4971 + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11120> + +2026-03-23 22:53:08 +0200 Sebastian Dröge <sebastian@centricular.com> + + * ext/vulkan/vkvp9dec.c: + vulkanvp9dec: Fix case in device-specific factory name + Previously this would become `vulkanVp9device1dec` and now it becomes + `vulkanvp9device1dec` which is consistent with the format used by all other + decoders. + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11117> + +2026-03-20 10:11:23 +0100 Johan Sternerup <johast@axis.com> + + * gst-libs/gst/webrtc/nice/nice.c: + nice: Fix leak of nice thread + Leak of nice thread also means leaking the nice object, its members, the + associated main context along with its file descriptor etc. + This is a scenario that could cause a leak: + 1. Application sets webrtcbin state to NULL. + 2. webrtcbin calls ice_close() when transitioning to NULL state. + 3. nice triggers a close function (close_main_cb) to execute within the + nice thread. + 4. close_main_cb starts executing within the nice thread, obtains a + strong ref on the nice object, invokes nice_agent_close_async() and + waits until its associated callback fires. + 5. Application unrefs webrtcbin triggering its dispose() method which in + turn unrefs the nice object. + 6. Within the nice thread nice_agent_close_async() finishes and + close_main_cb unrefs the nice object and now this is the last reference, + which means that disposing/finalization is invoked. + 7. The finalization of nice now runs within the nice thread itself, + which means that that it gets stuck when trying to stop the thread, i.e. + it's waiting for itself to finish. + The main problem here is that webrtcbin, which is the entity having + ownership of the ice object along with its thread, does not fully take + the responsibility of managing the lifecycle of the ice object. If + webrtcbin is responsible for starting the thread (indirectly by creating + the ice object) it also needs to wait for that thread to finish. The + explicit call to ice_close() when going to the NULL state seems like the + right place to free resources and stop threads. We just need to make + sure that when ice_close() has completed, the ice object should no + longer be in an active state, so that we then can safely proceed with + unrefing the ice object. + We previously had the complete procedure for tearing down the ice object + and wait for its completion in-place within the nice-finalize method, + which however turns out to be too late. So instead of having two ways of + closing the ice object, one incomplete and one at the wrong location, + this commit now merge those solutions into one solution that is complete + and invoked at the right location. + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11112> + +2026-03-20 20:30:35 +0530 Nirbheek Chauhan <nirbheek@centricular.com> + + * sys/applemedia/vtdec.c: + vtdec: Do not hold the stream lock when pushing out frames + This can (and does) cause a deadlock, you should not hold the stream + lock when pushing. + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11099> + +2026-03-20 13:59:19 +0000 Thibault Saunier <tsaunier@igalia.com> + + * gst/videoparsers/gstav1parse.c: + * gst/videoparsers/gstvp9parse.c: + vp9parse, av1parse: Remove segment clipping to let downstream handle frame boundaries + Remove the GST_BASE_PARSE_FRAME_FLAG_CLIP flag that was causing frames outside + segment boundaries to be dropped. This was problematic when seeking to positions + where keyframes don't align with segment boundaries, as essential keyframes + needed for decoding would get dropped. + Let downstream elements (decoders, sinks) decide what to do with frames that + may fall outside segment boundaries. This is more flexible and consistent + with h264parse which also doesn't set this flag. + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11087> + +2026-03-17 11:21:40 +0100 Albert Sjölund <alberts@axis.com> + + * ext/dtls/gstdtlsdec.c: + * ext/dtls/gstdtlsdec.h: + * ext/dtls/gstdtlsenc.c: + * ext/dtls/gstdtlsenc.h: + dtls: unregister signal handlers from connection + There is a risk of receiving invalid_closure_notify due to the different + lifetimes between connection and self (Dtls), as the unref is part of + gstreamer state management and not finalization/dispose. When the + connection is cleared make sure to also disconnect the signal handlers. + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11079> + +2026-03-18 23:43:20 +0100 Tim-Philipp Müller <tim@centricular.com> + + * po/LINGUAS: + * po/kk.po: + gst-plugins-bad: update translations + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11077> + +2026-03-18 13:39:29 +0200 Vivia Nikolaidou <vivia@ahiru.eu> + + * gst/mpegtsmux/tsmux/tsmux.c: + tsmux: Fix integer overflow in SCTE35 NULL interval + The default value corresponds to 300 seconds in ticks of the 90kHz clock. A + simple pipeline with `mpegtsmux scte-35-pid=49`, analysed with e.g. Wireshark, + showed the SCTE35 NULL packets every 140 seconds instead of 300. Turns out, the + default value fits in a guint, but not when multiplied by 300. + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11076> + +2026-03-17 12:52:18 +0200 Sebastian Dröge <sebastian@centricular.com> + + * gst-libs/gst/codecparsers/gsth264parser.c: + h264parser: Fix memory leak in gst_h264_parser_parse_nal() + Thanks to Nicholas Soh for finding the issue and suggesting the correct fix. + Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/4966 + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11060> + +2026-03-17 10:38:37 +0530 Nirbheek Chauhan <nirbheek@centricular.com> + + * gst-libs/gst/vulkan/gstvkimagememory.c: + vulkan: Clear mutex when GstVulkanImageMemory is freed + Fixes leaks on every frame. + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11059> + +2026-03-08 10:27:05 -0400 Daniel Morin <daniel.morin@collabora.com> + + * ext/tflite/gsttfliteinference.c: + tflite: set PAR to 1:1 by default + - Set PAR to 1:1 by default + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11048> + +2026-03-07 10:21:37 -0500 Daniel Morin <daniel.morin@collabora.com> + + * ext/onnx/gstonnxinference.c: + onnx: set default pixel-aspect-ratio + - All models we currently support expect a par of 1:1 + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11048> + +2026-03-13 13:14:23 +0530 Nirbheek Chauhan <nirbheek@centricular.com> + + * sys/applemedia/vtdec.c: + * sys/applemedia/vtdec.h: + vtdec: Store supplemental codec support in a global variable + The detection only worked for the first instance, because the lifetime + of `av1_once` and `vp9_once` exceeded the lifetime of the `vtdec` + instance. + Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/4964 + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11045> + +2026-01-29 16:08:33 +0900 Seungha Yang <seungha@centricular.com> + + * gst/videoparsers/gsth265parse.c: + h265parse: Update buffer duration only when it's invalid + Framerate parsed from VUI or upstream caps may be inaccurate or + variable. Preserve the upstream buffer duration if it is already valid. + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11016> + +2026-01-29 16:05:20 +0900 Seungha Yang <seungha@centricular.com> + + * gst/videoparsers/gsth264parse.c: + h264parse: Do not update valid DTS and duration + Update timestamp only if DTS or duration is invalid + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11016> + +2026-02-26 18:21:15 +0900 Seungha Yang <seungha@centricular.com> + + * gst/gdp/gstgdppay.c: + gdppay: Fix null pointer dereference on duplicated caps event + Also, instead of dropping duplicated caps events, record all events as-is. + Given that gdppay is meant to record pipeline data and event flow for + reproduction, preserving duplicated events helps to reproduce the original + pipeline behavior correctly + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11021> + +2026-03-11 08:40:14 +0200 Sebastian Dröge <sebastian@centricular.com> + + * docs/plugins/gst_plugins_cache.json: + * ext/soundtouch/gstpitch.cc: + soundtouch: Only allow up to 192kHz and 16 channels + Any higher numbers are not supported. + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11011> + +2026-03-11 20:01:39 +0100 Mathieu Duponchelle <mathieu@centricular.com> + + * sys/decklink/gstdecklinkvideosink.cpp: + decklinkvideosink: fix element leak in decklink callback + SetScheduledFrameCompletionCallback takes a reference on the passed-in + callback, we thus need to initialize its refcount to 0 for it to + get destroyed when we finally call + SetScheduledFrameCompletionCallback(NULL); + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11009> + +2026-03-11 14:49:08 +0800 He Junyan <junyan.he@intel.com> + + * gst/videoparsers/gstav1parse.c: + av1parse: Fix a latent wrong setting of cll in update_src_caps + In gst_av1_parse_update_src_caps(), "content-light-level" should be + updated when having the cll_str, not the mdi_str. + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11003> + +2026-03-11 14:40:19 +0800 He Junyan <junyan.he@intel.com> + + * gst/videoparsers/gstav1parse.c: + av1parse: Fix the consumed typo in _read_leb128 + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11003> + +2026-02-21 17:03:48 +0100 Robert Mader <robert.mader@collabora.com> + + * ext/aom/gstav1dec.c: + av1dec: Enable VIDEO_META and VIDEO_ALIGNMENT for pool + The decoders relies on the GstVideoDecoder base class for buffer pool + negotiation, however the later doesn't handle the VIDEO_META and thus + doesn't enable the respective pool options as it can't know whether + derived classes actually support those. + GstAV1Dec does so just fine and enabling the options is required for + certain pools like GstVideoDmabufPool. Thus iterate over the pools from + the allocation query and enable the options, deferring all further + handling to the base class. + This approach could potentially serve as a template for varios other sw + video decoders as it keeps most complexity in the base class. + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10993> + +2026-03-04 13:33:11 +0100 Ognyan Tonchev <ognyan@axis.com> + + * ext/srtp/gstsrtpenc.c: + srtpenc: preserve ROC when master key is updated for an ongoing session + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10977> + +2026-01-29 12:34:46 +0100 Fabian Orccon <forccon@fluendo.com> + + * ext/avtp/gstavtpcrfbase.c: + * tests/examples/key-handler.c: + all: GThreadFunc return type fixes + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10955> + +2026-02-25 16:02:05 +0100 Piotr Brzeziński <piotr@centricular.com> + + * ext/vulkan/meson.build: + * gst-libs/gst/vulkan/meson.build: + * sys/applemedia/meson.build: + vulkan: Fix libMoltenVK.dylib not found when installed + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10918> + +2026-02-11 16:35:29 +0100 Stéphane Cerveau <scerveau@igalia.com> + + * ext/dash/gstdashsink.c: + dashsink: guard splitmuxsink removal in release_pad during dispose + During element dispose, GstBin::dispose removes all children before + GstElement::dispose releases request pads. This causes release_pad + to attempt removing splitmuxsink after it has already been removed, + triggering a "not in bin" warning. + Check GST_OBJECT_PARENT before calling gst_bin_remove. + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10914> + +2026-01-16 13:01:16 +0100 Stéphane Cerveau <scerveau@igalia.com> + + * tests/check/elements/dashsink.c: + dashsink: test: use playbin3 for DASH playback verification + playbin uses decodebin2 which does not set GST_BIN_FLAG_STREAMS_AWARE. + dashdemux2 checks for this flag on its parent bin during NULL_TO_READY + (gstadaptivedemux.c:744) and errors out when it is missing, causing + memory leaks detected by valgrind as "Early exit with return value 20" + in a certain timing. + With playbin3, the error never happens at all because decodebin3 is streams-aware + Switch to playbin3 which uses streams-aware decodebin3, and update + expected timestamps since playbin3 normalizes the first PTS to 0. + Fixes #4888 + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10914> + +2026-02-11 13:04:09 +0000 Cole Richardson <crichardson@edgeaisolutions.com> + + * ext/svtav1/gstsvtav1enc.c: + svtav1: fix "Level of parallelism" property type discrepencies + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10913> + +2026-02-22 15:21:09 +0800 He Junyan <junyan.he@intel.com> + + * gst/videoparsers/gstav1parse.c: + av1parse: Split the stream format and alignment logic + In current code, the alignment and stream format logic are mixed in one + enum, which makes the code logic not very clear. We have a assumption + before that the annex-b stream format only appears when the input is TU + aligned. But in fact, other kind of input alignments can also have annex-b + stream format. So we now split the stream format and alignment logic. + Fixes: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/4919 + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10912> + +2026-02-22 14:43:22 +0800 He Junyan <junyan.he@intel.com> + + * gst/videoparsers/gstav1parse.c: + av1parse: Add the GstAV1ParseStreamFormat enum and helper functions + Because we split the stream format logic from alignment, so all the helper + functions related to alignment also should be improved. + Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10912> + +2026-02-26 01:53:07 +0000 Tim-Philipp Müller <tim@centricular.com> + + * meson.build: + Back to development after 1.28.1 + === release 1.28.1 === 2026-02-26 01:44:06 +0000 Tim-Philipp Müller <tim@centricular.com>
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/RELEASE -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/RELEASE
Changed
@@ -1,4 +1,4 @@ -This is GStreamer gst-plugins-bad 1.28.1 +This is GStreamer gst-plugins-bad 1.28.2 The GStreamer team is thrilled to announce a new major feature release of your favourite cross-platform multimedia framework!
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/docs/plugins/gst_plugins_cache.json -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/docs/plugins/gst_plugins_cache.json
Changed
@@ -246149,12 +246149,12 @@ "long-name": "Pitch controller", "pad-templates": { "sink": { - "caps": "audio/x-raw:\n format: F32LE\n rate: 8000, 2147483647 \n channels: 1, 2147483647 \n layout: interleaved\n", + "caps": "audio/x-raw:\n format: F32LE\n rate: 8000, 192000 \n channels: 1, 16 \n layout: interleaved\n", "direction": "sink", "presence": "always" }, "src": { - "caps": "audio/x-raw:\n format: F32LE\n rate: 8000, 2147483647 \n channels: 1, 2147483647 \n layout: interleaved\n", + "caps": "audio/x-raw:\n format: F32LE\n rate: 8000, 192000 \n channels: 1, 16 \n layout: interleaved\n", "direction": "src", "presence": "always" }
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/ext/aom/gstav1dec.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/ext/aom/gstav1dec.c
Changed
@@ -85,6 +85,8 @@ static GstFlowReturn gst_av1_dec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame); +static gboolean gst_av1_dec_decide_allocation (GstVideoDecoder * dec, + GstQuery * query); static void gst_av1_dec_image_to_buffer (GstAV1Dec * dec, const aom_image_t * img, GstBuffer * buffer); @@ -129,6 +131,8 @@ vdec_class->set_format = GST_DEBUG_FUNCPTR (gst_av1_dec_set_format); vdec_class->handle_frame = GST_DEBUG_FUNCPTR (gst_av1_dec_handle_frame); + vdec_class->decide_allocation = + GST_DEBUG_FUNCPTR (gst_av1_dec_decide_allocation); klass->codec_algo = &aom_codec_av1_dx_algo; GST_DEBUG_CATEGORY_INIT (av1_dec_debug, "av1dec", 0, "AV1 decoding element"); @@ -487,3 +491,40 @@ return ret; } + +static gboolean +gst_av1_dec_decide_allocation (GstVideoDecoder * dec, GstQuery * query) +{ + guint n_pools; + + if (!gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL)) + goto out; + + n_pools = gst_query_get_n_allocation_pools (query); + for (guint i = 0; i < n_pools; i++) { + GstBufferPool *pool = NULL; + GstStructure *config; + guint size, min, max; + + gst_query_parse_nth_allocation_pool (query, i, &pool, &size, &min, &max); + if (!pool) + continue; + + config = gst_buffer_pool_get_config (pool); + if (gst_buffer_pool_has_option (pool, GST_BUFFER_POOL_OPTION_VIDEO_META)) { + gst_buffer_pool_config_add_option (config, + GST_BUFFER_POOL_OPTION_VIDEO_META); + if (gst_buffer_pool_has_option (pool, + GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT)) { + gst_buffer_pool_config_add_option (config, + GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT); + } + } + gst_buffer_pool_set_config (pool, config); + gst_query_set_nth_allocation_pool (query, i, pool, size, min, max); + gst_object_unref (pool); + } + +out: + return GST_VIDEO_DECODER_CLASS (parent_class)->decide_allocation (dec, query); +}
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/ext/avtp/gstavtpcrfbase.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/ext/avtp/gstavtpcrfbase.c
Changed
@@ -72,7 +72,7 @@ GValue * value, GParamSpec * pspec); static GstStateChangeReturn gst_avtp_crf_base_change_state (GstElement * element, GstStateChange transition); -static void crf_listener_thread_func (GstAvtpCrfBase * avtpcrfbase); +static gpointer crf_listener_thread_func (GstAvtpCrfBase * avtpcrfbase); static int setup_socket (GstAvtpCrfBase * avtpcrfbase); #define gst_avtp_crf_base_parent_class parent_class @@ -489,7 +489,7 @@ data->current_ts = first_pkt_tstamp; } -static void +static gpointer crf_listener_thread_func (GstAvtpCrfBase * avtpcrfbase) { GstAvtpCrfThreadData *data = &avtpcrfbase->thread_data; @@ -532,6 +532,8 @@ calculate_average_period (avtpcrfbase, crf_pdu); } + + return NULL; } static void
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/ext/dash/gstdashsink.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/ext/dash/gstdashsink.c
Changed
@@ -1147,7 +1147,8 @@ if (stream->splitmuxsink) { gst_element_set_locked_state (stream->splitmuxsink, TRUE); gst_element_set_state (stream->splitmuxsink, GST_STATE_NULL); - gst_bin_remove (GST_BIN (sink), stream->splitmuxsink); + if (GST_OBJECT_PARENT (stream->splitmuxsink) == GST_OBJECT (sink)) + gst_bin_remove (GST_BIN (sink), stream->splitmuxsink); gst_object_unref (stream->splitmuxsink); }
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/ext/dtls/gstdtlsdec.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/ext/dtls/gstdtlsdec.c
Changed
@@ -118,6 +118,8 @@ static GstDtlsAgent *get_agent_by_pem (const gchar * pem); static void agent_weak_ref_notify (gchar * pem, GstDtlsAgent *); static void create_connection (GstDtlsDec *, gchar * id); +static void clear_signals (GstDtlsDec *); + static void connection_weak_ref_notify (gchar * id, GstDtlsConnection *); static void @@ -214,6 +216,10 @@ self->srtp_cipher = DEFAULT_SRTP_CIPHER; self->srtp_auth = DEFAULT_SRTP_AUTH; + self->signal_peer_certificate = 0; + self->signal_decoder_key = 0; + self->signal_state_changed = 0; + g_mutex_init (&self->src_mutex); self->src = NULL; @@ -261,6 +267,7 @@ } if (self->connection) { + clear_signals (self); g_object_unref (self->connection); self->connection = NULL; } @@ -342,11 +349,11 @@ switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: if (self->connection) { - g_signal_connect_object (self->connection, - "on-decoder-key", G_CALLBACK (on_key_received), self, 0); - g_signal_connect_object (self->connection, + self->signal_decoder_key = g_signal_connect (self->connection, + "on-decoder-key", G_CALLBACK (on_key_received), self); + self->signal_peer_certificate = g_signal_connect (self->connection, "on-peer-certificate", G_CALLBACK (on_peer_certificate_received), - self, 0); + self); } else { GST_WARNING_OBJECT (self, "trying to change state to ready without connection id and pem"); @@ -732,6 +739,27 @@ } static void +clear_signals (GstDtlsDec * self) +{ + if (self->connection) { + if (self->signal_decoder_key) { + g_signal_handler_disconnect (self->connection, self->signal_decoder_key); + self->signal_decoder_key = 0; + } + if (self->signal_peer_certificate) { + g_signal_handler_disconnect (self->connection, + self->signal_peer_certificate); + self->signal_peer_certificate = 0; + } + if (self->signal_state_changed) { + g_signal_handler_disconnect (self->connection, + self->signal_state_changed); + self->signal_state_changed = 0; + } + } +} + +static void agent_weak_ref_notify (gchar * pem, GstDtlsAgent * agent) { G_LOCK (agent_table); @@ -786,8 +814,7 @@ g_return_if_fail (GST_IS_DTLS_AGENT (self->agent)); if (self->connection) { - g_signal_handlers_disconnect_by_func (self->connection, - on_connection_state_changed, self); + clear_signals (self); g_object_unref (self->connection); self->connection = NULL; } @@ -807,9 +834,9 @@ self->connection = g_object_new (GST_TYPE_DTLS_CONNECTION, "agent", self->agent, NULL); - g_signal_connect_object (self->connection, + g_signal_connect (self->connection, "notify::connection-state", G_CALLBACK (on_connection_state_changed), - self, 0); + self); on_connection_state_changed (NULL, NULL, self); g_object_weak_ref (G_OBJECT (self->connection),
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/ext/dtls/gstdtlsdec.h -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/ext/dtls/gstdtlsdec.h
Changed
@@ -63,6 +63,10 @@ GstBuffer *decoder_key; guint srtp_cipher; guint srtp_auth; + + gulong signal_peer_certificate; + gulong signal_decoder_key; + gulong signal_state_changed; }; struct _GstDtlsDecClass {
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/ext/dtls/gstdtlsenc.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/ext/dtls/gstdtlsenc.c
Changed
@@ -84,6 +84,7 @@ #define INITIAL_QUEUE_SIZE 64 static void gst_dtls_enc_finalize (GObject *); +static void gst_dtls_enc_dispose (GObject *); static void gst_dtls_enc_set_property (GObject *, guint prop_id, const GValue *, GParamSpec *); static void gst_dtls_enc_get_property (GObject *, guint prop_id, GValue *, @@ -97,6 +98,7 @@ static gboolean src_activate_mode (GstPad *, GstObject *, GstPadMode, gboolean active); static void src_task_loop (GstPad *); +static void clear_signals (GstDtlsEnc *); static GstFlowReturn sink_chain (GstPad *, GstObject *, GstBuffer *); static gboolean sink_event (GstPad * pad, GstObject * parent, GstEvent * event); @@ -116,6 +118,7 @@ element_class = (GstElementClass *) klass; gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_dtls_enc_finalize); + gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_dtls_enc_dispose); gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_dtls_enc_set_property); gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_dtls_enc_get_property); @@ -194,6 +197,9 @@ self->srtp_cipher = DEFAULT_SRTP_CIPHER; self->srtp_auth = DEFAULT_SRTP_AUTH; + self->signal_notify_id = 0; + self->signal_key_receive_id = 0; + g_queue_init (&self->queue); g_mutex_init (&self->queue_lock); g_cond_init (&self->queue_cond_add); @@ -236,6 +242,36 @@ } static void +gst_dtls_enc_dispose (GObject * object) +{ + GstDtlsEnc *self = GST_DTLS_ENC (object); + + if (self->connection) { + clear_signals (self); + g_object_unref (self->connection); + self->connection = NULL; + } + + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +clear_signals (GstDtlsEnc * self) +{ + if (self->connection) { + if (self->signal_key_receive_id) { + g_signal_handler_disconnect (self->connection, + self->signal_key_receive_id); + self->signal_key_receive_id = 0; + } + if (self->signal_notify_id) { + g_signal_handler_disconnect (self->connection, self->signal_notify_id); + self->signal_notify_id = 0; + } + } +} + +static void gst_dtls_enc_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { @@ -318,11 +354,11 @@ return GST_STATE_CHANGE_FAILURE; } - g_signal_connect_object (self->connection, - "on-encoder-key", G_CALLBACK (on_key_received), self, 0); - g_signal_connect_object (self->connection, + self->signal_key_receive_id = g_signal_connect (self->connection, + "on-encoder-key", G_CALLBACK (on_key_received), self); + self->signal_notify_id = g_signal_connect (self->connection, "notify::connection-state", - G_CALLBACK (on_connection_state_changed), self, 0); + G_CALLBACK (on_connection_state_changed), self); on_connection_state_changed (NULL, NULL, self); gst_dtls_connection_set_send_callback (self->connection, @@ -345,6 +381,7 @@ gst_dtls_connection_close (self->connection); gst_dtls_connection_set_send_callback (self->connection, NULL, NULL, NULL); + clear_signals (self); g_object_unref (self->connection); self->connection = NULL; }
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/ext/dtls/gstdtlsenc.h -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/ext/dtls/gstdtlsenc.h
Changed
@@ -63,6 +63,9 @@ guint srtp_auth; gboolean send_initial_events; + + gulong signal_notify_id; + gulong signal_key_receive_id; }; struct _GstDtlsEncClass {
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/ext/gtk/gstgtkwaylandsink.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/ext/gtk/gstgtkwaylandsink.c
Changed
@@ -364,11 +364,18 @@ GST_DEBUG_OBJECT (self, "handling %s event", GST_EVENT_TYPE_NAME (event)); switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_STREAM_START: + gst_gtk_wayland_sink_set_rotate_method (self, + GST_VIDEO_ORIENTATION_IDENTITY, TRUE); + break; case GST_EVENT_TAG: gst_event_parse_tag (event, &taglist); if (gst_video_orientation_from_tag (taglist, &method)) { gst_gtk_wayland_sink_set_rotate_method (self, method, TRUE); + } else { + gst_gtk_wayland_sink_set_rotate_method (self, + GST_VIDEO_ORIENTATION_IDENTITY, TRUE); } break;
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/ext/onnx/gstonnxinference.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/ext/onnx/gstonnxinference.c
Changed
@@ -1058,6 +1058,9 @@ self->scalesi, self->offsetsi); } + gst_caps_set_simple (self->input_tensors_caps, "pixel-aspect-ratio", + GST_TYPE_FRACTION, 1, 1, NULL); + g_free (tensor_name); if (onnx_input_tensor_name) self->allocator->Free (self->allocator, (char *) onnx_input_tensor_name);
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/ext/sctp/sctpassociation.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/ext/sctp/sctpassociation.c
Changed
@@ -227,8 +227,15 @@ */ usrsctp_sysctl_set_sctp_default_frag_interleave (2); + /* Set the default number of SCTP streams to the same value for both incoming and outgoing streams. + * This makes sense for at least WebRTC data channels where the number of streams is the same in both directions. + * Not setting this to the same value can cause issues with some WebRTC implementations, trying to open more + * outgoing streams than the number of incoming streams this peer is configured to support. + */ usrsctp_sysctl_set_sctp_nr_outgoing_streams_default (DEFAULT_NUMBER_OF_SCTP_STREAMS); + usrsctp_sysctl_set_sctp_nr_incoming_streams_default + (DEFAULT_NUMBER_OF_SCTP_STREAMS); #if defined(SCTP_DEBUG) && !defined(GST_DISABLE_GST_DEBUG) if (USRSCTP_GST_DEBUG_LEVEL <= GST_LEVEL_MAX
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/ext/soundtouch/gstpitch.cc -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/ext/soundtouch/gstpitch.cc
Changed
@@ -71,15 +71,15 @@ #define SUPPORTED_CAPS \ "audio/x-raw, " \ "format = (string) " GST_AUDIO_NE (F32) ", " \ - "rate = (int) 8000, MAX , " \ - "channels = (int) 1, MAX , " \ + "rate = (int) 8000, 192000 , " \ + "channels = (int) 1, 16 , " \ "layout = (string) interleaved" #elif defined(SOUNDTOUCH_INTEGER_SAMPLES) #define SUPPORTED_CAPS \ "audio/x-raw, " \ "format = (string) " GST_AUDIO_NE (S16) ", " \ - "rate = (int) 8000, MAX , " \ - "channels = (int) 1, MAX , " \ + "rate = (int) 8000, 192000 , " \ + "channels = (int) 1, 16 , " \ "layout = (string) interleaved" #else #error "Only integer or float samples are supported"
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/ext/srtp/gstsrtpenc.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/ext/srtp/gstsrtpenc.c
Changed
@@ -380,9 +380,9 @@ * Should be called with the filter locked */ static srtp_err_status_t -gst_srtp_enc_create_session (GstSrtpEnc * filter) +gst_srtp_enc_manage_session (GstSrtpEnc * filter) { - srtp_err_status_t ret; + srtp_err_status_t ret = srtp_err_status_fail; srtp_policy_t policy; GstMapInfo map; guchar tmp1; @@ -462,11 +462,26 @@ policy.window_size = filter->replay_window_size; policy.allow_repeat_tx = filter->allow_repeat_tx; - /* If it is the first stream, create the session - * If not, add the stream to the session - */ - ret = srtp_create (&filter->session, &policy); - filter->first_session = FALSE; + if (filter->session) { + /* + * Update all outbound streams/SSRCs. + * The existing ROC value of all streams will be preserved. + */ + ret = srtp_update_stream (filter->session, &policy); + } else if (filter->first_session) { + /* + * Create the session. The policy will apply to any outbound stream/SSRC + * later on. + * + * Streams are created on the fly. The first time a packet is processed + * in srtp_protect_*(): + * - libsrtp looks at the packet’s SSRC + * - It creates a new internal stream state for that SSRC + * - ROC starts at 0, sequence numbers tracked, crypto context initialized + */ + ret = srtp_create (&filter->session, &policy); + filter->first_session = FALSE; + } done: @@ -1063,21 +1078,21 @@ GST_OBJECT_LOCK (filter); - if (filter->key_changed) { - gst_srtp_enc_reset_no_lock (filter); - do_setcaps = TRUE; - } - - if (filter->first_session) { - srtp_err_status_t status = gst_srtp_enc_create_session (filter); + if (filter->first_session || filter->key_changed) { + srtp_err_status_t status = gst_srtp_enc_manage_session (filter); if (status != srtp_err_status_ok) { GST_OBJECT_UNLOCK (filter); GST_ELEMENT_ERROR (filter, LIBRARY, INIT, ("Could not initialize SRTP encoder"), - ("Failed to add stream to SRTP encoder (err: %d)", status)); + ("Failed to manage session in SRTP encoder (err: %d)", status)); return GST_FLOW_ERROR; } + + if (filter->key_changed) { + filter->key_changed = FALSE; + do_setcaps = TRUE; + } } GST_OBJECT_UNLOCK (filter);
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/ext/svtav1/gstsvtav1enc.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/ext/svtav1/gstsvtav1enc.c
Changed
@@ -436,7 +436,7 @@ break; case PROP_LEVEL_OF_PARALLELISM: #if SVT_AV1_CHECK_VERSION(3, 0, 0) - svtav1enc->level_of_parallelism = g_value_get_int (value); + svtav1enc->level_of_parallelism = g_value_get_uint (value); #endif break; case PROP_LOGICAL_PROCESSORS: @@ -502,7 +502,7 @@ case PROP_LEVEL_OF_PARALLELISM: case PROP_LOGICAL_PROCESSORS: #if SVT_AV1_CHECK_VERSION(3, 0, 0) - g_value_set_int (value, svtav1enc->level_of_parallelism); + g_value_set_uint (value, svtav1enc->level_of_parallelism); #else g_value_set_uint (value, svtav1enc->logical_processors); #endif
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/ext/tflite/gsttfliteinference.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/ext/tflite/gsttfliteinference.c
Changed
@@ -658,6 +658,9 @@ gst_caps_set_simple (priv->model_incaps, "format", G_TYPE_STRING, gst_format, NULL); + gst_caps_set_simple (priv->model_incaps, "pixel-aspect-ratio", + GST_TYPE_FRACTION, 1, 1, NULL); + g_free (tensor_name); }
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/ext/vulkan/meson.build -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/ext/vulkan/meson.build
Changed
@@ -103,6 +103,7 @@ objc_args : gst_plugins_bad_args, link_args : noseh_link_args, include_directories : configinc, + kwargs: vulkan_plugin_kwargs, dependencies : gstvideo_dep, gstbase_dep, gstvulkan_dep, vulkan_dep, gio_dep + extra_deps, install : true, install_dir : plugins_install_dir,
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/ext/vulkan/vkvp9dec.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/ext/vulkan/vkvp9dec.c
Changed
@@ -1188,7 +1188,7 @@ gst_vulkan_create_feature_name (device, "GstVulkanVp9Decoder", "GstVulkanVp9Device%dDecoder", &type_name, "vulkanvp9dec", - "vulkanVp9device%ddec", &feature_name, &cdata->description, &rank); + "vulkanvp9device%ddec", &feature_name, &cdata->description, &rank); type_info.class_data = cdata;
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/ext/wayland/gstwaylandsink.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/ext/wayland/gstwaylandsink.c
Changed
@@ -618,16 +618,24 @@ GST_DEBUG_OBJECT (self, "handling %s event", GST_EVENT_TYPE_NAME (event)); switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_STREAM_START: + gst_wayland_sink_set_rotate_method (self, + GST_VIDEO_ORIENTATION_IDENTITY, TRUE); + break; case GST_EVENT_TAG: gst_event_parse_tag (event, &taglist); if (gst_video_orientation_from_tag (taglist, &method)) { gst_wayland_sink_set_rotate_method (self, method, TRUE); + } else { + gst_wayland_sink_set_rotate_method (self, + GST_VIDEO_ORIENTATION_IDENTITY, TRUE); } break; case GST_EVENT_FLUSH_STOP: - gst_wl_window_flush (self->window); + if (self->window) + gst_wl_window_flush (self->window); break; default: break;
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/gst-libs/gst/codecparsers/gstav1parser.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/gst-libs/gst/codecparsers/gstav1parser.c
Changed
@@ -295,13 +295,18 @@ if (*retval != GST_AV1_PARSER_OK) return 0; - value |= (((gint) leb128_byte & 0x7f) << (i * 7)); + value |= (((guint64) leb128_byte & 0x7f) << (i * 7)); if (!(leb128_byte & 0x80)) break; + + if (i == 7 && leb128_byte & 0x80) { + *retval = GST_AV1_PARSER_BITSTREAM_ERROR; + return 0; + } } /* check for bitstream conformance see chapter4.10.5 */ - if (value < G_MAXUINT32) { + if (value <= G_MAXUINT32) { return (guint32) value; } else { GST_WARNING ("invalid leb128");
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/gst-libs/gst/codecparsers/gsth264parser.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/gst-libs/gst/codecparsers/gsth264parser.c
Changed
@@ -1830,18 +1830,26 @@ GstH264ParserResult gst_h264_parser_parse_nal (GstH264NalParser * nalparser, GstH264NalUnit * nalu) { - GstH264SPS sps; - GstH264PPS pps; + GstH264ParserResult res = GST_H264_PARSER_OK; switch (nalu->type) { - case GST_H264_NAL_SPS: - return gst_h264_parser_parse_sps (nalparser, nalu, &sps); + case GST_H264_NAL_SPS:{ + GstH264SPS sps; + + res = gst_h264_parser_parse_sps (nalparser, nalu, &sps); + gst_h264_sps_clear (&sps); + break; + } + case GST_H264_NAL_PPS:{ + GstH264PPS pps; + + res = gst_h264_parser_parse_pps (nalparser, nalu, &pps); + gst_h264_pps_clear (&pps); break; - case GST_H264_NAL_PPS: - return gst_h264_parser_parse_pps (nalparser, nalu, &pps); + } } - return GST_H264_PARSER_OK; + return res; } /** @@ -2036,8 +2044,6 @@ READ_UE_MAX (nr, mvc->num_views_minus1, GST_H264_MAX_VIEW_COUNT - 1); mvc->view = g_new0 (GstH264SPSExtMVCView, mvc->num_views_minus1 + 1); - if (!mvc->view) - goto error_allocation_failed; for (i = 0; i <= mvc->num_views_minus1; i++) READ_UE_MAX (nr, mvc->viewi.view_id, GST_H264_MAX_VIEW_ID); @@ -2075,8 +2081,6 @@ mvc->level_value = g_new0 (GstH264SPSExtMVCLevelValue, mvc->num_level_values_signalled_minus1 + 1); - if (!mvc->level_value) - goto error_allocation_failed; for (i = 0; i <= mvc->num_level_values_signalled_minus1; i++) { GstH264SPSExtMVCLevelValue *const level_value = &mvc->level_valuei; @@ -2087,8 +2091,6 @@ level_value->applicable_op = g_new0 (GstH264SPSExtMVCLevelValueOp, level_value->num_applicable_ops_minus1 + 1); - if (!level_value->applicable_op) - goto error_allocation_failed; for (j = 0; j <= level_value->num_applicable_ops_minus1; j++) { GstH264SPSExtMVCLevelValueOp *const op = &level_value->applicable_opj; @@ -2097,8 +2099,6 @@ READ_UE_MAX (nr, op->num_target_views_minus1, 1023); op->target_view_id = g_new (guint16, op->num_target_views_minus1 + 1); - if (!op->target_view_id) - goto error_allocation_failed; for (k = 0; k <= op->num_target_views_minus1; k++) READ_UE_MAX (nr, op->target_view_idk, GST_H264_MAX_VIEW_ID); @@ -2107,11 +2107,6 @@ } return TRUE; -error_allocation_failed: - GST_WARNING ("failed to allocate memory"); - gst_h264_sps_clear (sps); - return FALSE; - error: gst_h264_sps_clear (sps); return FALSE; @@ -2628,15 +2623,19 @@ g_free (mvc->view); mvc->view = NULL; - for (i = 0; i <= mvc->num_level_values_signalled_minus1; i++) { - GstH264SPSExtMVCLevelValue *const level_value = &mvc->level_valuei; - - for (j = 0; j <= level_value->num_applicable_ops_minus1; j++) { - g_free (level_value->applicable_opj.target_view_id); - level_value->applicable_opj.target_view_id = NULL; + if (mvc->level_value) { + for (i = 0; i <= mvc->num_level_values_signalled_minus1; i++) { + GstH264SPSExtMVCLevelValue *const level_value = &mvc->level_valuei; + + if (level_value->applicable_op) { + for (j = 0; j <= level_value->num_applicable_ops_minus1; j++) { + g_free (level_value->applicable_opj.target_view_id); + level_value->applicable_opj.target_view_id = NULL; + } + } + g_free (level_value->applicable_op); + level_value->applicable_op = NULL; } - g_free (level_value->applicable_op); - level_value->applicable_op = NULL; } g_free (mvc->level_value); mvc->level_value = NULL;
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/gst-libs/gst/codecparsers/gsth266parser.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/gst-libs/gst/codecparsers/gsth266parser.c
Changed
@@ -380,7 +380,7 @@ gst_h266_parse_profile_tier_level (GstH266ProfileTierLevel * ptl, NalReader * nr, guint8 profileTierPresentFlag, guint8 MaxNumSubLayersMinus1) { - gint8 i; + gint i; GST_LOG ("parsing \"Profile Tier Level parameters\"");
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/gst-libs/gst/cuda/cuda-gst.h -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/gst-libs/gst/cuda/cuda-gst.h
Changed
@@ -170,6 +170,10 @@ CUdevice dev); GST_CUDA_API +CUresult CUDAAPI CuDeviceGetUuid (CUuuid *uuid, + CUdevice dev); + +GST_CUDA_API CUresult CUDAAPI CuDeviceCanAccessPeer (int *canAccessPeer, CUdevice dev, CUdevice peerDev);
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/gst-libs/gst/cuda/gstcudacontext.cpp -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/gst-libs/gst/cuda/gstcudacontext.cpp
Changed
@@ -296,8 +296,19 @@ } } +/** + * gst_cuda_context_find_dxgi_adapter_luid: + * @cuda_device: a CUDA device index + * + * Finds the DXGI adapter LUID corresponding to the given CUDA device. + * This is useful for matching CUDA devices with Direct3D adapters on Windows. + * + * Returns: The DXGI adapter LUID or 0 if not found or on non-Windows platforms + * + * Since: 1.28.2 + */ #ifdef G_OS_WIN32 -static gint64 +gint64 gst_cuda_context_find_dxgi_adapter_luid (CUdevice cuda_device) { gint64 ret = 0; @@ -335,7 +346,14 @@ return ret; } +#else +gint64 +gst_cuda_context_find_dxgi_adapter_luid (CUdevice cuda_device) +{ + return 0; +} #endif + static gboolean init_cuda_ctx (void) {
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/gst-libs/gst/cuda/gstcudacontext.h -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/gst-libs/gst/cuda/gstcudacontext.h
Changed
@@ -93,5 +93,8 @@ gboolean gst_cuda_context_can_access_peer (GstCudaContext * ctx, GstCudaContext * peer); +GST_CUDA_API +gint64 gst_cuda_context_find_dxgi_adapter_luid (CUdevice cuda_device); + G_END_DECLS
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/gst-libs/gst/cuda/gstcudaloader.cpp -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/gst-libs/gst/cuda/gstcudaloader.cpp
Changed
@@ -130,6 +130,7 @@ CUresult (CUDAAPI * CuDeviceGetName) (char *name, int len, CUdevice dev); CUresult (CUDAAPI * CuDeviceGetAttribute) (int *pi, CUdevice_attribute attrib, CUdevice dev); + CUresult (CUDAAPI * CuDeviceGetUuid) (CUuuid *uuid, CUdevice dev); CUresult (CUDAAPI * CuDeviceCanAccessPeer) (int *canAccessPeer, CUdevice dev, CUdevice peerDev); CUresult (CUDAAPI * CuDriverGetVersion) (int *driverVersion); @@ -414,6 +415,7 @@ LOAD_SYMBOL (cuDeviceGetCount, CuDeviceGetCount); LOAD_SYMBOL (cuDeviceGetName, CuDeviceGetName); LOAD_SYMBOL (cuDeviceGetAttribute, CuDeviceGetAttribute); + LOAD_SYMBOL (cuDeviceGetUuid, CuDeviceGetUuid); LOAD_SYMBOL (cuDeviceCanAccessPeer, CuDeviceCanAccessPeer); LOAD_SYMBOL (cuDriverGetVersion, CuDriverGetVersion); @@ -830,6 +832,14 @@ } CUresult CUDAAPI +CuDeviceGetUuid (CUuuid * uuid, CUdevice dev) +{ + g_assert (gst_cuda_vtable.CuDeviceGetUuid != nullptr); + + return gst_cuda_vtable.CuDeviceGetUuid (uuid, dev); +} + +CUresult CUDAAPI CuDeviceCanAccessPeer (int *canAccessPeer, CUdevice dev, CUdevice peerDev) { g_assert (gst_cuda_vtable.CuDeviceCanAccessPeer != nullptr);
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/gst-libs/gst/cuda/stub/cuda.h -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/gst-libs/gst/cuda/stub/cuda.h
Changed
@@ -39,6 +39,11 @@ typedef guintptr CUdeviceptr; typedef gint CUdevice; +typedef struct CUuuid_st +{ + char bytes16; +} CUuuid; + typedef enum { CUDA_SUCCESS = 0,
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/gst-libs/gst/hip/stub/cuda.h -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/gst-libs/gst/hip/stub/cuda.h
Changed
@@ -38,6 +38,11 @@ typedef guintptr CUdeviceptr; typedef gint CUdevice; +typedef struct CUuuid_st +{ + char bytes16; +} CUuuid; + typedef enum { CUDA_SUCCESS = 0,
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/gst-libs/gst/vulkan/cocoa/gstvkwindow_cocoa.m -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/gst-libs/gst/vulkan/cocoa/gstvkwindow_cocoa.m
Changed
@@ -141,6 +141,7 @@ GstVulkanNSWindow *internal_win_id = (__bridge GstVulkanNSWindow *)priv->internal_win_id; GST_DEBUG_OBJECT (window_cocoa, "showing"); + NSApp setActivationPolicy:NSApplicationActivationPolicyRegular; internal_win_id makeMainWindow; internal_win_id orderFrontRegardless; internal_win_id setViewsNeedDisplay:YES;
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/gst-libs/gst/vulkan/gstvkimagememory.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/gst-libs/gst/vulkan/gstvkimagememory.c
Changed
@@ -407,6 +407,8 @@ gst_object_unref (mem->device); + g_mutex_clear (&mem->lock); + g_free (mem); }
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/gst-libs/gst/vulkan/gstvkswapper.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/gst-libs/gst/vulkan/gstvkswapper.c
Changed
@@ -661,7 +661,7 @@ { GstVulkanSwapperPrivate *priv = GET_PRIV (swapper); GstStructure *s; - GstCaps *caps; + GstCaps *caps, *allowed_caps; g_return_val_if_fail (GST_IS_VULKAN_SWAPPER (swapper), NULL); @@ -703,6 +703,13 @@ G_MAXINT, 1, NULL); } + /* Make sure we only advertise what's listed in GST_VULKAN_SWAPPER_VIDEO_FORMATS */ + allowed_caps = + gst_caps_from_string (GST_VIDEO_CAPS_MAKE_WITH_FEATURES + (GST_CAPS_FEATURE_MEMORY_VULKAN_IMAGE, GST_VULKAN_SWAPPER_VIDEO_FORMATS)); + caps = gst_caps_intersect_full (caps, allowed_caps, GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (allowed_caps); + GST_INFO_OBJECT (swapper, "Probed the following caps %" GST_PTR_FORMAT, caps); return caps;
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/gst-libs/gst/vulkan/meson.build -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/gst-libs/gst/vulkan/meson.build
Changed
@@ -114,6 +114,7 @@ vulkan_conf.set(option, 0) endforeach +vulkan_plugin_kwargs = {} if host_system == 'darwin' vulkan_dep = dependency('vulkan', method: 'pkg-config', required : false) if not vulkan_dep.found() @@ -127,6 +128,8 @@ vulkan_dep = objcpp.find_library('MoltenVK', required: false) if not vulkan_dep.found() vulkan_dep = dependency('MoltenVK', fallback: 'moltenvk', required: vulkan_opt) + # We need this to find libMoltenVK.dylib when installed + vulkan_plugin_kwargs += {'install_rpath': '@loader_path/..'} endif endif elif host_system == 'windows'
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/gst-libs/gst/wayland/gstwldisplay.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/gst-libs/gst/wayland/gstwldisplay.c
Changed
@@ -455,7 +455,10 @@ GST_INFO ("---"); g_mutex_lock (&priv->outputs_mutex); - g_hash_table_replace (priv->outputs, g_strdup (name), output); + if (name) + g_hash_table_replace (priv->outputs, g_strdup (name), output); + else + GST_WARNING ("Compositor has provided an unnamed output, ignoring."); g_mutex_unlock (&priv->outputs_mutex); }
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/gst-libs/gst/wayland/gstwlwindow.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/gst-libs/gst/wayland/gstwlwindow.c
Changed
@@ -749,12 +749,8 @@ priv->video_width = priv->buffer_width = info->width; priv->video_height = priv->buffer_height = info->height; - /* we don't have video_width/height saved initially, so if we didn't have a - * crop meta the width/height needs to be fixed from its reset value of 0 */ - if (crop.w == 0) - crop.w = priv->video_width; - if (crop.h == 0) - crop.h = priv->video_height; + crop.w = priv->video_width; + crop.h = priv->video_height; needs_layout_update = TRUE; }
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/gst-libs/gst/webrtc/nice/nice.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/gst-libs/gst/webrtc/nice/nice.c
Changed
@@ -202,6 +202,7 @@ g_mutex_unlock (&ice->priv->lock); g_thread_unref (ice->priv->thread); + ice->priv->thread = NULL; } struct NiceStreamItem @@ -1609,43 +1610,29 @@ struct close_data { - GWeakRef nice_weak; GstPromise *promise; gboolean agent_closed; }; static struct close_data * -close_data_new (GstWebRTCNice * ice, GstPromise * p) +close_data_new (GstPromise * p) { - struct close_data *d = g_atomic_rc_box_new0 (struct close_data); - g_weak_ref_init (&d->nice_weak, ice); + struct close_data *d = g_new0 (struct close_data, 1); d->promise = p ? gst_promise_ref (p) : NULL; d->agent_closed = FALSE; return d; } static void -close_data_clear (struct close_data *d) +close_data_free (struct close_data *d) { - g_weak_ref_clear (&d->nice_weak); if (d->promise) gst_promise_unref (d->promise); -} - -static struct close_data * -close_data_ref (struct close_data *d) -{ - return (struct close_data *) g_atomic_rc_box_acquire (d); + g_free (d); } static void -close_data_unref (struct close_data *d) -{ - g_atomic_rc_box_release_full (d, (GDestroyNotify) close_data_clear); -} - -static void -on_agent_closed (GObject * src, GAsyncResult * result, gpointer user_data) +_agent_closed_cb (GObject * src, GAsyncResult * result, gpointer user_data) { struct close_data *d = (struct close_data *) user_data; @@ -1658,41 +1645,76 @@ } d->agent_closed = TRUE; - close_data_unref (d); } static gboolean -close_main_cb (gpointer user_data) +_agent_closed_timeout_cb (gpointer user_data) { - struct close_data *d = (struct close_data *) user_data; - GstWebRTCNice *nice = g_weak_ref_get (&d->nice_weak); - - if (nice) { - /* 8. Destroy connection's ICE Agent, abruptly ending any active ICE - * processing and releasing any relevant resources (e.g. TURN permissions). */ - nice_agent_close_async (NICE_AGENT (nice->priv->nice_agent), - on_agent_closed, close_data_ref (d)); - if (!d->promise) { - while (!d->agent_closed) { - g_main_context_iteration (nice->priv->main_context, TRUE); - } - } - gst_object_unref (nice); + gboolean *agent_timeout = user_data; + + *agent_timeout = TRUE; + return FALSE; +}; + +static void +_close_agent (GstWebRTCNice * ice, GstPromise * promise) +{ + GMainContext *main_context = NULL; + struct close_data *agent_close_data = NULL; + gboolean agent_timeout = FALSE; + GSource *timeout_source; + + if (!ice->priv->thread) { + if (promise) { + GError *error = + g_error_new (GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_INTERNAL_FAILURE, + "ICE thread not running"); + GstStructure *s = gst_structure_new ("application/x-gst-promise", "error", + G_TYPE_ERROR, error, NULL); + gst_promise_reply (promise, s); + g_clear_error (&error); + }; + return; } - return G_SOURCE_REMOVE; + g_cancellable_cancel (ice->priv->resolve_cancellable); + + main_context = g_main_context_new (); + g_main_context_push_thread_default (main_context); + timeout_source = g_timeout_source_new (MAX_CLOSING_TIME_MILLI_SECONDS); + g_source_set_callback (timeout_source, _agent_closed_timeout_cb, + &agent_timeout, NULL); + g_source_attach (timeout_source, main_context); + + /* 8. Destroy connection's ICE Agent, abruptly ending any active ICE + * processing and releasing any relevant resources (e.g. TURN permissions). */ + agent_close_data = close_data_new (promise); + nice_agent_close_async (ice->priv->nice_agent, _agent_closed_cb, + agent_close_data); + + while (!agent_close_data->agent_closed && !agent_timeout) { + g_main_context_iteration (main_context, TRUE); + } + if (agent_timeout) { + GST_WARNING ("nice_agent_close_async() did not finish"); + } + g_source_destroy (timeout_source); + g_source_unref (timeout_source); + g_main_context_pop_thread_default (main_context); + g_main_context_unref (main_context); + close_data_free (agent_close_data); + + outstanding_resolves_wait (ice->priv->outstanding_resolves); + _stop_thread (ice); } static void gst_webrtc_nice_close (GstWebRTCICE * ice, GstPromise * promise) { GstWebRTCNice *nice = GST_WEBRTC_NICE (ice); - struct close_data *d = close_data_new (nice, promise); /* https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-close */ - - g_main_context_invoke_full (nice->priv->main_context, G_PRIORITY_DEFAULT, - close_main_cb, d, (GDestroyNotify) close_data_unref); + _close_agent (nice, promise); } static void @@ -1761,62 +1783,13 @@ } static void -_agent_closed_cb (GObject * source_object, GAsyncResult * res, - gpointer user_data) -{ - gboolean *agent_closed = user_data; - - *agent_closed = TRUE; -} - -static gboolean -_agent_closed_timeout_cb (gpointer user_data) -{ - gboolean *agent_timeout = user_data; - - *agent_timeout = TRUE; - return FALSE; -}; - -static void -_close_agent (GstWebRTCNice * ice) -{ - GMainContext *main_context = g_main_context_new (); - gboolean agent_closed = FALSE; - gboolean agent_timeout = FALSE; - GSource *timeout_source; - - g_main_context_push_thread_default (main_context); - timeout_source = g_timeout_source_new (MAX_CLOSING_TIME_MILLI_SECONDS); - g_source_set_callback (timeout_source, _agent_closed_timeout_cb, - &agent_timeout, NULL); - g_source_attach (timeout_source, main_context); - nice_agent_close_async (ice->priv->nice_agent, _agent_closed_cb, - &agent_closed); - while (!agent_closed && !agent_timeout) { - g_main_context_iteration (main_context, TRUE); - } - if (agent_timeout) { - GST_WARNING ("nice_agent_close_async() did not finish"); - } - g_source_destroy (timeout_source); - g_source_unref (timeout_source); - g_main_context_pop_thread_default (main_context); - g_main_context_unref (main_context); -} - -static void gst_webrtc_nice_finalize (GObject * object) { GstWebRTCNice *ice = GST_WEBRTC_NICE (object); g_signal_handlers_disconnect_by_data (ice->priv->nice_agent, ice); - g_cancellable_cancel (ice->priv->resolve_cancellable); - _close_agent (ice); - outstanding_resolves_wait (ice->priv->outstanding_resolves); - - _stop_thread (ice); + _close_agent (ice, NULL); g_clear_object (&ice->priv->resolve_cancellable); outstanding_resolves_unref (ice->priv->outstanding_resolves);
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/gst-plugins-bad.doap -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/gst-plugins-bad.doap
Changed
@@ -35,6 +35,16 @@ <release> <Version> + <revision>1.28.2</revision> + <branch>1.28</branch> + <name></name> + <created>2026-04-07</created> + <file-release rdf:resource="https://gstreamer.freedesktop.org/src/gst-plugins-bad/gst-plugins-bad-1.28.2.tar.xz" /> + </Version> + </release> + + <release> + <Version> <revision>1.28.1</revision> <branch>1.28</branch> <name></name>
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/gst/gdp/gstgdppay.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/gst/gdp/gstgdppay.c
Changed
@@ -513,7 +513,7 @@ static gboolean gst_gdp_pay_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) { - GstBuffer *outbuffer; + GstBuffer *outbuffer = NULL; GstGDPPay *this = GST_GDP_PAY (parent); GstFlowReturn flowret; GstCaps *caps; @@ -522,13 +522,15 @@ GST_DEBUG_OBJECT (this, "received event %p of type %s (%d)", event, gst_event_type_get_name (event->type), event->type); - /* now turn the event into a buffer */ - outbuffer = gst_gdp_buffer_from_event (this, event); - if (!outbuffer) - goto no_outbuffer; + if (GST_EVENT_TYPE (event) != GST_EVENT_CAPS) { + /* now turn the event into a buffer */ + outbuffer = gst_gdp_buffer_from_event (this, event); + if (!outbuffer) + goto no_outbuffer; - GST_BUFFER_TIMESTAMP (outbuffer) = GST_CLOCK_TIME_NONE; - GST_BUFFER_DURATION (outbuffer) = 0; + GST_BUFFER_TIMESTAMP (outbuffer) = GST_CLOCK_TIME_NONE; + GST_BUFFER_DURATION (outbuffer) = 0; + } /* if we got a new segment or tag event, we should put it on our streamheader, * and not send it on */ @@ -545,22 +547,24 @@ GST_DEBUG_OBJECT (this, "Received caps %" GST_PTR_FORMAT, event); this->have_caps = TRUE; gst_event_parse_caps (event, &caps); - gst_buffer_replace (&outbuffer, NULL); if (this->caps == NULL || !gst_caps_is_equal (this->caps, caps)) { GST_INFO_OBJECT (pad, "caps changed to %" GST_PTR_FORMAT, caps); gst_caps_replace (&this->caps, caps); - outbuffer = gst_gdp_buffer_from_caps (this, caps); - if (outbuffer == NULL) - goto no_buffer_from_caps; - - GST_BUFFER_DURATION (outbuffer) = 0; } + + outbuffer = gst_gdp_buffer_from_caps (this, caps); + if (outbuffer == NULL) + goto no_buffer_from_caps; + + GST_BUFFER_DURATION (outbuffer) = 0; break; } default: break; } + g_assert (outbuffer); + if (GST_EVENT_IS_STICKY (event)) { GST_BUFFER_FLAG_SET (outbuffer, GST_BUFFER_FLAG_HEADER); this->reset_streamheader = TRUE;
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/gst/jp2kdecimator/jp2kcodestream.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/gst/jp2kdecimator/jp2kcodestream.c
Changed
@@ -499,7 +499,7 @@ siz->yto = gst_byte_reader_get_uint32_be_unchecked (reader); siz->n_components = gst_byte_reader_get_uint16_be_unchecked (reader); - if (length < 38 + 3 * siz->n_components) { + if (length < 38 + 3 * (gsize) siz->n_components) { GST_ERROR_OBJECT (self, "Invalid SIZ marker"); return GST_FLOW_ERROR; } @@ -591,9 +591,9 @@ if ((Scod & 0x01)) { gint i; - /* User defined precincts */ - if (length < 12 + (Scod & 0x01) * (cod->n_decompositions + 1)) { + /* User defined precincts */ + if (length < 12 + 1 || length - 12 - 1 < cod->n_decompositions) { GST_ERROR_OBJECT (self, "Invalid COD marker"); return GST_FLOW_ERROR; } @@ -1072,8 +1072,8 @@ tile->sot.tile_part_index = gst_byte_reader_get_uint8_unchecked (reader); tile->sot.n_tile_parts = gst_byte_reader_get_uint8_unchecked (reader); - if (tile->sot.tile_part_size > - 2 + 10 + gst_byte_reader_get_remaining (reader)) { + if (tile->sot.tile_part_size < 12 || tile->sot.tile_part_size - 12 > + gst_byte_reader_get_remaining (reader)) { GST_ERROR_OBJECT (self, "Truncated tile part"); ret = GST_FLOW_ERROR; goto done; @@ -1581,13 +1581,31 @@ return GST_FLOW_ERROR; } + if (header->siz.xt == 0 || header->siz.yt == 0) { + GST_ERROR_OBJECT (self, "Invalid zero tile sizes"); + return GST_FLOW_ERROR; + } + + if (header->siz.xto > header->siz.x || header->siz.yto > header->siz.y) { + GST_ERROR_OBJECT (self, "Invalid tile origin"); + return GST_FLOW_ERROR; + } + header->n_tiles_x = (header->siz.x - header->siz.xto + header->siz.xt - 1) / header->siz.xt; header->n_tiles_y = (header->siz.y - header->siz.yto + header->siz.yt - 1) / header->siz.yt; - header->n_tiles = header->n_tiles_x * header->n_tiles_y; + if (header->n_tiles_x == 0 || header->n_tiles_y == 0) { + GST_ERROR_OBJECT (self, "Zero tiles in one direction"); + return GST_FLOW_ERROR; + } + if (!g_uint_checked_mul (&header->n_tiles, header->n_tiles_x, + header->n_tiles_y)) { + GST_ERROR_OBJECT (self, "Too many tiles"); + return GST_FLOW_ERROR; + } - header->tiles = g_malloc0 (sizeof (Tile) * header->n_tiles); + header->tiles = g_new0 (Tile, header->n_tiles); /* now at SOT marker, read the tiles */ {
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/gst/mpegtsmux/tsmux/tsmux.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/gst/mpegtsmux/tsmux/tsmux.c
Changed
@@ -1476,9 +1476,9 @@ program->next_scte35_pcr); if (program->next_scte35_pcr == -1) program->next_scte35_pcr = - next_pcr + program->scte35_null_interval * 300; + next_pcr + program->scte35_null_interval * 300ULL; else - program->next_scte35_pcr += program->scte35_null_interval * 300; + program->next_scte35_pcr += program->scte35_null_interval * 300ULL; GST_DEBUG ("next scte35 NOW pcr %" G_GINT64_FORMAT, program->next_scte35_pcr);
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/gst/mxf/mxfdemux.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/gst/mxf/mxfdemux.c
Changed
@@ -2363,6 +2363,16 @@ MIN (etrack->min_edit_units, (segment->index_start_position + segment->index_duration) - position); entry->size = segment->edit_unit_byte_count * entry->duration; + + if (entry->size > G_MAXUINT32) { + GST_ERROR_OBJECT (demux, + "Suspisciously large entry size %" G_GINT64_FORMAT + " = edit_unit_byte_count %" G_GUINT32_FORMAT " * entry duration %" + G_GINT64_FORMAT ", exceeds pullable size => not proceeding", + entry->size, segment->edit_unit_byte_count, entry->duration); + entry = NULL; + return FALSE; + } } else { entry->size = segment->edit_unit_byte_count; } @@ -2397,14 +2407,13 @@ /* Apply reverse temporal reordering if present */ if (index_table->reordered_delta_entry == etrack->delta_id) { - if (position >= index_table->reverse_temporal_offsets->len) { - GST_WARNING_OBJECT (demux, - "Can't apply temporal offset for position %" G_GINT64_FORMAT - " (max:%d)", position, index_table->reverse_temporal_offsets->len); - } if (demux->temporal_order_misuse) { GST_DEBUG_OBJECT (demux, "Handling temporal order misuse"); entry->pts = position + segment_index_entry->temporal_offset; + } else if (position >= index_table->reverse_temporal_offsets->len) { + GST_WARNING_OBJECT (demux, + "Can't apply temporal offset for position %" G_GINT64_FORMAT + " (max:%d)", position, index_table->reverse_temporal_offsets->len); } else { entry->pts = position + g_array_index (index_table->reverse_temporal_offsets, @@ -2578,6 +2587,17 @@ (index_segment->index_start_position + index_segment->index_duration) - position); retentry->size = index_segment->edit_unit_byte_count * retentry->duration; + + if (retentry->size > G_MAXUINT32) { + GST_ERROR_OBJECT (demux, + "Suspisciously large entry size %" G_GINT64_FORMAT + " = edit_unit_byte_count %" G_GUINT32_FORMAT " * entry duration %" + G_GINT64_FORMAT ", exceeds pullable size => not proceeding", + retentry->size, index_segment->edit_unit_byte_count, + retentry->duration); + retentry = NULL; + return FALSE; + } } else { retentry->size = index_segment->edit_unit_byte_count; } @@ -2667,12 +2687,17 @@ if (index_entry && delta_entry && delta_entry->pos_table_index == -1) { retentry->keyframe = (index_entry->flags & 0x80) == 0x80; - if (!demux->temporal_order_misuse) + if (demux->temporal_order_misuse) { + retentry->pts = position + index_entry->temporal_offset; + } else if (position >= index_table->reverse_temporal_offsets->len) { + GST_WARNING_OBJECT (demux, + "Can't apply temporal offset for position %" G_GINT64_FORMAT + " (max:%d)", position, index_table->reverse_temporal_offsets->len); + } else { retentry->pts = position + g_array_index (index_table->reverse_temporal_offsets, gint8, position); - else - retentry->pts = position + index_entry->temporal_offset; + } GST_LOG_OBJECT (demux, "Applied temporal offset. dts:%" G_GINT64_FORMAT " pts:%" G_GINT64_FORMAT, position, retentry->pts);
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/gst/sdp/gstsdpdemux.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/gst/sdp/gstsdpdemux.c
Changed
@@ -501,7 +501,7 @@ { const gchar *str; guint remaining; - gchar *del; + const gchar *del; gsize size; guint min_size; gboolean is_incl;
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/gst/videoparsers/gstav1parse.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/gst/videoparsers/gstav1parse.c
Changed
@@ -95,10 +95,15 @@ GST_AV1_PARSE_ALIGN_OBU, GST_AV1_PARSE_ALIGN_FRAME, GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT, - GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B, - GST_AV1_PARSE_ALIGN_ANNEX_B, } GstAV1ParseAligment; +typedef enum +{ + GST_AV1_PARSE_STREAM_FORMAT_ERROR = -1, + GST_AV1_PARSE_STREAM_FORMAT_OBU, + GST_AV1_PARSE_STREAM_FORMAT_ANNEX_B, +} GstAV1ParseStreamFormat; + struct _GstAV1Parse { GstBaseParse parent; @@ -124,8 +129,10 @@ gboolean has_input_fps; GstAV1ParseAligment in_align; + GstAV1ParseStreamFormat in_stream_format; gboolean detect_annex_b; GstAV1ParseAligment align; + GstAV1ParseStreamFormat stream_format; GstAV1Parser *parser; GstAdapter *cache_out; @@ -223,7 +230,8 @@ } static guint32 -_read_leb128 (guint8 * data, GstAV1ParserResult * retval, guint32 * comsumed) +_read_leb128 (guint8 * data, gsize size, GstAV1ParserResult * retval, + guint32 * consumed) { guint8 leb128_byte = 0; guint64 value = 0; @@ -232,7 +240,7 @@ GstBitReader br; guint32 cur_pos; - gst_bit_reader_init (&br, data, 8); + gst_bit_reader_init (&br, data, size); cur_pos = gst_bit_reader_get_pos (&br); for (i = 0; i < 8; i++) { @@ -243,14 +251,19 @@ return 0; } - value |= (((gint) leb128_byte & 0x7f) << (i * 7)); + value |= (((guint64) leb128_byte & 0x7f) << (i * 7)); if (!(leb128_byte & 0x80)) break; + + if (i == 7 && leb128_byte & 0x80) { + *retval = GST_AV1_PARSER_BITSTREAM_ERROR; + return 0; + } } - *comsumed = (gst_bit_reader_get_pos (&br) - cur_pos) / 8; + *consumed = (gst_bit_reader_get_pos (&br) - cur_pos) / 8; /* check for bitstream conformance see chapter4.10.5 */ - if (value < G_MAXUINT32) { + if (value <= G_MAXUINT32) { *retval = GST_AV1_PARSER_OK; return (guint32) value; } else { @@ -339,6 +352,8 @@ self->bit_depth = 0; self->align = GST_AV1_PARSE_ALIGN_NONE; self->in_align = GST_AV1_PARSE_ALIGN_NONE; + self->stream_format = GST_AV1_PARSE_STREAM_FORMAT_OBU; + self->in_stream_format = GST_AV1_PARSE_STREAM_FORMAT_OBU; self->detect_annex_b = FALSE; self->discont = TRUE; self->header = FALSE; @@ -546,24 +561,17 @@ } static const gchar * -gst_av1_parse_alignment_to_steam_format_string (GstAV1ParseAligment align) +gst_av1_parse_stream_format_to_string (GstAV1ParseStreamFormat stream_format) { - switch (align) { - case GST_AV1_PARSE_ALIGN_BYTE: - return "obu-stream"; - case GST_AV1_PARSE_ALIGN_OBU: - case GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT: - case GST_AV1_PARSE_ALIGN_FRAME: + switch (stream_format) { + case GST_AV1_PARSE_STREAM_FORMAT_OBU: return "obu-stream"; - case GST_AV1_PARSE_ALIGN_ANNEX_B: - case GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B: + case GST_AV1_PARSE_STREAM_FORMAT_ANNEX_B: return "annexb"; default: - GST_WARNING ("Unrecognized steam format"); + return "unrecognized stream format"; break; } - - return NULL; } static const gchar * @@ -571,180 +579,104 @@ { switch (align) { case GST_AV1_PARSE_ALIGN_BYTE: - case GST_AV1_PARSE_ALIGN_ANNEX_B: return "byte"; case GST_AV1_PARSE_ALIGN_OBU: return "obu"; case GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT: - case GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B: return "tu"; case GST_AV1_PARSE_ALIGN_FRAME: return "frame"; default: - GST_WARNING ("Unrecognized alignment"); + return "unrecognized alignment"; break; } - - return NULL; } -static GstAV1ParseAligment -gst_av1_parse_alignment_from_string (const gchar * align, - const gchar * stream_format) +static GstAV1ParseStreamFormat +gst_av1_parse_stream_format_from_string (const gchar * stream_format) { - if (!align && !stream_format) - return GST_AV1_PARSE_ALIGN_NONE; + /* OBU stream is the default stream format. */ + if (!stream_format) + return GST_AV1_PARSE_STREAM_FORMAT_OBU; - if (stream_format) { - if (g_strcmp0 (stream_format, "annexb") == 0) { - if (align && g_strcmp0 (align, "tu") == 0) { - return GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B; - } else if (align && g_strcmp0 (align, "none") == 0) { - return GST_AV1_PARSE_ALIGN_ANNEX_B; - } else { - return GST_AV1_PARSE_ALIGN_ERROR; - } - } else if (g_strcmp0 (stream_format, "obu-stream") != 0) { - /* unrecognized */ - return GST_AV1_PARSE_ALIGN_NONE; - } - - /* stream-format is obu-stream, depends on align */ + if (g_strcmp0 (stream_format, "annexb") == 0) { + return GST_AV1_PARSE_STREAM_FORMAT_ANNEX_B; + } else if (g_strcmp0 (stream_format, "obu-stream") == 0) { + return GST_AV1_PARSE_STREAM_FORMAT_OBU; } - if (align) { - if (g_strcmp0 (align, "byte") == 0) { - return GST_AV1_PARSE_ALIGN_BYTE; - } else if (g_strcmp0 (align, "obu") == 0) { - return GST_AV1_PARSE_ALIGN_OBU; - } else if (g_strcmp0 (align, "tu") == 0) { - return GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT; - } else if (g_strcmp0 (align, "frame") == 0) { - return GST_AV1_PARSE_ALIGN_FRAME; - } else { - /* unrecognized */ - return GST_AV1_PARSE_ALIGN_NONE; - } - } - - return GST_AV1_PARSE_ALIGN_NONE; + /* Unrecognized stream format. */ + return GST_AV1_PARSE_STREAM_FORMAT_ERROR; } -static gboolean -gst_av1_parse_caps_has_alignment (GstCaps * caps, GstAV1ParseAligment alignment) +static GstAV1ParseAligment +gst_av1_parse_alignment_from_string (const gchar * align) { - guint i, j, caps_size; - const gchar *cmp_align_str = NULL; - const gchar *cmp_stream_str = NULL; - - GST_DEBUG ("Try to find alignment %d in caps: %" GST_PTR_FORMAT, - alignment, caps); - - caps_size = gst_caps_get_size (caps); - if (caps_size == 0) - return FALSE; + if (!align) + return GST_AV1_PARSE_ALIGN_NONE; - switch (alignment) { - case GST_AV1_PARSE_ALIGN_BYTE: - cmp_align_str = "byte"; - cmp_stream_str = "obu-stream"; - break; - case GST_AV1_PARSE_ALIGN_OBU: - cmp_align_str = "obu"; - cmp_stream_str = "obu-stream"; - break; - case GST_AV1_PARSE_ALIGN_FRAME: - cmp_align_str = "frame"; - cmp_stream_str = "obu-stream"; - break; - case GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT: - cmp_align_str = "tu"; - cmp_stream_str = "obu-stream"; - break; - case GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B: - cmp_align_str = "tu"; - cmp_stream_str = "annexb"; - break; - case GST_AV1_PARSE_ALIGN_ANNEX_B: - cmp_align_str = "none"; - cmp_stream_str = "annexb"; - break; - default: - return FALSE; + if (g_strcmp0 (align, "byte") == 0) { + return GST_AV1_PARSE_ALIGN_BYTE; + } else if (g_strcmp0 (align, "obu") == 0) { + return GST_AV1_PARSE_ALIGN_OBU; + } else if (g_strcmp0 (align, "tu") == 0) { + return GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT; + } else if (g_strcmp0 (align, "frame") == 0) { + return GST_AV1_PARSE_ALIGN_FRAME; } - for (i = 0; i < caps_size; i++) { - GstStructure *s = gst_caps_get_structure (caps, i); - const GValue *alignment_value = gst_structure_get_value (s, "alignment"); - const GValue *stream_value = gst_structure_get_value (s, "stream-format"); - - if (!alignment_value || !stream_value) - continue; - - if (G_VALUE_HOLDS_STRING (alignment_value)) { - const gchar *align_str = g_value_get_string (alignment_value); - - if (g_strcmp0 (align_str, cmp_align_str) != 0) - continue; - } else if (GST_VALUE_HOLDS_LIST (alignment_value)) { - guint num_values = gst_value_list_get_size (alignment_value); - - for (j = 0; j < num_values; j++) { - const GValue *v = gst_value_list_get_value (alignment_value, j); - const gchar *align_str = g_value_get_string (v); + /* Unrecognized alignment. */ + return GST_AV1_PARSE_ALIGN_ERROR; +} - if (g_strcmp0 (align_str, cmp_align_str) == 0) - break; - } +static gboolean +gst_av1_parse_caps_has_tu_alignment (GstAV1Parse * self, GstCaps * caps) +{ + gboolean ret; + GstCaps *tu_caps = gst_caps_from_string + ("video/x-av1,alignment=(string)tu,stream-format=(string)obu-stream"); - if (j == num_values) - continue; - } + GST_DEBUG_OBJECT (self, "Try to find tu alignment and obu stream format " + "in caps: %" GST_PTR_FORMAT, caps); - if (G_VALUE_HOLDS_STRING (stream_value)) { - const gchar *stream_str = g_value_get_string (stream_value); + ret = gst_caps_can_intersect (caps, tu_caps); - if (g_strcmp0 (stream_str, cmp_stream_str) != 0) - continue; - } else if (GST_VALUE_HOLDS_LIST (stream_value)) { - guint num_values = gst_value_list_get_size (stream_value); + gst_caps_unref (tu_caps); - for (j = 0; j < num_values; j++) { - const GValue *v = gst_value_list_get_value (stream_value, j); - const gchar *stream_str = g_value_get_string (v); + return ret; +} - if (g_strcmp0 (stream_str, cmp_stream_str) == 0) - break; - } +static GstAV1ParseStreamFormat +gst_av1_parse_stream_format_from_caps (GstCaps * caps, gboolean * use_default) +{ + GstAV1ParseStreamFormat stream_format = GST_AV1_PARSE_STREAM_FORMAT_OBU; + gboolean has_stream_format = FALSE; - if (j == num_values) - continue; - } + if (caps && gst_caps_get_size (caps) > 0) { + GstStructure *s = gst_caps_get_structure (caps, 0); + const gchar *str_stream = gst_structure_get_string (s, "stream-format"); + if (str_stream) + has_stream_format = TRUE; - return TRUE; + stream_format = gst_av1_parse_stream_format_from_string (str_stream); } - return FALSE; + if (use_default) + *use_default = !has_stream_format; + + return stream_format; } static GstAV1ParseAligment gst_av1_parse_alignment_from_caps (GstCaps * caps) { - GstAV1ParseAligment align; - - align = GST_AV1_PARSE_ALIGN_NONE; - - GST_DEBUG ("parsing caps: %" GST_PTR_FORMAT, caps); + GstAV1ParseAligment align = GST_AV1_PARSE_ALIGN_NONE; if (caps && gst_caps_get_size (caps) > 0) { GstStructure *s = gst_caps_get_structure (caps, 0); - const gchar *str_align = NULL; - const gchar *str_stream = NULL; - - str_align = gst_structure_get_string (s, "alignment"); - str_stream = gst_structure_get_string (s, "stream-format"); + const gchar *str_align = gst_structure_get_string (s, "alignment"); - align = gst_av1_parse_alignment_from_string (str_align, str_stream); + align = gst_av1_parse_alignment_from_string (str_align); } return align; @@ -843,10 +775,11 @@ gst_caps_set_simple (final_caps, "colorimetry", G_TYPE_STRING, self->colorimetry, NULL); - g_assert (self->align > GST_AV1_PARSE_ALIGN_NONE); + g_assert (self->align > GST_AV1_PARSE_ALIGN_NONE && + self->align <= GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT); gst_caps_set_simple (final_caps, "parsed", G_TYPE_BOOLEAN, TRUE, "stream-format", G_TYPE_STRING, - gst_av1_parse_alignment_to_steam_format_string (self->align), + gst_av1_parse_stream_format_to_string (self->stream_format), "alignment", G_TYPE_STRING, gst_av1_parse_alignment_to_string (self->align), NULL); @@ -894,7 +827,7 @@ if (s) cll_str = gst_structure_get_string (s, "content-light-level"); - if (mdi_str) { + if (cll_str) { gst_caps_set_simple (final_caps, "content-light-level", G_TYPE_STRING, cll_str, NULL); } else if (self->content_light_level_state != GST_AV1_PARSE_OBU_EXPIRED && @@ -917,12 +850,43 @@ self->update_caps = FALSE; } +static gboolean +is_valid_align_and_stream_format (GstAV1ParseAligment align, + GstAV1ParseStreamFormat stream_format, GstPadDirection direction) +{ + if (direction == GST_PAD_SRC) { + if (align <= GST_AV1_PARSE_ALIGN_NONE) + return FALSE; + } else { + /* NONE is allowed for input to guess. */ + if (align == GST_AV1_PARSE_ALIGN_ERROR) + return FALSE; + } + + if (stream_format == GST_AV1_PARSE_STREAM_FORMAT_ERROR) + return FALSE; + + /* We only output annex-b stream in TU alignment */ + if (direction == GST_PAD_SRC && + stream_format == GST_AV1_PARSE_STREAM_FORMAT_ANNEX_B && + align != GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT) + return FALSE; + + /* Unknow input alignment with stream format of annex-b is not allowed */ + if (direction == GST_PAD_SINK && align == GST_AV1_PARSE_ALIGN_NONE && + stream_format == GST_AV1_PARSE_STREAM_FORMAT_ANNEX_B) + return FALSE; + + return TRUE; +} + /* check downstream caps to configure format and alignment */ static void gst_av1_parse_negotiate (GstAV1Parse * self, GstCaps * in_caps) { GstCaps *caps; GstAV1ParseAligment align; + GstAV1ParseStreamFormat stream_format; caps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (self)); GST_DEBUG_OBJECT (self, "allowed caps: %" GST_PTR_FORMAT, caps); @@ -934,25 +898,26 @@ GST_DEBUG_OBJECT (self, "negotiating with caps: %" GST_PTR_FORMAT, caps); } - /* prefer TU as default */ - if (gst_av1_parse_caps_has_alignment (caps, - GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT)) { + /* prefer TU alignment with obu-stream format as the default */ + if (gst_av1_parse_caps_has_tu_alignment (self, caps)) { self->align = GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT; + self->stream_format = GST_AV1_PARSE_STREAM_FORMAT_OBU; goto done; } - /* Both upsteam and downstream support, best */ + /* Both upstream and downstream support, best */ if (in_caps && caps) { if (gst_caps_can_intersect (in_caps, caps)) { GstCaps *common_caps = NULL; common_caps = gst_caps_intersect (in_caps, caps); align = gst_av1_parse_alignment_from_caps (common_caps); + stream_format = gst_av1_parse_stream_format_from_caps (common_caps, NULL); gst_clear_caps (&common_caps); - if (align != GST_AV1_PARSE_ALIGN_NONE - && align != GST_AV1_PARSE_ALIGN_ERROR) { + if (is_valid_align_and_stream_format (align, stream_format, GST_PAD_SRC)) { self->align = align; + self->stream_format = stream_format; goto done; } } @@ -963,19 +928,23 @@ /* fixate to avoid ambiguity with lists when parsing */ caps = gst_caps_fixate (caps); align = gst_av1_parse_alignment_from_caps (caps); + stream_format = gst_av1_parse_stream_format_from_caps (caps, NULL); - if (align != GST_AV1_PARSE_ALIGN_NONE && align != GST_AV1_PARSE_ALIGN_ERROR) { + if (is_valid_align_and_stream_format (align, stream_format, GST_PAD_SRC)) { self->align = align; + self->stream_format = stream_format; goto done; } } /* default */ self->align = GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT; + self->stream_format = GST_AV1_PARSE_STREAM_FORMAT_OBU; done: - GST_INFO_OBJECT (self, "selected alignment %s", - gst_av1_parse_alignment_to_string (self->align)); + GST_INFO_OBJECT (self, "selected alignment: %s, stream format: %s", + gst_av1_parse_alignment_to_string (self->align), + gst_av1_parse_stream_format_to_string (self->stream_format)); gst_clear_caps (&caps); } @@ -1032,6 +1001,8 @@ GstAV1Parse *self = GST_AV1_PARSE (parse); GstStructure *str; GstAV1ParseAligment align; + GstAV1ParseStreamFormat stream_format; + gboolean default_stream_format; GstCaps *in_caps = NULL; const gchar *profile; @@ -1053,17 +1024,22 @@ self->has_input_fps = FALSE; } - /* get upstream align from caps */ + /* get upstream align and stream format from caps */ align = gst_av1_parse_alignment_from_caps (caps); - if (align == GST_AV1_PARSE_ALIGN_ERROR) { - GST_ERROR_OBJECT (self, "Sink caps %" GST_PTR_FORMAT " set stream-format" - " and alignment conflict.", caps); + stream_format = + gst_av1_parse_stream_format_from_caps (caps, &default_stream_format); + if (!is_valid_align_and_stream_format (align, stream_format, GST_PAD_SINK)) { + GST_ERROR_OBJECT (self, "Sink caps %" GST_PTR_FORMAT " has invalid " + "alignment(%s) or stream format(%s) setting.", caps, + gst_av1_parse_alignment_to_string (align), + gst_av1_parse_stream_format_to_string (stream_format)); return FALSE; } in_caps = gst_caps_copy (caps); /* default */ if (align == GST_AV1_PARSE_ALIGN_NONE) { + g_assert (stream_format == GST_AV1_PARSE_STREAM_FORMAT_OBU); align = GST_AV1_PARSE_ALIGN_BYTE; gst_caps_set_simple (in_caps, "alignment", G_TYPE_STRING, gst_av1_parse_alignment_to_string (align), @@ -1083,17 +1059,17 @@ gst_caps_unref (in_caps); self->in_align = align; + self->in_stream_format = stream_format; + /* Some upstream element such as ivfparse may fail to recognize the + stream format. We can infer it in TU alignment by detecting the + first input data. */ if (self->in_align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT - || self->in_align == GST_AV1_PARSE_ALIGN_ANNEX_B) + && default_stream_format) self->detect_annex_b = TRUE; - if (self->in_align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B - || self->in_align == GST_AV1_PARSE_ALIGN_ANNEX_B) { - gst_av1_parser_reset (self->parser, TRUE); - } else { - gst_av1_parser_reset (self->parser, FALSE); - } + gst_av1_parser_reset (self->parser, + self->in_stream_format == GST_AV1_PARSE_STREAM_FORMAT_ANNEX_B); return TRUE; } @@ -1108,11 +1084,12 @@ GstFlowReturn ret = GST_FLOW_OK; /* Need to generate the final TU annex-b format */ - if (self->align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B) { + if (self->stream_format == GST_AV1_PARSE_STREAM_FORMAT_ANNEX_B) { guint8 size_dataGST_AV1_MAX_LEB_128_SIZE; guint size_len = 0; guint len; + g_assert (self->align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT); /* When push a TU, it must also be a frame end. */ g_assert (frame_finished); @@ -1353,22 +1330,16 @@ gst_av1_parse_cache_one_obu (GstAV1Parse * self, GstBuffer * buffer, GstAV1OBU * obu, guint8 * data, guint32 size, gboolean frame_complete) { - gboolean need_convert = FALSE; GstBuffer *buf; - if (self->in_align != self->align - && (self->in_align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B - || self->align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B)) - need_convert = TRUE; - - if (need_convert) { - if (self->in_align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B) { + if (self->in_stream_format != self->stream_format) { + if (self->in_stream_format == GST_AV1_PARSE_STREAM_FORMAT_ANNEX_B) { gst_av1_parse_convert_from_annexb (self, buffer, obu); } else { gst_av1_parse_convert_to_annexb (self, buffer, obu, frame_complete); } - } else if (self->align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B) { - g_assert (self->in_align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B); + } else if (self->stream_format == GST_AV1_PARSE_STREAM_FORMAT_ANNEX_B) { + g_assert (self->in_stream_format == GST_AV1_PARSE_STREAM_FORMAT_ANNEX_B); gst_av1_parse_convert_to_annexb (self, buffer, obu, frame_complete); } else { buf = gst_buffer_new_memdup (data, size); @@ -1994,20 +1965,40 @@ if (res == GST_AV1_PARSER_BITSTREAM_ERROR || res == GST_AV1_PARSER_MISSING_OBU_REFERENCE) { - /* Discard the whole frame */ + /* Input is annex-b but alignment is less than TU, we do not know + how many bytes to skip and so just get a error. */ + if (self->in_stream_format == GST_AV1_PARSE_STREAM_FORMAT_ANNEX_B && + self->in_align < GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT) { + GST_ERROR_OBJECT (parse, "Parse annex-b format get error %d", res); + *skipsize = 0; + ret = GST_FLOW_ERROR; + goto out; + } + + /* Discard the whole frame or TU */ *skipsize = map_info.size; GST_WARNING_OBJECT (parse, "Parse obu error, discard %d", *skipsize); - if (self->in_align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B) + if (self->in_stream_format == GST_AV1_PARSE_STREAM_FORMAT_ANNEX_B) gst_av1_parser_reset_annex_b (self->parser); gst_av1_parse_reset_obu_data_state (self); ret = GST_FLOW_OK; goto out; } else if (res == GST_AV1_PARSER_NO_MORE_DATA) { + /* Input is annex-b but alignment is less than TU, we do not know + how many bytes to skip and so just get a error. */ + if (self->in_stream_format == GST_AV1_PARSE_STREAM_FORMAT_ANNEX_B && + self->in_align < GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT) { + GST_ERROR_OBJECT (parse, "Parse annex-b format get error %d", res); + *skipsize = 0; + ret = GST_FLOW_ERROR; + goto out; + } + /* Discard the whole buffer */ *skipsize = map_info.size; GST_WARNING_OBJECT (parse, "Parse obu need more data, discard %d.", *skipsize); - if (self->in_align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B) + if (self->in_stream_format == GST_AV1_PARSE_STREAM_FORMAT_ANNEX_B) gst_av1_parser_reset_annex_b (self->parser); gst_av1_parse_reset_obu_data_state (self); @@ -2095,13 +2086,14 @@ break; } - if (self->align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT || + if (self->stream_format == GST_AV1_PARSE_STREAM_FORMAT_ANNEX_B) { + g_assert (self->align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT); + gst_av1_parse_convert_to_annexb (self, buffer, &obu, frame_complete); + } else if (self->align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT || self->align == GST_AV1_PARSE_ALIGN_FRAME) { GstBuffer *buf = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, self->last_parsed_offset, consumed); gst_adapter_push (self->cache_out, buf); - } else if (self->align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B) { - gst_av1_parse_convert_to_annexb (self, buffer, &obu, frame_complete); } else { g_assert_not_reached (); } @@ -2259,7 +2251,7 @@ goto out; } - tu_sz = _read_leb128 (map_info.data, &res, &consumed); + tu_sz = _read_leb128 (map_info.data, map_info.size, &res, &consumed); if (tu_sz == 0 || res != GST_AV1_PARSER_OK) { /* error to get the TU size, should not be annex b. */ goto out; @@ -2272,7 +2264,7 @@ } GST_INFO_OBJECT (self, "Detect the annex-b format"); - self->in_align = GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B; + self->in_stream_format = GST_AV1_PARSE_STREAM_FORMAT_ANNEX_B; self->detect_annex_b = FALSE; gst_av1_parser_reset (self->parser, TRUE); ret = TRUE; @@ -2329,55 +2321,72 @@ upstream_caps = gst_pad_peer_query_caps (GST_BASE_PARSE_SINK_PAD (self), NULL); if (upstream_caps) { - gboolean detect_annex_b = FALSE; + gboolean default_stream_format = FALSE; + + GST_DEBUG_OBJECT (self, "upstream caps: %" GST_PTR_FORMAT, upstream_caps); if (!gst_caps_is_empty (upstream_caps) && !gst_caps_is_any (upstream_caps)) { GstAV1ParseAligment align; - - GST_LOG_OBJECT (self, "upstream caps: %" GST_PTR_FORMAT, upstream_caps); + GstAV1ParseStreamFormat stream_format; /* fixate to avoid ambiguity with lists when parsing */ upstream_caps = gst_caps_fixate (upstream_caps); align = gst_av1_parse_alignment_from_caps (upstream_caps); - if (align == GST_AV1_PARSE_ALIGN_ERROR) { - GST_ERROR_OBJECT (self, "upstream caps %" GST_PTR_FORMAT - " set stream-format and alignment conflict.", upstream_caps); + stream_format = gst_av1_parse_stream_format_from_caps (upstream_caps, + &default_stream_format); + + if (!is_valid_align_and_stream_format (align, stream_format, + GST_PAD_SINK)) { + GST_ERROR_OBJECT (self, "upstream caps %" GST_PTR_FORMAT " has " + "invalid alignment(%s) or stream format(%s) setting.", + upstream_caps, gst_av1_parse_alignment_to_string (align), + gst_av1_parse_stream_format_to_string (stream_format)); gst_caps_unref (upstream_caps); return GST_FLOW_ERROR; } self->in_align = align; + self->in_stream_format = stream_format; } gst_caps_unref (upstream_caps); - if (self->in_align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B - || self->in_align == GST_AV1_PARSE_ALIGN_ANNEX_B) - detect_annex_b = TRUE; + gst_av1_parser_reset (self->parser, + self->in_stream_format == GST_AV1_PARSE_STREAM_FORMAT_ANNEX_B); - gst_av1_parser_reset (self->parser, detect_annex_b); + /* Some upstream element such as ivfparse may fail to recognize the + stream format. We can infer it in TU alignment by detecting the + first input data. */ + if (self->in_align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT + && default_stream_format) + self->detect_annex_b = TRUE; } if (self->in_align != GST_AV1_PARSE_ALIGN_NONE) { - GST_LOG_OBJECT (self, "Query the upstream get the alignment %s", - gst_av1_parse_alignment_to_string (self->in_align)); + GST_LOG_OBJECT (self, "Query the upstream get the alignment %s, " + "stream format %s", + gst_av1_parse_alignment_to_string (self->in_align), + gst_av1_parse_stream_format_to_string (self->in_stream_format)); } else { self->in_align = GST_AV1_PARSE_ALIGN_BYTE; - GST_DEBUG_OBJECT (self, "alignment set to default %s", - gst_av1_parse_alignment_to_string (GST_AV1_PARSE_ALIGN_BYTE)); + self->in_stream_format = GST_AV1_PARSE_STREAM_FORMAT_OBU; + GST_DEBUG_OBJECT (self, "set alignment to default %s, stream format " + "to default %s", gst_av1_parse_alignment_to_string (self->in_align), + gst_av1_parse_stream_format_to_string (self->in_stream_format)); } } - if ((self->in_align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT - || self->in_align == GST_AV1_PARSE_ALIGN_ANNEX_B) - && self->detect_annex_b) { + if (self->detect_annex_b) { + g_assert (self->in_align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT); + /* Only happend at the first time of handle_frame, try to recognize the annex b stream format. */ if (gst_av1_parse_detect_stream_format (parse, frame)) { - GST_INFO_OBJECT (self, "Input alignment %s", - gst_av1_parse_alignment_to_string (self->in_align)); + GST_INFO_OBJECT (self, "Input alignment %s, stream format %s.", + gst_av1_parse_alignment_to_string (self->in_align), + gst_av1_parse_stream_format_to_string (self->in_stream_format)); } else { /* Because the input is already TU aligned, we should skip the whole problematic TU and check the next one. */ @@ -2393,11 +2402,7 @@ gst_av1_parse_negotiate (self, NULL); in_level = self->in_align; - if (self->in_align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B) - in_level = GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT; out_level = self->align; - if (self->align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B) - out_level = GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT; if (self->in_align <= GST_AV1_PARSE_ALIGN_OBU && self->align == GST_AV1_PARSE_ALIGN_OBU) { @@ -2417,8 +2422,6 @@ { GstAV1Parse *self = GST_AV1_PARSE (parse); - frame->flags |= GST_BASE_PARSE_FRAME_FLAG_CLIP; - if (!frame->buffer) return GST_FLOW_OK;
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/gst/videoparsers/gsth264parse.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/gst/videoparsers/gsth264parse.c
Changed
@@ -2825,7 +2825,7 @@ sps->vui_parameters.num_units_in_tick, sps->vui_parameters.time_scale); } - } else { + } else if (!GST_CLOCK_TIME_IS_VALID (*out_dur)) { GstClockTime dur; GST_LOG_OBJECT (h264parse, "duration based ts"); @@ -2865,7 +2865,8 @@ /* don't mess with timestamps if provided by upstream, * particularly since our ts not that good they handle seeking etc */ - if (h264parse->do_ts) { + if (h264parse->do_ts && (!GST_BUFFER_DTS_IS_VALID (buffer) || + !GST_BUFFER_DURATION_IS_VALID (buffer))) { gst_h264_parse_get_timestamp (h264parse, &GST_BUFFER_DTS (buffer), &GST_BUFFER_DURATION (buffer), h264parse->frame_start);
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/gst/videoparsers/gsth265parse.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/gst/videoparsers/gsth265parse.c
Changed
@@ -2708,7 +2708,8 @@ gst_h265_parse_update_src_caps (h265parse, NULL); - if (h265parse->fps_num > 0 && h265parse->fps_den > 0) { + if (h265parse->fps_num > 0 && h265parse->fps_den > 0 && + !GST_BUFFER_DURATION_IS_VALID (buffer)) { GstClockTime val = gst_h265_parse_is_field_interlaced (h265parse) ? GST_SECOND / 2 : GST_SECOND;
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/gst/videoparsers/gstvp9parse.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/gst/videoparsers/gstvp9parse.c
Changed
@@ -441,8 +441,6 @@ { GstVp9Parse *self = GST_VP9_PARSE (parse); - frame->flags |= GST_BASE_PARSE_FRAME_FLAG_CLIP; - if (!frame->buffer) return GST_FLOW_OK;
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/gst/vmnc/vmncdec.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/gst/vmnc/vmncdec.c
Changed
@@ -438,6 +438,7 @@ } else { dec->cursor.cursordata = g_malloc (rect->width * rect->height * 4); memcpy (dec->cursor.cursordata, data + 2, rect->width * rect->height * 4); + dec->cursor.cursormask = NULL; } return datalen;
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/meson.build -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/meson.build
Changed
@@ -1,5 +1,5 @@ project('gst-plugins-bad', 'c', 'cpp', - version : '1.28.1', + version : '1.28.2', meson_version : '>= 1.4', default_options : 'warning_level=1', 'buildtype=debugoptimized' )
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/po/LINGUAS -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/po/LINGUAS
Changed
@@ -1,1 +1,1 @@ -af ar ast az bg ca cs da de el en_GB eo es eu fi fr fur gl hr hu id it ja ka ky lt lv mt nb nl or pl pt_BR ro ru sk sl sq sr sv tr uk vi zh_CN zh_TW +af ar ast az bg ca cs da de el en_GB eo es eu fi fr fur gl hr hu id it ja ka kk ky lt lv mt nb nl or pl pt_BR ro ru sk sl sq sr sv tr uk vi zh_CN zh_TW
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/po/gst-plugins-bad-1.0.pot -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/po/gst-plugins-bad-1.0.pot
Changed
@@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: gst-plugins-bad-1.28.1\n" +"Project-Id-Version: gst-plugins-bad-1.28.2\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-26 01:45+0000\n" +"POT-Creation-Date: 2026-04-07 20:03+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/po/gst-plugins-bad.pot -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/po/gst-plugins-bad.pot
Changed
@@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: gst-plugins-bad-1.28.1\n" +"Project-Id-Version: gst-plugins-bad-1.28.2\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-26 01:45+0000\n" +"POT-Creation-Date: 2026-04-07 20:03+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
View file
_service:download_files:gst-plugins-bad-1.28.2.tar.xz/po/kk.po
Added
@@ -0,0 +1,130 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2026 gst-plugins-bad's COPYRIGHT HOLDER +# This file is distributed under the same license as the gst-plugins-bad package. +# Baurzhan Muftakhidinov <baurthefirst@gmail.com>, 2026. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: gst-plugins-bad 1.27.90\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-03-18 23:43+0100\n" +"PO-Revision-Date: 2026-03-01 14:48+0500\n" +"Last-Translator: Baurzhan Muftakhidinov <baurthefirst@gmail.com>\n" +"Language-Team: Kazakh <(nothing)>\n" +"Language: kk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Bugs: Report translation errors to the Language-Team address.\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 3.8\n" + +msgid "No URL set." +msgstr "URL орнатылмаған." + +msgid "OpenCV failed to load template image" +msgstr "OpenCV үлгі суретін жүктеу сәтсіз аяқталды" + +msgid "Could not read title information for DVD." +msgstr "DVD үшін тақырып ақпаратын оқу мүмкін болмады." + +#, c-format +msgid "Failed to open DVD device '%s'." +msgstr "'%s' DVD құрылғысын ашу сәтсіз аяқталды." + +msgid "Failed to set PGC based seeking." +msgstr "PGC негізіндегі іздеуді орнату сәтсіз аяқталды." + +msgid "" +"Could not read DVD. This may be because the DVD is encrypted and a DVD " +"decryption library is not installed." +msgstr "" +"DVD-ні оқу мүмкін болмады. Бұл DVD шифрленгендіктен немесе DVD-ні дешифрлеу " +"кітапханасы орнатылмағандықтан болуы мүмкін." + +msgid "Could not read DVD." +msgstr "DVD-ні оқу мүмкін болмады." + +msgid "This file contains no playable streams." +msgstr "Бұл файлда ойнатылатын ағындар жоқ." + +msgid "Could not open sndfile stream for reading." +msgstr "Оқу үшін sndfile ағынын ашу мүмкін болмады." + +msgid "Generated file has a larger preroll time than its streams duration" +msgstr "" +"Генерацияланған файлдың алдын ала жүктеу уақыты оның ағындарының ұзақтығынан " +"көп" + +#, c-format +msgid "Missing element '%s' - check your GStreamer installation." +msgstr "'%s' элементі жетіспейді - GStreamer орнатылымын тексеріңіз." + +msgid "File location is set to NULL, please set it to a valid filename" +msgstr "Файл орны NULL мәніне орнатылған, оны жарамды файл атына орнатыңыз" + +msgid "Digitalzoom element couldn't be created" +msgstr "Digitalzoom элементін жасау мүмкін болмады" + +msgid "Subpicture format was not configured before data flow" +msgstr "Мәліметтер ағыны басталмай тұрып қосымша сурет пішімі бапталмады" + +msgid "Failed to get fragment URL." +msgstr "Фрагмент URL-ін алу сәтсіз аяқталды." + +#, c-format +msgid "Couldn't download fragments" +msgstr "Фрагменттерді жүктеп алу мүмкін болмады" + +msgid "Internal data stream error." +msgstr "Ішкі деректер ағынының қатесі." + +#, c-format +msgid "Device \"%s\" does not exist." +msgstr "\"%s\" құрылғысы жоқ." + +#, c-format +msgid "Could not open frontend device \"%s\"." +msgstr "\"%s\" интерфейс құрылғысын ашу мүмкін болмады." + +#, c-format +msgid "Could not get settings from frontend device \"%s\"." +msgstr "\"%s\" интерфейс құрылғысынан баптауларды алу мүмкін болмады." + +#, c-format +msgid "Cannot enumerate delivery systems from frontend device \"%s\"." +msgstr "" +"\"%s\" интерфейс құрылғысынан жеткізу жүйелерін тізіп шығу мүмкін емес." + +#, c-format +msgid "Could not open file \"%s\" for reading." +msgstr "\"%s\" файлын оқу үшін ашу мүмкін болмады." + +#, c-format +msgid "Couldn't find channel configuration file" +msgstr "Арна баптаулары файлы табылмады" + +#, c-format +msgid "Couldn't load channel configuration file: '%s'" +msgstr "Арна баптаулары файлын жүктеу мүмкін болмады: '%s'" + +#, c-format +msgid "Couldn't find details for channel '%s'" +msgstr "'%s' арнасының мәліметтері табылмады" + +#, c-format +msgid "No properties for channel '%s'" +msgstr "'%s' арнасының қасиеттері жоқ" + +#, c-format +msgid "Failed to set properties for channel '%s'" +msgstr "'%s' арнасының қасиеттерін орнату сәтсіз аяқталды" + +#, c-format +msgid "Couldn't find channel configuration file: '%s'" +msgstr "Арна баптаулары файлы табылмады: '%s'" + +#, c-format +msgid "Channel configuration file doesn't contain any channels" +msgstr "Арна баптаулары файлында ешқандай арна жоқ"
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/release-notes-1.28.md -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/release-notes-1.28.md
Changed
@@ -2,11 +2,11 @@ GStreamer 1.28.0 was originally released on 27 January 2026. -The latest bug-fix release in the stable 1.28 series is 1.28.1(#1.28.1) and was released on 26 February 2026. +The latest bug-fix release in the stable 1.28 series is 1.28.2(#1.28.2) and was released on 07 April 2026. See https://gstreamer.freedesktop.org/releases/1.28/latest for the latest version of this document. -*Last updated: Thursday 26 February 2026, 01:00 UTC (log)gitlog* +*Last updated: Tuesday 07 April 2026, 12:30 UTC (log)gitlog* latest: https://gstreamer.freedesktop.org/releases/1.28/ gitlog: https://gitlab.freedesktop.org/gstreamer/www/commits/main/src/htdocs/releases/1.28/release-notes-1.28.md @@ -1667,6 +1667,283 @@ - List of Merge Requests applied in 1.28.1(https://gitlab.freedesktop.org/groups/gstreamer/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.28.1) - List of Issues fixed in 1.28.1(https://gitlab.freedesktop.org/groups/gstreamer/-/issues?scope=all&utf8=%E2%9C%93&state=closed&milestone_title=1.28.1) +<a id="1.28.2"></a> + +### 1.28.2 + +The second 1.28 bug-fix release (1.28.2) was released on 07 April 2026. + +This release only contains bugfixes and important security fixessecurity. +It *should* be safe to update from 1.28.x and we recommend you do so at your +earliest convenience. + +security: https://gstreamer.freedesktop.org/security/ + +#### Highlighted bugfixes in 1.28.2 + + - Various security fixessecurity and playback fixes + - audioencoder: allow change of channel configuration with avenc_aac + - audioinvert: fix float format handling + - h264parse, h265parse, baseparse: Preserve upstream buffer duration if possible + - compositor: fix segfault with force-live=true and no sink pads (regression) + - fallbacksrc: send select-streams event to collection source element directly + - hlsdemux2: fix seekable range for live HLS streams + - glupload: Fix linking glupload with restrictive caps filter + - nvcodec: Add capability caching to speed up plugin initialization + - RTP and RTCP packet handling fixes + - RTSP server fixes for clean-up of timed out play requests + - video-converter: fix I420/A420 BGRA/ARGB output on big-endian + - qtdemux: fix invalid WebVTT timestamps, and other fixes + - qmlgl6sink: Qt6GLVideoItem caps update handling fixes + - threadshare udp sink and source fixes + - transcriberbin and speechmatics text-to-speech fixes and improvements + - videorate: Fix wrong caps in case of PTS going backward + - vtdec: more Apple VideoToolbox decoder fixes + - wavparse: Fix parsing of RF64 wave files + - wasapi2sink: Ignore transient device errors from default device + - waylandsink: various fixes and improvements + - WebRTC DTLS robustness/stability improvements + - Cerbero: Various inno Windows installer fixes and improvements; new 'gstreamer_bundle' wheels meta-package + - Various bug fixes, build fixes, memory leak fixes, and other stability and reliability improvements + +#### gstreamer + + - bin: iterator is not nullable(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11036) + - registry: Skip .dSYM bundles when loading plugins, try 3(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10970) + - baseparse: Preserve upstream buffer duration if possible(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11016) + - baseparse: Fix out_buffer leak in frame_free and missing ref in frame_copy(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11056) + - filesink: Fix wrong open() in overwrite mode(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10990) + - queue: Fix potential use-after-free in log function(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11192) + - GThreadFunc return type fixes(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10955) + - Strange File-sink-file-mode property value in filesink plugin(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/4946) + +#### gst-plugins-base + + - GstAudio/VideoDecoder: Fix different seqnum for eos event error(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11136) + - gst-validate reports event::eos-has-wrong-seqnum in GstAudio/VideoDecoder(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/work_items/4987) + - audioencoder: Remove fixed caps from srcpad(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11131) + - audio-resampler-neon: read array operand by hand to fix build errors with some armv7hf toolchains(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11231) + - audio-resampler: build error with some armv7hf toolchains: 'asm' operand has impossible constraints(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/work_items/5015) + - compositor: move gst_compositor_init_blend() to element class_init(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11080) + - exiftag: Add missing bounds check and integer overflow protections in various places(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11261) + - exiftag: Ignore invalid fractions with numerator/denominator G_MININT(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11229) + - exiftag: Unmap buffer if parsing a rational number gives a zero denominator(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11210) + - gl: upload: Fix linking glupload with restrictive caps filter(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11050) + - glupload: can't handle caps video/x-raw(memory:GLMemory)(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/work_items/4622) + - glcolorconvert: Fix NULL pointer dereference on buffers without video meta(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10953) + - libs_gstglcolorconvert test failure in 1.28.1(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/4935) + - opusenc: Use correct memcpy() size when copying Vorbis channel positions(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10984) + - opusenc: using invalid size for memcpy?(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/4948) + - playback: Make sure to check for empty/any caps before getting the first structure(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11212) + - rtcp: Fix buffer overread in SDES packet parsing(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10971) + - rtpbuffer: Add validation for CSRC list length(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10957) + - rtsp: gstrtspurl: Parse URL having user without password(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11083) + - rtsp: Does not parse URL with user but no password as valid(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/work_items/4922) + - subparse: Avoid NULL-pointer dereferences in mdvdsub parsing code(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11256) + - subparse: Fix integer overflow when calculating qttext timestamp(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11265) + - subparse: Replace regex string matching / replacing with plain C string parsing(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11249) + - typefindfunctions: Avoid signed 32 bit integer overflow and OOB reads when parsing LEB128 values(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11259) + - video-converter: fix I420/A420 BGRA/ARGB output on big-endian(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11024) + - video: fix too small default stride for UYVP with odd widths(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11039) + - videorate: Fix unrestored caps on backward PTS(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11038) + - GThreadFunc return type fixes(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10955) + +#### gst-plugins-good + + - audioinvert: fix float truncation in transform_float(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11171) + - audioinvert float path broken(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/work_items/4998) + - compositor: segfault with force-live=true and no sink pads (regression in 1.28)(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/work_items/4978) + - flvdemux: Avoid assertions on corrupted streams(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11258) + - flvmux: fix race condition on caps get and check(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11235) + - hlsdemux2: fix seekable range for live HLS streams(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11051) + - matroskademux: Fix calculation of bz2 buffer sizes(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11263) + - qtqml: Avoid parsing caps on every buffer (same fix for both qt5 and qt6)(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11184) + - qtdemux: Add various integer overflow and bounds checks to uncompressed video handling(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11252) + - qtdemux: fix invalid WebVTT timestamps(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11019) + - qtdemux: fix handling of in-between fragments without tfdt(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11067) + - qtdemux: Don't immediately push segment after moov in push mode for fmp4(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11055) + - qtdemux: Preserve Metas and Flags when doing row alignment(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11156) + - qtdemux: Avoid a couple of integer overflows(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11164) + - qtdemux: Various fixes related to audio channel counts(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11253) + - Qt6GLVideoItem: caps update fixed(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10968) + - GstGLQt6VideoItem crashes after source pipeline change(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/work_items/4944) + - rgvolume: don't apply dBSPL reference level compensation for LUFS values(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11043) + - rtspsrc: Discard early data in ONVIF mode(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11197) + - rtspsrc: Fix const-correctness issue around strchr() usage(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11217) + - rtph264depay: fix invalid memory access in gst_rtp_h264_finish_fragmentation_unit(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10960) + - rtptwcc: fix feedback packet count wrapping at 255(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10925) + - vmncdec: Set cursormask to NULL to prevent double free(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11264) + - wavenc: Skip writing empty LIST INFO chunk(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11058) + - wavparse: Avoid overflow in length when setting ignore-length=true(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11026) + - wavparse: Fix integer overflow when checking available buffer size for reading cues(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11262) + - wavparse: Fix parsing of RF64 wave files(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11028) + - GThreadFunc return type fixes(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10955) + +#### gst-plugins-bad + + - analytics: Set default pixel-aspect-ratio for inference elements(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11048) + - av1dec: Enable VIDEO_META and VIDEO_ALIGNMENT for pool(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10993) + - av1parse, vp9parse: Remove segment clipping to let downstream handle frame boundaries(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11087) + - av1parse: Avoid signed 32 bit integer overflow and OOB reads when parsing LEB128 values(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11259) + - av1parse: split the alignment and stream type logic(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10912) + - av1parse: Misc fixes 2 typo(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11003) + - av1parse: Invalid assertion in gst_av1_parse_detect_stream_format()(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/4919) + - dashsink: test: use playbin3 for DASH playback verification(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10914) + - decklinkvideosink: fix element leak in decklink callback(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11009) + - dtls: unregister signal handlers from connection(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11079) + - gdppay: Fix null pointer dereference on duplicated caps event(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11021) + - h264parse, h265parse: Preserve upstream buffer duration if possible(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11016) + - h264parser: Fix memory leak in gst_h264_parser_parse_nal()(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11060) + - h264parse: Avoid NULL pointer dereferences when freeing partially parsed SPS/MVC data(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11251) + - h264: Memory Leak in gst_h264_parser_parse_nal()(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/4966) + - h266parser: Avoid integer overflow when parsing profile / tier / level(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11257) + - jp2kdecimator: Avoid integer overflows and divisions by zero on invalid tile configurations(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11239) + - mxfdemux: hardening(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11127) + - nice: Fix leak of webrtc libnice thread(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11112) + - nvcodec: Add capability caching to speed up plugin initialization(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10767) + - tsmux: Fix integer overflow in SCTE35 NULL interval(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11076) + - sctp: Set number of outgoing & incoming streams to the same value(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11209) + - shm: fix shmsink exit code 1 on clean shutdown(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11163) + - soundtouch: Only allow up to 192kHz and 16 channels(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11011) + - srtpenc: preserve ROC when master key is updated for an ongoing session(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10977) + - svtav1: fix "Level of parallelism" property type discrepencies(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10913) + - vkswapper/vksink: Don't advertise unsupported formats(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11160) + - vmncdec: Set cursormask to NULL to prevent double free(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11264) + - vtdec: vp9 support is only enabled in first vtdec element(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/4964) + - vtdec: Do not hold the stream lock when pushing out frames(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11099) + - vtdec: Prefer outputting VulkanImage instead of sysmem, fix some leaks, ensure vulkansink provides a window(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11138) + - vtdec: Store supplemental codec support in a global variable(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11045) + - vtdec: Supplemental VideoToolbox decoders now registered via vtutil helper(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11146) + - vtdec: handle decoder error status for iOS, vtenc: restart if VTCompressionSessionCompleteFrames fails(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/erge_requests/11233) + - vulkan: Clear mutex when GstVulkanImageMemory is freed(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11059) + - vulkanvp9dec: Fix case in device-specific factory name(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11117) + - wasapi2: Log target device information(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11202) + - wasapi2sink: Ignore device errors from default device(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11120) + - wayland: display: Add protection when replacing wl_output(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11086) + - waylandsink: fix waylandsink crash when call window flush(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11137) + - waylandsink: Properly reset the tag orientation(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11216) + - wlwindow: fix viewport source outside buffer when play resolution change stream(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11142) + - Fix a couple of const correctness bugs around strchr() usage(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11186) + - GThreadFunc return type fixes(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10955) + - meson: Fix downloading MoltenVK SDK, make it work when meson-installed(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10918) + +#### gst-plugins-ugly + + - No changes + +#### GStreamer Rust plugins + + - burn: yoloxinference: Restrict widths/heights to a multiple of 32(https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/2967) + - fallbacksrc: Send select-streams event to collection source element(https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/2923) + - gtk4paintablesink: Error out in NULL->READY if there is no default GDK display(https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/2932) + - png: implement image repacking when buffer is padded(https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/2972) + - rtpbin2: don't panic in Drop impl(https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/2960) + - rtpbin2: improve logs(https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/2999) + - rtpbin2: jitterbuffer: fix deadline for re-ordered packets(https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/2998) + - rtpbin2: more log improvements(https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/2994) + - rtprecv: JitterBufferStream: avoid polling JitterBuffer when possible(https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/3003) + - speechmatics: fix first_buffer_pts race condition in dispatch_message(https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/2910) + - speechmatics, textaccumulate: fix flushing issues(https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/2943) + - threadshare: fix socket leak in ts-udpsink(https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/2920) + - threadshare: udpsink/src: don't error out failing to send packet to a client / receiving an ICMP error(https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/2950) + - tracers: Mark enum types as plugin API(https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/3000) + - transcriberbin: ignore flow errors from transcription branch(https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/2978) + - webrtc: Silence new clippy warning(https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/2935) + - webrtc: tests: run signalling server with unique port number(https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/2995) + - whisper: fix compiling on ARM(https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/2986) + - whisper: update to latest release 0.16(https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/2952) + - Don't transform push_event() false returns into flow errors(https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/2915) + - Switch from `std::os::raw` to `std::ffi` for C types(https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/3011) + - Update dependencies(https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/2917) + - Update dependencies(https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/3006) + - meson: only add example features when dependencies are found(https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/2937) + - build: update rustfmt edition to 2024(https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/2965) + +#### gst-libav + + - avviddec: Refcount codec frame associated with video frame(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11188) + +#### gst-rtsp-server + + - rtsp-client: Lock media when unlinking session medias(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11041) + - rtsp-stream: Clear send_thread when it's freed(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10950) + - Attempt to use freed thread for reusable RTSP media(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/4920) + - Fix a couple of const correctness bugs around strchr() usage(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11186) + +#### gstreamer-sharp + + - No changes + +#### gst-python + + - bin: iterator is not nullable(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11036) + +#### gst-editing-services + + - Remove spurious python-embed dependency from libges(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11069) + - Fix a couple of const correctness bugs around strchr() usage(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11186) + +#### gst-devtools, gst-validate + gst-integration-testsuites + + - No changes + +#### gst-examples + + - No changes + +#### gstreamer-docs + + - No changes + +#### Development build environment + + - libxml2: update wrap to v2.15.2(https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10979) + +#### Cerbero build tool and packaging changes in 1.28.2 + + - Update to Rust 1.94 and cargo-c 0.10.21(https://gitlab.freedesktop.org/gstreamer/cerbero/-/merge_requests/2157) + - build: include plugin's .pc file in Linux and macOS(https://gitlab.freedesktop.org/gstreamer/cerbero/-/merge_requests/2155) + - inno Windows installer: Restructure features and fix required components triggering on Devel and Debug levels(https://gitlab.freedesktop.org/gstreamer/cerbero/-/merge_requests/2086) + - inno Windows installer: fix environment variable being created outside SessionManager/Environment(https://gitlab.freedesktop.org/gstreamer/cerbero/-/merge_requests/2153) + - inno: assorted fixes for Registry key handling(https://gitlab.freedesktop.org/gstreamer/cerbero/-/merge_requests/2173) + - libpng: update to 1.6.56(https://gitlab.freedesktop.org/gstreamer/cerbero/-/merge_requests/2182) + - libsoup: update to 3.6.6(https://gitlab.freedesktop.org/gstreamer/cerbero/-/merge_requests/2164) + - libsrtp: update to v2.8.0(https://gitlab.freedesktop.org/gstreamer/cerbero/-/merge_requests/2168) + - soundtouch: update to 2.4.1(https://gitlab.freedesktop.org/gstreamer/cerbero/-/merge_requests/2189) + - packaging: Fix missing devel payloads for gstreamer-1.0-python(https://gitlab.freedesktop.org/gstreamer/cerbero/-/merge_requests/2172) + - recipe: do not run symbolication if nodebug(https://gitlab.freedesktop.org/gstreamer/cerbero/-/merge_requests/2151) + - wheels: Add a new meta-package 'gstreamer_bundle'(https://gitlab.freedesktop.org/gstreamer/cerbero/-/merge_requests/2147) + - GStreamer 1.28 installer issue. GSTREAMER_1_0_ROOT_MSVC_X86_64 env variable(https://gitlab.freedesktop.org/gstreamer/cerbero/-/issues/574) + - GStreamer 1.28.1 Windows doesn't have python-devel component(https://gitlab.freedesktop.org/gstreamer/cerbero/-/issues/576) + - GStreamer 1.28.1 Windows uninstaller doesn't remove the registry values(https://gitlab.freedesktop.org/gstreamer/cerbero/-/issues/575) + - Shipping a pkg-config for consuming Android binaries on macOS(https://gitlab.freedesktop.org/gstreamer/cerbero/-/work_items/522) + - Fixes for cross-compiling to android on macOS and consuming the built binaries(https://gitlab.freedesktop.org/gstreamer/cerbero/-/merge_requests/2188) + - Adjust CI for xcframework iOS tutorials(https://gitlab.freedesktop.org/gstreamer/cerbero/-/merge_requests/2186) + +#### Contributors to 1.28.2 + +Albert Sjölund, Alicia Boya García, Adrian Perez de Castro, +Andoni Morales Alastruey, Charles, Cameron O'Neal, Cole Richardson, +Daniel Morin, Dominique Leroux, Emil Ljungdahl, Fabian Orccon, François Laignel, +Frédéric Chanal, Haihua Hu, Havard Graff, He Junyan, Hou Qi, James Liu, +Jan Alexander Steffens (heftig), Jan Schmidt, Jeongmin Kwak, Johan Sternerup, +László Károlyi, L. E. Segovia (Amyspark),Marko Kohtala, Mathieu Duponchelle, +Matthew Waters, Mattia, Michael Olbrich, Nicolas Dufresne, Nirbheek Chauhan, +Ognyan Tonchev, Olivier Crête, Pablo García, Pavel Guzenfeld, Per Enstedt, +Peter Stensson, Piotr Brzeziński, Robert Mader, Sanchayan Maity, +Sebastian Dröge, Sergey Radionov, Seungha Yang, Seungmin Lee, Stéphane Cerveau, +Taruntej Kanakamalla, Thibault Saunier, Tim-Philipp Müller, Tobias Rapp, +Tobias Schlager, Tulio Beloqui, Vadym Markov, Vitaly Vlasov, Vivia Nikolaidou, +Vivienne Watermeier, Wojciech Kapsa, Xabier Rodriguez Calvar, Xavier Claessens, + +... and many others who have contributed bug reports, translations, sent +suggestions or helped testing. Thank you all! + +#### List of merge requests and issues fixed in 1.28.2 + +- List of Merge Requests applied in 1.28.2(https://gitlab.freedesktop.org/groups/gstreamer/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&milestone_title=1.28.2) +- List of Issues fixed in 1.28.2(https://gitlab.freedesktop.org/groups/gstreamer/-/issues?scope=all&utf8=%E2%9C%93&state=closed&milestone_title=1.28.2) + ## Schedule for 1.30 Our next major feature release will be 1.30, and 1.29 will be the unstable
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/sys/applemedia/meson.build -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/sys/applemedia/meson.build
Changed
@@ -134,6 +134,7 @@ endforeach applemedia_objcpp_args = +applemedia_kwargs = {} vulkan_option = get_option('vulkan') vk_required = applemedia_option.enabled() and vulkan_option.enabled() if gstvulkan_dep.found() and not vulkan_option.disabled() @@ -149,6 +150,10 @@ applemedia_frameworks += moltenvk_dep, gstvulkan_dep, metal_dep applemedia_sources += vulkan_sources applemedia_args += '-DAPPLEMEDIA_MOLTENVK' + if moltenvk_dep.type_name() == 'internal' + # Needed to find libMoltenVK.dylib when installed + applemedia_kwargs += {'install_rpath': '@loader_path/..'} + endif # override_options : 'cpp_std=c++11' doesn't seem to work for objcpp applemedia_objcpp_args += objcpp.get_supported_arguments( '-std=c++11', @@ -163,6 +168,7 @@ objc_args : gst_plugins_bad_args + applemedia_args + applemedia_objc_args, objcpp_args : gst_plugins_bad_args + applemedia_args + applemedia_objc_args + applemedia_objcpp_args, link_args : noseh_link_args, + kwargs: applemedia_kwargs, include_directories : configinc, libsinc, dependencies : gstvideo_dep, gstpbutils_dep, gst_dep, gstbase_dep, gstgl_dep, gstglproto_dep, gstcodecparsers_dep + applemedia_frameworks, override_options : 'cpp_std=c++11',
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/sys/applemedia/vtdec.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/sys/applemedia/vtdec.c
Changed
@@ -58,15 +58,6 @@ #include <gst/video/gstvideodecoder.h> #include <gst/gl/gstglcontext.h> -#if TARGET_OS_OSX || TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION -#define HAVE_SUPPLEMENTAL -#if (TARGET_OS_OSX && __MAC_OS_X_VERSION_MAX_ALLOWED >= 110000) || (TARGET_OS_IOS && __IPHONE_OS_VERSION_MAX_ALLOWED >= 260200) || (TARGET_OS_TV && __TV_OS_VERSION_MAX_ALLOWED >= 260200) || (TARGET_OS_VISION && __VISION_OS_VERSION_MAX_ALLOWED >= 260200) -#define HAVE_SUPPLEMENTAL_DEFINITION -#else -#include <dlfcn.h> -#endif -#endif - #include "vtutil.h" #include "helpers.h" #include "corevideobuffer.h" @@ -79,6 +70,13 @@ GST_DEBUG_CATEGORY_STATIC (gst_vtdec_debug_category); #define GST_CAT_DEFAULT gst_vtdec_debug_category +typedef enum +{ + NoneSupported = 0, + Av1Supported = 1 << 0, + Vp9Supported = 1 << 1, +} SupplementalSupport; + enum { /* leave some headroom for new GstVideoCodecFrameFlags flags */ @@ -159,6 +157,8 @@ " width=(int)64, MAX, height=(int)64, MAX;") ); +static SupplementalSupport gst_vtdec_codec_support = NoneSupported; + /* define EnableHardwareAcceleratedVideoDecoder in < 10.9 */ #if defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < 1090 const CFStringRef @@ -172,15 +172,15 @@ #define VIDEO_SRC_CAPS_FORMATS "{ NV12, AYUV64, ARGB64_BE, P010_10LE }" #define VIDEO_SRC_CAPS_NATIVE \ - GST_VIDEO_CAPS_MAKE(VIDEO_SRC_CAPS_FORMATS) ";" \ GST_VIDEO_CAPS_MAKE_WITH_FEATURES(GST_CAPS_FEATURE_MEMORY_GL_MEMORY,\ VIDEO_SRC_CAPS_FORMATS) ", " \ - "texture-target = (string) rectangle " + "texture-target = (string) rectangle ;" \ + GST_VIDEO_CAPS_MAKE(VIDEO_SRC_CAPS_FORMATS) #if defined(APPLEMEDIA_MOLTENVK) -#define VIDEO_SRC_CAPS VIDEO_SRC_CAPS_NATIVE "; " \ +#define VIDEO_SRC_CAPS \ GST_VIDEO_CAPS_MAKE_WITH_FEATURES(GST_CAPS_FEATURE_MEMORY_VULKAN_IMAGE, \ - VIDEO_SRC_CAPS_FORMATS) + VIDEO_SRC_CAPS_FORMATS) ";" VIDEO_SRC_CAPS_NATIVE #else #define VIDEO_SRC_CAPS VIDEO_SRC_CAPS_NATIVE #endif @@ -206,6 +206,7 @@ caps = gst_vtutil_caps_append_video_format (caps, "RGBA64_LE"); gst_element_class_add_pad_template (element_class, gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, caps)); + gst_caps_unref (caps); } gst_element_class_set_static_metadata (element_class, @@ -261,6 +262,7 @@ vtdec->is_flushing = FALSE; vtdec->is_draining = FALSE; vtdec->downstream_ret = GST_FLOW_OK; + g_atomic_int_set (&vtdec->require_reset, FALSE); vtdec->reorder_queue = gst_vec_deque_new (0); /* Create the output task, but pause it immediately */ @@ -369,8 +371,6 @@ /* we need to check this in case dpb_size=0 (jpeg for * example) or we're draining/flushing */ if (frame) { - GST_VIDEO_DECODER_STREAM_LOCK (vtdec); - if (frame->flags & VTDEC_FRAME_FLAG_ERROR) { GST_VIDEO_DECODER_ERROR (vtdec, 1, STREAM, DECODE, ("Got frame %d with an error flag", frame->system_frame_number), @@ -389,8 +389,6 @@ GST_TRACE_OBJECT (vtdec, "frame %d push ret %s", frame_num, gst_flow_get_name (ret)); } - - GST_VIDEO_DECODER_STREAM_UNLOCK (vtdec); } g_mutex_lock (&vtdec->queue_mutex); @@ -845,6 +843,8 @@ gst_video_codec_state_unref (vtdec->input_state); vtdec->input_state = gst_video_codec_state_ref (state); + g_atomic_int_set (&vtdec->require_reset, FALSE); + return negotiate_now ? gst_vtdec_negotiate (decoder) : TRUE; } @@ -940,6 +940,51 @@ transition); } +static gboolean +gst_vtdec_reset_session (GstVtdec * vtdec) +{ + GstVideoDecoder *decoder = GST_VIDEO_DECODER_CAST (vtdec); + GstVideoCodecState *output_state; + GstVideoFormat format; + OSStatus status; + + if (!vtdec->session) { + GST_ERROR_OBJECT (vtdec, "Cannot reset without a valid session!"); + return FALSE; + } + + output_state = gst_video_decoder_get_output_state (decoder); + if (!output_state) { + GST_ERROR_OBJECT (vtdec, + "Cannot reset session without a current output state!"); + return FALSE; + } + + gst_vtdec_invalidate_session (vtdec); + + format = GST_VIDEO_INFO_FORMAT (&output_state->info); + gst_video_codec_state_unref (output_state); + + status = gst_vtdec_create_session (vtdec, format, TRUE); + if (status == noErr) { + GST_INFO_OBJECT (vtdec, "reset session using hardware decoder"); + } else if (status == kVTVideoDecoderNotAvailableNowErr) { + GST_WARNING_OBJECT (vtdec, "hw decoder not available after reset"); + status = gst_vtdec_create_session (vtdec, format, FALSE); + } + + if (status != noErr) { + GST_ERROR_OBJECT (vtdec, + "Could not reset decoder session, VTDecompressionSessionCreate returned %d", + (int) status); + return FALSE; + } + + g_atomic_int_set (&vtdec->require_reset, FALSE); + + return TRUE; +} + static GstFlowReturn gst_vtdec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame) { @@ -956,6 +1001,17 @@ goto drop; } + if (g_atomic_int_get (&vtdec->require_reset)) { + GST_DEBUG_OBJECT (vtdec, "Resetting session due to decoder error"); + gst_video_decoder_request_sync_point (decoder, frame, + GST_VIDEO_DECODER_REQUEST_SYNC_POINT_DISCARD_INPUT); + + if (!gst_vtdec_reset_session (vtdec)) { + ret = GST_FLOW_ERROR; + goto drop; + } + } + /* Check if we need to extract AV1 sequence header for delayed initialization */ if (vtdec->av1_needs_sequence_header && vtdec->session == NULL) { if (gst_vtdec_handle_av1_sequence_header (vtdec, frame)) { @@ -1067,6 +1123,32 @@ input_flags, frame, NULL); GST_VIDEO_DECODER_STREAM_LOCK (vtdec); + GST_LOG_OBJECT (vtdec, "VTDecompressionSessionDecodeFrame returned: %d", + status); + + /* kVTInvalidSessionErr is usually returned on iOS if the application goes + * into background mode, if so, we can reset the session and request an + * intra frame to continue decoding. + * + * kVTVideoDecoderMalfunctionErr is returned for some unknown reason. It is + * only seen on iOS so far, but could also happen on macOS. + */ + if (status == kVTInvalidSessionErr || +#if TARGET_OS_OSX + status == codecErr || +#endif + status == kVTVideoDecoderMalfunctionErr) { + GST_WARNING_OBJECT (vtdec, "DecodeFrame returned %i, resetting session", + status); + if (!gst_vtdec_reset_session (vtdec)) + return GST_FLOW_ERROR; + + gst_video_decoder_request_sync_point (decoder, frame, + GST_VIDEO_DECODER_REQUEST_SYNC_POINT_DISCARD_INPUT); + gst_video_decoder_drop_frame (decoder, frame); + return GST_FLOW_OK; + } + if (status != noErr) { GST_VIDEO_DECODER_ERROR (vtdec, 1, STREAM, DECODE, ("Failed to decode frame"), @@ -1563,12 +1645,24 @@ frame->decode_frame_number); frame->flags |= VTDEC_FRAME_FLAG_ERROR; break; +#if TARGET_OS_OSX + case codecErr: +#endif + case kVTVideoDecoderMalfunctionErr: + GST_WARNING_OBJECT (vtdec, + "MalfunctionError when decoding frame %d, resetting", + frame->decode_frame_number); + frame->flags |= VTDEC_FRAME_FLAG_ERROR; + g_atomic_int_set (&vtdec->require_reset, TRUE); + break; default: GST_ERROR_OBJECT (vtdec, "Error decoding frame %d: %d", frame->decode_frame_number, (int) status); frame->flags |= VTDEC_FRAME_FLAG_ERROR; break; } + } else if (g_atomic_int_get (&vtdec->require_reset)) { + GST_INFO_OBJECT (vtdec, "Got decoded frame while reset is scheduled"); } if (image_buffer) { @@ -1578,7 +1672,7 @@ state = gst_video_decoder_get_output_state (GST_VIDEO_DECODER (vtdec)); if (state == NULL) { GST_WARNING_OBJECT (vtdec, "Output state not configured, release buffer"); - frame->flags &= VTDEC_FRAME_FLAG_SKIP; + frame->flags |= VTDEC_FRAME_FLAG_SKIP; } else { buf = gst_core_video_buffer_new (image_buffer, &state->info, @@ -1928,9 +2022,6 @@ gst_video_decoder_set_latency (GST_VIDEO_DECODER (vtdec), latency, latency); } -typedef void (*VTRegisterSupplementalVideoDecoderIfAvailableFunc) - (CMVideoCodecType codecType); - static gboolean gst_vtdec_check_vp9_support (GstVtdec * vtdec) { @@ -1938,24 +2029,7 @@ GST_DEBUG_OBJECT (vtdec, "Checking VP9 VideoToolbox support"); -#ifdef HAVE_SUPPLEMENTAL -#ifdef HAVE_SUPPLEMENTAL_DEFINITION - if (__builtin_available (macOS 11.0, iOS 26.2, tvOS 26.2, visionOS 26.2, *)) { - VTRegisterSupplementalVideoDecoderIfAvailable (kCMVideoCodecType_VP9); - } -#else - /* Needed temporarily till we can require a new-enough Xcode that has - * VTRegisterSupplementalVideoDecoderIfAvailable on iOS, tvOS, visionOS 26.2 - */ - VTRegisterSupplementalVideoDecoderIfAvailableFunc func = - (VTRegisterSupplementalVideoDecoderIfAvailableFunc) - dlsym (RTLD_DEFAULT, "VTRegisterSupplementalVideoDecoderIfAvailable"); - - if (func != NULL) { - func (kCMVideoCodecType_VP9); - } -#endif -#endif + gst_vtutil_register_supplemental_decoder (kCMVideoCodecType_VP9); vp9_supported = VTIsHardwareDecodeSupported (kCMVideoCodecType_VP9); @@ -1976,25 +2050,7 @@ GST_DEBUG_OBJECT (vtdec, "Checking AV1 VideoToolbox support"); -#ifdef HAVE_SUPPLEMENTAL -#ifdef HAVE_SUPPLEMENTAL_DEFINITION - if (__builtin_available (macOS 11.0, iOS 26.2, tvOS 26.2, visionOS 26.2, *)) { - VTRegisterSupplementalVideoDecoderIfAvailable (kCMVideoCodecType_AV1); - } -#else - /* Needed temporarily till we can require a new-enough Xcode that has - * VTRegisterSupplementalVideoDecoderIfAvailable on iOS, tvOS, visionOS 26.2 - */ - VTRegisterSupplementalVideoDecoderIfAvailableFunc func = - (VTRegisterSupplementalVideoDecoderIfAvailableFunc) - dlsym (RTLD_DEFAULT, - "VTRegisterSupplementalVideoDecoderIfAvailable"); - - if (func != NULL) { - func (kCMVideoCodecType_AV1); - } -#endif -#endif + gst_vtutil_register_supplemental_decoder (kCMVideoCodecType_AV1); /* Check if hardware decode is supported for AV1 */ av1_supported = VTIsHardwareDecodeSupported (kCMVideoCodecType_AV1); @@ -2028,21 +2084,21 @@ if (gst_structure_has_name (s, "video/x-av1")) { if (g_once_init_enter (&av1_once)) { if (gst_vtdec_check_av1_support (vtdec)) - vtdec->codec_support |= Av1Supported; + g_atomic_int_or (&gst_vtdec_codec_support, Av1Supported); g_once_init_leave (&av1_once, Av1Supported); } } else if (gst_structure_has_name (s, "video/x-vp9")) { if (g_once_init_enter (&vp9_once)) { if (gst_vtdec_check_vp9_support (vtdec)) - vtdec->codec_support |= Vp9Supported; + g_atomic_int_or (&gst_vtdec_codec_support, Vp9Supported); g_once_init_leave (&vp9_once, Vp9Supported); } } if ((gst_structure_has_name (s, "video/x-av1") - && !(vtdec->codec_support & Av1Supported)) + && !(g_atomic_int_get (&gst_vtdec_codec_support) & Av1Supported)) || (gst_structure_has_name (s, "video/x-vp9") - && !(vtdec->codec_support & Vp9Supported))) { + && !(g_atomic_int_get (&gst_vtdec_codec_support) & Vp9Supported))) { gst_caps_remove_structure (sinkcaps, i); n--; } else {
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/sys/applemedia/vtdec.h -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/sys/applemedia/vtdec.h
Changed
@@ -48,13 +48,6 @@ #define GST_VTDEC_DPB_MAX_SIZE 16 -typedef enum -{ - NoneSupported = 0, - Av1Supported = 1 << 0, - Vp9Supported = 1 << 1, -} SupplementalSupport; - struct _GstVtdec { GstVideoDecoder base_vtdec; @@ -78,13 +71,15 @@ /* protected by the STREAM_LOCK */ GstFlowReturn downstream_ret; + /* access via g_atomic_int_* */ + gboolean require_reset; + #if defined(APPLEMEDIA_MOLTENVK) GstVulkanInstance *instance; GstVulkanDevice *device; #endif gboolean require_hardware; - SupplementalSupport codec_support; gboolean av1_needs_sequence_header; /* TRUE if we need to wait for sequence header OBU before creating session */ GstBuffer *av1_sequence_header_obu; /* Store the sequence header OBU for format description */
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/sys/applemedia/vtenc.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/sys/applemedia/vtenc.c
Changed
@@ -966,6 +966,7 @@ if (strlen (level) == 1) { level1 = '_'; level2 = '0'; + level3 = 0; } else if (strlen (level) == 3) { level1 = '_'; } @@ -1948,22 +1949,20 @@ gst_vtenc_push_all_pending_frames (GstVTEnc * self) { OSStatus status; - gboolean ret = TRUE; GST_VIDEO_ENCODER_STREAM_UNLOCK (self); GST_DEBUG_OBJECT (self, "starting VTCompressionSessionCompleteFrames"); status = VTCompressionSessionCompleteFrames (self->session, kCMTimePositiveInfinity); GST_DEBUG_OBJECT (self, "VTCompressionSessionCompleteFrames ended"); + GST_VIDEO_ENCODER_STREAM_LOCK (self); if (status != noErr) { GST_WARNING_OBJECT (self, "VTCompressionSessionCompleteFrames returned %d", (int) status); - ret = FALSE; } - GST_VIDEO_ENCODER_STREAM_LOCK (self); - return ret; + return status == noErr; } static void @@ -1974,13 +1973,13 @@ /* We need to push out all frames still inside the encoder, * otherwise destroy_session() will wait for all callbacks to fire * and very likely deadlock due to the object lock being taken */ - if (!gst_vtenc_push_all_pending_frames (self)) { - GST_DEBUG_OBJECT (self, "Will retry session restart on next frame encode"); - return; + if (gst_vtenc_push_all_pending_frames (self)) { + GST_DEBUG_OBJECT (self, "All frames out, restarting encoder session"); + } else { + GST_DEBUG_OBJECT (self, "Failed to push all pending frames, restarting " + "encoder session anyway"); } - GST_DEBUG_OBJECT (self, "All frames out, restarting encoder session"); - GST_OBJECT_LOCK (self); gst_vtenc_destroy_session (self, &self->session); GST_OBJECT_UNLOCK (self);
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/sys/applemedia/vtutil.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/sys/applemedia/vtutil.c
Changed
@@ -18,6 +18,17 @@ */ #include "vtutil.h" +#include <VideoToolbox/VideoToolbox.h> +#include <TargetConditionals.h> + +#if TARGET_OS_OSX || TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION +#define HAVE_SUPPLEMENTAL +#if (TARGET_OS_OSX && __MAC_OS_X_VERSION_MAX_ALLOWED >= 110000) || (TARGET_OS_IOS && __IPHONE_OS_VERSION_MAX_ALLOWED >= 260200) || (TARGET_OS_TV && __TV_OS_VERSION_MAX_ALLOWED >= 260200) || (TARGET_OS_VISION && __VISION_OS_VERSION_MAX_ALLOWED >= 260200) +#define HAVE_SUPPLEMENTAL_DEFINITION +#else +#include <dlfcn.h> +#endif +#endif gchar * gst_vtutil_object_to_string (CFTypeRef obj) @@ -159,3 +170,40 @@ gst_structure_set_list (s, "format", arr); return caps; } + +typedef void (*VTRegisterSupplementalVideoDecoderIfAvailableFunc) + (CMVideoCodecType codecType); + +gboolean +gst_vtutil_register_supplemental_decoder (CMVideoCodecType codec_type) +{ + GST_INFO ("Registering supplemental VideoToolbox decoder: %" + GST_FOURCC_FORMAT, GST_FOURCC_ARGS (GUINT32_FROM_BE (codec_type))); + +#ifdef HAVE_SUPPLEMENTAL +#ifdef HAVE_SUPPLEMENTAL_DEFINITION + if (__builtin_available (macOS 11.0, iOS 26.2, tvOS 26.2, visionOS 26.2, *)) { + GST_INFO ("Registering supplemental VideoToolbox decoder by direct call"); + VTRegisterSupplementalVideoDecoderIfAvailable (codec_type); + return TRUE; + } +#else + /* Needed temporarily till we can require a new-enough Xcode that has + * VTRegisterSupplementalVideoDecoderIfAvailable on iOS/tvOS/visionOS 26.2. + */ + VTRegisterSupplementalVideoDecoderIfAvailableFunc func = + (VTRegisterSupplementalVideoDecoderIfAvailableFunc) + dlsym (RTLD_DEFAULT, "VTRegisterSupplementalVideoDecoderIfAvailable"); + + if (func != NULL) { + GST_INFO ("Registering supplemental VideoToolbox decoder by symbolic call"); + func (codec_type); + return TRUE; + } +#endif +#endif + + GST_INFO ("Supplemental decoder registration not available: %" + GST_FOURCC_FORMAT, GST_FOURCC_ARGS (GUINT32_FROM_BE (codec_type))); + return FALSE; +}
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/sys/applemedia/vtutil.h -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/sys/applemedia/vtutil.h
Changed
@@ -50,6 +50,7 @@ GstCaps * gst_vtutil_caps_append_video_format (GstCaps * caps, const char * vfmt); +gboolean gst_vtutil_register_supplemental_decoder (CMVideoCodecType codec_type); G_END_DECLS
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/sys/decklink/gstdecklinkvideosink.cpp -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/sys/decklink/gstdecklinkvideosink.cpp
Changed
@@ -628,7 +628,7 @@ { public: GStreamerVideoOutputCallback (GstDecklinkVideoSink * sink) - :IDeckLinkVideoOutputCallback (), m_refcount (1) + :IDeckLinkVideoOutputCallback (), m_refcount (0) { m_sink = GST_DECKLINK_VIDEO_SINK_CAST (gst_object_ref (sink)); g_mutex_init (&m_mutex);
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/sys/nvcodec/gstnvav1encoder.cpp -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/sys/nvcodec/gstnvav1encoder.cpp
Changed
@@ -1562,6 +1562,7 @@ cdata->src_caps = gst_caps_from_string (src_caps_str.c_str ()); cdata->device_caps = dev_caps; cdata->device_mode = device_mode; + cdata->codec = cudaVideoCodec_AV1; /* *INDENT-OFF* */ for (const auto &iter: formats) @@ -1588,8 +1589,7 @@ } GstNvEncoderClassData * -gst_nv_av1_encoder_register_cuda (GstPlugin * plugin, GstCudaContext * context, - guint rank) +gst_nv_av1_encoder_inspect (GstPlugin * plugin, GstCudaContext * context) { NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS session_params = { 0, }; gpointer session; @@ -1615,10 +1615,13 @@ GST_NV_ENCODER_DEVICE_CUDA); NvEncDestroyEncoder (session); - if (!cdata) - return nullptr; + return cdata; +} - gst_nv_encoder_class_data_ref (cdata); +GstNvEncoderClassData * +gst_nv_av1_encoder_register (GstPlugin * plugin, + GstNvEncoderClassData * cdata, guint rank) +{ GType type; gchar *type_name; @@ -1629,7 +1632,7 @@ nullptr, (GClassInitFunc) gst_nv_av1_encoder_class_init, nullptr, - cdata, + gst_nv_encoder_class_data_ref (cdata), sizeof (GstNvAv1Encoder), 0, (GInstanceInitFunc) gst_nv_av1_encoder_init, @@ -1873,6 +1876,7 @@ cdata->src_caps = gst_caps_from_string (src_caps_str.c_str ()); cdata->device_caps = dev_caps; cdata->device_mode = GST_NV_ENCODER_DEVICE_AUTO_SELECT; + cdata->codec = cudaVideoCodec_AV1; cdata->adapter_luid = adapter_luid_list0; cdata->adapter_luid_size = adapter_luid_size; memcpy (&cdata->adapter_luid_list,
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/sys/nvcodec/gstnvav1encoder.h -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/sys/nvcodec/gstnvav1encoder.h
Changed
@@ -23,9 +23,11 @@ G_BEGIN_DECLS -GstNvEncoderClassData * gst_nv_av1_encoder_register_cuda (GstPlugin * plugin, - GstCudaContext * context, - guint rank); +GstNvEncoderClassData * gst_nv_av1_encoder_inspect (GstPlugin * plugin, + GstCudaContext * context); +GstNvEncoderClassData * gst_nv_av1_encoder_register (GstPlugin * plugin, + GstNvEncoderClassData *cdata, + guint rank); #ifdef G_OS_WIN32 GstNvEncoderClassData * gst_nv_av1_encoder_register_d3d11 (GstPlugin * plugin,
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/sys/nvcodec/gstnvdecoder.cpp -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/sys/nvcodec/gstnvdecoder.cpp
Changed
@@ -1257,7 +1257,8 @@ gboolean gst_nv_decoder_check_device_caps (GstCudaContext * context, - cudaVideoCodec codec, GstCaps ** sink_template, GstCaps ** src_template) + GList * cached_decoders, cudaVideoCodec codec, GstCaps ** sink_template, + GstCaps ** src_template) { CUresult cuda_ret; guint max_width = 0, min_width = G_MAXINT; @@ -1285,6 +1286,21 @@ std::set < std::string > formats; std::set < std::string > planar_formats; CUcontext cuda_ctx = gst_cuda_context_get_handle (context); + + if (cached_decoders) { + for (GList * l = cached_decoders; l; l = l->next) { + GstNvDecoderClassData *info = (GstNvDecoderClassData *) l->data; + + for (i = 0; i < G_N_ELEMENTS (codec_map_list); i++) { + if (codec_map_listi.codec == codec && + !g_strcmp0 (codec_map_listi.codec_name, info->codec_name)) { + *sink_template = gst_caps_ref (info->sink_caps); + *src_template = gst_caps_ref (info->src_caps); + return TRUE; + } + } + } + } #ifdef G_OS_WIN32 gboolean is_stateless = FALSE; @@ -1615,6 +1631,20 @@ return "unknown"; } +cudaVideoCodec +gst_cuda_video_codec_from_string (const gchar * codec_name) +{ + if (!codec_name) + return cudaVideoCodec_NumCodecs; + + for (guint i = 0; i < G_N_ELEMENTS (codec_map_list); i++) { + if (g_strcmp0 (codec_map_listi.codec_name, codec_name) == 0) + return codec_map_listi.codec; + } + + return cudaVideoCodec_NumCodecs; +} + void gst_nv_decoder_handle_set_context (GstNvDecoder * decoder, GstElement * element, GstContext * context)
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/sys/nvcodec/gstnvdecoder.h -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/sys/nvcodec/gstnvdecoder.h
Changed
@@ -35,6 +35,7 @@ typedef struct _GstNvDecoderClassData { + const gchar *codec_name; GstCaps *sink_caps; GstCaps *src_caps; guint cuda_device_id; @@ -84,11 +85,13 @@ /* utils for class registration */ gboolean gst_nv_decoder_check_device_caps (GstCudaContext * context, + GList *cached_decoders, cudaVideoCodec codec, GstCaps **sink_template, GstCaps **src_template); -const gchar * gst_cuda_video_codec_to_string (cudaVideoCodec codec); +const gchar * gst_cuda_video_codec_to_string (cudaVideoCodec codec); +cudaVideoCodec gst_cuda_video_codec_from_string (const gchar * codec_name); /* helper methods */ void gst_nv_decoder_handle_set_context (GstNvDecoder * decoder,
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/sys/nvcodec/gstnvencoder.h -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/sys/nvcodec/gstnvencoder.h
Changed
@@ -19,6 +19,7 @@ #pragma once +#include "cuviddec.h" #include <gst/gst.h> #include <gst/video/video.h> @@ -221,6 +222,8 @@ GstNvEncoderDeviceMode device_mode; GstNvEncoderDeviceCaps device_caps; + cudaVideoCodec codec; + GList *formats; GList *profiles;
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/sys/nvcodec/gstnvh264encoder.cpp -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/sys/nvcodec/gstnvh264encoder.cpp
Changed
@@ -2398,6 +2398,7 @@ cdata->src_caps = gst_caps_from_string (src_caps_str.c_str ()); cdata->device_caps = dev_caps; cdata->device_mode = device_mode; + cdata->codec = cudaVideoCodec_H264; /* *INDENT-OFF* */ for (const auto &iter: formats) @@ -2427,8 +2428,7 @@ } GstNvEncoderClassData * -gst_nv_h264_encoder_register_cuda (GstPlugin * plugin, GstCudaContext * context, - guint rank) +gst_nv_h264_encoder_inspect (GstPlugin * plugin, GstCudaContext * context) { NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS session_params = { 0, }; gpointer session; @@ -2454,10 +2454,13 @@ GST_NV_ENCODER_DEVICE_CUDA); NvEncDestroyEncoder (session); - if (!cdata) - return nullptr; + return cdata; +} - gst_nv_encoder_class_data_ref (cdata); +GstNvEncoderClassData * +gst_nv_h264_encoder_register (GstPlugin * plugin, + GstNvEncoderClassData * cdata, guint rank) +{ GType type; gchar *type_name; @@ -2732,6 +2735,7 @@ cdata->src_caps = gst_caps_from_string (src_caps_str.c_str ()); cdata->device_caps = dev_caps; cdata->device_mode = GST_NV_ENCODER_DEVICE_AUTO_SELECT; + cdata->codec = cudaVideoCodec_H264; cdata->adapter_luid = adapter_luid_list0; cdata->adapter_luid_size = adapter_luid_size; memcpy (&cdata->adapter_luid_list,
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/sys/nvcodec/gstnvh264encoder.h -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/sys/nvcodec/gstnvh264encoder.h
Changed
@@ -23,9 +23,11 @@ G_BEGIN_DECLS -GstNvEncoderClassData * gst_nv_h264_encoder_register_cuda (GstPlugin * plugin, - GstCudaContext * context, - guint rank); +GstNvEncoderClassData * gst_nv_h264_encoder_inspect (GstPlugin * plugin, + GstCudaContext * context); +GstNvEncoderClassData * gst_nv_h264_encoder_register (GstPlugin * plugin, + GstNvEncoderClassData *cdata, + guint rank); #ifdef G_OS_WIN32 GstNvEncoderClassData * gst_nv_h264_encoder_register_d3d11 (GstPlugin * plugin,
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/sys/nvcodec/gstnvh265encoder.cpp -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/sys/nvcodec/gstnvh265encoder.cpp
Changed
@@ -2437,6 +2437,7 @@ cdata->src_caps = gst_caps_from_string (src_caps_str.c_str ()); cdata->device_caps = dev_caps; cdata->device_mode = device_mode; + cdata->codec = cudaVideoCodec_HEVC; /* *INDENT-OFF* */ for (const auto &iter: formats) @@ -2466,8 +2467,7 @@ } GstNvEncoderClassData * -gst_nv_h265_encoder_register_cuda (GstPlugin * plugin, GstCudaContext * context, - guint rank) +gst_nv_h265_encoder_inspect (GstPlugin * plugin, GstCudaContext * context) { NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS session_params = { 0, }; gpointer session; @@ -2493,10 +2493,13 @@ GST_NV_ENCODER_DEVICE_CUDA); NvEncDestroyEncoder (session); - if (!cdata) - return nullptr; + return cdata; +} - gst_nv_encoder_class_data_ref (cdata); +GstNvEncoderClassData * +gst_nv_h265_encoder_register (GstPlugin * plugin, + GstNvEncoderClassData * cdata, guint rank) +{ GType type; gchar *type_name; @@ -2774,6 +2777,7 @@ cdata->src_caps = gst_caps_from_string (src_caps_str.c_str ()); cdata->device_caps = dev_caps; cdata->device_mode = GST_NV_ENCODER_DEVICE_AUTO_SELECT; + cdata->codec = cudaVideoCodec_HEVC; cdata->adapter_luid = adapter_luid_list0; cdata->adapter_luid_size = adapter_luid_size; memcpy (&cdata->adapter_luid_list,
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/sys/nvcodec/gstnvh265encoder.h -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/sys/nvcodec/gstnvh265encoder.h
Changed
@@ -23,9 +23,11 @@ G_BEGIN_DECLS -GstNvEncoderClassData * gst_nv_h265_encoder_register_cuda (GstPlugin * plugin, - GstCudaContext * context, - guint rank); +GstNvEncoderClassData * gst_nv_h265_encoder_inspect (GstPlugin * plugin, + GstCudaContext * context); +GstNvEncoderClassData * gst_nv_h265_encoder_register (GstPlugin * plugin, + GstNvEncoderClassData *cdata, + guint rank); #ifdef G_OS_WIN32 GstNvEncoderClassData * gst_nv_h265_encoder_register_d3d11 (GstPlugin * plugin,
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/sys/nvcodec/gstnvjpegenc.cpp -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/sys/nvcodec/gstnvjpegenc.cpp
Changed
@@ -1199,8 +1199,8 @@ } gboolean -gst_nv_jpeg_enc_register (GstPlugin * plugin, GstCudaContext * context, - guint rank, gboolean have_nvrtc) +gst_nv_jpeg_enc_register (GstPlugin * plugin, guint cuda_device_id, + guint rank, gboolean have_nvrtc, gboolean autogpu) { GST_DEBUG_CATEGORY_INIT (gst_nv_jpeg_enc_debug, "nvjpegenc", 0, "nvjpegenc"); @@ -1221,13 +1221,6 @@ (GInstanceInitFunc) gst_nv_jpeg_enc_init, }; - guint cuda_device_id = 0; - gboolean autogpu = FALSE; - if (!context) - autogpu = TRUE; - else - g_object_get (context, "cuda-device-id", &cuda_device_id, nullptr); - std::string format_string; #ifdef NVCODEC_CUDA_PRECOMPILED have_nvrtc = TRUE;
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/sys/nvcodec/gstnvjpegenc.h -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/sys/nvcodec/gstnvjpegenc.h
Changed
@@ -24,8 +24,9 @@ G_BEGIN_DECLS gboolean gst_nv_jpeg_enc_register (GstPlugin * plugin, - GstCudaContext * context, - guint rank, - gboolean have_nvrtc); + guint cuda_device_id, + guint rank, + gboolean have_nvrtc, + gboolean auto_gpu); G_END_DECLS
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/sys/nvcodec/plugin.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/sys/nvcodec/plugin.c
Changed
@@ -84,6 +84,56 @@ #define NVRTC_LIBNAME "libnvrtc.so" #endif /* G_OS_WIN32 */ +/* X-macro listing all GstNvEncoderDeviceCaps fields for serialization */ +#define GST_NV_ENCODER_DEVICE_CAPS_FIELDS(X) \ + X(max_bframes) \ + X(ratecontrol_modes) \ + X(field_encoding) \ + X(monochrome) \ + X(fmo) \ + X(qpelmv) \ + X(bdirect_mode) \ + X(cabac) \ + X(adaptive_transform) \ + X(stereo_mvc) \ + X(temoral_layers) \ + X(hierarchical_pframes) \ + X(hierarchical_bframes) \ + X(level_max) \ + X(level_min) \ + X(separate_colour_plane) \ + X(width_max) \ + X(height_max) \ + X(temporal_svc) \ + X(dyn_res_change) \ + X(dyn_bitrate_change) \ + X(dyn_force_constqp) \ + X(dyn_rcmode_change) \ + X(subframe_readback) \ + X(constrained_encoding) \ + X(intra_refresh) \ + X(custom_vbv_buf_size) \ + X(dynamic_slice_mode) \ + X(ref_pic_invalidation) \ + X(preproc_support) \ + X(async_encoding_support) \ + X(mb_num_max) \ + X(mb_per_sec_max) \ + X(yuv444_encode) \ + X(lossless_encode) \ + X(sao) \ + X(meonly_mode) \ + X(lookahead) \ + X(temporal_aq) \ + X(supports_10bit_encode) \ + X(num_max_ltr_frames) \ + X(weighted_prediction) \ + X(bframe_ref_mode) \ + X(emphasis_level_map) \ + X(width_min) \ + X(height_min) \ + X(multiple_ref_frames) + static void plugin_deinit (gpointer data) { @@ -113,6 +163,536 @@ return TRUE; } +#ifdef HAVE_NVCODEC_DGPU + +static gchar * +gst_cuda_uuid_to_string (const CUuuid * uuid) +{ + const guint8 *b = (const guint8 *) uuid->bytes; + + return + g_strdup_printf + ("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, + b12, b13, b14, b15); +} + +typedef struct +{ + gchar *device_uuid; + gint64 adapter_luid; + GList *decoders; + GList *encoders; +} DeviceCachedCodecs; + +static GList * +gst_nvcodec_load_decoders_from_cache (GstPlugin * plugin, + const GstStructure * device_struct) +{ + const GValue *decoders_arr; + guint i, n_decoders; + GList *decoder_list = NULL; + + decoders_arr = gst_structure_get_value (device_struct, "decoders"); + if (!decoders_arr) + return NULL; + g_return_val_if_fail (GST_VALUE_HOLDS_ARRAY (decoders_arr), NULL); + + n_decoders = gst_value_array_get_size (decoders_arr); + GST_INFO ("Loading %u decoders from cache", n_decoders); + + for (i = 0; i < n_decoders; i++) { + const GValue *decoder_val = gst_value_array_get_value (decoders_arr, i); + if (decoder_val == NULL || !GST_VALUE_HOLDS_STRUCTURE (decoder_val)) { + GST_WARNING ("Invalid cached decoder data"); + g_list_free_full (decoder_list, (GDestroyNotify) g_free); + return NULL; + } + const GstStructure *decoder_struct = gst_value_get_structure (decoder_val); + GstNvDecoderClassData *class_data = g_new0 (GstNvDecoderClassData, 1); + if (!gst_structure_get (decoder_struct, + "codec", G_TYPE_STRING, &class_data->codec_name, + "sink_caps", GST_TYPE_CAPS, &class_data->sink_caps, + "src_caps", GST_TYPE_CAPS, &class_data->src_caps, NULL)) { + GST_WARNING ("Invalid cached nvcodec decoder data"); + + g_free (class_data); + g_list_free_full (decoder_list, (GDestroyNotify) g_free); + return NULL; + } + + decoder_list = g_list_append (decoder_list, class_data); + } + + return decoder_list; +} + +static gboolean +gst_nvcodec_load_encoder_device_caps (const GstStructure * caps_struct, + GstNvEncoderDeviceCaps * caps) +{ +#define GET_CAPS_FIELD(field) \ + #field, G_TYPE_INT, &caps->field, + + gst_structure_get (caps_struct, + GST_NV_ENCODER_DEVICE_CAPS_FIELDS (GET_CAPS_FIELD) + NULL); + +#undef GET_CAPS_FIELD + + return TRUE; +} + +static GstNvEncoderClassData * +gst_nvcodec_load_encoder_class_data (const GstStructure * + encoder_struct, const gchar * codec_name) +{ + GstNvEncoderClassData *cdata; + GstCaps *sink_caps = NULL, *src_caps = NULL; + const gchar *device_mode_str; + const GValue *formats_arr, *profiles_arr; + const GstStructure *device_caps_struct; + guint i, n; + cudaVideoCodec codec; + + gst_structure_get (encoder_struct, + "sink_caps", GST_TYPE_CAPS, &sink_caps, + "src_caps", GST_TYPE_CAPS, &src_caps, NULL); + device_mode_str = gst_structure_get_string (encoder_struct, "device_mode"); + + if (!sink_caps || !src_caps || !device_mode_str) { + gst_clear_caps (&sink_caps); + gst_clear_caps (&src_caps); + return NULL; + } + + /* Convert codec name to cudaVideoCodec */ + codec = gst_cuda_video_codec_from_string (codec_name); + if (codec == cudaVideoCodec_NumCodecs) { + GST_WARNING ("Unknown codec name: %s", codec_name); + gst_caps_unref (sink_caps); + gst_caps_unref (src_caps); + return NULL; + } + + cdata = g_new0 (GstNvEncoderClassData, 1); + cdata->ref_count = 1; + cdata->codec = codec; + cdata->sink_caps = sink_caps; + cdata->src_caps = src_caps; + + if (g_strcmp0 (device_mode_str, "cuda") == 0) + cdata->device_mode = GST_NV_ENCODER_DEVICE_CUDA; + else if (g_strcmp0 (device_mode_str, "d3d11") == 0) + cdata->device_mode = GST_NV_ENCODER_DEVICE_D3D11; + else + cdata->device_mode = GST_NV_ENCODER_DEVICE_AUTO_SELECT; + + gst_structure_get_uint (encoder_struct, "cuda_device_id", + &cdata->cuda_device_id); + + /* Parse formats list */ + formats_arr = gst_structure_get_value (encoder_struct, "formats"); + if (formats_arr) { + n = gst_value_array_get_size (formats_arr); + for (i = 0; i < n; i++) { + const GValue *format_val = gst_value_array_get_value (formats_arr, i); + const gchar *format_str = g_value_get_string (format_val); + cdata->formats = g_list_append (cdata->formats, g_strdup (format_str)); + } + } + + /* Parse profiles list */ + profiles_arr = gst_structure_get_value (encoder_struct, "profiles"); + if (profiles_arr) { + n = gst_value_array_get_size (profiles_arr); + for (i = 0; i < n; i++) { + const GValue *profile_val = gst_value_array_get_value (profiles_arr, i); + const gchar *profile_str = g_value_get_string (profile_val); + cdata->profiles = g_list_append (cdata->profiles, g_strdup (profile_str)); + } + } + + /* Parse device capabilities */ + if (gst_structure_get (encoder_struct, "device_caps", GST_TYPE_STRUCTURE, + &device_caps_struct, NULL)) { + gst_nvcodec_load_encoder_device_caps (device_caps_struct, + &cdata->device_caps); + } + + return cdata; +} + +static GList * +gst_nvcodec_load_encoder_from_cache (GstPlugin * plugin, + const GstStructure * device_struct) +{ + const GValue *encoders_arr; + guint i, n_encoders; + GList *encoder_list = NULL; + + encoders_arr = gst_structure_get_value (device_struct, "encoders"); + if (!encoders_arr) + return NULL; + + n_encoders = gst_value_array_get_size (encoders_arr); + GST_INFO ("Loading %u encoders from cache", n_encoders); + + for (i = 0; i < n_encoders; i++) { + const GValue *encoder_val = gst_value_array_get_value (encoders_arr, i); + const GstStructure *encoder_struct = gst_value_get_structure (encoder_val); + const gchar *codec_name; + GstNvEncoderClassData *cdata; + + codec_name = gst_structure_get_string (encoder_struct, "codec"); + if (!codec_name) { + GST_WARNING ("Invalid cached encoder data"); + continue; + } + + cdata = gst_nvcodec_load_encoder_class_data (encoder_struct, codec_name); + if (!cdata) { + GST_WARNING ("Failed to parse cached encoder data for %s", codec_name); + continue; + } + + /* Add to unified encoder list */ + encoder_list = g_list_append (encoder_list, cdata); + } + + return encoder_list; +} + +/* Forward declaration */ +static void gst_nvcodec_build_encoder_cache_data (GValue * encoders_arr, + const gchar * codec_name, GstNvEncoderClassData * cdata); + +static void +gst_nvcodec_save_cache (GstPlugin * plugin, guint api_major, guint api_minor, + GArray * devices) +{ + GstStructure *cache_data; + GstStructure *devices_save; + guint i; + + cache_data = gst_structure_new ("nvcodec-cache", + "cuda_api_major", G_TYPE_UINT, api_major, + "cuda_api_minor", G_TYPE_UINT, api_minor, NULL); + + devices_save = gst_structure_new_empty ("devices"); + + for (i = 0; i < devices->len; i++) { + DeviceCachedCodecs *device = + &g_array_index (devices, DeviceCachedCodecs, i); + GstStructure *device_struct; + GValue decoders_arr = { 0, }; + GValue encoders_arr = { 0, }; + + if (!device->device_uuid) { + GST_WARNING ("Could not get UUID for device %u, skipping cache save", i); + continue; + } + + device_struct = gst_structure_new ("device", + "device_id", G_TYPE_UINT, i, NULL); + + /* Save decoders */ + g_value_init (&decoders_arr, GST_TYPE_ARRAY); + for (GList * l = device->decoders; l; l = l->next) { + GstNvDecoderClassData *dec_cdata = (GstNvDecoderClassData *) l->data; + GstStructure *decoder_struct = gst_structure_new_empty ("decoder"); + + gst_structure_set (decoder_struct, + "codec", G_TYPE_STRING, dec_cdata->codec_name, + "sink_caps", GST_TYPE_CAPS, dec_cdata->sink_caps, + "src_caps", GST_TYPE_CAPS, dec_cdata->src_caps, NULL); + + GValue decoder_val = { 0, }; + g_value_init (&decoder_val, GST_TYPE_STRUCTURE); + g_value_take_boxed (&decoder_val, decoder_struct); + gst_value_array_append_and_take_value (&decoders_arr, &decoder_val); + } + gst_structure_set_value (device_struct, "decoders", &decoders_arr); + g_value_unset (&decoders_arr); + + /* Save encoders */ + g_value_init (&encoders_arr, GST_TYPE_ARRAY); + for (GList * l = device->encoders; l; l = l->next) { + GstNvEncoderClassData *enc_cdata = (GstNvEncoderClassData *) l->data; + gst_nvcodec_build_encoder_cache_data (&encoders_arr, + gst_cuda_video_codec_to_string (enc_cdata->codec), enc_cdata); + } + gst_structure_set_value (device_struct, "encoders", &encoders_arr); + g_value_unset (&encoders_arr); + + /* Add device to devices structure using UUID as key */ + GValue device_value = G_VALUE_INIT; + g_value_init (&device_value, GST_TYPE_STRUCTURE); + gst_value_set_structure (&device_value, device_struct); + gst_structure_take_value (devices_save, device->device_uuid, &device_value); + gst_structure_free (device_struct); + } + + /* Store devices structure in cache */ + GValue devices_value = G_VALUE_INIT; + g_value_init (&devices_value, GST_TYPE_STRUCTURE); + gst_value_set_structure (&devices_value, devices_save); + gst_structure_take_value (cache_data, "devices", &devices_value); + gst_structure_free (devices_save); + + GST_INFO ("Saving complete cache data"); + gst_plugin_set_cache_data (plugin, cache_data); +} + +static GArray * +gst_nvcodec_get_or_build_cache (GstPlugin * plugin, guint current_api_major, + guint current_api_minor, gint dev_count, gboolean nvenc_available, + gboolean nvdec_available) +{ + const GstStructure *cache_data; + const GstStructure *devices_struct = NULL; + guint i; + guint cached_api_major = 0, cached_api_minor = 0; + gboolean cache_valid = FALSE; + gboolean cache_needs_save = FALSE; + GArray *result = g_array_new (FALSE, FALSE, sizeof (DeviceCachedCodecs)); + + cache_data = gst_plugin_get_cache_data (plugin); + if (cache_data) { + GST_INFO ("Found serialized cache, validating..."); + + /* Check CUDA API version for cache invalidation (detects driver updates) */ + if (gst_structure_get_uint (cache_data, "cuda_api_major", &cached_api_major) + && gst_structure_get_uint (cache_data, "cuda_api_minor", + &cached_api_minor)) { + if (cached_api_major == current_api_major + && cached_api_minor == current_api_minor) { + /* Get devices structure (UUID-keyed) */ + if (gst_structure_get (cache_data, "devices", GST_TYPE_STRUCTURE, + &devices_struct, NULL)) { + cache_valid = TRUE; + GST_INFO ("Serialized cache is valid (CUDA API %u.%u)", + cached_api_major, cached_api_minor); + } + } else { + GST_INFO ("CUDA API version mismatch. Cached: %u.%u, Current: %u.%u", + cached_api_major, cached_api_minor, current_api_major, + current_api_minor); + } + } + } else { + GST_INFO ("No serialized cache found"); + } + + /* Build complete cache for all devices */ + for (i = 0; i < (guint) dev_count; i++) { + DeviceCachedCodecs device_cache = { 0, }; + const GstStructure *cached_device_struct = NULL; + gboolean use_cached_data = FALSE; + + /* Get current device UUID for cache lookup and later saving */ + CUuuid current_uuid; + CUresult cuda_ret = CuDeviceGetUuid (¤t_uuid, i); + if (cuda_ret == CUDA_SUCCESS) { + device_cache.device_uuid = gst_cuda_uuid_to_string (¤t_uuid); + } + + if (cache_valid && device_cache.device_uuid && devices_struct) { + if (gst_structure_get (devices_struct, device_cache.device_uuid, + GST_TYPE_STRUCTURE, &cached_device_struct, NULL)) { + use_cached_data = TRUE; + GST_INFO ("Device %u: found matching cache entry by UUID %s", i, + device_cache.device_uuid); + } else { + GST_INFO ("Device %u: no matching cache entry found for UUID %s, " + "will query hardware", i, device_cache.device_uuid); + } + } + + /* Use cached data or query hardware */ + if (use_cached_data) { + /* Load from serialized cache */ + device_cache.decoders = + gst_nvcodec_load_decoders_from_cache (plugin, cached_device_struct); + device_cache.encoders = + gst_nvcodec_load_encoder_from_cache (plugin, cached_device_struct); + +#ifdef G_OS_WIN32 + /* Query current LUID - it changes per boot so can't use cached value */ + device_cache.adapter_luid = gst_cuda_context_find_dxgi_adapter_luid (i); + + /* Update encoder class data with current LUID */ + for (GList * l = device_cache.encoders; l; l = l->next) { + GstNvEncoderClassData *enc_cdata = (GstNvEncoderClassData *) l->data; + enc_cdata->adapter_luid = device_cache.adapter_luid; + } +#endif + } else { + cache_needs_save = TRUE; + /* Query hardware to build cache */ + GstCudaContext *context = gst_cuda_context_new (i); + + if (!context) { + GST_WARNING ("Failed to create context for device %d", i); + g_array_append_val (result, device_cache); + continue; + } + +#ifdef G_OS_WIN32 + g_object_get (context, "dxgi-adapter-luid", &device_cache.adapter_luid, + NULL); +#endif + + GST_INFO ("Device %u: querying hardware to build cache", i); + + /* Build decoder list */ + if (nvdec_available) { + for (gint j = 0; j < cudaVideoCodec_NumCodecs; j++) { + GstCaps *sink_template = NULL; + GstCaps *src_template = NULL; + cudaVideoCodec codec = (cudaVideoCodec) j; + + if (gst_nv_decoder_check_device_caps (context, NULL, + codec, &sink_template, &src_template)) { + GstNvDecoderClassData *dec_cdata = + g_new0 (GstNvDecoderClassData, 1); + dec_cdata->codec_name = + g_strdup (gst_cuda_video_codec_to_string (codec)); + dec_cdata->sink_caps = sink_template; + dec_cdata->src_caps = src_template; + dec_cdata->cuda_device_id = i; + device_cache.decoders = + g_list_append (device_cache.decoders, dec_cdata); + } + } + } + + /* Build encoder list */ + if (nvenc_available) { + GstNvEncoderClassData *enc_cdata; + + enc_cdata = gst_nv_h264_encoder_inspect (plugin, context); + if (enc_cdata) + device_cache.encoders = + g_list_append (device_cache.encoders, enc_cdata); + + enc_cdata = gst_nv_h265_encoder_inspect (plugin, context); + if (enc_cdata) + device_cache.encoders = + g_list_append (device_cache.encoders, enc_cdata); + + enc_cdata = gst_nv_av1_encoder_inspect (plugin, context); + if (enc_cdata) + device_cache.encoders = + g_list_append (device_cache.encoders, enc_cdata); + } + + gst_object_unref (context); + } + + g_array_append_val (result, device_cache); + } + + /* Only save cache if we had to query hardware */ + if (cache_needs_save) + gst_nvcodec_save_cache (plugin, current_api_major, current_api_minor, + result); + + return result; +} + +static void +gst_nvcodec_build_encoder_device_caps_structure (GstStructure * encoder_struct, + const GstNvEncoderDeviceCaps * caps) +{ + GstStructure *caps_struct = gst_structure_new_empty ("device_caps"); + GValue v = { 0, }; + +#define SET_CAPS_FIELD(field) \ + #field, G_TYPE_INT, caps->field, + + gst_structure_set (caps_struct, + GST_NV_ENCODER_DEVICE_CAPS_FIELDS (SET_CAPS_FIELD) + NULL); + +#undef SET_CAPS_FIELD + + g_value_init (&v, GST_TYPE_STRUCTURE); + g_value_take_boxed (&v, caps_struct); + gst_structure_take_value (encoder_struct, "device_caps", &v); +} + +static void +gst_nvcodec_build_encoder_cache_data (GValue * encoders_arr, + const gchar * codec_name, GstNvEncoderClassData * cdata) +{ + GstStructure *encoder_struct = gst_structure_new_empty ("encoder"); + GValue encoder_val = { 0, }; + const gchar *device_mode_str; + GValue formats_arr = { 0, }; + GValue profiles_arr = { 0, }; + GList *l; + + /* Codec name */ + gst_structure_set (encoder_struct, "codec", G_TYPE_STRING, codec_name, NULL); + + gst_structure_set (encoder_struct, + "sink_caps", GST_TYPE_CAPS, cdata->sink_caps, + "src_caps", GST_TYPE_CAPS, cdata->src_caps, NULL); + + /* Device mode */ + switch (cdata->device_mode) { + case GST_NV_ENCODER_DEVICE_CUDA: + device_mode_str = "cuda"; + break; + case GST_NV_ENCODER_DEVICE_D3D11: + device_mode_str = "d3d11"; + break; + default: + device_mode_str = "auto"; + break; + } + gst_structure_set (encoder_struct, + "device_mode", G_TYPE_STRING, device_mode_str, + "cuda_device_id", G_TYPE_UINT, cdata->cuda_device_id, NULL); + + /* Formats array */ + g_value_init (&formats_arr, GST_TYPE_ARRAY); + for (l = cdata->formats; l; l = l->next) { + GValue format_val = { 0, }; + g_value_init (&format_val, G_TYPE_STRING); + g_value_set_string (&format_val, (const gchar *) l->data); + gst_value_array_append_value (&formats_arr, &format_val); + g_value_unset (&format_val); + } + gst_structure_set_value (encoder_struct, "formats", &formats_arr); + g_value_unset (&formats_arr); + + /* Profiles array */ + g_value_init (&profiles_arr, GST_TYPE_ARRAY); + for (l = cdata->profiles; l; l = l->next) { + GValue profile_val = { 0, }; + g_value_init (&profile_val, G_TYPE_STRING); + g_value_set_string (&profile_val, (const gchar *) l->data); + gst_value_array_append_value (&profiles_arr, &profile_val); + g_value_unset (&profile_val); + } + gst_structure_set_value (encoder_struct, "profiles", &profiles_arr); + g_value_unset (&profiles_arr); + + /* Device capabilities */ + gst_nvcodec_build_encoder_device_caps_structure (encoder_struct, + &cdata->device_caps); + + /* Add to encoders array */ + g_value_init (&encoder_val, GST_TYPE_STRUCTURE); + g_value_take_boxed (&encoder_val, encoder_struct); + gst_value_array_append_value (encoders_arr, &encoder_val); + g_value_unset (&encoder_val); +} + +#endif /* HAVE_NVCODEC_DGPU */ + static gboolean plugin_init (GstPlugin * plugin) { @@ -137,13 +717,11 @@ GST_DEBUG_CATEGORY_INIT (gst_nvdec_debug, "nvdec", 0, "nvdec"); GST_DEBUG_CATEGORY_INIT (gst_nvenc_debug, "nvenc", 0, "nvenc"); GST_DEBUG_CATEGORY_INIT (gst_nv_decoder_debug, "nvdecoder", 0, "nvdecoder"); - if (!gst_cuda_load_library ()) { gst_plugin_add_status_warning (plugin, "CUDA library \"" CUDA_LIBNAME "\" was not found."); return TRUE; } - #ifdef HAVE_NVCODEC_DGPU /* get available API version from nvenc and it will be passed to * nvdec */ @@ -163,6 +741,7 @@ if (!nvdec_available && !nvenc_available) return TRUE; + #endif cuda_ret = CuInit (0); @@ -209,61 +788,50 @@ "check CUDA toolkit package installation"); } - for (i = 0; i < dev_count; i++) { - GstCudaContext *context = gst_cuda_context_new (i); -#if defined(G_OS_WIN32) || defined(HAVE_NVCODEC_DGPU) - gint64 adapter_luid = 0; -#endif + /* Get or build complete cache (loads from serialized data or queries hardware) */ + GArray *cache = gst_nvcodec_get_or_build_cache (plugin, api_major_ver, + api_minor_ver, dev_count, nvenc_available, nvdec_available); - if (!context) { - GST_WARNING ("Failed to create context for device %d", i); - continue; - } -#ifdef G_OS_WIN32 - g_object_get (context, "dxgi-adapter-luid", &adapter_luid, NULL); -#endif + /* Register elements from cache (cache was already built/loaded above) */ + if (cache && cache->len > 0) { + for (i = 0; i < cache->len; i++) { + DeviceCachedCodecs *device = + &g_array_index (cache, DeviceCachedCodecs, i); #ifdef HAVE_NVCODEC_DGPU - if (nvdec_available) { - gint j; - - for (j = 0; j < cudaVideoCodec_NumCodecs; j++) { - GstCaps *sink_template = NULL; - GstCaps *src_template = NULL; - cudaVideoCodec codec = (cudaVideoCodec) j; - gboolean register_cuviddec = FALSE; - - if (gst_nv_decoder_check_device_caps (context, - codec, &sink_template, &src_template)) { - const gchar *codec_name = gst_cuda_video_codec_to_string (codec); + /* Register decoders from cache */ + if (nvdec_available && device->decoders) { + for (GList * l = device->decoders; l; l = l->next) { + GstNvDecoderClassData *dec_cdata = (GstNvDecoderClassData *) l->data; + const gchar *codec_name = dec_cdata->codec_name; + cudaVideoCodec codec = gst_cuda_video_codec_from_string (codec_name); + gboolean register_cuviddec = FALSE; - GST_INFO ("CUDA video codec %s, sink template %" GST_PTR_FORMAT - "src template %" GST_PTR_FORMAT, codec_name, - sink_template, src_template); + GST_INFO ("Registering decoder for codec %s", codec_name); switch (codec) { case cudaVideoCodec_H264: - /* higher than avdec_h264 */ - gst_nv_h264_dec_register (plugin, i, adapter_luid, - GST_RANK_PRIMARY + 1, sink_template, src_template); + gst_nv_h264_dec_register (plugin, i, dec_cdata->adapter_luid, + GST_RANK_PRIMARY + 1, dec_cdata->sink_caps, + dec_cdata->src_caps); break; case cudaVideoCodec_HEVC: - /* higher than avdec_h265 */ - gst_nv_h265_dec_register (plugin, i, adapter_luid, - GST_RANK_PRIMARY + 1, sink_template, src_template); + gst_nv_h265_dec_register (plugin, i, dec_cdata->adapter_luid, + GST_RANK_PRIMARY + 1, dec_cdata->sink_caps, + dec_cdata->src_caps); break; case cudaVideoCodec_VP8: - gst_nv_vp8_dec_register (plugin, i, adapter_luid, - GST_RANK_PRIMARY, sink_template, src_template); + gst_nv_vp8_dec_register (plugin, i, dec_cdata->adapter_luid, + GST_RANK_PRIMARY, dec_cdata->sink_caps, dec_cdata->src_caps); break; case cudaVideoCodec_VP9: - gst_nv_vp9_dec_register (plugin, i, adapter_luid, - GST_RANK_PRIMARY, sink_template, src_template); + gst_nv_vp9_dec_register (plugin, i, dec_cdata->adapter_luid, + GST_RANK_PRIMARY, dec_cdata->sink_caps, dec_cdata->src_caps); break; case cudaVideoCodec_AV1: - /* rust dav1ddec has "primary" rank */ - gst_nv_av1_dec_register (plugin, i, adapter_luid, - GST_RANK_PRIMARY + 1, sink_template, src_template); + gst_nv_av1_dec_register (plugin, i, dec_cdata->adapter_luid, + GST_RANK_PRIMARY + 1, dec_cdata->sink_caps, + dec_cdata->src_caps); break; default: register_cuviddec = TRUE; @@ -271,67 +839,84 @@ } if (register_cuviddec) { - gst_nvdec_plugin_init (plugin, - i, codec, codec_name, sink_template, src_template); + gst_nvdec_plugin_init (plugin, i, codec, codec_name, + dec_cdata->sink_caps, dec_cdata->src_caps); } - - gst_caps_unref (sink_template); - gst_caps_unref (src_template); } } - } - - if (nvenc_available) { - GstNvEncoderClassData *cdata; + /* Register encoders from cache */ + if (nvenc_available && device->encoders) { #ifdef G_OS_WIN32 - if (g_win32_check_windows_version (6, 0, 0, G_WIN32_OS_ANY)) { - GstD3D11Device *d3d11_device; - - d3d11_device = gst_d3d11_device_new_for_adapter_luid (adapter_luid, - D3D11_CREATE_DEVICE_BGRA_SUPPORT); - if (!d3d11_device) { - GST_WARNING ("Failed to d3d11 create device"); - } else { - cdata = gst_nv_h264_encoder_register_d3d11 (plugin, - d3d11_device, GST_RANK_NONE); - if (cdata) - h264_enc_cdata = g_list_append (h264_enc_cdata, cdata); - - cdata = gst_nv_h265_encoder_register_d3d11 (plugin, - d3d11_device, GST_RANK_NONE); - if (cdata) - h265_enc_cdata = g_list_append (h265_enc_cdata, cdata); - - cdata = gst_nv_av1_encoder_register_d3d11 (plugin, - d3d11_device, GST_RANK_NONE); - if (cdata) - av1_enc_cdata = g_list_append (av1_enc_cdata, cdata); - - gst_object_unref (d3d11_device); + /* Register D3D11 encoders on Windows */ + if (g_win32_check_windows_version (6, 0, 0, G_WIN32_OS_ANY)) { + GstD3D11Device *d3d11_device; + + d3d11_device = + gst_d3d11_device_new_for_adapter_luid (device->adapter_luid, + D3D11_CREATE_DEVICE_BGRA_SUPPORT); + if (d3d11_device) { + GstNvEncoderClassData *cdata; + + cdata = gst_nv_h264_encoder_register_d3d11 (plugin, + d3d11_device, GST_RANK_NONE); + if (cdata) + h264_enc_cdata = g_list_append (h264_enc_cdata, cdata); + + cdata = gst_nv_h265_encoder_register_d3d11 (plugin, + d3d11_device, GST_RANK_NONE); + if (cdata) + h265_enc_cdata = g_list_append (h265_enc_cdata, cdata); + + cdata = gst_nv_av1_encoder_register_d3d11 (plugin, + d3d11_device, GST_RANK_NONE); + if (cdata) + av1_enc_cdata = g_list_append (av1_enc_cdata, cdata); + + gst_object_unref (d3d11_device); + } + } +#endif // G_OS_WIN32 + + /* Register CUDA encoders */ + for (GList * l = device->encoders; l; l = l->next) { + GstNvEncoderClassData *enc_cdata = (GstNvEncoderClassData *) l->data; + + GST_INFO ("Registering encoder for codec %s", + gst_cuda_video_codec_to_string (enc_cdata->codec)); + + switch (enc_cdata->codec) { + case cudaVideoCodec_H264: + gst_nv_h264_encoder_register (plugin, + gst_nv_encoder_class_data_ref (enc_cdata), + GST_RANK_PRIMARY + 1); + h264_enc_cdata = g_list_append (h264_enc_cdata, enc_cdata); + break; + case cudaVideoCodec_HEVC: + gst_nv_h265_encoder_register (plugin, + gst_nv_encoder_class_data_ref (enc_cdata), + GST_RANK_PRIMARY + 1); + h265_enc_cdata = g_list_append (h265_enc_cdata, enc_cdata); + break; + case cudaVideoCodec_AV1: + gst_nv_av1_encoder_register (plugin, + gst_nv_encoder_class_data_ref (enc_cdata), + GST_RANK_PRIMARY + 1); + av1_enc_cdata = g_list_append (av1_enc_cdata, enc_cdata); + break; + default: + GST_WARNING ("Unknown encoder codec: %d", enc_cdata->codec); + break; + } } } -#endif - cdata = gst_nv_h264_encoder_register_cuda (plugin, - context, GST_RANK_PRIMARY + 1); - if (cdata) - h264_enc_cdata = g_list_append (h264_enc_cdata, cdata); - - cdata = gst_nv_h265_encoder_register_cuda (plugin, - context, GST_RANK_PRIMARY + 1); - if (cdata) - h265_enc_cdata = g_list_append (h265_enc_cdata, cdata); - - cdata = gst_nv_av1_encoder_register_cuda (plugin, - context, GST_RANK_PRIMARY + 1); - if (cdata) - av1_enc_cdata = g_list_append (av1_enc_cdata, cdata); - } - if (gst_nv_jpeg_enc_register (plugin, context, GST_RANK_NONE, have_nvrtc)) - have_nvjpegenc = TRUE; -#endif - gst_object_unref (context); + /* Register JPEG encoder */ + if (gst_nv_jpeg_enc_register (plugin, i, GST_RANK_NONE, have_nvrtc, + FALSE)) + have_nvjpegenc = TRUE; +#endif // HAVE_NVCODEC_DGPU + } } #ifdef HAVE_NVCODEC_DGPU @@ -351,7 +936,7 @@ } if (have_nvjpegenc) - gst_nv_jpeg_enc_register (plugin, NULL, GST_RANK_NONE, have_nvrtc); + gst_nv_jpeg_enc_register (plugin, 0, GST_RANK_NONE, have_nvrtc, TRUE); #endif gst_cuda_memory_copy_register (plugin, GST_RANK_NONE);
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/sys/shm/gstshmsink.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/sys/shm/gstshmsink.c
Changed
@@ -839,6 +839,8 @@ } while (rv < 0 && errno == EINTR); if (rv < 0) { + if (self->stop) + return NULL; GST_ELEMENT_ERROR (self, RESOURCE, READ, ("Failed waiting on fd activity"), ("gst_poll_wait returned %d, errno: %d", rv, errno));
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/sys/wasapi2/gstwasapi2rbuf.cpp -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/sys/wasapi2/gstwasapi2rbuf.cpp
Changed
@@ -2796,6 +2796,13 @@ hr = gst_wasapi2_rbuf_process_write (self); } + if ((hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED || + hr == AUDCLNT_E_DEVICE_INVALIDATED) && priv->ctx->is_default + && !gst_wasapi2_is_loopback_class (priv->ctx->endpoint_class)) { + GST_WARNING_OBJECT (self, "Ignore write error from default device"); + hr = S_OK; + } + if (FAILED (hr)) { gst_wasapi2_rbuf_post_io_error (self, hr, TRUE); gst_wasapi2_rbuf_start_fallback_timer (self); @@ -3160,6 +3167,10 @@ cmd->low_latency = low_latency; cmd->exclusive = exclusive; + GST_DEBUG_OBJECT (rbuf, "device-id: %s, endpoint-class: %d, pid: %u, " + "low-latency: %d, exclusive: %d", GST_STR_NULL (device_id), + endpoint_class, pid, low_latency, exclusive); + gst_wasapi2_rbuf_push_command (rbuf, cmd); WaitForSingleObject (cmd->event_handle, INFINITE);
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/tests/check/elements/dashsink.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/tests/check/elements/dashsink.c
Changed
@@ -107,8 +107,13 @@ GstBus *bus = gst_element_get_bus (GST_ELEMENT (pipeline)); GstMessage *msg; guint segments_seen = 0; + GstStateChangeReturn ret; - gst_element_set_state (pipeline, GST_STATE_PLAYING); + ret = gst_element_set_state (pipeline, GST_STATE_PLAYING); + if (ret == GST_STATE_CHANGE_ASYNC) { + ret = gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); + fail_unless (ret != GST_STATE_CHANGE_FAILURE); + } do { msg = gst_bus_poll (bus, @@ -269,7 +274,7 @@ GST_DEBUG ("Playing back file %s", filename); - pipeline = gst_element_factory_make ("playbin", NULL); + pipeline = gst_element_factory_make ("playbin3", NULL); fail_if (pipeline == NULL); appsink = gst_element_factory_make ("appsink", NULL); @@ -348,9 +353,7 @@ fail_unless (count == 4, "Expected 4 output files, got %d", count); filename = g_build_filename (tmpdir, "dash.mpd", NULL); - // mpegtsmux generates a first PTS at 0.125 second and does not end at 3 seconds exactly. - test_playback (filename, 0.125 * GST_SECOND, 2.925 * GST_SECOND, 3, - durations); + test_playback (filename, 0, 2.8 * GST_SECOND, 3, durations); g_free (filename); }
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/tests/check/elements/shm.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/tests/check/elements/shm.c
Changed
@@ -229,6 +229,52 @@ GST_END_TEST; +GST_START_TEST (test_shm_stop_no_error) +{ + GstElement *pipeline, *fakesrc, *shmsink; + GstBus *bus; + GstMessage *msg; + GstStateChangeReturn state_res; + + fakesrc = gst_element_factory_make ("fakesrc", NULL); + g_object_set (fakesrc, "num-buffers", 5, "sizetype", 2, NULL); + + shmsink = gst_element_factory_make ("shmsink", NULL); + g_object_set (shmsink, "socket-path", "shm-stop-test", + "wait-for-connection", FALSE, NULL); + + pipeline = gst_pipeline_new ("stop-test"); + gst_bin_add_many (GST_BIN (pipeline), fakesrc, shmsink, NULL); + fail_unless (gst_element_link (fakesrc, shmsink)); + + bus = gst_element_get_bus (pipeline); + + state_res = gst_element_set_state (pipeline, GST_STATE_PLAYING); + fail_unless (state_res != GST_STATE_CHANGE_FAILURE); + + /* Wait for EOS */ + msg = gst_bus_timed_pop_filtered (bus, 5 * GST_SECOND, + GST_MESSAGE_EOS | GST_MESSAGE_ERROR); + fail_unless (msg != NULL); + fail_unless (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_EOS, + "Expected EOS but got %s", GST_MESSAGE_TYPE_NAME (msg)); + gst_message_unref (msg); + + /* Set to NULL — this triggers gst_poll_set_flushing() in the poll thread. + * Before the fix, this would post a spurious GST_MESSAGE_ERROR with + * errno=EBUSY on the bus. */ + gst_element_set_state (pipeline, GST_STATE_NULL); + + /* Check no error was posted during shutdown */ + msg = gst_bus_pop_filtered (bus, GST_MESSAGE_ERROR); + fail_unless (msg == NULL, "Unexpected error on bus during clean shutdown"); + + gst_object_unref (bus); + gst_object_unref (pipeline); +} + +GST_END_TEST; + static Suite * shm_suite (void) { @@ -243,6 +289,7 @@ tc = tcase_create ("shm2"); tcase_add_test (tc, test_shm_live); + tcase_add_test (tc, test_shm_stop_no_error); suite_add_tcase (s, tc); return s;
View file
_service:download_files:gst-plugins-bad-1.28.1.tar.xz/tests/examples/key-handler.c -> _service:download_files:gst-plugins-bad-1.28.2.tar.xz/tests/examples/key-handler.c
Changed
@@ -114,6 +114,8 @@ G_PRIORITY_DEFAULT, (GSourceFunc) handler_source_func, data, (GDestroyNotify) g_free); } + + return NULL; } void
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.