Skip to content

v1.28.10

Choose a tag to compare

@github-actions github-actions released this 12 Sep 14:33
· 53 commits to main since this release

The release where the containers the gir hides finally cross the boundary. A
GBytes is an argument and a return like any other, a GHashTable of strings
arrives as a dictionary, a GSList return is read the way a GList already
was, a counted array the caller supplies is filled in place, and the borrowed constant
structure a C lookup hands back is copied out rather than refused. Around them a
fraction becomes a value type the property system knows, the child properties of
a timeline element can be listed and overridden, an RTSP message yields the
credentials it was challenged with, an ICE agent the candidates it gathered, and
a bus the descriptor a foreign event loop can wait on. Net, forty-three fewer
symbols sit under the catch-all skip reason. Three
things changed behaviour, and each of them is one line below. All eighteen
packages ship as one version, 1.28.10, generated from the GStreamer 1.28.6
.gir files, 50 commits after 1.28.9.

Added

  • A block of bytes across the boundary. Gst.Buffer.NewWrappedBytes(Gst.GLib.Bytes)
    wraps the block zero-copy as read-only memory, and an empty block gives a
    buffer with no memory in it.
  • The adapter copy that answers a block. Gst.Base.Adapter.Copy(nuint offset, nuint size)
    answers a Gst.GLib.Bytes; a size of zero is an empty block, and an offset
    past Available throws even then.
  • The RTP payload and header extension as blocks. Gst.Rtp.RTPBuffer.GetPayload()
    and GetExtensionData(out ushort bits) answer the payload and the header
    extension as blocks, and the static
    GetExtensionOnebyteHeaderFromBytes(Gst.GLib.Bytes, ushort, byte, uint, out byte[]?)
    reads the nth one-byte header extension of a given id back out of one.
  • A MIKEY message from and to a block. Gst.Sdp.MIKEYMessage.NewFromBytes(Gst.GLib.Bytes, Gst.Sdp.MIKEYDecryptInfo?)
    answers null for a malformed message, and ToBytes(Gst.Sdp.MIKEYEncryptInfo?)
    serialises one back out.
  • A fraction the property system knows. Gst.Fraction is a readonly record
    struct whose ToString is N/D, with GetFraction() on
    Gst.GObject.Value, ValueView and ValueRef, SetFraction(Gst.Fraction)
    on Value and ValueRef, and
    Gst.GObject.Object.SetProperty(string, object) and GetProperty<Gst.Fraction>
    widened to carry it — writing a denominator of zero, or either term as
    int.MinValue, is an ArgumentOutOfRangeException, and GStreamer reduces and
    sign-normalises what it stores.
  • The first fraction-typed property. Gst.Audio.AudioAggregator.OutputBufferDurationFraction
    is emitted through those accessors.
  • The child properties of a timeline element. GES.TimelineElement.ListChildrenProperties()
    answers an owned Gst.GObject.ParamSpec[] in the name order GES sorts, and the
    caller disposes each element.
  • Three child-property slots to override. GES.TimelineElement.OnListChildrenProperties,
    OnLookupChild(string, out Gst.GObject.Object?, out Gst.GObject.ParamSpec?) and
    OnSetChildProperty(Gst.GObject.Object, Gst.GObject.ParamSpec, Gst.GObject.ValueView)
    with their chain-ups; a ParamSpec returned or passed on is consumed, a
    borrowed one is call-scoped, and a true answer requires both outputs.
  • The query and fragment of a URI as tables. Gst.Uri.GetQueryTable() and
    GetMediaFragmentTable() answer a Dictionary<string, string?>? snapshot —
    a null value is a key with no =, "" is key=, no query or fragment is
    null and a bare ? or # is empty — and Gst.Uri.SetQueryTable(IReadOnlyDictionary<string, string?>?)
    copies one in, or clears the query when given null.
  • Every control binding of a track element. GES.TrackElement.GetAllControlBindings()
    answers a Dictionary<string, Gst.ControlBinding> snapshot keyed by the name
    passed to SetControlSource, whose values are interned and need no dispose.
  • The debug categories the library registered. Gst.Global.DebugGetAllCategories()
    answers an IReadOnlyList<Gst.DebugCategory> snapshot of borrowed categories
    that live until gst_deinit.
  • A format list that carries its own end. Gst.Global.FormatsContains(ReadOnlySpan<Gst.Format>, Gst.Format)
    searches one without the caller writing the terminator loop.
  • A control source sampled a run at a time. Gst.ControlBinding.GetGValueArray(ClockTime timestamp, ClockTime interval, Span<Value> values)
    and Gst.Object.GetGValueArray(string propertyName, ClockTime, ClockTime, Span<Value>)
    fill empty slots the caller supplies; what lands in them is the control
    source's business.
  • A MIKEY timestamp whose length its kind decides. Gst.Sdp.MIKEYPayload.TSet(MIKEYTSType, ReadOnlySpan<byte>)
    and Gst.Sdp.MIKEYMessage.AddT(MIKEYTSType, ReadOnlySpan<byte>) take exactly
    the 8, 8 or 4 bytes the type calls for.
  • One VBI line at a time. Gst.Video.VideoVBIEncoder.WriteLine(Span<byte>)
    and Gst.Video.VideoVBIParser.AddLine(ReadOnlySpan<byte>) want one line of
    the stride the format and the pixel width of New fix, which the wrapper now
    remembers.
  • A channel order a ring buffer will accept. Gst.Audio.AudioRingBuffer.SetChannelPositions(ReadOnlySpan<Gst.Audio.AudioChannelPosition>)
    checks the acquired state and the channel count, and may be called from inside
    OnPrepare.
  • Both blocks of a DSD conversion measured. Gst.Audio.AudioGlobal.DsdConvert(...)
    validates the extent, the overlap and the whole-frame rule of the input and
    output blocks before the call.
  • The credentials a message was challenged with. Gst.Rtsp.RTSPMessage.ParseAuthCredentials(RTSPHeaderField)
    answers an RTSPAuthCredential[] of the Basic and Digest credentials of a
    WWW-Authenticate, Proxy-Authenticate or Authorization header, copied so
    they outlive the message, and an absent header is an empty array.
  • The parameters of one credential. Gst.Rtsp.RTSPAuthCredential.GetParams()
    answers a fresh RTSPAuthParam[] on each call, which the caller disposes.
  • The ICE candidates an agent gathered. Gst.WebRTC.WebRTCICE.GetLocalCandidates(WebRTCICEStream)
    and GetRemoteCandidates(WebRTCICEStream) answer a WebRTCICECandidateStats[]
    snapshot whose elements belong to the caller.
  • The transports a session media keeps a slot for. Gst.RtspServer.RTSPSessionMedia.GetTransports()
    answers an RTSPStreamTransport?[] indexed by stream index, with null where
    no SETUP has happened yet.
  • Six borrowed constant structures copied out. Gst.FormatExtensions.GetDetails(Gst.Format),
    Gst.Rtp.RTPPayloadInfo.ForName(string media, string encodingName) and
    ForPt(byte), Gst.Sdp.MIKEYMessage.GetCsSrtp(uint) and
    Gst.Sdp.MIKEYPayload.SpGetParam(uint) answer a nullable copy of the static
    row the C points at, null for a value the library does not know, while
    Gst.Video.VideoColorPrimariesExtensions.GetInfo(VideoColorPrimaries) is
    non-nullable behind a guard; Gst.Sdp.MIKEYPayloadSPParam.Val reads the
    counted block that record's C field points at.
  • A property-notify message built without losing the value.
    Gst.Message.NewPropertyNotify(Gst.Object src, string propertyName, in Gst.GObject.Value? value)
    hands the C a g_value_copy duplicate, so the caller's Value stays alive and
    stays the caller's to dispose and an object value keeps a reference of the
    message's own; null is a notification without a value and an empty Value is
    an ArgumentException.
  • A poll descriptor and the wait over it. Gst.GLib.PollFD (Fd, Events,
    Revents), Gst.GLib.IOCondition and the static
    Gst.GLib.PollFD.Poll(Span<PollFD>, int timeoutMs) project GPollFD and
    g_poll with the descriptor width the platform decides — a HANDLE on 64-bit
    Windows, a file descriptor elsewhere, checked by the ABI probe against the
    running library; an empty set is an ArgumentException, Windows waits on
    handles, answers Revents = Events and stops at 64, and a Unix wait broken by
    a signal resumes with the remaining timeout. Gst.PollFD is GstPollFD and
    Gst.GLib.PollFD is GPollFD, so code that opens both namespaces qualifies
    the two, as it already does for Gst.DateTime.
  • The descriptor a bus signals through. Gst.Bus.GetPollfd() gives a foreign
    event loop the descriptor that reports a pending message; the descriptor
    belongs to the bus and must not be read, written or closed, and a bus built
    without asynchronous delivery throws InvalidOperationException.
  • The read half of a poll set. Gst.Poll.GetReadGpollfd() supplies the out
    direction the gir omits; Gst.Poll itself is still not constructible from
    managed code.
  • A variant handle and the discoverer round trip. Gst.GLib.Variant
    (Handle, TypeString, ToBytes(), FromBytes(string, Gst.GLib.Bytes),
    Dispose) sinks the floating GVariant the C returns and refuses an
    indefinite type string, and Gst.Pbutils.DiscovererInfo.ToVariant(DiscovererSerializeFlags)
    / static FromVariant(Gst.GLib.Variant) carry a discoverer result through
    bytes — ToVariant refuses a result that is neither Ok nor
    MissingPlugins or has no stream tree, FromVariant refuses anything that is
    not a "v", both of them ahead of a NULL dereference in the C.

Behavioural

  • Gst.Sdp.MIKEYMessage.NewFromData(ReadOnlySpan<byte>, Gst.Sdp.MIKEYDecryptInfo? info) takes a nullable info and is callable for the first time: the argument used to be non-nullable and every call threw ArgumentNullException before reaching the C, and an empty span is still a GLib critical and an InvalidOperationException.
  • Every generated method, extension and subclass chain-up now places its GC.KeepAlive barriers at the end of the body rather than before the output conversions, closing a latent window in which a wrapper could be finalized while a borrowed output array, string or list was still being read; no signature and no observable behaviour changed.
  • Gst.Rtp.RTCPBuffer.NewTakeData(Span<byte>) copies the block: the generated member pinned the caller's span for the length of the call only and handed the address to a constructor that keeps it as buffer memory and frees it with g_free on the last unreference, so the public signature is unchanged and the content is now a g_memdup2 duplicate, with an empty span refused as an ArgumentException.

Tooling

  • Gst.GLib.Bytes is a runtime type-table type, so every GBytes argument and
    return the gir declares is generated from here on. Three members stay hand
    bound for their C preconditions — gst_buffer_new_wrapped_bytes,
    gst_adapter_copy_bytes and gst_webrtc_data_channel_send_data_full — and
    the deprecated send_data stays deliberately unbound.
  • The generator accepts three GHashTable shapes (a string-to-string return, a
    string-to-string argument and a string-to-object return), a GSList return
    under the rules a GList return already had, a counted block of parameter
    specifications in return position, and a constant plain-structure return,
    which it copies by value rather than refusing the member.
  • Gst.Fraction joins the runtime beside the other value projections, with its
    GValue accessors and the property emission that uses them.
  • Gst.WebRTC.WebRTCDataChannel.OnMessageData and its OnMessageDataSignalArgs
    are generated now rather than hand written; the shape and the borrow and
    release contract are the same, and the delivery-thread contract moved to the
    remarks of the class. Gst.Video.VideoVBIEncoder and VideoVBIParser went the
    other way — New and Copy are hand written so the wrapper can remember the
    geometry the line members need — with the same public shape.
  • The integration suite now exercises the new surface against the installed
    library: the hash table members, the category registry, the GBytes members, the
    child-property slots, the poll descriptors and the discoverer round trip.
  • The documentation moved with the surface, and no public surface moved with
    the documentation: the remark on a transfer-full boxed argument now says a
    reference is passed for the types whose registered copy function is a _ref
    the dt argument of Gst.DateTime.NewFromGDateTime and the eight frame
    arguments of VideoDecoder and VideoEncoder — and docs/ownership.md gains
    the caveat about a property getter that answers a floating GstObject its
    owner never sank.

Compatibility

Three items changed behaviour and each has its line above: MIKEYMessage.NewFromData
becomes callable, the generated keep-alive barriers moved to the end of the body
with no observable effect, and RTCPBuffer.NewTakeData copies the block it is
given instead of lending it. Everything else is additive, which is what the
1.28.x promise allows. The binding is generated from the GStreamer 1.28.6
.gir files and the run-time floor is still GStreamer 1.24 — neither moved.

The census of what the gir declares — classes, records, interfaces, enumerations
and bitfields — is unchanged. What moved is the ledger and the emission. In
girs/skip-report.md, UnsupportedSignature falls from 109 entries to 66 and
HandBound grows from 122 to 146: Gst counts 30 unsupported signatures rather
than 43 and 69 hand-bound symbols rather than 62, GstSdp 0 rather than 6 and 2
rather than 0, GstRtp 2 rather than 8 and 9 rather than 8, GstVideo 2 rather
than 5 and 12 rather than 6, GstWebRTC 0 rather than 3 and 4 rather than 3,
GstPbutils 0 rather than 2 and 4 rather than 2, GstAudio 1 rather than 4 and
8 rather than 6, GES 5 rather than 8, GstRtsp 10 rather than 12 and 3 rather
than 2, GstRtspServer 13 rather than 14 and 2 rather than 1, and GstBase 3
rather than 4 and 3 rather than 2. Beside them Virtuals falls from 20 to 17,
the three child-property slots that can be overridden now; the three GES slots
that stay out — a throwing one and two dead deprecated ones — are filed under the
reason that really keeps them out rather than under the catch-all.
Fields falls from 143 to 142 and Fields exposed elsewhere grows from 18
to 19, OverlaySkip from 58 to 63, ShadowedBy from 10 to 12, while
NotIntrospectable falls from 162 to 160 and MovedTo from 304 to 302.

The emitted surface grows with it: Gst counts 1450 methods rather than 1445,
GstSdp 168 rather than 164, GstRtp 188 rather than 184, GES 384 rather than
382 with 26 virtual methods rather than 23 over 245 slots rather than 242,
GstAudio 33 properties rather than 32 and GstWebRTC 8 signals rather than 7.
GstVideo counts 379 methods rather than 382, which is not a removal: the New
and Copy of the VBI encoder and of the VBI parser — four members — left the
generated tree for the hand-written partials of the same public shape, and
VideoColorPrimariesExtensions.GetInfo arrived in their place.

PackageValidationBaselineVersion in src/Directory.Build.props is 1.28.9, and
all eighteen packages are packed against it.

Changes

  • Tidy three review nits of the step 12 bundle
  • Add a minimal GLib.Variant and the discoverer round trip
  • Add GLib.PollFD and the bus and poll descriptor accessors
  • Bind gst_message_new_property_notify by copying the value
  • Skip the take_data family and hand-bind RTCPBuffer.NewTakeData by copy
  • Copy a borrowed plain structure out of a const return
  • Say only what the ICE test measured
  • Address the review findings of the RTSP bundle
  • Put the unsafe of the RTSP partials on the class
  • Read the transports a session media keeps a slot for
  • List the ICE candidates an agent gathered
  • Read the credentials a message was challenged with
  • Drop the boxed row nothing can reach
  • Say which boxed copies are references
  • Say when a hand-written member may not take the object lock
  • Let the copied VBI encoder prove it holds its own packets
  • Measure both blocks of a DSD conversion
  • Bound the channel order a ring buffer is handed
  • Measure the VBI line a caller has to hand over
  • Set a MIKEY timestamp whose length its kind decides
  • Sample a controlled property a run at a time
  • Search a format list that carries its own end
  • Read the category registry against the installed library
  • Say what the snapshot of the category registry is worth
  • Bind a singly linked list a call hands back
  • Say where the media fragment table comes from
  • Exercise the hash table members against the installed library
  • Note what the four hash table members do not say
  • Bind the hash tables of a URI query and of the control bindings
  • Copy a GHashTable of string keys across the boundary
  • Note the caller's contract on the child property slots
  • Exercise the child property slots against the installed editing services
  • Bind the child property slots of a timeline element
  • Skip the dead and deprecated GES child property slots by overlay
  • Bind a counted block of parameter specifications in return position
  • Correct the C citation and the doc lists of the fraction accessors
  • Emit a fraction property through the fraction accessors
  • Give the runtime a fraction value type and its accessors
  • Correct the count of result-named parameters in a test comment
  • Move the receiving contract to the remarks of the class
  • Move the barriers of a virtual method to the end of its body
  • Drive the generated on-message-data trampoline with a real block
  • Refuse an offset the adapter does not hold for every size
  • Drop the GBytes overload of SendData
  • Note the on-message-data delivery thread and the hand-bound GBytes entries
  • Keep wrapper arguments alive until their outputs are converted
  • Cover the GBytes members with integration tests
  • Bind gst_buffer_new_wrapped_bytes and gst_adapter_copy_bytes by hand
  • Marshal GLib.Bytes through the runtime type table
  • Move the version and the validation baseline to 1.28.9

Full Changelog: v1.28.9...v1.28.10