Changelog¶
Changes and updates for all .Net SDKs.
2026.9.1¶
-
[Video Capture SDK .Net] Removed: the RTSP X network streaming output.
NetworkStreamingFormat.RTSP_Xand theRTSPXOutputsettings class are gone fromVideoCaptureCore, and theVisioForge.DotNet.Core.Redist.RTSPX.x64package is no longer published - it carried its own GStreamer runtime that had not been refreshed since 2024 and loaded alongside the current one. UseVideoCaptureCoreXwithRTSPServerOutput/RTSPServerSettings, which serves RTSP from the maintained runtime and needs no extra package.NetworkStreamingFormat.RTSP_H264_AAC_SWremains available onVideoCaptureCore(#1262). -
[Media Blocks SDK .Net] Fixed: on Windows, stopping an SRT pipeline never returned when the receiving peer had gone away.
StopAsyncblocked indefinitely onSRTSinkBlockandSRTMPEGTSSinkBlock, and the pipeline could never be disposed - the bundled SRT plugin kept closing and reopening the connection, and End-Of-Stream could not be delivered while the sink's streaming thread was inside that loop. The Windows redistributable now carries the corrected SRT plugin macOS has shipped since 2026.8.5, so a stop against an unreachable or flapping peer completes in about a second (#1190). -
[Core] The RAV1E AV1 encoder now encodes across CPU cores.
rav1encsplits work by tiles and the SDK never set that property, so it ran the whole frame as a single tile and encoded at the same speed on 4 cores as on 32. The newRAV1EEncoderSettings.Tilesdefaults to 16: measured on 720p30, 8 seconds of content now takes about 29 seconds instead of 84, for roughly 1% more bitrate at the sameQuantizer. SetTiles = 0for the previous single-tile output (#1345). -
[Media Blocks SDK .Net] Fixed: a Basler camera was opened by its position in the device list, not by the camera you named.
BaslerCameraInforead onlyDeviceIndex, so an instance built withnew BaslerCameraInfo(name)- which leaves that index at 0 - read its sensor size from, and streamed, the first Basler device on the machine whatever the name said. The camera is now found by its serial number, full name, user-defined name or name, andpylonsrcis pointed at it by identity rather than by index; a named camera that is not present is now reported and the capture fails to start, instead of quietly streaming another one (#1344).
2026.8.31¶
-
[Media Blocks SDK .Net] Fixed: a video mixer could save a source that would not load back, and a restored Basler source could report zero frame rate. A mixer source whose camera name had been cleared was written into the document without it, the snapshot reported success, and loading that document failed - it is refused at save time now, naming the block. And a Basler camera whose frame rate could not be read when the document was saved kept a zero frame rate on every later load, which reached the recording's frame info; it is re-read now, as the sensor size already was.
-
[Media Blocks SDK .Net] Fixed: a Spinnaker source could open a different camera than the one it was told to, without saying so. The camera was addressed by its position in the enumerated list rather than by its own index, so one camera failing to initialize - held by another process, for instance - shifted every camera after it, and the source silently opened its neighbour. A name matching no camera at all, or matching two identical bodies (the name is the model name, which they share), was equally silent. The index is now the camera's own,
SpinnakerCameraInfocarries the serial number, and all three cases are reported. two handles leaked during enumeration are released; one camera failing to answer no longer hides every other camera on the rig, and no longer leaves a truncated list cached; a camera whose model name cannot be read is listed under its serial number instead of under a name every unreadable camera shares; and a camera index the element cannot address fails the source instead of quietly opening a different camera - the element accepts 0-7, so on a rig with nine or more cameras the ninth and beyond now report an error at build time rather than streaming a neighbour. -
[X-engines] Fixed: an SDK error killed the process when the application had not subscribed
OnError.VideoEditCoreXreported such an error by logging it, and the log is what raises the error event, so every error re-entered the reporting path and recursed until the stack overflowed - the process died with no exception and no message. A render that could not build its encoder was the common way in. The error is now reported once, and shown on the video view exactly as the other engines do.MediaBlocksPipelinehad the same loop on its two "VisioForge_MFP.dll not found" messages, which recursed whenever a debugger was attached (#1173). -
[Media Blocks SDK .Net] Fixed: a virtual camera sink with an input that was created but never connected wedged the pipeline.
VirtualCameraSinkBlockbuilt the chain for a pad that exists rather than for one that is connected, so an unconnected input left a branch with nothing feeding it - a branch that can neither preroll nor reach End-Of-Stream, leaving eitherStartAsyncorStopAsyncnever returning. Two connected inputs of the same type are now reported as an error too - only one of them was ever linked (#1288). -
[Media Blocks SDK .Net]
NDISinkBlock.IsAvailable()now reportsfalsewhen the NDI runtime is missing. It answered from the GStreamer element alone, so on a machine carrying the plugin but no NDI runtime it reported the sink as available and the pipeline then failed to start (#1288). -
[Media Blocks SDK .Net] Fixed: stopping a pipeline whose
NDISinkBlockhad only a video input never returned.StopAsyncblocked forever and the pipeline could never be disposed; adding an audio input was the only workaround. The sink built its audio chain even when no audio was connected, and the unfed combiner pad stalled the End-Of-Stream a graceful stop sends. A video-only NDI sink now stops normally. An NDI sink with no video input, which cannot produce an NDI stream at all, is now reported as a build error instead of hanging the same way (#1288). -
[Media Blocks SDK .Net] Fixed: nothing decoded when a decoder was connected to
UniversalDemuxBlock. The demuxer hands out encoded data, so a decoder behind it is the normal way to use it - and that graph delivered no frames at all, while the pipeline reported a successful start and put nothing on the bus. A stream the demuxer was told not to render was sent to a plain null sink, which stalled the demuxer until the pipeline reached playing, and the pipeline could not reach playing because the decoder branch was starved of the frames it needed. This affectsUniversalDemuxBlockandUniversalAutoDemuxerBlockwithrenderVideoorrenderAudioturned off, and every decoder behind them,UniversalDecoderBlock,DecodeBinBlockand the codec-specific decoder blocks alike. A demuxer also no longer throws when the file turns out to hold more streams of a type than its media info reported, andUniversalDemuxBlockcan now output a metadata stream (#836). -
[Media Blocks SDK .Net]
UniversalDemuxSettings.Typecan now be set. It was declared without a setter, so that settings class always meant automatic container detection whatever was assigned to it; the per-format settings classes were the only way to pick a specific demuxer. The default is unchanged (#836). -
[Media Blocks SDK .Net] Pipeline documents now write enum settings by name instead of by number. Many of the SDK's enums declare their members per platform, so the same ordinal meant a different member elsewhere -
1wasWASAPIon Windows andDecklinkon macOS - and a document moved between platforms silently restored the wrong device API, encoder or format. A saved pipeline now reads"api": "WASAPI". Documents written before this still load; a document written by this build cannot be opened by an earlier one (#1322). -
[Media Blocks SDK .Net] A pipeline document now restores the audio device a block was using.
AudioRendererBlock,SystemAudioSourceBlockand the WASAPI, WASAPI2, DirectSound, loopback and PulseAudio audio sources hold anAudioOutputDeviceInfoorAudioCaptureDeviceInfo, and neither could be written to a document and read back - so a saved pipeline came back either refusing to load or holding no device at all. A document now stores what identifies the device (its name, path, API and, on macOS, the stable CoreAudiounique-id), and materialization matches that against the devices the machine actually has, handing the block a live device again. This also fixes a saved configuration opening the wrong speaker or microphone: the numeric CoreAudio id and the WASAPI path are both reassigned between runs, and the match now re-reads the current ones. When the named device is gone, the pipeline still builds on a system device of the same API and materialization reports it as the newMBS063warning naming both devices.AlliedVisionSourceSettingsrestores from the camera's identity the same way, without opening the camera (#1322). -
[Media Blocks SDK .Net] Fixed: a pipeline document silently lost mandatory block settings and restored a block wired to the wrong thing. A setting exposed as a read-only property - the bridge
Channelabove all, but alsoCustomMediaBlockSettings.ElementName,GLOverlaySettings.Filename,GLEquirectangularViewSettings.VideoWidth/VideoHeight,AlliedVisionSourceSettings.Cameraand the GenICam region, frame rate and pixel format - was never written into a saved document, and came back asnullor0with validation, deserialization and materialization all reporting success. Two app bridges saved on different channels reloaded onto the same one. Those settings now round-trip, a document missing one is reported asMBS043naming the property instead of restoring a mis-wired block, andMediaBlockDescriptor.Propertieslists them (with the newIsRequiredandIsReadOnlyflags) so an editor can author them. Eight settings types could not be restored at all, because a constructor parameter matched no property and the serializer refuses to bind such a constructor - every document holding aBridgeAudioSource,HTTPSource,AudioRenderer,OpenCVTemplateMatch,LiveSourceSwitch,LiveSourceSwitchDynamic,AlliedVisionSourceorVideoAspectRatioCropblock failed to load. All of them now restore. The parameters are renamed to match their properties:BridgeAudioSourceSettings(channel, info),HTTPSourceSettings(location, isLive),AudioRendererSettings(info),CVTemplateMatchSettings(templateImage)andLiveSourceSwitchSettings(videoWidth, videoHeight, videoFrameRate). Positional calls are unaffected; code passing these by name must be updated (#1322). -
[Media Blocks SDK .Net] Fixed: a pipeline document holding a
SpinnakerSourceblock could not be loaded, and a mixer holding a Spinnaker source could not be saved. The constructor's first parameter matched no property, which the serializer refuses outright, and the region, frame rate and pixel format were never written into the document. All four settings now round-trip. The parameter is renamed to match its property:SpinnakerSourceSettings(name, region, frameRate, pixelFormat). Positional calls are unaffected; code passing the first argument by name must be updated (#1338). -
[Media Blocks SDK .Net] Fixed: a pipeline document holding a
GenICamSourceorBaslerSourceblock came back without its camera.GenICamSourceSettingsdeclares two constructors and no parameterless one, which the serializer refuses outright, so no document holding the block loaded at all - while its region, frame rate and pixel format were written into the document regardless.BaslerSourceSettings.Camerawas never written, so the block restored with no camera while saving, validation and loading all reported success. Both now round-trip from the identity the document carries, and a Basler document that carries the sensor size no longer opens the camera to re-read it. The first parameter of bothGenICamSourceSettingsconstructors is renameddeviceName->nameto match its property; positional calls are unaffected. ASpinnakerSourceorGenICamSourcedocument carrying no camera name, or an empty one, is now reported asMBS043instead of silently opening the first camera on the machine (#1338). -
[Media Blocks SDK .Net] Fixed: a video mixer holding an Allied Vision or GenICam camera could not be saved. The mixer wrote a source only when it could read it back, and that check looked at public constructors alone - so it refused a settings class whose deserialization constructor is private, with an
MBS060, even though loading a document restores it correctly. Both cameras now save and reload as mixer sources. A mixer source missing a mandatory setting - the region above all - is reported now too, where it used to load as a camera with no region and then fail when the pipeline started (#1338). -
[Core] Fixed: a capture device whose sample rate range lies outside 22050-96000 Hz disappeared from the device's format list. A narrow-band device publishing, say,
rate=(int)[ 8000, 16000 ]matched none of the rates the enumeration samples a range at, so it produced no entries at all. Its own bounds are published instead (#1317). -
[Core] Fixed: a capture device publishing its sample rate or channel count as a list disappeared from the device's format list entirely.
AudioCaptureDeviceInfo.Formatsread only the single-value and range forms, so a caps structure written asrate=(int){ 44100, 48000 }produced no entries at all rather than one per combination (#1317). -
[Core] Fixed: audio frames delivered as 24-bit-in-32 or as 20-/18-bit reported the wrong bytes per sample.
AudioFrame.Info.BPScarried the number of significant bits rather than the container width, so a consumer ofBufferSinkBlockorAudioSampleGrabberBlockread 3 bytes per sample where the buffer holds 4 (S24_32*) - a 25% undercount that garbles the audio - and 2 bytes where 20- and 18-bit formats hold 3.S24BEreported 0. Unchanged for 8-, 16-, 32- and 64-bit formats, which is everything the SDK produces by default (#1317). -
[Core] Fixed: 24-bit-in-32 audio formats were dropped from capture-device format lists and could not be requested. GStreamer writes these as
S24_32LE/S24_32BE/U24_32LE/U24_32BEwhile theAudioFormatXenum spells them without the underscore, and the SDK converted between the two by name. A device offering one of them lost it fromAudioCaptureDeviceInfo.Formats, and asking for it anywhere a format is applied - audio capture, the audio mixer, WAV output, a push source, the iOS/Mac audio renderer - produced a format name no element accepts. Both directions are now translated (#1317). -
[Core] On macOS and Mac Catalyst the default audio capture format now follows the device's own sample rate.
AudioCaptureDeviceInfo.GetDefaultFormat()preferred 44100 Hz and, when a device published no 16-bit stereo combination at all, fell back to whichever entry sorted first alphabetically. Since the capture format is applied to the capture device itself, that could ask CoreAudio to run an input at a rate it does not use - CoreAudio cannot resample an input, so the hardware's nominal rate was changed instead. The rate now comes from the format the device reports as its own; 16-bit stereo is still preferred for the sample format and channel count, which CoreAudio does convert. Devices publishing 16-bit stereo at 44100 or 48000 Hz - the common case - keep the format they had (#1317). -
[Media Blocks SDK .Net]
IsAvailable()on the video and audio encoders and decoders no longer reports a codec that cannot actually be created. It answered from the GStreamer registry alone, and the registry caches a plugin's element list while the elements a plugin registers are decided when it loads — the Media Foundation plugin names its encoders by hardware-MFT enumeration index, and the NVIDIA, Intel and Direct3D plugins register their elements only for the hardware present at scan time. After a driver, GPU or Windows-codec change the registry could still list an element the plugin no longer provides;IsAvailable()returnedtrueand the pipeline then failed to build with an unrelated-looking error. The check now also loads the element's plugin and asks it again, which refreshes the registry's list for that plugin. The firstIsAvailable()call for a given backend is correspondingly slower, since it now loads that backend's plugin — around 0.3 s for NVIDIA and 0.7 s for Media Foundation on the measured host, once per plugin per process — and that plugin's vendor libraries are loaded into the process even if the pipeline ends up encoding in software (#1175). -
[Media Blocks SDK .Net]
MFH264EncoderSettings.GetDeviceIDs()andMFHEVCEncoderSettings.GetDeviceIDs()no longer list a Media Foundation device that cannot be created, and they identify each device from the loaded MFT rather than from the cached registry metadata, which could name a different encoder. Two consequences on a host where such a stale entry existed: a device that used to appear and then fail is now absent, andDeviceID— a position in this list — can shift, so an application that persisted aDeviceIDshould re-resolve it againstGetDeviceIDs()rather than assume last run's number (#1175). -
[Media Blocks SDK .Net] Windows: using a Media Foundation encoder no longer permanently breaks every later NVIDIA NVENC encode in the process. GStreamer eagerly activated NVIDIA's Media Foundation H.264 and HEVC MFTs while registering the plugin, even when the pipeline only requested the Microsoft AAC encoder. If the public NVENC API had already been initialized, the next
nvh264enc/nvh265encsession failed withNV_ENC_ERR_INVALID_VERSION(0xf) and no later session could recover. The bundled Media Foundation plugin now excludes NVIDIA's video MFTs beforeIMFActivate::ActivateObject. Microsoft, Intel, AMD, software Media Foundation video encoders, all Media Foundation audio codecs, video capture (mfvideosrc) and device enumeration remain available. What changes on an NVIDIA machine: NVIDIA's Media Foundation video encoders are no longer registered by the plugin.MFH264EncoderSettingsandMFHEVCEncoderSettingskeep selecting the same encoder and the sameDeviceIDnumbering as before — they already excluded NVIDIA entries when enumerating — with one exception: a host whose only Media Foundation HEVC encoder was NVIDIA's. There the settings class enumerated nothing and fell back to the baremfh265encelement, which used to be the NVIDIA one; nothing registers that name now, soHEVCEncoderBlock.IsAvailable(new MFHEVCEncoderSettings())returnsfalseandHEVCEncoderType.MF_HEVCis unavailable. Install the Microsoft HEVC Video Extensions, or encode HEVC throughNVENCHEVCEncoderSettings. H.264 is not affected in the same way: Windows always registers the Microsoft software H.264 MFT. What changes is the plain GStreamer element:mfh264encandmfh265encare now backed by the next non-NVIDIA MFT on the host — Intel or AMD hardware where present, otherwise the Microsoft software H.264 MFT and the HEVC Video Extension — so a hand-written pipeline string naming them gets a different encoder. UseNVENCH264EncoderSettings,NVENCHEVCEncoderSettingsorNVENCAV1EncoderSettingsfor NVIDIA hardware encoding; they are unaffected and are the faster path in any case (#842). -
[Media Blocks SDK .Net]
MFAACEncoderSettingsis no longer deprecated. It was marked obsolete because using it broke NVENC later in the same process; that was never the AAC encoder's doing — requesting it loads the Media Foundation plugin, whose video-MFT registration was the real cause, and that is fixed above. Code using it no longer produces a compiler warning.AVENCAACEncoderSettingsstays the Windows default forMP4Output; preferMFAACEncoderSettingsforVideoEditCoreXrender paths, where libav AAC does not round-trip the GstPreset (#842). -
[Media Blocks SDK .Net] Fixed:
AudioRendererBlock.Mutecould not turn audio back on on iOS and Mac Catalyst. Setting it tofalsewrote volume 0 again, leaving the renderer silent and reporting itself muted. Muting now preserves the configured volume, and unmuting restores audible output (#1318). -
[Core] Fixed: HTTPS and RTSPS connections on Mac Catalyst could not initialize TLS. The GStreamer runtime was searched for in a
libsubfolder that Mac Catalyst app bundles do not contain, so its OpenSSL TLS backend and certificate database were never loaded. The SDK now finds the bundled runtime and verifies TLS peers as on macOS (#1327). -
[Core] On macOS and Mac Catalyst an application no longer re-scans the whole GStreamer plugin set on every launch. The scan is now cached in the application's own Caches directory (
Library/Caches/VisioForge/<bundle-id>/gstreamer/, inside the sandbox container for a sandboxed app) and paid once - on the first start after installing or updating the application, and after that only for plugins whose files changed. Nothing needs to be deployed or configured; deleting the cache folder costs one more scan (#1299). -
[Core] On macOS and Mac Catalyst
GST_PLUGIN_PATHis no longer set in the .NET environment. It is published to the process environment GStreamer itself reads, which the .NET one on Unix never was - soEnvironment.GetEnvironmentVariable("GST_PLUGIN_PATH")now returns nothing on these platforms, and a child process started by the application no longer inherits the application's own plugin directory. Pass it explicitly to a child that needs it (#1299).
2026.8.30¶
-
[Media Blocks SDK .Net] Fixed: a chroma key saved into a pipeline document lost its source video resolution, and restored as a block that never worked.
ChromaKeySettingsX.SourceVideoResolutionis the one setting the keying filter cannot do without - it builds its video format from it - and it was read-only, so it was never written into a saved document and every restored chroma key came back with no resolution at all. Materialization reported success, and the failure showed up only when the pipeline was started: the block could not be built, and a block that cannot be built stops the whole pipeline from starting, with nothing in the diagnostics to say why. The property is now settable and round-trips, andChromaKeyBlockrefuses settings whose resolution is missing or has a zero extent, so such a document is reported as failing withMBS040naming the property instead of restoring a dead block (#1319). -
[Media Blocks SDK .Net] The OpenCV blocks now work on macOS. All sixteen blocks in the
VisioForge.Core.MediaBlocks.OpenCVnamespace,VideoStabilizationBlockamong them, were documented as cross-platform but their GStreamer plugin shipped for Windows only, so on macOS every one of them reportedIsAvailable()asfalse. Add the new VisioForge.CrossPlatform.OpenCV.macOS redistributable alongsideVisioForge.CrossPlatform.Core.macOSand they work as they do on Windows. The package is one universal (x64 + ARM64) plugin with OpenCV 4.14.0 linked into it, so there are no separate OpenCV libraries to deploy. Linux, iOS, Mac Catalyst, Android and Windows arm64 still have no OpenCV redistributable and the blocks stay unavailable there (#1283). -
[Media Blocks SDK .Net] Fixed: on macOS
CVFaceDetectBlock,CVFaceBlurBlockandCVHandDetectBlocknever found their default Haar cascade files. The default cascade names were resolved against anx64orx86subfolder of the application directory and nowhere else - a layout only the Windows redistributables create. Detection silently produced no results, with the cause visible only in the GStreamer log. The cascades are now looked up in the redistributable's own layout on every platform. Setting a cascade property to a full path is unaffected (#1283). -
[Core] Fixed: reading or writing a GStreamer property whose type is
glongorgulongthrewEntryPointNotFoundExceptionon Windows. Those two value types were read and written through four native functions that no shipped GStreamer build has ever exported, so every access to such a property failed on x86, x64 and ARM64 alike. They now go through the standard GLib accessors, and a value too large for the 32-bit Windowsglongis reported as an overflow rather than stored as a different number (#1160). -
[Demos] Fixed: restarting the Bridge Demo no longer leaves an MP4 recorder running in the background. Starting another recording now finalizes and releases the preceding recorder first, whether Start is pressed again directly or after Stop. The output file is no longer held open by an abandoned muxer, and completed recordings retain their MP4 index.
-
[Demos] Fixed: several demos started an operation and moved on without waiting for it. The Bridge, Bridge Source Switch, Audio Extractor and all three PreEventRecording demos (WPF and both Avalonia heads) destroyed the SDK, or let the process go, while engine teardown was still running - a recording being closed with the window could be left unfinalized, and the Media Blocks Avalonia one disposed its pipeline without stopping it first. Those window-close handlers now cancel the close, finish stopping and disposing, and then close for real; a second close request during teardown no longer slips past. The RTSP MultiViewSync demo's Stop button returned before the three pipelines had stopped, and the Video Edit Main Demo's Join button reported completion immediately; both now wait. The macOS Simple Media Player closed its window without blocking the main thread on player teardown, and the two Avalonia PreEventRecording motion handlers no longer block an SDK callback thread on the UI thread.
-
[Media Blocks SDK .Net]
OSXAudioSourceBlockhas been removed - useSystemAudioSourceBlockwithOSXAudioSourceSettings. It was a leftover second macOS audio capture block: it built the sameosxaudiosrc, but ignored the requested audio format and offered no volume or mute control, and nothing in the SDK, the demos or the documentation samples that actually ran ever created it -OSXAudioSourceSettings.CreateBlock(),DeviceEnumeratorand every macOS demo have built aSystemAudioSourceBlockfor years. Replacenew OSXAudioSourceBlock(settings)withnew SystemAudioSourceBlock(settings); the settings class, the device selection and the captured audio are unchanged. A pipeline JSON document saved with that block in it names a block type the SDK no longer has, so it is reported as unknown at validation and restores without its audio source - rebuild and re-save such a document (#1290). -
[Media Blocks SDK .Net] Fixed: on macOS and Mac Catalyst the audio format requested through
OSXAudioSourceSettings.Formatwas silently ignored. The capture device negotiated whatever it preferred - typically 32-bit float - so an application asking for 16-bit stereo got something else without any warning. The requested sample format, sample rate and channel count now reachosxaudiosrc.Formatno longer defaults to a hardcoded 16-bit 44100 Hz stereo, because that value is now enforced and no longer a placeholder: leave it null to let the device choose, or take a real one from the enumeration withAudioCaptureDeviceInfo.GetDefaultFormat(), which is whatCreateSourceSettings()already does (#1290). -
[Media Blocks SDK .Net] The Metal video processing blocks now work on an iOS device.
MetalVideoCompositorBlock,MetalConvertScaleBlock,MetalTransformBlock,MetalDeinterlaceBlock,MetalOverlayBlockandMetalVideoFilterBlockwere documented as available on iOS and compiled there, but the Metal plugin behind them was never loaded, so every one of them reportedIsAvailable()asfalseand could not be built into a pipeline. The plugin is now part of the iOS runtime, and it is the same current build the macOS and Mac Catalyst packages carry - soMetalVideoCompositorBlockalso composes onto an output of any size, rather than failing negotiation whenever something downstream asked for a size other than the size of its inputs. Two limits remain, both unchanged: the Metal renderer (MetalVideoRendererSettings) is macOS only, and the blocks are unavailable in the iOS Simulator, whereIsAvailable()still returnsfalse(#1296). -
[Media Blocks SDK .Net] Fixed: a pipeline document naming
VideoMixerSourcepassed validation and then failed to build, and the mixer's sources were never saved in the first place.MediaBlocksPipelineValidatorreported the block as constructible whileMediaBlocksPipelineMaterializerthrewMBS040: ... The method or operation is not implementedand discarded the whole pipeline, becauseVideoMixerSourceSettings.CreateBlock()was not implemented. It now builds the block, so a document restores it. The settings also persist their inputs: the sources, their rectangles and their chroma keys were held in a private list that was silently left out of every saved document and everyToDocument()snapshot, so a two-camera mixer came back as an empty canvas. They are now the publicVideoMixerSourceSettings.Sourceslist ofVideoMixerSourceStream, written and read with the source's own settings class named in the JSON; a source class this build does not contain - several are platform-specific - is reported rather than restored as an empty input. Capturing a live pipeline now also warns (MBS060) about any block the document cannot rebuild, instead of reporting the snapshot complete. API change:VideoMixerSourceBlocknow derives fromSuperMediaBlockrather thanSourceMediaBlock, which is what lets a block built fromVideoMixerSourceSettings.CreateBlock()wire itself up when you connect only its output - previously that produced a pipeline that stalled at start with no error. It keeps behaving as a source; the only members it no longer inherits areStop(), which did nothing, andIsSubtitlesAvailable(), which it still provides. Renamed arguments:VideoMixerSourceSettings.Add(source, left, top, width, height)never took a width and a height - the last two arguments went straight intoRect(left, top, right, bottom), soAdd(src, 960, 0, 960, 1080)produced a zero-width input, not a 960-wide one. The parameters are now namedrightandbottom. Behaviour is unchanged, so positional calls keep working; a call that passed the arguments by name (width:/height:) no longer compiles, and it was producing the rectangle the new names describe all along (#1230). -
[Core] The Windows GStreamer plugin cache is now kept per SDK version, and a rebuilt plugin of the same size is no longer ignored. On Windows the SDK mirrors an application's
x64/x86native folder into a shared folder under%PUBLIC%\.gstreamerand loads from there, so that every VisioForge application on the machine shares one warm GStreamer plugin registry instead of each paying a full cold scan. That folder was shared by every SDK version ever run on the machine and was only ever added to, so a native library a newer release no longer ships stayed on the load path indefinitely - an application could keep working on a machine that had run an older release and fail on a clean one. It is now%PUBLIC%\.gstreamer\<sdk-version>-<native-set>\<arch>, keyed to the SDK version together with a stamp of the core and Libav redistributables the application actually deployed, so deployments on different natives no longer overwrite each other's files on every start; a cache the SDK created and nothing has started for 30 days is removed, while a folder left by an older SDK that still uses the previous shared layout is left alone. Whether a cached file is up to date is decided by its size and its timestamp, rather than by size alone - a rebuilt library of the same size used to be kept forever. The first start after an SDK upgrade repopulates the cache and rebuilds the registry once.VisioForgeX.CacheFolderstill overrides the location: point it at the application's own native folder beforeInitSDKto skip the shared cache entirely and load exactly what the application deployed (#1289). -
[Core] Fixed: an ARM64 Windows application could not find the SDK's native libraries. The runtime looked for them in an
x64subfolder whatever the process architecture, while the ARM64 redistributable packages deploy toarm64, so initialization failed with "GStreamer libraries not found. Check the deployment and add required NuGet packages." x86, x64 and ARM64 processes now each use their own folder (#1289). -
[Media Blocks SDK .Net] Fixed:
AOMAV1EncoderSettingscan now create and configure the AOM AV1 encoder on macOS, Mac Catalyst, and Linux. The settings are applied for both Media Blocks pipelines and Video Capture / Video Edit output; the required AOM runtime is bundled for the Apple packages. Two defaults changed so that rate control actually works:MaxQuantizernow defaults to 63 - at its previous 0 the quantizer was pinned, the encoder ignoredTargetBitrate, the buffer sizes and the overshoot/undershoot values, and a 720p clip asked for 1500 kbits/sec was written at about 66 Mbits/sec - andTargetBitratenow defaults to 0, meaning the encoder scales its own default to the frame size (256 kbits/sec at 320x240, about 6900 kbits/sec at 1920x1080) instead of applying 256 kbits/sec at every resolution. Any value the encoder would refuse -CPUUsedoutside 0-9,DropFrame,OvershootPCTorUndershootPCTabove 100,TileColumnsorTileRowsabove 6, a resize or super-resolution denominator outside 8-16, a super-resolution threshold outside 1-63, aTargetBitrateabove 2000000 kbits/sec, a quantizer above 63 or a minimum above the maximum - is now left unapplied and reported as a warning rather than dropped in silence or failing the whole pipeline inside the encoder; a refused quantizer pair encodes at 0-63 rather than at the element's own 0, which would have disabled rate control.Threadsis now always resolved by the SDK: 0 and any value above the 64 threads the encoder accepts both become this machine's processor count, clamped to 1-64, because the encoder's own automatic count is not clamped and fails to initialize on a host wider than that.TileColumnsandTileRowsare log2 counts (0 = one, 1 = two, 2 = four), as the encoder takes them. AOM is intended for quality-focused offline encoding; prefer SVT-AV1 for general software encoding because it is substantially faster. On Windows, iOS and Android theav1encelement is still not part of the runtime, soAOMAV1EncoderSettings.IsAvailable()staysfalsethere (#1286). -
[Core] The OpenCV redistributable packages are rebuilt on OpenCV 4.14.0 and are much smaller.
VisioForge.CrossPlatform.OpenCV.Windows.x64and.x86shipped OpenCV 4.7.0 from February 2023 together with 42 OpenCV libraries the GStreamer OpenCV elements never load. They now carry OpenCV 4.14.0 and only the libraries those elements need, so the x86 package drops from 94 MB to 44 MB and the x64 package from 113 MB to 64 MB. Part of what the x86 package shed is a 26 MB 64-bitopencv_videoio_ffmpeg470_64.dllthat no 32-bit application could ever load. All 23 OpenCV elements are unchanged. The plugin now requires GStreamer 1.28 or newer - the version it is built against, and the version the matchingVisioForge.CrossPlatform.Core.Windows.*packages ship; it previously declared 1.22. An application that puts an older GStreamer ahead of the SDK's own onPATHwill find the plugin refused, and GStreamer reports that as a single warning, so the OpenCV elements would simply be missing (#1276). -
[Media Blocks SDK .Net] Fixed:
AV1EncoderBlockignored every SVT-AV1 setting, and several of them did nothing on the other engines too. In Media Blocks the encoder was built and then never configured, soPreset,TargetBitrate,MaxBitrate,CQP,CRFandIntraPeriodLengthwere all dropped and the encoder ran at its own defaults (preset 10, CRF 35). On every engine,Threads,Tier,TileColumnsandTileRowswere written to element propertiessvtav1encdoes not have, which GStreamer answers with a warning and no effect; they now reach the encoder the way SVT-AV1 takes them, andTileColumnsandTileRowsare log2 counts (0 = one, 1 = two, 2 = four) - up to 4 for columns, up to 6 for rows, and at most 128 tiles between them. Values above that are clamped rather than passed through: SVT-AV1 rejects such a configuration outright ("MaxTiles is 128 and MaxTileCols is 16") and the encoder can take the process down with it. Every other setting the encoder would refuse - aPresetoutside 0-13, a bitrate outside 1-100000 kbits/sec, aCQPorCRFoutside 1-63, anIntraPeriodLengthbelow -2 - is now left unapplied and reported as a warning instead of being dropped in silence, and so is any setting a different rate-control mode makes irrelevant. The encoder keeps its own working default in each case rather than being handed a value it cannot use.CQPnever took effect either, on any engine: the encoder picks its rate-control mode in the order bitrate, CRF, CQP, and CRF has a non-zero default, so a CQP-only configuration encoded in CRF mode - settingCQPnow disables CRF as it always claimed to. Behavior change: an application that set SVT-AV1 properties through Media Blocks and tuned around them being ignored will now get the encoder it asked for. (#835) -
[Media Blocks SDK .Net] Fixed: the default SVT-AV1 configuration produced a stream with no keyframes after the first.
IntraPeriodLengthdefaulted to-1, which this encoder reads as insert no further intra frames rather than automatic - so a recording was hard to seek, and a client joining an SRT or RIST stream mid-flight never received a keyframe and never rendered. The default is now-2, the encoder's own automatic setting; pass-1explicitly if a single-keyframe stream is what you want. This affected the VideoCaptureCoreX / VideoEditCoreX render path, where the value was applied; Media Blocks left the encoder at its own-2default because it applied nothing at all (#835). -
[Media Blocks SDK .Net] The SVT-AV1 encoder (
SVTAV1EncoderSettings) is now available on macOS and Mac Catalyst. Thesvtav1encelement and its library ship in the additional runtime package -VisioForge.CrossPlatform.Core.macOS.AddsandVisioForge.CrossPlatform.Core.macCatalyst.Adds- the same waygstsvtav1.dllhas always shipped in the Windows.Addspackages. Reference the.Addspackage for your platform beside the core one -VisioForge.CrossPlatform.Core.macOS.Adds2026.8.25 or newer,VisioForge.CrossPlatform.Core.macCatalyst.Adds2026.8.26 or newer; without itAV1EncoderBlock.IsAvailable(new SVTAV1EncoderSettings())returnsfalseand the rav1e encoder (RAV1EEncoderSettings) remains the software AV1 option. On iOS no AV1 encoder is available at all (#835). -
[Core] Fixed: AV1 files did not play on iOS. No AV1 decoder was registered at all, and GStreamer's FFmpeg wrapper deliberately does not provide one, so playback worked only on the chips whose VideoToolbox decodes AV1 (A17 Pro and later) and produced nothing anywhere else. The
dav1dsoftware decoder is now registered on iOS, so AV1 plays on every supported device; VideoToolbox is still preferred where the hardware has it. AV1 encoding remains unavailable on iOS - Apple ships no AV1 hardware encoder, and the software AV1 encoders are not part of the iOS redistributable, soSVTAV1EncoderSettingsandRAV1EEncoderSettingsreport unavailable there (#1287). -
[Core] Fixed: several Apple VideoToolbox encoder settings did nothing on iOS.
ForceHWUsagewas ignored,PreserveAlphawas not offered at all,AppleMediaHEVCProfile.Main10warned that it could not negotiate, andRateControl/DataRateLimitBitrate/DataRateLimitDurationwere dropped with a warning - all because the SDK still assumed the iOS runtime was the old GStreamer 1.24.9 build. iOS has shipped 1.28.6 for some time, so the HEVC alpha encoder (vtenc_h265a), 10-bit HEVC and the CBR/capped-ABR rate control now work there exactly as they do on macOS and Mac Catalyst.AppleMediaH264EncoderSettings.ForceHWUsage,AppleMediaHEVCEncoderSettings.ForceHWUsageandAppleMediaHEVCEncoderSettings.PreserveAlphaare now present in the iOS build;ForceHWUsagehas no effect there, because every VideoToolbox encoder on iOS is hardware and GStreamer registers no separate hardware-only element (#1287). -
[Core] Fixed: VP8 and VP9 were unavailable in the iOS Simulator. The
vpxplugin was registered only on a physical device, although the simulator framework contains it (#1287). -
[Core] Fixed: on Mac Catalyst no GStreamer log message ever reached the SDK. Every GStreamer debug line was routed to a static shim meant for iOS devices instead of to the SDK's own handler, so nothing appeared in the log context or in
Trace, and the DeckLink "Signal lost" notification - which is raised from that handler - never fired on this platform.Gst.GstDebug.RemoveLogFunctionalso always reported that it had removed nothing, so a host's own log handler installed throughGst.GstDebug.AddLogFunctioncould not be taken down again. Mac Catalyst now behaves exactly as macOS does: log messages are delivered to managed handlers and removing a handler works. Real iOS is unchanged (#1259). -
[Media Blocks SDK .Net] Fixed: an RTSP RAW or NDI source restored from a pipeline document validated clean, built clean and then refused to start.
StartAsyncreturnedfalsewith "Media info is not available" or "Unable to get NDISource info.", because a document carries a source's endpoint but never its media information, and those two sources pick their elements from it - the depayloader and parser for RTSP RAW, the converters for NDI on desktop.MediaBlocksPipeline.StartAsyncnow probes such a source once, before it builds the graph, so a restored pipeline starts the way a hand-built one does - as does one whose settings you construct with the public constructor and configure by hand.VideoCaptureCoreXandMediaPlayerCoreXbuild their graph through the synchronousStart, so an NDI or RTSP RAW source there still needsNDISourceSettings.CreateAsync/RTSPRAWSourceSettings.CreateAsync, as before. The endpoint has to be reachable at that moment, and a source that cannot be read is reported by name. The synchronousStarthas nowhere to await a probe and is unchanged - useRTSPRAWSourceSettings.CreateAsync/NDISourceSettings.CreateAsyncthere.NDISourceSettingsgains aReadInfoAsyncmethod for probing an existing instance. Behavior change:MediaBlocksPipeline.Connectnow returnsfalsewhen a block it would have to add is refused - it reported success and left the block out of the pipeline before, so the graph was built without it and nothing said so. That happens when the pipeline is not stopped: useAddBlockLive/ConnectLiveto change a running graph (#1229).
2026.8.29¶
-
[Core] Fixed: Mac Catalyst reported one placeholder audio device and never asked for camera or microphone permission.
AudioSources/AudioSourcesAsyncandAudioOutputs/AudioOutputsAsyncanswered every Catalyst caller with a single "Default" entry carrying no CoreAudio identity, the audio device monitors refused to start (soOnDeviceEnumerationCompletednever fired for them), and the permission request was skipped outright. All three are lifted: Catalyst now enumerates the real CoreAudio inputs and outputs, its audio monitors run, and camera and microphone access is requested the same way as on macOS. The behaviour was introduced against a deadlock that turned out to belong to a test host launched as a bare executable rather than to Mac Catalyst itself. Action required for Mac Catalyst apps: the bundle'sInfo.plistmust now declareNSCameraUsageDescriptionandNSMicrophoneUsageDescription- the system terminates a process that requests access without them, rather than denying it - and preferAudioSourcesAsync/AudioOutputsAsyncover the synchronous overloads there, since starting the CoreAudio device provider waits behind the permission prompt (#1242). -
[Media Blocks SDK .Net] Fixed: a pipeline that was stopped and disposed still held every block it contained, so memory grew with each pipeline an application built. Each block's input and output pads carry an end-of-stream probe whose callback is pinned for the life of the underlying GStreamer pad, and nothing released it - the pad, the block, its settings and its encoder or renderer element all stayed alive for the rest of the process. Disposing a pipeline now releases the pads of every block it owns, and a block disposed on its own releases its own; restarting a stopped pipeline is unaffected (#827).
-
[Core] New:
Gst.Contextis now part of the SDK, andElement.GetContexts()hands back real contexts instead of unusable list wrappers. The generated type had been left out of the build and, as generated, was unusable - a structure with no fields at all, so every one of its members was commented out because it would have handed GStreamer a one-byte buffer where a context pointer belongs. It now carries the native context handle and its members work: constructing a context from its type, reading the context type, the payload structure (read-only and writable) and the persistent and writable flags, testing the type, taking a writable copy withMakeWritable(), andRef/Unref.Gst.Element.SetContextis new, and theGst.Element.Contextsproperty is replaced by aGst.Element.GetContexts()method returningGst.Context[]- a breaking change against the previous release, where it wasGLib.List[]. It is a method because every call takes a reference on every context that is yours to give back: call it once into a local, release each context with its ownUnref(), and do not touch the array afterwards. That replaces the previously documented release step,Gst.Global.ContextReplace(ref handle). A struct has no finalizer, so release a long-lived context once, on the owning instance, sinceContextcopies share the handle; after that release, and on the empty valueGst.Context.Zero, its members throwObjectDisposedExceptionandInvalidOperationExceptionrather than handingNULLto GStreamer, andIsEmptyis the empty-state discriminator. In the same spirit, three calls that GStreamer would have answered with a log line and a plausible-looking result now say what is wrong:WritableStructure()throwsInvalidOperationExceptionon a context something else already holds a reference to (only an unshared context is writable, so write before setting it on an element, not after),Element.SetContextthrowsArgumentExceptionon an empty or released context instead of silently doing nothing, and a null context type is refused rather than turned into an empty context or a false type match. The struct also carries an internal released flag next to the handle, so passGst.Contextvalues to native code by theirhandlefield, not by marshaling the struct itself.Gst.Uri.Zeroand the newGst.Context.Zeroarestatic readonlyrather than plain static fields: now that both structs carry a handle, assigning to the shared empty value would have poisoned it process-wide, so code that wrote toGst.Uri.Zerono longer compiles.Gst.TocandGst.TocEntryhad the same field-less defect and are covered by their own entry below (#1257). -
[Core] New:
Gst.TocandGst.TocEntryare now part of the SDK, so chapters can be read from a file and written into one. Both generated types had been left out of the build and, as generated, were unusable - structures with no fields at all, so every member handed GStreamer a one-byte buffer where a table-of-contents pointer belongs. They now carry the native handle and their members work: building a table of contents and nesting entries under it, reading and writing entry tags (the chapter title lives there), start/stop times and loops, finding an entry by UID at any depth, andRef/Unref/Copy.Toc.GetEntries()andTocEntry.GetSubEntries()returnGst.TocEntry[]and replace theToc.Entries/TocEntry.SubEntriesproperties, which handed back raw handles. Everything a table of contents is actually reached through came back with them:Message.ParseToc/Message.NewToc,Event.ParseToc/Event.NewToc,DiscovererInfo.Toc,DiscovererStreamInfo.Toc, andTocSetterAdapter.GetToc()/SetToc()- so a TOC can be pulled off the pipeline bus or the discoverer and set on a muxer such asmatroskamux- chapters written into a Matroska file this way read back out of it with their titles and start/stop times, nested under the edition Matroska wraps them in. The table of contents on aGst.ITocSetteris aGetToc()/SetToc()pair rather than aTocproperty, because the two halves have opposite ownership: reading takes a reference that is yours to release, writing leaves the reference with you.Toc.AppendEntryandTocEntry.AppendSubEntrytake their argument byref: the call takes the entry's reference over, and passing by reference is what lets the binding mark the caller's value released so a laterUnref()cannot corrupt GStreamer's reference count. Values that come from a getter GStreamer does not transfer - the entries of a TOC, an entry's parent or sub-entries, a discoverer's TOC - are borrowed: they are readable and editable but refuseUnref(), andIsBorrowedreports which is which; takeRef()orCopy()to keep one past its owner. Calls GStreamer would have answered with a log line and a plausible-looking result now say what is wrong: writing tags to or appending an entry to something else already holds a reference to, appending an entry that already belongs to a table of contents, parsing a TOC out of a message or event that is not a TOC one, and null or out-of-range arguments are all refused with an exception. A struct has no finalizer, so release a long-lived value once, on the owning instance; after that release, and on the empty valuesGst.Toc.Zero/Gst.TocEntry.Zero, members throw rather than handingNULLto GStreamer, andIsEmptyis the empty-state discriminator - it is also how a missedFindEntryand a top-level entry's absent parent report themselves. As withGst.Context, pass these values to native code by theirhandlefield, not by marshaling the struct itself (#1257). -
[Core] Fixed:
GES.Global.ListAssets()could hand out freed assets and leaked a native list on every call. GES lends out the assets its cache owns and asks the caller to free only the list holding them, but the binding did the opposite - it kept the list and released every asset, spending the reference the cache still relies on. An asset could then be finalized while still registered, so a later request for the same asset returned freed memory. The assets are now left alone and the list is released (#1231). -
[Core] Fixed: overriding a gio or GES virtual method that returns a list could corrupt memory or crash.
FileEnumerator.OnNextFilesFinish, the fourResolverlookups, the threeVolumeMonitorcollections,GES.Container.OnUngroupand the GES track-element creation callback each built two native lists over the same result and released neither, referencing every element twice and then walking the already-freed list from the finalizer, which crashes the process. Every callback that returns a list now hands the caller exactly one, with the ownership its documented transfer mode calls for, and gives up its own claim on it - so a list an override built and still holds is no longer freed twice (Resolver.OnLookupRecords,OnLookupRecordsFinish,TlsDatabase.OnLookupCertificatesIssuedBy,OnLookupCertificatesIssuedByFinish).Resolver.OnLookupServiceandOnLookupServiceFinishadditionally threw on every call and could not be overridden at all; they now work (#1248, #1247). -
[Media Blocks SDK .Net] Windows: the bundled GStreamer runtime moves from 1.28.2 to 1.28.6, on x64, x86 and ARM64. 1.28.3 through 1.28.6 are bug-fix and security-fix releases - nvcodec, RTP/RTCP,
h264parse/h265parseduration handling, a compositor regression and HLS live seekable ranges among them - and Windows now matches the runtime macOS, Mac Catalyst and iOS already ship. The WASAPI capture buffer size restored in 2026.8.1 is unaffected: the patchedwasapi2src/wasapi2sinkwere rebuilt against 1.28.6 and re-measured, since the upstream defect is still present in this release. New elements, on x64 and x86:objectdetectionoverlayandsegmentationoverlayfor drawing detection and segmentation results,onvifmeta2relationmeta/relationmeta2onvifmetafor moving analytics metadata to and from ONVIF,burn-yoloxinferencefor YOLOX inference,demucsfor audio source separation,msesrc, the curl sinks and source (curlhttpsink,curlfilesink,curlftpsink,curlsmtpsink,curlhttpsrc), andoriginalbuffersave/originalbufferrestore.rsvgdecandrsvgoverlayreach x86, which did not have them; x64 already did. ARM64 gains no elements in this release and losesdvdreadsrcandrsndvdbin- upstream no longer builds the DVD plugins for that architecture. No bundled library changes file name on x64 or x86, so an incremental rebuild needs nothing special there. -
[Media Blocks SDK .Net] Windows ARM64:
VisioForge.CrossPlatform.Core.Windows.Adds.arm64is an add-on package now, not a second copy of the runtime. It used to mirror the whole GStreamer install, so installing it next toVisioForge.CrossPlatform.Core.Windows.arm64downloaded 55 MB twice and wrote every file into the output folder twice, with no way to tell which copy won. It now carries only the additional plugins and their private dependencies, exactly as the x64 and x86 Adds packages do, and declares a dependency on the ARM64 Core package - referencing the Adds package alone is enough, NuGet brings the Core package with it. Nothing is lost: the two packages together still ship every element ARM64 had before.rsvgdecandrsvgoverlayalso move from the x86 Adds package into the x86 Core package, so the SVG elements come from the same package on all three architectures (#1261). -
[Media Blocks SDK .Net] Windows ARM64: three x64 DLLs that could never load are no longer shipped in the ARM64 runtime.
libgcc_s_seh-1.dll,libstdc++-6.dllandlibwinpthread-1.dllcame straight from the upstream ARM64 GStreamer installer, which ships the x64 MinGW runtime under its ARM64 tree; nothing in the ARM64 packages referenced them. Removing them makes the package about 8 MB smaller to download (27 MB on disk) with no element lost (#1261). -
[Media Blocks SDK .Net] Windows x64 and x86: the unused MinGW C++ runtime is no longer shipped. The GStreamer build drops
libstdc++-6.dlland friends into an otherwise MSVC runtime, and on x64 nothing referenced any of them -libgcc_s_seh-1.dll,libstdc++-6.dllandlibwinpthread-1.dllare all gone, about 8 MB less to download (27.9 MB on disk). On x86 onlylibstdc++-6.dllgoes, about 7.5 MB less (23.9 MB on disk): the rest of that runtime is really used there, by the mp3 decoder. Every plugin still loads on both architectures - verified withgst-inspect-1.0against the package files alone, 192 plugins and none blacklisted (#1277). -
[Core] Fixed:
GLib.ListandGLib.SListleaked the string copies they allocate. Building a list from managed strings withelementsOwned: falseduplicated every string into glib memory and freed nothing on dispose, leaking each copy for the life of the process. The wrapper now releases the storage it allocated itself onDispose()/Empty(), while elements a native list lent it stay untouched - a list mixing borrowed and managed elements frees exactly what it allocated. A borrowed wrapper that released element storage refuses further use: reads and appends throwObjectDisposedExceptioninstead of touching freed memory, while an owned list survivesEmpty()as an empty list whose later string appends are released on the nextEmpty().Clone()of a string list frees its copies on the clone instead of the source (#1232). -
[Core] Fixed: six more list-returning GStreamer properties handed back unreadable elements and leaked.
VideoDecoder.Frames,VideoEncoder.Frames,Toc.Entries,TocEntry.SubEntries,Adapter.GetListandAdapter.TakeListall typed their elements as the list container itself, so every element was a wrapper over a pointer that is not a list node and read as garbage. Where GStreamer transfers ownership of the elements, disposing that array also released each of them as if it were a GObject - which GStreamer silently ignores, leaking a reference per element on every call. Each property now returns its real element type with the ownership GStreamer documents:Gst.Buffer[]for the twoAdaptermethods, which release themselves, and raw handles forVideoDecoder.Frames/VideoEncoder.Frames, whose element type cannot carry a native pointer. Note where GStreamer transfers ownership, the reference is now yours to release: each handle from those two with the newGst.Video.VideoCodecFrame.Unref(IntPtr). The two table-of-contents properties are covered by theGst.Tocentry above. The oldGLib.List[]signatures are removed. The element contexts carried the same defect and are covered by theGst.Element.GetContexts()entry above (#1240). -
[Core] Fixed: native text in GStreamer binding structures was decoded with the system ANSI codepage instead of UTF-8. Names, descriptions, hosts, credentials and addresses read through
ElementFactory.StaticPadTemplates,Gst.Video.VideoFormatInfo,Gst.Audio.AudioFormatInfo,Gst.FormatDefinition,Gst.PluginDesc,Gst.Rtp.RTPPayloadInfo, the RTSP (RTSPUrl,RTSPTransport,RTSPAuthParam,RTSPAuthCredential,RTSPAddress), SDP, WebRTC, gio and Pango structures all came back as mojibake on any Windows codepage that is not UTF-8. They now decode as UTF-8.ElementFactory.StaticPadTemplatesadditionally leaked a string copy on every access to a template'sGet()orCapsand handed GStreamer a re-encoded copy of its own text in place of the original; that leak is gone. Two consequences there, both breaking:Gst.StaticPadTemplate.NameTemplateandGst.StaticCaps.Stringare now read-only properties rather than settable fields (they carry the native pointer, and code that assigned one, took it byref/out, or reflected over it as a field will not compile), and comparing twoStaticPadTemplateorStaticCapsvalues now compares the native text identity rather than the decoded characters (#1240).
2026.8.28¶
-
[Core] Fixed: GStreamer wrapper members silently did nothing after
Dispose(). Calling any member of a disposedGst.Caps,Buffer,BufferList,TagList,Structure,Message,Event,Query,Sample,Memory,MiniObject,DateTime,Iterator,PromiseorDebugMessagehanded a NULL handle to GStreamer, which logged a silent critical and carried on — or returned a quiet default that looked like real data; the struct-field accessors (Buffer.Pts,Caps/Structurefield reads) read through a NULL pointer outright. Those members now throwObjectDisposedExceptionnaming the type, so the misuse surfaces at the call site.Dispose()stays idempotent, andHandle,Owned,EqualsandGetHashCodekeep working on a disposed wrapper, so release-once code and comparisons are unaffected. Also fixed here, the same defect in three places:new Gst.Sample(buffer, caps, segment, null),Message.AddRedirectEntry(location)— which threw on every call — andBuffer.ReplaceMemory/ReplaceAllMemory/ReplaceMemoryRangewith a null memory (the way to drop memory blocks without inserting a replacement) all threwNullReferenceException, because the optional argument was dereferenced before its own null check (#1241). -
[Core] Fixed:
Gst.GstDebug.GetAllCategories()returned unusable data. Its elements were typed asGLib.SListwhile GStreamer actually hands back debug categories, so reading an element produced garbage values or a crash, and a category's name and description were unreachable. The method now returnsGst.DebugCategory[]- a value-copy struct exposing the category name, description, color and current threshold, decoded as UTF-8. Two members that silently did nothing now throwNotSupportedExceptionand are marked[Obsolete]:DebugCategory.Free()(deprecated upstream no-op) andDebugCategory.ResetThreshold()(wrote into a temporary copy, never into the live category).DebugCategoryequality now compares the category's native identity plus the copy's threshold and color, instead of comparing decoded strings. The oldGLib.SList[]signature is removed (#1233). -
[Core] Fixed: starting or stopping audio on iOS could hang the app. The bundled iOS GStreamer held the audio ring-buffer lock across the CoreAudio start/stop calls that wait for the render callback to finish; the render callback takes the same lock. The start path was already fixed upstream for iOS 17+, and the same fix now covers the stop path and the pre-1.28 render-callback teardown (#1131).
- [Core] The iOS bundled GStreamer runtime moved from 1.24.9 to 1.28.6, matching macOS and macCatalyst. Brings the 1.26/1.28 plugin set to iOS (the reworked direct-rendering decode path,
io_proc_droppingaudio teardown, the VideoToolbox rate-control properties and the alpha encoder variant) and ends the divergence where iOS alone shipped a runtime without the deadlock fixes above. The Metal compositor plugin (vfmetalcompositor) is now part of the iOS framework. The official 1.28.6 iOS package no longer carriesfrei0r, and it replacesy4mdec/y4mencwith the singley4mplugin. - [Media Blocks SDK .Net] Fixed: stopping a capture session after a source error could crash the process. A microphone or other live source that failed during the session no longer access-violates on
StopAsync; a recording that was still producing video is still finalized (#825). - [Media Player SDK .Net] Fixed: switching audio on a multi-track file jumped the picture back to the first video track, and switching video silenced the playing audio.
Audio_Stream_Select/Video_Stream_SelectonMediaPlayerCoreXandSimplePlayerCoreXnow keep the streams they are not switching.SimplePlayerCoreX.Audio_Streams_Currentreports the active audio index instead of a hardcoded1(#1216). - [Core]
Gst.Urimembers now throw on a released or empty instance instead of failing silently. Reading a property, converting to a string or mutating aGst.Uriafter itsUnref()— or on the empty valueGst.Uri.Zero— used to handNULLto GStreamer, which logged a silent critical or quietly returned an empty result indistinguishable from a real one. These members now throwObjectDisposedExceptionafter release andInvalidOperationExceptionon the empty handle; managed comparison (Equals/GetHashCode), a repeatedUnref()andToString()on the empty value (it renders as an empty string) keep working. The newIsEmptyproperty is the parse-failure discriminator. Struct copies taken before the release still share the handle and stay unreusable after it — release once, on the owning instance. The struct also carries an internal released flag next to the handle, so passGst.Urivalues by theirhandlefield to native code, not by marshaling the struct itself (16 bytes on 64-bit) (#1236). - [Core] New:
Gst.Uriis now part of the SDK. The generated type had been left out of the build and, as generated, was unusable. It now carries the native URI handle and its members work: constructing from parts or parsing a string, reading scheme, host, path, fragment, the query table and the query keys, joining a reference against a base. The handles the constructors return own a reference and a struct has no finalizer, so release a long-lived one with itsUnref()method - once, on the owning instance, sinceUricopies share the handle. Also,GLib.PtrArray.Clone()on an elements-owned array whose element type is not a GObject now throwsArgumentExceptioninstead of silently sharing element storage that dies with the source (#1205). - [Core] Fixed:
GES.TrackElement.AllControlBindingsreturned garbage on every read. GStreamer hands back a hash table there, not a list, and the binding read the hash table's memory as a list. The property now returns the control-binding property names throughg_hash_table_get_keysand frees the temporary list it builds; the list marshaller refuses any non-list native return with a clear exception, and aNULLreturn still reads as an empty array (#1205). - [Core] Fixed:
Gst.GstDebug.GetAllCategories()leaked the native category list on every call. GStreamer hands back a copy of the process-static debug categories that the caller must free, but theGLib.SListwrapper discarded its ownership flags, so disposing the wrapper freed neither that list nor - on any otherSList-based API - the elements it claimed to own. The flags are now honoured: an owned SList frees its container and takes a reference per GObject element, a borrowed one releases nothing; ownership of element storage it cannot release (boxed handles, raw ints, value-type copies) is refused withArgumentException,Clone()on both list wrappers now owns and frees its copy instead of leaking it and enumerating through a lost element type - and copies the elements themselves, so a clone survives its source's disposal - and every read of a disposed wrapper throwsObjectDisposedExceptioninstead of reading freed memory (#1205).
2026.8.27¶
- [Core] Fixed: device enumeration could hang forever on Mac Catalyst.
AudioOutputsAsync,AudioSourcesAsyncand camera/microphone permission requests relied on CoreAudio/AVFoundation calls that never return in some macabi processes; the permission ask is now bounded — skipped with a warning only where the query is measured to never answer — and audio enumeration falls back to a safe single default device, so Catalyst apps no longer wedge on startup-time enumeration (#1150). - [Core] Fixed: macOS startup logged hundreds of GIO module-load failures and a duplicate OpenSSL TLS backend registration. SSL initialization now loads only the intended GIO TLS module, once, instead of treating every dylib in the app bundle as a GIO module (#1200).
- [Core] Fixed: reading
Video_Streams,Audio_StreamsorSubtitle_Streamswhile a stream switch was in progress could throwInvalidOperationException. The bus thread used to empty and refill those lists in place; a property read that landed in the middle of that update now sees a complete snapshot (#1219). - [Video Edit SDK .Net] Fixed: audio settings changed between two renders on one
VideoEditCoreXwere silently ignored by the second render.Output_AudioChannelsandOutput_AudioSampleRatewritten after a render had finished never reached the rebuilt timeline's audio track, so the next output kept the previous render's channel count and sample rate. The output settings are now applied to the tracks of the pipeline being started (#850). - [Video Edit SDK .Net] Fixed:
Input_AddVideoLayerandInput_AddTestClipthrewNullReferenceExceptionwhen used after a render had finished. Both now rebuild the timeline first, asInput_Clear_Listand the file inputs already did, so a second editing session on one instance works (#850). - [Video Edit SDK .Net] Fixed:
Debug_Modedid not enable the SDK's debug-level diagnostics. The engine configured a debug logger but left its context in non-debug mode, so debug entries were dropped before reaching the log file (#850). - [Video Edit SDK .Net] Fixed: memory grew across renders that use fade transitions. Each
FadeIn/FadeOuton a clip leaked a GStreamer control source per render, so a long editing session or a batch of renders accumulated them (#850). - [Core]
GLib.Listnow refuses to build an element-owning list it cannot honour instead of corrupting reference counts. PassingelementsOwned: truewhile appending wrapped objects used to store their borrowed handles and release them onDispose(), spending references the list never took; it now takes a reference of its own for a GObject element, and throwsArgumentExceptionfor an element it cannot reference at all - anOpaque, an element that does not match the declared element type, or a disposed wrapper (#839). - [Core] Fixed: switching audio or video streams leaked a small amount of native memory on every switch.
Audio_Stream_Select/Video_Stream_SelectonMediaPlayerCoreXandSimplePlayerCoreXbuilt the SELECT_STREAMS stream-id list without ownership flags, so its disposal freed neither the list nodes nor the copied stream-ID strings; the list is now built owned and freed after the event is sent. A stream with no ID is now rejected with a log entry andfalse, whereSimplePlayerCoreXused to throw on a null stream and both engines silently sent an event that changed nothing (#1208). - [Core] Fixed:
Gst.Event.ParseSelectStreamsleaked the returned list. The C builds a fresh list of copied stream IDs and hands the ownership over, but the binding wrapped it without ownership flags, so disposing the wrapper freed neither the list nodes nor the strings (#1208). - [Core] New:
DeviceEnumerator.OnDeviceEnumerationCompletedreports when the first enumeration of a device list has finished, so an application can start a device monitor without waiting for it and show its own "enumerating..." state while the list fills throughOnVideoSourceAdded/OnAudioSourceAdded/OnAudioSinkAdded.DeviceEnumerationCompletedEventArgsnames the list:VideoSources,AudioSourcesorAudioOutputs(#1108). - [Core] Starting a device monitor no longer reads the device list while holding a lock shared by every
DeviceEnumeratorin the process. The monitor now waits for GStreamer to report that its device providers are up - they start on their own thread from GStreamer 1.28 on - and reads the list afterwards, when that read no longer blocks. On macOS the wait covers the camera or microphone permission dialog, so a dialog left on screen no longer holds up unrelated enumerations for as long as it is up (#1108). - [Media Blocks SDK .Net] Fixed: a recording or streaming branch could stop reporting end-of-stream, and a source could hand out a video or audio pad that was already dead. Across the output blocks (MP4, MKV, AVI, WebM, FLV, WMV, MP3, M4A, FLAC, Ogg, YouTube, Facebook Live), the RTMP/RTSP/NDI/UDP sources, the demuxers, the audio and video effects blocks and the overlay managers, a GStreamer pad was released while the block that owned it was still using it. Nothing failed visibly at the time - the next call on that pad simply did nothing - so the symptoms were downstream: end-of-stream never firing, a recording left unfinalized, or a pad handed to an
OnVideoPadAdded/OnAudioPadAddedsubscriber going inert as soon as the handler returned (#850). - [Media Blocks SDK .Net] Fixed:
InterPipeSinkBlock.IsAvailable()andInterPipeSourceBlock.IsAvailable()could report that InterPipe was installed when only the unrelated proxy elements were present. The probes now check the actualinterpipesinkandinterpipesrcelements, so platform and deployment availability is reported accurately (#1193). - [Core] Reading a queue's fill level no longer enumerates the element's whole property list.
QueueBlock.CurrentLevelBuffers,CurrentLevelBytesandCurrentLevelTimeare meant to be polled per frame, and each read used to build a managed descriptor for every property the element declares; a poll of all three now allocates about a fifth of what it did. The same applies to any element property probed throughPipelineHelper.ElementHasProperty, which additionally reportsfalsefor an element that has already been released instead of answering from the base element type. - [Media Blocks SDK .Net] A live pipeline can now be saved as a JSON document.
MediaBlocksPipeline.ToDocument()captures the running graph - blocks, their identities and their connections - andToJson()/SaveJsonAsync(path)write it out; the capture is safe while the pipeline is playing, which makes it the save-during-Run path. A block that does not expose its settings contributes its position but not its configuration, and says so through a diagnostic rather than producing a document that would rebuild it on defaults - checkMediaBlocksPipelineSnapshotResult.Completebefore treating a capture as a faithful copy. - [Media Blocks SDK .Net] A relative file path named by a
*Locationsetting now resolves against the document base directory, which is what the HLS sink calls its segments, its playlist and its init segment. - [Core] Fixed: reading or animating a video mixer input that has no sink pad crashed instead of reporting no such input. A stream added to the mixer settings after the block was built never gets a pad of its own, and reading it back or starting a fade or move on it walked off the end of the pad list. Such a call now returns
null/ does nothing and reports it through the log, onVideoMixerBlockandGLVideoMixerBlockon every platform and on the D3D11 compositor on Windows; the Metal compositor on macOS and iOS already behaved this way and now logs it too. A fade or move whose input pad is released while it is running also stops cleanly instead of leaving the input part-way through the animation (#1191). - [Core] Fixed: constructing a
GLib.PtrArraythrewEntryPointNotFoundExceptionon Windows. The type declared itsg_ptr_array_*entry points against libgobject and itsg_object_unrefagainst libglib - exactly backwards - so the first call into the type failed on Windows, while Linux and macOS resolved the symbols through library dependencies by accident. Each import now names the library that actually owns its symbol (#1207). - [Core] Fixed: cloning a
GLib.PtrArraycrashed the process, and every clone leaked the native container.Clone()calledg_ptr_array_copythrough a one-argument declaration, while the native function takes three (array, copy function, user data) - the missing arguments arrived as garbage and were called as a function pointer. It now declares the real signature and passes NULL for a shallow copy, as the C API allows, the clone owns its copied container soDispose()actually frees it, and cloning a disposed array throwsObjectDisposedExceptioninstead of crashing later (#1207). - [Media Blocks SDK .Net] New:
VideoMixerBlock.RemoveInputPadLiveremoves an input that was added withAddInputPadLiveand hands the mixer's input back to it. A live-added input used to occupy a mixer input permanently - the only way to reclaim it was to tear the pipeline down. Removal is safe against a running graph: the input is stopped and unlinked first, then the mixer reclaims its pad. Only live-added inputs can be removed; the inputs configured at build stay index-aligned with the mixer's stream settings. Also fixed: the tee helper and the muxer sinks'ConnectVideo(MP4, MKV, AVI, MOV, WebM, OGG, FLV, MPEG-TS) kept a requested pad when a connection failed instead of handing it back (#1210). - [Media Blocks SDK .Net] Fixed: the video and audio effect blocks could not be restored from a pipeline JSON document.
VideoBalance,VideoResize,VideoCrop,VideoBox, the OpenGL effects, the audio effects and thirty-odd of their siblings all failed with "no construction path", because their settings class is named after the effect -ResizeVideoEffect,CropVideoEffect- rather than ending inSettings. The block catalog now also reads a block's ownSettingsproperty. Across its 387 blocks, and counting the correction below, the number a document can restore went from 314 to 329 and the number a caller holding only a descriptor can create from 216 to 288 -TextOverlay,ImageOverlay,VideoMixer,HLSSinkand the OpenCV filters among them. - [Media Blocks SDK .Net] Fixed: a crop or a video box restored from a document came back cropping nothing.
CropVideoEffectandBoxVideoEffectkept their four edges behind a private setter, so the margins were dropped in both directions of the serializer and the stage became a passthrough while reporting success. The edges are now settable. - [Media Blocks SDK .Net] Three blocks that took their whole configuration as a bare value gained a settings class:
FlipRotateSettings,WAVSinkSettingsandBarcodeDetectorSettings. A rotation, a WAV recording destination and a barcode detector mode can now be stored in a pipeline document and edited through the block catalog's property metadata. The existing constructors are unchanged. - [Media Blocks SDK .Net]
ResizeVideoEffect,CropVideoEffect,BoxVideoEffect,GLResizeVideoEffect,ImageOverlaySettingsandTextOverlaySettingsgained a public parameterless constructor, which is what JSON deserialization needs; the crop and the box default to a passthrough and the two resizes to 1920x1080. - [Media Blocks SDK .Net] Fixed: seven network sources could not be restored from a pipeline JSON document.
HTTPMJPEGSource,NDISource,NDISourceX,RTMPSource,RTSPRAWSource,SRTSourceandSRTRAWSourcepassed preflight validation and then failed halfway through materialization, because the only constructor on their settings class was private - an asyncCreateAsyncprobes the endpoint before handing one back. Each of those settings classes now has a public parameterless constructor for the persistence path;CreateAsyncis unchanged and remains the way to probe a reachable endpoint up front. A source built from a document does not contact its endpoint until the pipeline opens it. - [Media Blocks SDK .Net] Fixed: a document naming
SRTSourceorNDISourceXbuilt the wrong block.SRTSourceSettingsis shared by the decoding and the raw SRT source andNDISourceSettingsby the NDI and the Windows-only NDI X source, whileCreateBlock()on each names only one of the pair - so the other came up as its sibling, with different pads, and the document's own connections then failed to resolve. A settings class shared by two blocks now reaches its block through the block's own constructor. - [Media Blocks SDK .Net]
RTSPRAWSourceSettings.Uriand.AudioEnabledare now settable. Both were read-only outsideCreateAsync, so a document's endpoint and audio flag were dropped in both directions of the serializer and the source came up pointing nowhere while reporting success. - [Media Blocks SDK .Net] Fixed: nineteen block types built a different block than the one you asked for.
MediaBlockCatalog.Get(MediaBlockType.MP4Output).CreateBlock()returned anMP4SinkBlock- a bare muxer instead of the whole encode-and-mux stage - and so did a document naming one.PlayBinSourcecame back as aUniversalSourceBlock,SeparateOutputas aBridgeVideoSourceBlock,UniversalSourceMinias aUniversalSourceBlock,SRTSinkas anSRTMPEGTSSinkBlock. The cause: several blocks share one settings class, whoseCreateBlock()names only one of them, and the catalog called it for all of them. A shared settings class now reaches its block through the block's own constructor. - [Media Blocks SDK .Net] A block whose settings alone cannot build it is now refused up front instead of failing halfway through loading a document. Twenty-four block types name a settings class but also require a second one the document cannot carry - the
*Outputblocks want encoder settings,DecklinkVideoAudioSinka second sink settings,SeparateOutputa live pipeline. They reported themselves constructible, passed preflight validation, and then failed during materialization, which discards the whole pipeline over one entry. Preflight now reportsMBS032naming the block, andMediaBlockDescriptor.CanConstructanswers what the loader can actually do. - [Media Blocks SDK .Net] Fixed:
RTSPSource,RTSPRAWSourceandRTMPSourcethrewNullReferenceExceptioninstead of reporting an empty URL. The "URL is empty" check dereferenced the URI it was testing, so a source built without one crashed rather than logging and refusing to build. - [Media Blocks SDK .Net] Fixed:
AudioMixerwas configured through the wrong settings class. The block catalog bound it toAudioMixerSourceSettings, which needs a live pipeline and cannot be created at all, instead ofAudioMixerSettings- so the mixer offered the wrong properties to edit, a pipeline document could not carry its output format, andIgnoreInactivePadswas unreachable from a document. The catalog now prefers a constructor that can actually be called when a block has several. - [Demos] Media Blocks Studio: the Player and picture-in-picture scenarios now carry the effect stages they describe - colour balance, a mirror and an upscale on the player, a crop and a resize on the picture-in-picture camera branch.
2026.8.26¶
- [Demos] Media Blocks Studio: nine bundled scenarios that run offline. The startup screen shows nine curated pipelines - player and live effects, camera capture, screen+camera picture-in-picture, live mixer, transcoding, multi-output streaming, AI vision, audio lab and RTSP - each with a still captured from its own output, an outcome line, media tags and platform/requirement chips. Every scenario is an ordinary JSON document under
Assets/Scenariosthat the app reads at runtime, so the file you open, edit and save is the file the gallery runs. The baseline needs no camera, network or media file: five scenarios generate their own video and audio and three read a bundled clip. "Run Demo" opens the graph and starts it; two scenarios first ask for what the bundle cannot carry - an RTSP endpoint and a path to an ONNX detection model. - [Demos] Fixed: the Media Blocks Studio editor came up empty. Opening a pipeline showed the toolbar over a blank area with no canvas, block catalog, inspector or panels, and the block catalog reported no blocks at all. The application did not include the Dock and Nodify control themes, presented its panels with the wrong data, and never initialized the SDK. Connections between blocks are now drawn as well: a node was previously built with one input and one output regardless of the block, so anything wired to an indexed pad - a mixer input, a source's audio output - was dropped silently.
- [Media Blocks SDK .Net] Fixed: several blocks could not be restored from a pipeline JSON document.
RTSPSource,VideoMixerandTeeentries failed to materialize, andVolumeandEqualizer10could not carry their gain, mute or band values at all, because those settings types had no constructor the persistence layer could call and, for the two audio blocks, no settings type at all.VolumeSettingsandEqualizer10Settingsare new;RTSPSourceSettingsandVideoMixerBaseSettingsgained a public parameterless constructor;TeeBlockgained constructor defaults. Settings whose only constructor takes all-optional parameters -VirtualAudioSourceamong them - are now accepted too. - [Media Blocks SDK .Net] A relative file path in a pipeline document now resolves against the document base directory even when the setting is a URI, which is the shape
UniversalSourceSettingsuses, so a document can reference an asset shipped beside it. - [Media Blocks SDK .Net] Preflight validation now reports an input asset that does not exist - a detection or OCR model path, or a local file URI - as an error instead of letting the pipeline materialize into a stage that silently does nothing. A sink filename is an output and is still not required to exist.
- [Core] Fixed:
ElementX.ReadProperties()returned structure-typed element properties (for examplertspsrcsdes) whose native memory was already freed, so reading such an entry afterwards could crash or return garbage. Boxed values are now kept as a deep copy (#1184). - [Core] Fixed:
ElementX.ReadProperties()aborted with an exception on elements holding properties without a managed representation (for examplegltransformation) instead of skipping them; unreadable properties are now skipped, and calling the method again refreshes existing entries instead of failing (#1184). - [Core] Fixed:
ElementX.ReadProperties()raised a GLib critical for every write-only element property (for exampleplaybinsubtitle-font-desc) by trying to read a value such a property cannot have. Those properties are still listed, with anullvalue, and are no longer read (#1184). - [Demos] Media Blocks Studio: generated Inspector, Help, runtime controls and crash recovery. The editor now generates the Inspector form from each block's descriptor property metadata (typed parsing with min/max clamping; live-safe properties apply to the running pipeline without a rebuild) and a Help card from the block descriptor. The workspace gained Run/Pause/Resume/Stop over
MediaBlocksPipelineMaterializerwith error/stop event logging, position polling, structured diagnostics navigation and a single-slot live video preview. Pipelines autosave to %AppData% on a 10 s debounce with a restore prompt on the next start, and unsaved changes are confirmed before New/Open/close. - [Media Blocks SDK .Net] Local file sources are now JSON-serializable.
UniversalSourceSettingsandDemuxerSourceSettingshad only a private constructor and private setters for their file/URI properties, so a pipeline document carrying a local file could not be loaded or materialized. Both now expose a public constructor and settable URI/Filename/render flags, so file-based pipelines round-trip through the versioned JSON document format. - [Core] Fixed: the LUT (color lookup table) video effect silently did nothing on Intel Macs. The native processor library shipped in the macOS and Mac Catalyst packages was built for Apple Silicon only, so on an x86_64 Mac it could not be loaded at all and every LUT-based effect was a no-op. The library is now a universal x86_64+arm64 binary (#1101).
- [Core] Fixed: calling
VProcessor.UpdateFilterParametersthrewEntryPointNotFoundExceptionon macOS/macCatalyst. The shipped native library predated the managed wrapper and did not export the entry point; it now does (#1157). - [Core] The GStreamer log callback no longer claims ownership of logged objects. The SDK's log handler built a managed wrapper around the subject object of every log line GStreamer emitted, including plugin-internal GObjects the SDK never created; for an object that logs while still floating (any
GstObjectlogging before its owner sinks it) the wrapper adopted the floating reference, so the owner's later unref finalized the object while the binding still held a toggle reference on it — surfacing as[VisioForge-Lifetime] toggle ref outlived its objectand, in Release, as a use-after-free risk whenever debug logging was enabled (#1165). Handlers registered throughGst.LogFunctionnow receive_object = nullunless a managed wrapper for the logged object already exists. - [Core] Fixed: custom GStreamer log handlers could never be detached on desktop platforms.
Gst.GstDebug.RemoveLogFunctioncompared against a freshly built native function pointer instead of the one recorded at registration time and therefore matched nothing; every handler stayed installed for the life of the process. Removal now unregisters by the handle captured when the handler was added — the same scheme already used on Unity. As a consequence, removing without an argument detaches only the handlers this assembly registered rather than every log function in the process, so third-party and default GStreamer logging survives SDK teardown (#1165). - [Core] Fixed: native memory grew steadily while reading GStreamer element properties. Long-running pipelines leaked a small native allocation on every property read:
QueueBlocklevel properties (CurrentLevelBuffers/CurrentLevelBytes/CurrentLevelTime, typically polled per frame), video mixer and compositor input reads, OpenGL shader and 360-view settings updates (a whole structure copy per update, so dragging a slider accumulated allocations for the process lifetime), file sink filename reads, and the volume/mute getters of the system and PulseAudio audio sources and of the audio renderer (#1185). - [Core] Fixed:
InterPipeSinkBlock.GetNumListeners()always returned 0, whatever the number of connected InterPipe sources (#1185). - [Core] Fixed a slow native memory leak in device enumeration: every probed device property leaked one boxed GValue per enumeration pass (#1174).
- [Core] Fixed: one audio device losing a property-probe race (device removed mid-enumeration) aborted the whole output-enumeration pass, hiding every device enumerated after it; the pass now continues, with the failure contained to that single entry.
2026.8.25¶
- [Demos] New: Media Blocks Studio, the cross-platform Avalonia showcase and pipeline editor for Media Blocks SDK. The first stage ships the application shell under
_DEMOS/Media Blocks SDK/Avalonia/Media Blocks Studio(Windowsnet10.0-windows, macOSnet10.0-macos, Linuxnet10.0): a dark broadcast-style startup gallery with New/Open/Recent projects, an IDE-style workspace built on Nodify.Avalonia 2.0.0 (infinite node canvas with pan, zoom, selection and connection dragging) and Dock.Avalonia 12.0.0.2 (catalog on the left, Inspector/Help tabs on the right, Preview/Metrics/Diagnostics/Logs docked at the bottom). The searchable block list reads the SDK's read-only block catalog directly; pipelines are created, edited, validated againstMediaBlocksPipelineValidator, saved to and loaded from the versioned JSON document format with undo/redo. - [Media Blocks SDK .Net] New: document-to-live materialization and preflight validation. A pipeline JSON document can now be turned into a running-ready
MediaBlocksPipeline:MediaBlocksPipelineMaterializer.Materializebuilds every block through the block catalog, binds settings from their JSON payloads (including all-optional-parameter constructors), resolves host resources throughIMediaBlockResourceResolver, restores connections using the documentedinput/output/input:N/output:Npad id convention, and returns a document-block-id to live-block mapping with full diagnostics. Blocks that cannot be created - unknown type, missing factory, unavailable on this platform - stay in the document as placeholders with an error diagnostic; they never discard the rest of the pipeline.MediaBlocksPipelineValidator.Validateperforms the complete preflight check: structure, known blocks, construction paths, availability probes, pad reference shape, resource resolver presence and unsupported feedback cycles; errors block materialization and run, warnings do not. Relative file paths inside settings resolve against the document directory when one is given (baseDirectory). New convenience:MediaBlocksPipeline.LoadJsonAsyncreplaces the contents of a stopped pipeline from JSON in one call. - [Media Blocks SDK .Net] Metal-accelerated video elements are now available on Intel Macs. The
vfmetal*plugin shipped in the macOS and Mac Catalyst runtime packages was built for Apple Silicon only, so on an Intel Mac it could not be loaded at all and every element it provides - the Metal compositor, video sink, filter, converter/scaler, transform, deinterlacer and overlay - was simply absent from the GStreamer registry. It is now a universal x86_64+arm64 binary (#1101). - [Video Capture SDK .Net] Fixed: video frames could silently stop flowing after live video effects were removed or cleared during capture (
Video_Effects_Removeby instance or name, andVideo_Effects_Clear). The pause issued before the filters are unplugged and the resume after are asynchronous GStreamer state changes, but the resume was not waited out - a PAUSED to PLAYING transition that never completes stops frames with no error raised anywhere. Both operations now wait (bounded) for the resume to settle and report throughOnErrorif the pipeline fails to return to the playing state (#1152). Behavior change: removing or clearing effects while capture is paused no longer resumes playback - a deliberate pause is preserved, matching what live effect addition has always done. - [Media Blocks SDK .Net] Fixed: stopping an SRT pipeline could hang
StopAsyncforever on macOS when the peer was unreachable or kept dropping the connection, and a test or app that gave up mid-stream could then die with a SIGSEGV at process exit. The native SRT sink captures the auto-reconnect setting once per write/read call, so turning reconnect off while the streaming thread was already inside its reconnect loop did not end the loop - EOS could never reach the sink and teardown blocked indefinitely. Both SRT sink blocks now receive an early stop signal (RequestStop) that disables auto-reconnect before EOS, and the macOS native package'slibgstsrt.dylibhonors a mid-flight reconnect switch-off instead of reopening forever (#879). - [Media Blocks SDK .Net] Fixed: the raw
MPEGTSSinkBlock→SRTSinkBlockpath published streams that carried bytes but no playable video. The muxer emitted one buffer per 188-byte TS packet and the SRT sink sent each as its own SRT message - seven times the message rate for the same payload, which starved video on the transport. The muxer output is now aligned to 7 TS packets (1316 bytes) per buffer, matching what the combined SRT MPEG-TS sink has always done. The alignment applies to every rawMPEGTSSinkBlockoutput, including default.tsfile recordings; the multiplexed stream itself is unchanged and stays spec-legal (#879). - [Media Blocks SDK .Net] Fixed: MPEG-1 video produced no video output through
UniversalDemuxDecoderBlock(and could not decode throughUniversalSourceBlockV2in the rare no-parser path). The by-name decoder selectors asked for an element gst-libav never registers - it builds decoder names at runtime and explicitly skipsmpeg1video, soavdec_mpeg1videodoes not exist and element creation failed silently, dropping the video stream. MPEG-1 is now handed toavdec_mpeg2video, which decodes both generations. MPEG audio Layer 1 and Layer 2 hit the same defect family:UniversalSourceBlockV2routed them toavdec_mp2andUniversalDecoderBlock's Layer 1/2 ladders listed only names gst-libav does not register (mp1/mp2are in its audio skip list), so that audio silently got no decoder; both now decode throughavdec_mp3, which handles every MPEG audio layer (#1132). - [Media Blocks SDK .Net] Fixed: a live element could be stopped while a buffer was still passing through it, which could freeze the pipeline. Updating
GLShaderBlocksettings on a running pipeline, and removing anAudioMixerBlockinput from one, both blocked the surrounding pads and then took the element to the NULL state - but installing a pad block does not wait for a streaming thread already inside it to leave, and stopping an element under that thread deadlocks against it. Both paths now wait for the element to be out of the data flow first, and report a failure instead of stopping it if that wait does not complete (#1143). Breaking:GLShaderBlock.Update()returnsboolinstead ofvoid, so a caller can see when the new shader did not go live - which is what a paused pipeline gives back, since a sink holding a buffer in preroll keeps a streaming thread inside the chain. Push the settings again after resuming. - [Core] macOS: audio capture/render devices are selected by their stable CoreAudio unique ID, not by the numeric device ID. The numeric AudioDeviceID CoreAudio assigns is reassigned on replug, on other devices being added, and across reboots, so a saved configuration could silently open a different device.
AudioCaptureDeviceInfoandAudioOutputDeviceInfonow publish the provider's stableUniqueID(plusIsDefault), andOSXAudioSourceSettings/OSXAudioSinkSettingsaccept it; the pipeline prefers the unique ID and falls back to the recorded numeric ID for configurations saved before this change. A saved unique ID that no longer exists now fails the pipeline start with a diagnostic instead of opening whatever sits at the old numeric ID (#1106). -
[Core] Fixed: selecting a specific macOS audio input device through
DeviceEnumeratornever worked - the enumeratedAudioCaptureDeviceInfo.DeviceIDwas never populated and stayed 0, so every capture built from a picked device opened the default input instead (#1106). -
[Media Blocks SDK .Net] New: a public block catalog.
MediaBlockCatalogenumerates every built-in Media Block the loaded SDK assemblies carry - over 400 blocks across VisioForge.Core and the AI/OpenGL satellites - with one descriptor per block: stable type, concrete and settings CLR types, human-readable name, visual category, keywords for search, an availability probe (wired to each block's ownIsAvailable()), factory support, and property metadata generated from the settings type (display name, default value, editor kind, enum values). Blocks whose settings are built by factories rather than edited as POCOs - device sources, demuxers created through asyncCreatemethods - are classified as runtime-configured instead of pretending to have an editable surface. New types:MediaBlockCatalog,MediaBlockDescriptor,MediaBlockPropertyDescriptor,MediaBlockAvailabilityResult,IMediaBlockResourceResolver. - [Media Blocks SDK .Net] Settings JSON now survives round trips for media value objects.
VideoFrameRateis persisted as its num/den pair,Sizeas width/height, and colors (SKColor) as RGBA bytes; previously these either could not be deserialized at all or came back zeroed. Read-only computed members of settings objects no longer enter the payload at all - they cannot be read back and silently corrupted document round trips. The DVB source's native tuning handle is excluded from serialization like every other native pointer. - [Media Blocks SDK .Net] MAUI:
VideoViewXgainsSetIPhotographyandSetCamera2Controlson Android, matching the Uno and Avalonia video views. They forward to the native view, so camera photography controls can be configured on the MAUI control itself; outside Android the methods do not exist (#311). - [Media Blocks SDK .Net] Fixed: the built-in RTSP server could fail to start with a Media Foundation H264 or HEVC encoder selected. The pipeline string for the RTSP media factory carried every MF encoder property unconditionally, but GStreamer installs those properties only when the Media Foundation transform advertises them - on a host where the MFT exposes less,
gst_parse_launchrejected the whole string (no property "qp" in element "mfh264enc") and the server never came up. The launch string now carries the element name and bitrate only, and the remaining settings are applied to the real element after the factory builds the pipeline, skipping any property the MFT does not advertise (#858). - [Media Blocks SDK .Net] Breaking: the unused
MPEG2VideoEncoderSettings.Profileproperty and theMPEG2VideoEncoderProfileenum have been removed. The FFmpeg MPEG-2 encoder these settings drive (avenc_mpeg2video) cannot apply an MPEG-2 profile or level at all - gst-libav deliberately skips the codec's profile/level options when exposing element properties and never maps them from caps either - so the property silently did nothing and every stream was written with the libav defaults (Main profile). Verified against GStreamer 1.28.2; a regression test now pins the stream profile the encoder actually produces (#259). -
[Media Blocks SDK .Net] Breaking: four more dead
MPEG2VideoEncoderSettingsproperties removed -ForceDuplicatedMatrix,IntraQuantBias,InterQuantBiasandMPEGQuant. None of them exists as a property onavenc_mpeg2video, so every pipeline logged a GLib critical per property and silently ignored the value; no caller could have observed any effect. Also fixedFrameSkipComparebeing rejected at runtime with a type-mismatch critical - the value is boxed as an integer now, like every other enum setting on this encoder. -
[Core] Mac Catalyst builds no longer silently lose macOS behaviour behind
#if !__IOS__guards. The__IOS__define is set fornet10.0-maccatalysttoo, so code guarded only against iOS was compiled out of every Catalyst build with no warning: the video overlay sink never hadforce-aspect-ratioset, opening or playing media could switch audio off while additional audio streams or audio processing blocks were queued, afile://URI passed toAudio_AdditionalStreams_AddAsyncfailed where a plain path worked, and the Video FingerPrinting log context stayed unwired so its diagnostics fell back to raw trace output instead of the SDK logger. All twenty-two affected sites now use the guard shape the rest of the SDK already used, which lets Mac Catalyst through wherever macOS is let through (#1141). - [Core] Blu-ray and DVB source types are declared on Mac Catalyst, matching the macOS API surface. Blu-ray playback needs only playbin, tsdemux and h264parse, all of which ship in the macCatalyst GStreamer runtime, so
BluRaySourceSettingsandBluRaySourceBlockwork there exactly as they do on macOS.dvbsrcships in neither Apple desktop runtime, so the DVB types now exist for API parity alone and their availability check reports false at runtime - the same answer macOS gives (#1141). - [Core]
Pango.CoreTextFontis now declared on Mac Catalyst, matching the macOS API surface. The file was hidden behind a bare#if !__IOS__, which compiles out of Catalyst as well because__IOS__is defined for it too (#1142); its DllImport now names the library that actually exports the symbol on the Apple builds (libpangocairo, notlibpango). - [Media Blocks SDK .Net] The unused public type
RemoveSilenceSettingshas been removed. No API in the SDK ever accepted it, so code holding an instance could not pass it anywhere; silence removal is configured throughRemoveSilenceAudioEffect(forAudioEffectsBlock/MediaPlayerCoreX) or directly onRemoveSilenceBlock, which expose the sameThresholdandSquashproperties (#1117). - [Media Blocks SDK .Net] New: versioned JSON persistence for pipelines and blocks. A pipeline can now be saved to and restored from a human-readable
.jsondocument that carries the pipeline settings, every block with its settings, the connections between blocks, and an optional opaque editor section. The integerMediaBlockTypevalue is the authoritative discriminator, so a document restores to exactly the blocks it was written with; unknown properties, unknown sections and blocks this SDK does not know about are preserved without loss, so newer files still load on older SDKs. New public API:MediaBlocksPipelineDocument,MediaBlockDocument,MediaBlocksPipelineJsonSerializer,MediaBlockJsonSerializer,MediaBlocksDiagnostic, and a schema-migration registry (IMediaBlocksPipelineDocumentMigration) for future format versions. Materializing a document into a live pipeline arrives in the next stage. - [Media Blocks SDK .Net] Every
MediaBlockTypemember now carries an explicit integer value, identical on every platform and build flavor. The values were previously implicit except for a few anchors, which made them differ between Windows and non-Windows builds around the platform-gated members - any integer-serialized block type crossing a flavor boundary was ambiguous. The numbering follows the existing Windows order, so existing explicit pins (251, 277, 400+) are unchanged. Two members that silently carried duplicate numbers move to fresh unique ones:UDPRAWMPEGTSSourcefrom 400 (collided withONNXInference) to 443, andWebView2Sourcefrom 401 on Windows (collided withYOLOObjectDetector) to 444 - the old numbers were ambiguous by construction, so no working code can have relied on them. - [Media Blocks SDK .Net] Blocks that shared a
MediaBlockTypevalue now have their own:UniversalAutoDemux,UniversalSourceMini,FallbackSwitchSource,ImageOverlayCairo,FrameDoubler,CustomColorspaceX,SqueezebackBlockV2,PreEventSeparateOutput,TextOverlaySource,ImageVideoSourceCairo,UniversalTransform,UniversalDecoder,UniversalDemuxDecoder,AppBridgeAudioSink/Source/VideoSink/VideoSource,StreamSourceWithDecoderandLiveSourceSwitchDynamic(424-442). The primary class of each pair keeps the historical value; the variants listed here are new members appended at the end, so nothing is renumbered. Affected classes:UniversalAutoDemuxerBlock,UniversalSourceBlockMini,FallbackSwitchSourceBlock,ImageOverlayCairoBlock,FrameDoublerBlock,CustomColorspaceXBlock,SqueezebackBlockV2,PreEventSeparateOutputBlock,TextOverlaySourceBlock,ImageVideoSourceCairoBlock, theAppBridge*Blockquartet,StreamSourceBlockWithDecoder,LiveSourceSwitchBlockDynamic, andIOSVideoSourceBlock, which now correctly reports the existingIOSVideoSourceinstead ofSystemVideoSource. Code that switched on these types may need the new members added to its cases. - [Media Blocks SDK .Net] Breaking: the unfinished YAML persistence API is removed.
YAMLBlock, the commented-outYAMLConfig,IMediaBlock.ToYAMLBlock()andMediaBlock.ToYAMLBlock()are gone; none of them ever produced output (ToYAMLBlockthrewNotImplementedException). JSON is the only supported Media Blocks persistence format. - [Media Blocks SDK .Net] macOS and Mac Catalyst: the Metal video renderer no longer hangs a process that has no window, and the Metal elements are no longer picked automatically. Two defects in the bundled
vfmetalplugin, both of which a customer could reach without ever naming a Metal element.vfmetalvideosinkcreated its own window through a blocking call onto the main thread; in a process whose main thread is not running a Cocoa event loop - a console tool, a service, a test host - that call never returned and the pipeline sat in preroll forever, with nothing on the bus to say why. Worse, the same call could deadlock an ordinary windowed application: an app that starts a pipeline and then waits for it on its UI thread was blocking the very thread the sink needed. The sink no longer waits at all - it asks for the window and drops frames until it appears, which lets the pipeline preroll and frees the UI thread to create it. The first frame is kept rather than discarded, so a pipeline that is only paused - a preview, a scrub, a thumbnail - still shows its picture the moment the window appears. If fifteen seconds pass with no window the pipeline reports an error saying whether a window handle was missing or simply never acted on, and a pipeline that finishes without ever displaying anything says so on the bus when it stops.vfmetalcompositorandvfmetalvideosinkalso registered at ranks high enough to be auto-selected, so the Metal compositor silently became the mixer inside everyVideoEditCoreXtimeline and the Metal sink was whatautovideosinkchose; both now register at rank none, like the other five Metal elements, and are used only when you ask for them by name. Separately,MetalVideoCompositorBlockfailed negotiation whenever anything downstream asked for an output size other than the size of its inputs; it now accepts the requested size and composes onto a canvas of that size, as the software compositor does - each input still sits where its pad properties put it rather than being stretched to fill. The plugin is also rebuilt against the 1.28.6 runtime the rest of the package ships (#878). - [Media Blocks SDK .Net] macOS: three further fixes in the Metal video renderer, found while fixing the above. Resizing the video window could briefly show the picture offset or stretched: the frame's position was computed against the new window size while the picture itself was still being drawn at the old one. A second defect could crash the process during teardown - the thread delivering frames read the render view at the moment the window was being closed, and could be left holding memory that had just been released. And
IVideoView-style re-parenting now works: handing the renderer a second, different window used to be ignored silently, so it kept drawing into the first one; it now detaches and attaches to the new one (#878). - [Media Blocks SDK .Net] GStreamer pipelines and reported codecs are built identically on every system locale. Six places wrote or compared locale-sensitive text where GStreamer only ever accepts invariant text. The Apple H.264 encoder writes its
qualityparameter into the pipeline string - fractional 0.5 by default, so with no property ever set - and on every comma-decimal locale (German, Russian, French and most of continental Europe) it producedquality=0,5, which the parser rejects: an RTSP server built on those settings handed every connecting client an error instead of a stream. The MP3 encoder had the same defect in its VBR quality parameter, reachable by selecting the Quality rate control with a fractional quality such as 2.5; the NVIDIA H.264 and HEVC encoders in theirconst-qualityparameter, reachable with any fractional quality value; and the VP8/VP9 encoders in their three buffer-size parameters - the element takes whole milliseconds there, so on those locales the comma form broke every duration, and a sub-millisecond duration is now truncated to the whole millisecond instead of being written as an unparsable fraction. And under the Turkish and Azerbaijani casing rules a codec name reported by stream discovery came back asVİDEO/H264instead ofH264- silently, with no error anywhere. gst-launch strings and codec identifiers are invariant by construction and are now written as such, on every platform (#1133). - [Media Blocks SDK .Net] macOS and Mac Catalyst: a new AAC encoder,
AppleAACEncoderSettings, backed by the AudioToolbox encoder built into the operating system. It is the same encoder the rest of macOS produces AAC with, it handles up to 8 channels where the existing AAC backends stop at six, and it offers four rate control modes including true VBR - setRateControltoVariableand drive the rate withVBRQualityinstead ofBitrate, which the two variable modes ignore. It appears in every output'sGetAudioEncoders()list as "Apple AAC". It is not the default, and that was a measurement rather than a preference: against a lossless source on Apple Silicon the two encoders trade places with the bitrate - behindavenc_aacat 96 kbps, level at 128 kbps, ahead at 192 kbps - while their CPU cost is indistinguishable, since AAC encoding runs well over a hundred times faster than realtime either way.AVENCAACEncoderSettingstherefore stays the default and nothing changes unless you select the new one. Not available on iOS: the GStreamer runtime shipped for iOS does not carry the element yet, so checkAppleAACEncoderSettings.IsAvailable()rather than the platform (#1110). - [Media Blocks SDK .Net] DV and DVCPRO files no longer fail to open at random with "Cannot access memory for read and write operation". Roughly one attempt in twenty - measured 1 in 30 on macOS - the file never reached PLAYING and the pipeline reported that error from
avdec_dvvideo. The libav decoder in GStreamer 1.28 can decode straight into the video renderer's own buffer pool, but it describes the frame with its own, more strongly aligned layout - for 720x480 DV that puts the second colour plane 768 bytes past what the renderer allocated - and reading the frame back then fails. This is not macOS-specific and the change is not platform-gated: the defect is in the runtime both platforms now ship (1.28.6 on macOS, 1.28.2 on Windows); macOS is simply where it was measured. The libav video decoders that take that path now decode into their own memory and copy the finished frame out. That is every libav decoder except H.264, H.265 and H.266, so expect one extra frame copy per frame wherever anavdec_decoder handles DV, DVCPRO, MPEG-1/2, MPEG-4, DivX/Xvid, WMV, MS-MPEG4 or ProRes - formats that are software-decoded anyway. Hardware decoders and every non-libav element are unchanged. The fix reaches both the blocks that pick a decoder by name -UniversalSourceBlockV2,UniversalDecoderBlock,UniversalDemuxDecoderBlock- and the decodersdecodebin,uridecodebin,playbinand GES build for themselves insideMediaBlocksPipeline,VideoEditCoreXandSimplePlayerCoreX. A pipeline you assemble yourself out of raw GStreamer elements is not covered, and neither is the internal media-info discovery graph, which cannot hit this (#1121). - [Media Blocks SDK .Net] New:
AppleMediaHEVCEncoderSettings- HEVC encoding through Apple VideoToolbox, including 10-bit and an alpha channel. There was no VideoToolbox HEVC encoder in the SDK at all, so on a MacHEVCEncoderBlock.GetDefaultSettings()found no hardware encoder and HEVC output was unavailable. It now returns this one.Profileselects Main or Main 10 (10-bit), andPreserveAlphaswitches to the alpha-capable encoder; both need the GStreamer 1.28.6 runtime, which ships in the macOS and Mac Catalyst packages - the iOS package still bundles 1.24.9, where neither is available. - [Media Blocks SDK .Net] New: constant-bitrate rate control on the VideoToolbox encoders.
AppleMediaH264EncoderSettingsandAppleMediaHEVCEncoderSettingsgainRateControl(ABR, the default, orCBR) plusDataRateLimitBitrate/DataRateLimitDuration, a bitrate ceiling averaged over a sliding window - what a fixed-bandwidth endpoint needs on top of a target bitrate. The two are alternatives, not complements: withCBRselected VideoToolbox ignores the data rate limits outright, because constant bitrate is already a ceiling; the limits apply inABRmode. Two caveats worth planning around: truly constant bitrate requires macOS 13+ or iOS 16+ on Apple Silicon - elsewhere VideoToolbox emulates it through limits of its own and says so in its log, and the output is near-constant rather than constant; and on iOS the properties do not exist in the bundled runtime at all, so the setting is discarded with a warning (#1109). - [Media Blocks SDK .Net] macOS and Mac Catalyst: the bundled GStreamer runtime moves from 1.24.12 to 1.28.6, and the audio output no longer hangs on shutdown. Stopping a pipeline whose audio went to the system output could wedge the process: pausing tore the CoreAudio render callback down from inside the audio device's own IO thread, and that inverted two locks against each other. Measured on this machine before the upgrade, one run in five of the audio processing suite hung and had to be killed after 15 minutes; after it, none. Three things come with the new runtime that are worth knowing about. VideoToolbox gains hardware decoding of VP9 and AV1 and 10-bit HEVC encoding, and the H.264/HEVC encoders gain real rate control (constant-bitrate, and a hard data-rate cap) - availability depends on the Mac, so ask the SDK rather than assuming. Vulkan-based elements work on Apple Silicon for the first time: the library we shipped was built for Intel only, so on an M-series Mac none of them loaded at all. And the iSAC speech codec is gone - GStreamer dropped it upstream, and there is no replacement in the runtime; pipelines that asked for it by name will report a missing element. Everything else the SDK creates was checked element by element against the old runtime and is unchanged. Delete
binandobjonce after taking this update. Several bundled libraries change file name in this release - OpenSSL, libsoup and the FFmpeg libraries all move to a new major version - and an incremental rebuild leaves the previous ones in the output directory beside the new ones. - [Media Blocks SDK .Net] [Video Edit SDK .Net] DV output now pins the video format to PAL SD (720x576, 25 fps) instead of failing negotiation on any non-SD source. The DV encoding profile carried no restriction caps, so the encoder was handed the source's native resolution and framerate and negotiation failed. Note that DV encoding is currently blocked by an upstream gst-libav defect (#1126); this fix makes the profile correct for when it is unblocked.
- [Media Blocks SDK .Net] macOS and Mac Catalyst: the bundled CoreAudio plugin carries one fix on top of upstream 1.28.6. Stopping a CoreAudio device holds a lock that the device's own audio callback needs, and the thread doing the stopping sits inside CoreAudio holding it for milliseconds - measured on an Apple Silicon Mac at a median of 1.6 ms and as long as 240 ms. Upstream removed that inversion where the device is started and never where it is stopped. In practice 1.28.6 is very hard to hang this way, because the callback now stands down before it touches that lock whenever the pipeline is paused first - which every shutdown does; the case it leaves open is an audio capture source renegotiating its format, which stops the device with no pause in front of it. The bundled
libgstosxaudio.dylibis therefore built from upstream 1.28.6 sources with the stop side removed too. Everything else in the runtime is unchanged upstream bytes. - [Media Blocks SDK .Net] macOS and Mac Catalyst: barcode detection through
BarcodeDetectorBlock(the GStreamerzbarelement) no longer crashes the whole process on the first frame. The bundledlibzbarwas built by a compiler that exploits undefined behaviour in zbar's backward image scan: the scan's row-step arithmetic wraps to an invalid pointer value, and the compiled code materializes that wrapped pointer literally instead of decrementing the pointer, so scanning any image wider than two pixels dereferences address 0xffffffffffffffff and dies with SIGSEGV - deterministically, in every host process, on both Apple Silicon and Intel. The two instructions are corrected in place; QR detection verified working after the fix (#1168). - [Media Blocks SDK .Net] A branch of a running pipeline could stop delivering data for good after a dynamic add or remove. Blocking a pad that was already blocked installed a second block the SDK had no handle on - it remembered only the first - so unblocking the pad left the second one in place for the life of the process, and the branch went silent or froze with nothing in the log. Reachable wherever two block scopes could overlap on one pad: the live audio and video mixers,
LiveVideoCompositorV2, and element removal or replacement in a running pipeline. The same bookkeeping was a shared static table with no locking, and it never released the pads of removed inputs - one pad object pinned in memory per removed mixer or compositor input, permanently. It is gone: each block now carries its own handle.MediaBlockPad.BlockPadLive()changes with it in two visible ways: blocking an already-blocked pad is now a no-op that reports success rather than a second block nobody can lift, and a block that could not be installed reportsfalseinstead of reporting success (#1115). - [Media Blocks SDK .Net] Updating an OpenGL shader's settings on a running pipeline no longer leaves the block half-connected.
GLShaderBlock.Update()swaps theglshaderelement for a freshly configured one, and the block kept holding the pads of the element that was removed - every later connection, pad block or end-of-stream notification through that block then went to an element nothing feeds. The block now re-reads both pads after the swap. The element replacement underneath it was also reporting success over a pipeline it had cut in half: a replacement element that has only one of the two pads the position needs threw or silently linked against nothing, and a link the SDK could not make was logged and then reported as a completed replacement. Both are refused now, with the old element left running (#1136). - [Core] Media analysis no longer fails on a rotated video when the system locale writes its negative sign with a non-ASCII character. ffprobe reports a portrait phone recording as
rotate=-90, and the rotation was read through the machine's current locale. On the 57 cultures whose negative sign is not a plain hyphen - every Arabic locale, which prefixes it with U+061C, and the Persian ones, which use U+200E U+2212 - that parse threw and the file could not be analysed at all. ffprobe output is invariant by construction and is now parsed as such, along with the container bitrate and every duration (#1104). - [Core] ONVIF: authenticated requests carry a valid timestamp on any system locale. The
Createdvalue of the WS-Security UsernameToken was rendered through the machine's calendar, so a Thai machine sent the year 2569, a Persian one 1405 and a Saudi one 1447 and the camera rejected the request. In the legacy ONVIF client the same string is also what the password digest is computed over, so both were wrong.xs:durationvalues had the matching defect in both directions: written with a comma on any comma-decimal locale, and read back either failing outright (Russian, French) or silently taken as five seconds instead of half a second (German) (#1104). - [Core] ONVIF: a device's log timestamps are read in the right era. The log reader picked out date fields using the machine's locale, so under the Umm al-Qura calendar (
ar-SA) a plain ISO timestamp was not recognised at all, and under the Persian and Thai Buddhist calendars it was read into the wrong era - 2026-05-12 became 2647 or 1483. The invariant form is now tried first, with the machine's locale kept only as a fallback for a device that formats its log the same way (#1104).
2026.8.24¶
- [Core] macOS: enumerating video sources no longer logs a warning for capture devices that are not AVFoundation cameras.
VideoCaptureDeviceInforead the AVFoundation-onlydevice-indexproperty from every device it was given, and any other device class - a Decklink card, an ATEM surfaced through the Decklink provider - has no such property, so building its entry failed part-way and logged a warning. The property is now read only for AVFoundation devices (#1091). - [Core] Breaking:
Gst.Rtsp.RTSPConnection.Receive,ReceiveUsec,ConnectWithResponseandConnectWithResponseUsectake their message byref, and now actually hand it back. All four marshalled the message into a temporary block, let GStreamer write the parsed message into that block, and then threw the block away - so every successful receive returnedOkwith the caller's message unchanged - a fresh one stillRTSPMsgType.Invalid, carrying no headers and no body, and everything C had allocated into it leaked. Worse on the failure path: GStreamer releases the message's contents before returning an error, so the caller was left holding freed pointers and a laterUnset()released them a second time. The message is read back on every path now, so a read that reached the socket and then failed leaves it empty rather than dangling. A call rejected by GStreamer's own argument checks - a closed connection, which answersEinval- still returns the message untouched and owned by the caller (#1096). - [Media Blocks SDK .Net] Stopping or disposing a pipeline no longer waits without a time limit for it to reach the NULL state. A pipeline that reported the change as asynchronous and then never completed it left
StopAsync()andDispose()blocked for good. The wait is bounded now, matching the rest of the stop path: it logs a warning and the teardown carries on (#849). - [Media Blocks SDK .Net]
AudioMixerBlock.CreateNewInputLive()returnsnullwhen the input could not be added, instead of a pad that was never wired to anything. Check the result before linking: the previous pad produced a GLib critical out ofgst_pad_linkand a link result that looked like an ordinary refusal. - [Media Blocks SDK .Net]
RemoveSilenceBlockand theRemoveSilenceaudio effect now actually remove silence. The underlying element'sremoveproperty defaults to off and was never set, so the filter detected silence and then passed every buffer through unchanged - the block was a no-op whatever it was configured with. It is enabled now. Check yourThresholdbefore upgrading: it is a linear amplitude, and the documentation used to have its direction backwards - it claimed 1.0 meant "no silence detection", where 1.0 is in fact full scale and classifies every sample as silence. That was harmless while nothing was ever dropped; now a threshold near 1.0 removes the whole stream. Two defaults move with it, both onto the element's own:Thresholdfrom 0.05 (-26 dB, which would have cut ordinary quiet speech) to 0.001 (-60 dB), andSquashfromtruetofalse. Neither default breaks existing code - nothing was ever dropped, so neither had any effect to change; they are what the block does now that it works. One thing does:Thresholdis validated against its documented 0.0-1.0 range now, the way the compressor's already was, so a value outside it throwsArgumentOutOfRangeExceptionwhere it used to be accepted and ignored. With the block actually removing audio, an out-of-range threshold empties the track instead.Squash = truepulls every buffer after a removed passage back by its duration, so the audio track ends up shorter than the video of the same recording - set it yourself when you want the gapless, shortened output and nothing has to stay in sync with it. TheSquashdocumentation was describing the missingremoveproperty rather than whatSquashdoes: silence is always dropped, andSquashdecides whether the surviving buffers are pulled back to close the gap or keep their original timestamps (the default). - [Media Blocks SDK .Net]
RemoveSilenceBlock.ThresholdandRemoveSilenceAudioEffect.Thresholdnow reach the silence detector. The linear value was passed straight to an element property that is measured in decibels, and the conversion GLib applied silently turned the default 0.05 into 0 dB - full scale, where practically every sample counts as silence. The linear value is converted properly now; the public API is unchanged. - [Core]
Gst.Sdp.SDPMessage's property setters now actually set what they say. All seven wrote directly into the native struct at a computed field offset instead of calling GStreamer's own setter. ForVersion,SessionName,InformationandUrithat stored a fresh copy over the old string without releasing it, leaking on every assignment. ForOrigin,ConnectionandKeyit was worse: those fields are C structs embedded by value -GstSDPOriginis six strings in a row - and the setter wrote a pointer to a temporary block into the first eight bytes of one, somsg.Origin = o;corrupted the username field, left the other five untouched, and leaked the block, whilemsg.Connection = c;never wroteTtlorAddrNumberat all. All seven now go throughgst_sdp_message_set_*, which replaces every field properly (#1086). - [Core] Breaking: several
Gst.Sdpmembers change shape, and the GStreamer binding'sFree(),Unset()andClear()methods no longer corrupt the heap.SDPMedia.Media/Proto/Information/KeyandSDPTime.Start/Stopbecome read-only properties;SDPMessage.AddMedia,InsertTimeandReplaceTimetake their value byrefbecause C moves it into the message and the caller must not release it again; and the setters onSDPMedia.Fmts/Connections/Bandwidths/AttributesandSDPTime.Repeatare removed - they stored a plain pointer array in a field C keeps aGArray*in, so any call to one guaranteed a crash on the next release (useAddFormat,AddConnection,AddBandwidth,AddAttributeandSDPTime.Set). Those methods marshalled a copy of the value into a temporary native block and released that, which went wrong three ways at once: the marshaller allocates everystringfield withCoTaskMemAllocand C frees it withg_free, the block itself was allocated withAllocHGlobaland freed withg_free, and the wrapper then freed the same pointer a second time - soGst.Rtsp.RTSPTransport.Free(),Gst.Rtsp.RTSPRange.Free(),Gst.Rtsp.Global.RtspRangeFree(),Gst.Sdp.SDPMedia.Free()/Uninit()and theGst.Sdp.SDPAttribute/SDPBandwidth/SDPConnection/SDPTime/SDPZoneClear()methods aborted the process instead of releasing anything. Values whose fields the binding copies -RTSPTransport,RTSPTimeRange,SDPAttribute,SDPBandwidth,SDPConnection,SDPZone- own no native memory at all, their factory already released it, so releasing one now clears the value and makes no native call.SDPMediaandSDPTimeare the exceptions: they wrap live native memory, so their string fields become raw pointers behind read-only properties (SDPMedia.Media/Proto/Information/Key,SDPTime.Start/Stop), which is what makesSetMedia,SetProto,SetInformation,SetKey,SDPTime.Set,Uninit(),Free()andSDPTime.Clear()work; write through those methods rather than the properties, and only on a value you own - on one borrowed fromSDPMessage.GetMediathe setter frees a string the message still points at. One thing to know about that: those properties now read native memory on every access, so a value obtained fromSDPMessage.GetMedia/GetTimemust not be read after the message is disposed - copy what you need out while it is alive.EqualsandGetHashCodeon those two structs consequently compare by pointer rather than by string content, the way they already did for the array fields - two medias with the same text are no longer equal, and a value's hash changes after aSetMedia. And the release methods on those two now really do release: callFree()/Uninit()/Clear()only on a value you created (New,Init,Copy,SetMediaFromCaps,SDPTime.Set), never on one borrowed fromSDPMessage.GetMedia/GetTime- that one is a window onto memory the message owns, and releasing it leaves the message dangling until its own teardown trips over it. A borrowed value is also only valid until the message is next modified:RemoveMedia,ReplaceTimeand their siblings release the element they drop, so read what you need out of aGetMedia/GetTimeresult before changing the message, not after. The same allocator mismatch is gone from theInsert/Replaceoverloads that take anSDPAttribute,SDPBandwidth,SDPConnectionorSDPZone: C copies the struct into the message or media by shallowmemcpyand frees its strings withg_free, and the binding was handing it CLR-allocated ones - no signature changed, the strings are now GLib-allocated at the boundary.SDPMessage.AddMediatakesrefbecause C moves the media into the message and empties the source. The matching leaks are gone with them:Gst.Rtsp.Global.RtspMessageNew/NewData/NewRequest/NewResponseleaked an 88-byte message plus its header array on every call, andSDPMedia.New/Init/Copy/SetMediaFromCapsleaked a media plus four arrays, because the only documented release path was one of the broken methods (#1086). - [Core] Breaking:
Gst.Sdp.SDPMedia.Fmts,Connections,Bandwidths,AttributesandGst.Sdp.SDPTime.Repeatreturn typed arrays and finally read what they describe. All five threwArgumentExceptionon any value that held something: they walked their field as a NULL-terminated array of pointers, and the helper doing the walking calledMarshal.PtrToStructurein a form that refuses a value type - which is the only reason it did not hang instead, because its loop compared the walking address against zero while incrementing that same address and so had no exit at all. In C these fields areGArray *, not pointer arrays, so repairing the walk would still have taken the array's length field for an element pointer.FmtsandRepeatarestring[]now,ConnectionsisSDPConnection[],BandwidthsisSDPBandwidth[]andAttributesisSDPAttribute[], read through GStreamer's own indexed accessors - all butRepeat, for which C exports none, so that one reads the array directly; they wereIntPtr[]. Reading one on an empty or already-released value returns an empty array rather than crashing. UnlikeMedia,Proto,Information,Key,StartandStop, which read native memory on every access, the values these five hand back are copies taken at read time and stay valid after the media or time is released (#1087). - [Media Blocks SDK .Net] One stalled pipeline no longer freezes bus message delivery for every other pipeline in the process. Latency recalculation ran directly on the GLib main loop, which is shared process-wide and dispatches one source at a time. A pipeline whose latency query could not complete - a stalled mixer, a wedged source - therefore held that loop and stopped the EOS, error and state-change messages of all other pipelines, including the ones their
StopAsync/Disposewere waiting on, so unrelated pipelines appeared to hang (#1065). The recalculation now runs off the bus loop, with bursts of latency notifications coalesced so a graph is never recalculated twice at once. - [Core] Breaking:
Gst.Object.ReplaceandGst.Rtsp.Global.RtspAuthCredentialsFreechange signature, and the GStreamer binding'sT **out-parameters now return real data instead of uninitialised heap. Eighteen P/Invoke declarations passed a C out-parameter by value, so native wrote its eight-byte pointer into the front of a caller-allocated struct-sized block and everything past that was read back as garbage -Gst.Rtsp.RTSPUrl.Parsereturned a url whose host, path and credentials were undefined,Gst.Rtsp.RTSPRange.Parsereturned a range whose unit was a random integer, and the same held forRTSPTransport.New,SDPMedia.New/Copy, theRTSPMessageconstructors andRTSPAddressPool.ReserveAddress.Gst.Object.Replace(oldobj, newobj)was worse: it handed native the object pointer where C wants the address of a variable, so every call unreffed the object's class pointer and overwrote it - it becomesReplace(ref Gst.Object oldobj, Gst.Object newobj), and the parameterless overload becomesReplace(ref Gst.Object oldobj).RtspAuthCredentialsFreenow takes the credential array pointer (IntPtr) rather than a singleRTSPAuthCredential, which native was reading as a pointer and freeing. Two more of the same family are fixed with it:Gst.Sdp.SDPMessage.Initbecomes an instance method (msg.Init()) andGst.Sdp.Global.SdpMessageInitnow takes the message, because C'sgst_sdp_message_initre-initialises a message you already own - declared as an out-parameter it wrote a whole SDP message through an eight-byte stack slot and aborted the process inside malloc; andWebRTCICE.OnGetLocalCandidates/OnGetRemoteCandidatesnow returnWebRTCICECandidateStats[], since C returns a NULL-terminated array of pointers that was being read as a single struct.Gst.Video.VideoInfo.InitandGst.Audio.AudioInfo.Initbecome instance methods for the same reason - C'sgst_video_info_init/gst_audio_info_initinitialise an info you already own, and as out-parameters they wrote a whole GstVideoInfo over the caller's stack frame and returned null every time; usenew VideoInfo()/new AudioInfo()to get one, thenInit()to reset it.Gst.Rtsp.Global.RtspTransportInit,RTSPTransport.Init,Gst.Sdp.Global.SdpMediaInitandSDPMedia.Initno longer hand those C functions an uninitialised heap block, which they began by callingg_freeon. TheGst.Rtsp.RTSPMessagestruct also gains thetype_dataunion it was missing, so its layout matches the native one (#1062). - [Core] macOS: video capture no longer opens a different camera than the one selected. The device index passed to
avfvideosrcwas recorded once at enumeration time, but macOS may reorder cameras between enumeration and pipeline start (USB re-enumeration), so after such a reorder every new capture opened whatever device had taken the selected camera's position - typically failing with "Internal data stream error" or capturing from the wrong webcam. The position is now resolved from AVFoundation's live device list by stable unique ID right before each start; the enumerated index remains as a fallback. If the selected camera is no longer connected, capture now fails with an explicit error instead of silently opening a different camera.VideoCaptureDeviceInfogainsAvfUniqueIDon macOS (#843). - [Core] iOS: the selected camera is now opened by its AVFoundation unique ID rather than by its localized name. Video capture looked the camera up by display name across every AVFoundation device, microphones included, so a name that was not unique - or that changed with the device language - could open a different camera or none at all. The unique ID recorded at enumeration is now authoritative: a camera that no longer resolves by it fails outright rather than falling back to a name match that could open a different camera. The name search remains only for a settings object built by hand, which carries no unique ID at all. A camera that cannot be found now fails with an error naming both the device and its unique ID (#1089).
- [Core] Video capture blocks no longer throw
NullReferenceExceptionwhen no camera was found.CreateWithDefaultDeviceAsync()returns a block with no settings when device enumeration comes back empty - camera permission denied, a simulator, a machine with no webcam - and only the Android path checked for it. Every other platform dereferenced the missing settings and threw out of the publicBuild(); bothSystemVideoSourceBlockandIOSVideoSourceBlocknow returnfalseand log what is missing. The same applies to settings that exist but name no device, and on iOS to settings with no video format. - [Core] SDK log events now carry the exception object, not just its text. Every logging call that takes an exception passed it to Serilog as a message-template value rather than as the exception, and a template with no placeholders discards it - so a sink whose output template renders
{Exception}printed nothing there, and exception types and stack traces never reached the log at all. They are attached properly now, across the whole SDK. - [Core]
KLVDecoderandKLVRemuxare nowstaticclasses. Both only ever exposed static members, so documented usage (KLVDecoder.DecodeFromFile(...)) is unaffected; code that instantiated them withnewwill no longer compile. - [Core]
VideoFrameRategained the<=and>=operators, completing the comparison set alongside the existing==,!=,<and>. They use the same 0.0001 tolerance as==.
2026.8.23¶
-
[Core] WPF skin controls are now available on every Windows target framework.
VisioForge.Corepreviously compiled the WPF skins (SkinPlaylist,SkinCaptureControls,SkinPlayerControls, …) only fornet*-windows10.0and .NET Framework targets, so projects targeting a plain-windowsTFM such asnet10.0-windows— including the Skinned Player and Skinned Capture demos under the nano build flavour — failed with "The tag 'SkinPlaylist' does not exist in XML namespace" (#859). Note thatSkiaSharp.Views.WPFships no asset for plain-windowstargets, so restore falls back to its .NET Framework asset (NU1701); the controls compile and work. -
[Media Blocks SDK .Net] Fixed a process crash when a subtitle auto-hide timer fired after the overlay block had been torn down.
OverlayManagerBlock.Video_Overlay_Updatedereferenced its internal element without a null check on the re-add path, so a late subtitle hide tick raised an unhandledNullReferenceExceptionon a timer thread and aborted the whole process (#823). - [Media Blocks SDK .Net] Media Foundation H.264/HEVC encoders no longer log a GLib critical and silently drop the reference-frames setting on every run where it is left at the default. The default of 0 ("encoder default") lies below the encoder element's own property range, which starts at 1; the value is now skipped instead of being written out of range (#857).
2026.8.22¶
- [Core] Breaking:
new Gst.Buffer(size),new Gst.BufferX(size)andnew Gst.BufferList(size)are replaced byGst.Buffer.NewAllocate(size),Gst.BufferX.NewAllocate(size)andGst.BufferList.NewSized(size). The size constructor sat one implicit conversion away from the pointer constructorBuffer(IntPtr), and since .NET 7 anintliteral converts implicitly to a native integer - sonew Gst.Buffer(1024)silently bound to the pointer overload and produced a buffer wrapper over address 1024. Nothing failed at the call site; it crashed later inside GStreamer with no hint of where it came from. The allocating form is now a named factory that cannot be confused with wrapping a pointer, and both old spellings fail to compile with a message naming the replacement. Wrapping an existing native pointer is unchanged. - [Core] Long GStreamer sessions no longer grow their native memory footprint on every negotiation, frame push and dropped frame. The managed wrappers for
GstCaps,GstBuffer,GstEvent,GstMessage,GstMemory,GstSample,GstQueryandGstTagListnever released the native object:Dispose()andusingon them did nothing at all, so every capability negotiation, every pad-caps query and every self-allocated buffer that was created and released left its native allocation behind for the life of the process. The effect grew with running time and with the number of pipelines built and torn down; it was largest on paths that touch caps or buffers per frame - pad probes, overlays, VU metering, and the custom mixer's queue-overflow frame drops. Reference counting is restored, so disposing these objects - or letting the garbage collector do it - now actually frees them. - [Video Edit SDK .Net] Encoder settings on the render/output path are no longer silently lost on hosts where the encoder element exposes fewer properties. Video Edit renders configured the encoder through the GStreamer
encodebinprofile, which writes every property with an uncheckedg_object_set: a property the concrete element class does not expose - Media Foundation encoder classes are generated per device, so their property set differs from machine to machine - raised a GLib critical and was dropped without any error. The profile now pins only the encoder factory; the settings are applied to the encoder element after encodebin creates it, with each property probed first and a warning logged when one is not available. - [Media Blocks SDK .Net]
SimpleVideoMarkDetectBlock.VideoMarkDetectednow actually fires. The block installed its bus handler withBus.AddWatch, but a GStreamer bus supports a single watch and the pipeline already owns it, so the install silently failed and watermark detection never reported anything; the handler is now delivered through the pipeline's own bus signal dispatch. Two defects found behind the same dead event are fixed with it: the detection pattern was read from a message field that does not exist (the element posts it asdata), and the handler could be handed an already-released message by the pipeline's own bus handler running before it. - [Core] Disposing
DeviceEnumeratorwhile another thread was starting device monitoring or enumerating NDI/Decklink devices no longer risks disposing the same GStreamer device monitor twice - which surfaced as GLib object-lifetime criticals in the log, or as a device monitor left running after dispose. Monitor teardown now serializes with monitor creation through one lock (so device-monitor work is queued across enumerator instances), and concurrentDispose()calls are safe. NDI enumeration still never blocks other instances: its potentially slow mDNS discovery runs outside the shared lock on an exclusively claimed monitor. - [Core] Disposing any
DeviceEnumeratorinstance no longer breaks NDI device-provider toggling for every other enumerator in the process. Dispose released the shared registry-feature wrapper all instances use to load/unload the NDI provider, so after one enumerator was disposed its siblings passed a dead pointer into the GStreamer registry on every later enumeration (gst_registry_remove_feature: assertion 'GST_IS_PLUGIN_FEATURE' failedin the log). The reference is now dropped instead of disposed. - [Core] Dropping an engine object without disposing it no longer risks killing GStreamer for the rest of the process.
VideoCaptureCoreX,MediaPlayerCoreX,SimplePlayerCoreX,MediaBlocksPipeline, the Live Video Compositor and its outputs, the overlay managers and several other classes ran their full GStreamer teardown from the garbage collector's finalizer thread when an instance was never disposed - which could take the process-global GStreamer registry with it, so every pipeline created afterwards failed to build with nothing in the log connecting the failure to the object collected minutes earlier. Finalizers now leave the native objects to the binding's deferred release path;Disposeremains the way to stop pipelines deterministically. One trade to know about: a recording whose engine was never disposed ends without a muxer trailer and stays unplayable - dispose explicitly to finalize files. - [Core] An undisposed GigE (Aravis) camera now releases its stream and camera handles at collection instead of taking locks, tearing down timers and raising events from the finalizer thread. Stopping acquisition still requires an explicit
Disconnect(). - [Media Player SDK .Net] A faulted dispose of
MediaPlayerCoreXno longer leaves the player permanently half-torn-down with no way to finish it. If stopping or closing the pipeline threw duringDispose/DisposeAsync, the player marked itself as disposed while the GStreamer pipeline had never reached NULL and internal resources were never released - and every later dispose call only re-observed the stored failure instead of retrying. A faulted teardown now leaves the player usable, flushes and re-arms the debug log for the next attempt, and a subsequentDispose()orDisposeAsync()completes the teardown. - [Video Capture SDK .Net] DirectShow Picture-in-Picture recording no longer fails with "Unable to set PIP layer settings" in Horizontal and Vertical layouts, and
PIP_CustomOutputSize_Setnow produces output of exactly the requested size. The struct passed by value to the video mixer filter declared its frame-duration field as 32-bit while the native filter reads it as 64-bit, so every output-settings call was rejected and the mixer silently kept its previous canvas: in Horizontal/Vertical layouts the later layer-position calls then failed with an error at start, and with a custom output size smaller than the main video the recording came out at the wrong size. Output size is now applied before layer positions, the main video fills a custom canvas, and a failed PiP configuration call logs the failing parameters with the native result code.
2026.8.21¶
- [Demos] The Avalonia demos and the console RTSP servers build again on macOS regardless of which macOS workload patch is installed. They pinned
net10.0-macos26.2, a target platform version that only machines whose workload manifests declare 26.2 accept - everywhere else the build failed before compilation withNETSDK1140: 26.2 is not a valid TargetPlatformVersion for macOS. The demos now usenet10.0-macoswith no version suffix, like the rest of the sample tree, so the platform version follows whatever the machine has installed. - [Demos] The remaining Media Blocks console demos and the Blazor RTSP servers build again on Apple-silicon Macs. An unconditional
PlatformTarget x64conflicted with theosx-arm64runtime identifier inferred fornet10.0-macos(NETSDK1032) in VideoResizer, FrameRateAdjuster, RTSPViewCV and both Blazor RTSP servers; the pin is now Windows-only. The ones used as.appbundles on macOS also lacked a bundle identifier and now declare one. - [Demos] The Live Subtitles console sample no longer declares a macOS target. Whisper.net requires static whisper.cpp archives on Apple platforms and
Whisper.net.Runtimeships none for macOS, so the sample's speech-to-text pipeline could not link there; it stays available on Windows and Linux. - [Media Blocks SDK .Net] Stopping a pipeline with
ObjectAnalyticsBlockno longer logs analytics or overlay errors and no longer loses the frame that was in flight. Teardown freed the block's renderer, tracker, zones and lines while the streaming thread could still be using them, so a frame arriving during the stop was dropped with a loggedObjectDisposedExceptionor null-reference message; teardown now waits for the frame in flight before freeing anything. - [Media Blocks SDK .Net]
FallbackSwitchenabled on source settings passed directly to a source block is no longer silently ignored.RTSPSourceSettings.FallbackSwitch(and the same property on the SRT, NDI, RTMP and HTTP source settings) is applied byVideoCaptureCoreXand by an explicitFallbackSwitchSourceBlock; a bareRTSPSourceBlock,SRTSourceBlock,SRTRAWSourceBlock,NDISourceBlock(or the Windows-onlyNDISourceXBlock),RTMPSourceBlockorHTTPSourceBlockdoes not use it, and enabling it there now logs a warning at build time explaining how to get automatic failover instead of proceeding without any message. - [Core]
MediaInfoReaderXno longer spins up a full-throughput decoder just to read file metadata. The discovery pipeline let GStreamer auto-plugdav1ddecwith its defaults - threading and frame delay sized to the CPU core count - so reading the metadata of one 8K AV1 file pre-allocated a reference-frame pool costing ~700 MB of working set on a 14-core machine and growing with every core. Discovery now pins that decoder to low-latency single-thread mode before it starts, bounding the same read by the stream's reference structure instead of the machine's core count (~310 MB for 8K AV1 on any machine). - [Core] The built-in HLS/DASH HTTP server on macOS and Linux no longer dies if a player connects while it is starting.
- [Core] The built-in HLS/DASH HTTP server on macOS and Linux now accepts IPv6 clients, including
http://localhost/when that name resolves to::1. - [Media Blocks SDK .Net] Adding an audio or video effect to a running pipeline no longer leaves it paused. Under concurrent effect changes, the pipeline could still be resuming when the add returned, leaving later effect operations or stopping playback waiting indefinitely.
- [Media Blocks SDK .Net] A video or audio effect added while the pipeline has just left Playing now reaches the running graph. A pause that landed during the add used to leave a video filter in NULL, and to skip the audio filter until the next build.
- [Media Blocks SDK .Net] A pipeline that was preloaded and then resumed no longer flickers back to paused, and no longer seeks
StartPosition, after playback was already started. Resume (or the nextStartAsync) had already publishedPlay, but a late confirmation of the preload's pause could overwrite it and re-seek.MediaPlayerCoreX.State, which reports the pipeline's state, is covered by the same fix. - [Media Blocks SDK .Net] A live-added proxy, buffer or subtitle bridge source now brings its whole graph up with the pipeline. Those three sources published no core wrapper, so a live add synced only the one GStreamer element the block exposed and left the rest of the bridge in NULL.
- [Media Blocks SDK .Net]
MediaBlocksPipeline.SyncBlockStateLiveno longer throws on a block that was never built, and no longer races the block's own teardown. Calling it out of order - beforeAddBlockLivebuilt the block, or after it had been cleaned up - raised aNullReferenceExceptionout of the SDK instead of returningfalsewith a logged reason like every other refusal in that method. It also read the block's element and then synchronised it after releasing the lock that guarded it, so a teardown landing in that window left the live add reported as "failed to set block to Playing" with the real reason only in a GStreamer log line. The same "has not been built" refusal now also applies toMediaBlockHelper.SetStateandMediaBlockHelper.SendEvent. - [Media Blocks SDK .Net] RTSP playback no longer fails with "Failed to link RTSP pad: WasLinked" when the source re-announces a pad. On a reconnect, or when an RTSP server re-announces a stream,
UniversalSourceBlockV2could report a pad it had already linked as a link error and end the session - intermittently, since two of rtspsrc's streaming threads can pass the "is this pad linked" checks together. A duplicate announcement is now recognised from the link result itself - a second attempt reportsWasLinked, which is logged at debug level instead of failing the session - and the handler's check-and-link section is serialised. - [Core] A handler connected with
Connect(...)or with+=on a generated GStreamer event no longer keeps that object alive for the life of the process. EveryConnect(...)on an element - the mechanism behind source, demuxer and decoder auto-plugging - and every+=on a generated event was recorded in a process-wide table that only an explicit unsubscribe ever cleared, and the entry held the element, the handler, and everything the handler had captured. An application that builds and tears down sources or decoders in a loop, a playlist or a transcode over a directory, grew without bound with nothing disposable to blame. A connection is now owned by the object it was made on and is released with it. Two defects of the same family go with it: a handler silently stopped being delivered once its wrapper had been disposed, and the callback's handle was released while an emission could still be inside it - a rare crash on a streaming thread when a recording was stopped on a file split.
2026.8.20¶
- [Video Capture SDK .Net]
VideoCaptureCoreX.WaitForStartAsyncno longer waits forever, and no longer returns before the capture starts. It polled forPLAYINGand nothing else, so a source that never gets there - an RTSP or HTTP address that black-holes, a capture device with no signal, a Decklink with no input - parked a thread on aTaskthat never completed, and an asynchronous failure (which takes the pipeline back toREADYwithout tearing it down) did the same. The wait now ends when the start settles somewhere it will not leave, and has a 30-second deadline; the newWaitForStartAsync(TimeSpan timeout, CancellationToken cancellationToken = default)overload chooses that deadline, cancels the wait, and returns whetherPLAYINGwas actually reached. The documented fire-and-forget pairing_ = StartAsync(); await WaitForStartAsync();also no longer completes instantly against a capture whose pipeline does not exist yet. -
[X-engines] A second
Start()landing while the first is still building is now rejected instead of building over it.VideoCaptureCoreX.Start()andMediaBlocksPipeline.Start()had the guard only on their async twins, so a concurrent call cleared the first start's state and re-entered the build over the pipeline that call was still assembling. Relatedly, a start that fails now finishes its own rollback before it releases the start, so processing blocks registered by another thread are no longer disposed under it, and a throw out of a restart's teardown no longer leaves the instance permanently unable to start. -
[Media Blocks SDK .Net] A
ChromaKeyBlockadded to a running pipeline now brings its whole graph up with the pipeline, not just the compositor. The block builds six elements, and a live add synchronised the state of only one of them, so the other five - the background scaler and capsfilter, the alpha key, and both converters - stayed in whatever state they had been created in. They now live in one bin, which is the one thing the pipeline brings up. - [Media Blocks SDK .Net] A start the pipeline refuses is now reported as stopped instead of as playing. When an element refused the transition to playing - a capture device that cannot be opened, a renderer that cannot create its window -
Start()returnedfalsebut leftStatereportingPlay, and left every element that had already opened a device, handle or socket holding it. The pipeline is now torn down and reportsState = Free, so a retry rebuilds it. WithPauseOnStopenabled that retry previously returnedtruewithout rebuilding anything, on a graph that never started. A start that never started no longer raisesOnStopwhen it is stopped afterwards.MediaPlayerCoreX.State, which reports the pipeline's state, is covered by the same fix, andVideoCaptureCoreX.Startnow returns as soon as the pipeline fails instead of going on to start the auto-start outputs against it. - [Media Blocks SDK .Net] A preload that fails while prerolling is now reported.
StartAsync(onlyPreload: true)andStart(onlyPreload: true)returnedtruewhenever the source failed asynchronously - a camera already in use, an unplayable file, a stream that never connects - and left the pipeline holding whatever its elements had opened, with nothing telling the caller. Only a transition the pipeline refused outright was reported. Both now returnfalseand tear the partial graph down;Pause()on a running pipeline reports the same failure the same way. - [Media Blocks SDK .Net] The processing block passed to an
LVCVideoInputconstructor is now applied. On LiveVideoCompositor V2, the optionalprocessingBlockargument of bothLVCVideoInputconstructors was stored and never linked into the graph: the input composited unprocessed, with no error and no log line, while the identically shaped argument ofLVCVideoAudioInputworked. It is now an alias forLVCVideoInput.ProcessingVideoBlocks, so the block runs between the source and the mixer as the argument always implied. Code that already usesProcessingVideoBlocksis unaffected. - [Media Blocks SDK .Net] The
channelparameter ofLiveVideoCompositorV2.Video_Effects_*is deprecated. V2 has a single effects block on the composed output, after the mixer, so the index never selected anything -Video_Effects_Clear(channel: 1)cleared the whole composition's effects, where the identically named V1 call validates the index and ignores a channel that does not exist. EveryVideo_Effects_*method now has a channel-free form; the overloads that take achannelstill work, forward to it and warn. To process a single input rather than the composition, add aVideoEffectsBlockto that input'sLVCVideoInput.ProcessingVideoBlocks- those blocks run between the source and the mixer, which is where V1's per-channel effects were. V1 is unchanged. - [Media Blocks SDK .Net] An effect added to a running pipeline while that pipeline is being stopped is no longer left in the graph unreachable.
VideoEffectsBlock.AddOrUpdateAsyncandAudioEffectsBlock.AddOrUpdatesplice the new effect into the live graph, and that work can take seconds - it runs yourOnUpdatehandler twice and pauses the pipeline to relink it. A stop that gave up waiting for it went ahead and released the block anyway, and the insertion then carried on and spliced its element in regardless: the block no longer knew about it, soRemove()reported success without removing anything and the nextBuild()created a second element under the same name, for the rest of the run. Both blocks now stop an insertion the moment a teardown has been through, and leave the element to the pipeline's own disposal - on an ordinary stop that is what releases it. The effect stays registered, so the next build puts it in the graph. - [Media Blocks SDK .Net]
MediaBlocksPipeline.Statenow reportsPauseas soon asStartAsync(onlyPreload: true)/Start(onlyPreload: true)returns, instead of briefly reportingFreewhile the pipeline was already preloading. Inside that window a preloaded pipeline looked stopped to every "is anything running?" check:StopAsyncandStopreturned without tearing it down and without raisingOnStop,Disposeskipped the stop it does first,ClearBlocksdisposed the blocks of a live pipeline instead of refusing, aStartPositionset on the preloaded pipeline was dropped instead of seeked, and starting playback right after a preload could be rejected with "Already starting or start in progress".MediaPlayerCoreX.State, which reports the pipeline's state, is covered by the same fix.
2026.8.19¶
- [Media Blocks SDK .Net]
RTSPSourceSettings.BufferModeandDropOnLatencynow reach the RTSP source. Setting them previously had no effect, so jitter-buffer tuning was silently ignored. The default jitter buffer is 500 ms;LowLatencyModeuses 150 ms, or the explicitLatencyif you set it to 150 ms or less. - [Media Blocks SDK .Net] Changing video mixer settings while the pipeline is being stopped no longer crashes or silently does nothing.
SetSettings,Input_Update,Input_Move,StartFadeIn,StartFadeOut,Input_UpdateChromaKeySettingsandInput_SetChromaKeyEnabledran with nothing serialising them against the block's own teardown, so a call that landed during a stop reached GStreamer through an element the teardown had already released - aNullReferenceException, or a change that was accepted and quietly not applied. Building a mixer while it was being stopped had the same problem and could throw out ofBuild(). AffectsVideoMixerBlock,VideoMixerSourceBlock,GLVideoMixerBlock,D3D11VideoCompositorBlockandMetalVideoCompositorBlock.AddInputPadLiveon a mixer that is not built now returnsnulland logs, instead of throwing. - [Media Blocks SDK .Net] A video mixer fade or move animation no longer outlives the block that started it.
StartFadeIn,StartFadeOutandInput_Moveanimate on a background thread for the duration requested; stopping or disposing the mixer while one was running left that thread writing to a released element, which took the whole application process down with an unhandledNullReferenceException. Teardown now stops the animations and waits for them first. They also no longer keep the process alive after everything else has finished. - [Video Fingerprinting SDK .Net] Disposing a
FrameSourcewhilePlayAsyncwas still starting no longer leaves a playing pipeline behind. The teardown and the start shared no synchronization, so aDispose()- or aStopAsync()- landing mid-start tore down the session the start was still building, and the start went on to leave a fully wired pipeline that nothing owned:OnVideoFramekept firing for the rest of the process. OverlappingPlayAsync/StopAsynccalls, which a UI can produce with two quick clicks, could also tear the same pipeline down twice.FrameSourcenow also implementsIAsyncDisposable;await frameSource.DisposeAsync()is the deterministic teardown, because a synchronousDispose()cannot wait for a start already in flight. - [Media Blocks SDK .Net] Disposing a pipeline that was only preloaded (
StartAsync(onlyPreload: true)) no longer hangs. The teardown skipped the stop for a preloaded pipeline and set its elements to the null state under a live streaming thread, which wedged the disposing thread and the streaming thread against each other indefinitely. - [Media Blocks SDK .Net] Disposing a pipeline while it was reporting a state change no longer hangs. The teardown and the pipeline's own message thread could block on each other for good.
- [Media Blocks SDK .Net]
VP8EncoderSettings.GetCaps()now reportsvideo/x-vp8instead ofvideo/x-vp9. - [Media Blocks SDK .Net] An IPv6 URL such as
udp://[ff05::1]:5004now reaches a UDP source, a universal source and an RTSP server without the brackets, so the element binds and joins multicast instead of failing silently. A Windows link-local zone id (%12) is left intact instead of being decoded as a byte. - [Media Blocks SDK .Net]
LiveSourceSwitchBlock.Switch(i)no longer pairs one source's video with another's audio on a switcher that holds a mix of input types. A video-only input and a video+audio input take their switch pads from two independent counters, so the same index meant a different source in each of the two switches: with a video-only input added first,Switch(1)played the second input's picture with silence, because no input feeds audio pad 1.Switchnow resolves the input at the given index and moves each switch to that input's own pad. An input that carries only one of the two streams leaves the other switch where it was, so switching to a video-only input keeps the audio that was playing. NewCurrentVideoIndex/CurrentAudioIndexproperties report the pads actually selected. Two smaller changes come with it: an index past the last added input is now refused and logged instead of pointing the switch at a reserved pad that carries nothing, andSourceSwitchBlock.Switchreturnsbool-falsewhen the block is not built yet, the index is out of range, the pad at that index was never obtained, or a concurrent stop tore the element down - where it used to returnvoid. Every one of those is logged; a switch that could not be applied no longer passes silently. - [Media Blocks SDK .Net]
LiveSourceSwitchBlockDynamic.Switch(slot)no longer silences the audio when the slot holds a video-only input. Nothing feeds that slot's audio pad, so moving the audio switch there played silence; it now stays where it was, matchingLiveSourceSwitchBlock.Switch. An empty slot is not that case - switching to a slot with no input in it still takes the audio with it, rather than leaving the previous source's sound playing under a black picture; one limit is structural, in that a switcher whoseMaxAudioInputsCountis smaller than itsMaxVideoInputsCounthas no audio pad above the audio limit for the audio to move to. A slot index past the last slot is now refused and logged; on a switcher whose audio switch has more pads than its video one it used to move the audio switch while the video switch declined, so the sound went silent under a picture that kept running. ItsCurrentVideoIndex/CurrentAudioIndexalso start at-1instead of0- they used to report slot 0 before any switch had been applied, which was not true, and they now record only a switch the block actually applied. Code that reads either property before the first switch and indexes its own array with the result has to handle-1. - [Media Blocks SDK .Net] Disposing a
LiveSourceSwitchBlocknow releases its inputs and internal resources. The teardown freed nothing at all, so an application that created and disposed switchers - or added file inputs to one - leaked a whole graph, including a pipeline per input, on every instance. - [Media Blocks SDK .Net] A
LiveSourceSwitchBlockconfigured for one stream only (VideoStreamorAudioStreamturned off) now starts. It threw aNullReferenceExceptionon the firstStartAsync, so the setting could not be used at all.Input_AddAsyncnow also refuses an input for a stream the switch does not carry and returnsfalseinstead of throwing, or - for an audio input on a video-only switch - accepting it and playing nothing. The same applies toLiveSourceSwitchBlockDynamic.Input_AddToSlotAsync, where a video/audio input on a switch without audio is now refused rather than half-connected. - [Media Blocks SDK .Net] Building a
BridgeBufferSourceBlockwhose paired sink was never created, or has already been disposed, no longer throwsArgumentNullException—Build()returnsfalseinstead. - [Media Blocks SDK .Net] Retargeting a UDP sink at runtime no longer sends to a mixed destination.
UDPSinkBlock.SetFilenameOrURLand the UDP MPEG-TS sinks pushed the new host and the new port as two separate steps, so two calls landing at once could leave the sink streaming to one URL's host and the other's port. An IPv6 URL now reaches the sink correctly -udp://[ff05::1]:5004used to arrive with the brackets still on the address, which it cannot resolve, the URL reported back byGetFilenameOrURLcould not be parsed again, and a link-local zone id (udp://[fe80::1%25eth0]:5004) kept its percent escape. This covers the UDP sink; the UDP source, universal source and RTSP server are the matching follow-up. New public overloadUDPSinkSettings.TryParseUrl(string url, out string host, out int port)returns the parsed pair, for callers that must not read it back off shared settings. - [Core] Fixed a memory leak on every GStreamer property or caps field set to a string, or to a caps, structure, buffer or tag reference. The value handed to the element was copied but the caller's copy was never released, so each set leaked the string's allocation - or, for caps and elements, held a reference that kept a live GStreamer object alive for the rest of the process. Worst on properties pushed repeatedly: text and image overlay contents, bridge channel names, device paths, file names and URLs, and every caps renegotiation. Numeric and boolean properties were never affected.
- [Media Blocks SDK .Net] A media block that is garbage-collected without being disposed no longer tears its GStreamer elements down from the finalizer thread. An application that forgot a
Dispose(), or dropped a block after an exception, could see a crash or a stall inside the .NET finalizer during collection; abandoned blocks now leave their elements to the pipeline that owns them. - [Core] The WPF
VideoViewno longer shows a black preview in a remote-desktop session when the D3D11 composable renderer is requested. Such a session composes WPF in software and its Direct3D9 device sits on a different adapter, so the GPU surface can never be presented; the view now detects that and falls back to its software rendering path automatically, logging a warning, instead of displaying nothing. - [Core] Fixed the WPF
VideoViewsilently dropping back to software rendering on the second playback. After aStop()the next start rebuilt the view from the engine's renderer mode alone — and both theD3D11ComposableandDirect2DManagedpaths rewrite that mode toFrameCallback— so GPU-resident composition degraded to a per-frame CPU upload, with no error andGetSurfaceProvider()returningnull. The view now remembers the renderer it was asked for and restores it on the next start; setting a different renderer mode on the engine between two starts still switches away from it, as before. - [Media Blocks SDK .Net] Audio effects added during playback are now inserted at their position in the effect list, so the applied order no longer depends on whether an effect was added before or during playback - and a second effect added straight after the first is no longer silently left out of the pipeline. The block's output also correctly follows the last effect after live additions and removals; removing the last effect used to leave the block pointing at the removed one.
- [Media Blocks SDK .Net] An audio or video effect added while the pipeline was being stopped or disposed is no longer silently lost. Stopping the pipeline from the effect's own
OnUpdatehandler let the block build the effect's element against a pipeline that no longer existed: nothing failed, nothing was reported, and the effect was simply absent from the graph. The block now reports it and keeps the effect registered, so the next start puts it in. - [Core] Calling
Dispose()on a GStreamer wrapper object no longer prints a GLib critical such asgst_iterator_free: assertion 'it != NULL' failedorgst_structure_free: assertion 'structure != NULL' failed. The object was always freed correctly; a second, redundant free with a null handle produced the log line. This affectedGst.Iterator,Gst.Structure,Gst.Video.VideoInfo,Gst.Audio.AudioInfo,Gst.Video.VideoConverter,Gst.ParseContextand the other non-reference-counted opaque wrapper types, all of which are now safe to dispose.
2026.8.18¶
- [Core] Fixed a crash when playback was stopped while the WPF
VideoViewwas rendering throughDirect2DManaged. The view freed the RGBA staging buffer on the UI thread while a frame was still being converted into it on the streaming thread, which corrupted the heap or took the process down outright. The same buffer was also sized from the very first frame and never grown, so a source that switched to a higher resolution mid-stream overflowed it. - [Core] Fixed the WPF
VideoViewsilently replacing a classic engine'sWPF_WinUI_Callback/FrameCallback,None,Direct2DManagedorD3D11Composablerenderer mode with EVR. The view built a native HWND renderer instead of the requested one, so WPF controls placed over the video stopped composing (airspace), and forWPF_WinUI_CallbackandNonethe engine'sVideo_Renderer.VideoRendererread backEVR— a mode the application never set. (Direct2DManagedandD3D11Composablestill read back asFrameCallback: the view draws those itself and the engine feeds it frames.) CallingVideoView1.SetNativeRendering(false)is no longer required for the software rendering path. - [Media Blocks SDK .Net] Stopping a pipeline that has already reached the end of its stream no longer waits ten seconds for an end-of-stream that has already happened. The output file was already complete; the stop just took that long to return.
- [Media Blocks SDK .Net] Fixed stopping a pipeline reporting a spurious error —
Resume for EOS did not reach PLAYING ... Muxer may not finalize— when the pipeline had not finished starting up yet. The stop also stalled two seconds before reporting it, and applications that treat an SDK error as a failure saw a clean stop as a failed one. - [Media Blocks SDK .Net] Fixed a crash when chroma-key settings were changed while the pipeline was being stopped. Updating the key color, alpha or sensitivity from one thread used to be able to land on the filter while another thread was tearing it down.
- [Media Blocks SDK .Net] Fixed audio effect settings being silently discarded when changed while the pipeline was being stopped. Every audio effect — volume, balance, amplify, echo, compressor/expander, both equalizers, pitch, loudness normalization, RNNoise, HRTF, Csound, the Chebyshev filters, karaoke, wide stereo, reverberation and the rest — used to be able to push a change onto an element another thread had already released, in which case nothing happened and nothing was reported.
- [Media Blocks SDK .Net] Fixed removing an audio effect while the pipeline is being stopped leaving that effect in the graph. The removal reported success while the effect was still spliced into the chain, and could also throw
IndexOutOfRangeExceptionout ofAudioEffectsBlock.Clear. - [Media Blocks SDK .Net] Fixed
AudioEffectsBlock.Removenot removing an effect that had been updated since it was added. The live element was unplugged but the effect stayed in the list, so the next time playback started it came back. - [Media Blocks SDK .Net] Fixed
AudioEffectsBlock.AddOrUpdatecalled twice with the same effect object stopping that effect's later property changes from reaching the graph. - [Media Blocks SDK .Net] Audio effect names are now matched the same way everywhere — case-insensitively. Adding
Volumeand thenvolumeused to create two effects that both drove the first one. - [Media Blocks SDK .Net] Fixed a
NullReferenceExceptionwhen an audio effect property was changed after the pipeline had been stopped. - [Media Blocks SDK .Net] Pipelines containing an
AudioEffectsBlockno longer carry one unused audio converter element each. - [Media Blocks SDK .Net] Fixed the whole video or audio effect chain silently disappearing for the rest of the run after a stop that had to give up waiting for an effect operation to finish. The block was left claiming it was built while owning nothing, so every later start produced no effects at all and reported no error.
- [Media Blocks SDK .Net] Fixed
VideoEffectsBlockkeeping every effect object it was given alive after it was disposed. The effects stayed subscribed to the disposed block, so neither they nor the pipeline's elements could be collected, and changing one of their properties afterwards reached a block whose pipeline was gone.
2026.8.17¶
- [Media Blocks SDK .Net] Fixed playback freezing for the rest of the run when a video or audio effect added to a running pipeline is refused by the graph. The effect is simply not applied now, instead of leaving the chain cut at the point it was being inserted.
- [Media Blocks SDK .Net] Fixed the same freeze on the removal side: removing a video or audio effect from a running pipeline no longer cuts the chain when the surrounding elements cannot be linked to each other. The effect stays in place and the removal reports failure, instead of reporting success over a chain nothing flows through.
- [Media Blocks SDK .Net] Removing an effect that is built from several elements — box, crop, aspect-ratio crop, resize, pan/zoom, fisheye, LUT, text overlay, image overlay, QR overlay, mouse highlight, overlay manager, pitch, compressor/expander, loudness normalization — now takes them out of a running graph as one unit. A removal that succeeded for some of an effect's elements and failed for the rest used to leave the effect half in the graph: the next effect added live could end up in the wrong position, or the block could stop producing output altogether. The removal now either takes the whole effect out or leaves it running untouched and reports failure.
- [Media Blocks SDK .Net] Removing a LUT or QR-code overlay effect live no longer leaves the chain pinned to that effect's pixel format. Both build an internal format filter, and it used to stay in the graph after the effect was gone, forcing RGB on everything downstream of it for the rest of the run.
- [Media Blocks SDK .Net] Repeatedly adding and removing a LUT effect during playback no longer leaves an unused element in the pipeline for every add. That internal format filter is now taken out with the rest of the effect instead of accumulating one per add; the QR-code overlay releases its own the same way.
- [Media Blocks SDK .Net] Changing an effect's settings from one thread while the pipeline is being stopped on another no longer silently does nothing. The push used to be able to land on an element the teardown had already released, in which case it was discarded without any error being reported. Most visible on Android, where the renderer's resize is updated from the view thread whenever the view is resized or the device is rotated.
- [Media Blocks SDK .Net] Fixed a
NullReferenceExceptionwhen the Android renderer's view was resized while the pipeline was stopping.
2026.8.16¶
- [Core] Fixed video fingerprinting
FrameSource.PlayAsyncthrowingNullReferenceExceptionunless the optionalCropandCustomResolutionproperties were set. - [Core] Video fingerprinting: new
FrameSource.StopAsync()stops the current session and releases its pipeline so the instance can be reused — previously the only way to stop was disposing the whole object. - [Core] Video fingerprinting: the
VFPAnalyzererror callback now fires exactly once per failed analysis, on the caller's thread, with the underlying cause — previously mid-run errors could be swallowed entirely or delivered from the pipeline's internal thread. - [Core] Video fingerprinting: a repeated
FrameSource.PlayAsyncnow stops and disposes the previous session instead of leaving its pipeline playing for the life of the process, a failedPlayAsynccleans up the half-built pipeline and is reported through theVFPAnalyzererror callback instead of hanging the analysis, andDisposetears the session down in a safe order. - [Core] Fixed event handlers subscribed after start never being called in
VideoCaptureCoreX(OnError,OnStart, including separate outputs),MediaPlayerCoreX(OnError,OnStart,OnPause,OnResume) and the video fingerprintingFrameSource(OnError,OnStop) — the engines captured a snapshot of the handler list at start, so late subscribers were silently ignored and unsubscribing mid-session did not detach. - [Media Blocks SDK .Net] Fixed LiveVideoCompositor
Video_Effects_Clearremoving every channel's effects instead of only the requested channel's — clearing channel 0 no longer wipes the effects of all other channels for the rest of the run. - [Media Blocks SDK .Net] LiveVideoCompositor video-effect calls that target a channel which does not exist, or that run after the compositor was disposed, no longer throw
ArgumentOutOfRangeException— the call is ignored and reported through the log andOnError. Applies toVideo_Effects_AddOrUpdateAsync,Video_Effects_Get, bothVideo_Effects_RemoveAsyncoverloads andVideo_Effects_Clear. - [Media Blocks SDK .Net] Fixed LiveVideoCompositor
OnErrorhandlers never being called — pipeline errors were dropped instead of reaching subscribers. - [Media Blocks SDK .Net] Video effects added during playback are now inserted at their position in the effect list, so the applied order no longer depends on whether an effect was added before or during playback, and the block's output correctly follows the last effect after live additions and removals.
- [Media Blocks SDK .Net] Video effect names are now matched without regard to case. Adding
"Blur"and then"blur"updates one effect instead of creating a second one that could never be updated or removed, andVideo_Effects_Getkeeps finding an effect whatever case it is asked for. - [Media Blocks SDK .Net] Updating a video effect with one of a different type under the same name now replaces it in the pipeline. The graph used to keep applying the old effect and only report the mismatch.
- [Media Blocks SDK .Net] Fixed a video effect added while the pipeline was starting never reaching the pipeline for the rest of the run. It is now applied as soon as playback begins.
- [Media Blocks SDK .Net] Fixed adding, removing and updating video effects from several threads at once leaving a filter in the pipeline that no public call could reach, or applying settings to an effect that was being removed.
- [Media Blocks SDK .Net] Adding a video effect to a running pipeline now returns only once playback has resumed, so stopping right after it no longer reports that the pipeline could not be resumed.
2026.8.15¶
- [Media Player SDK .Net] / [Media Blocks SDK .Net] Fixed
Video_Effects_RemoveAsyncnever returning when the pipeline has nothing to pause — a player that was never opened, or one already being stopped. It polled for the paused state with no way out, and in one overload it blocked the calling thread outright, so the call could not be interrupted from outside either. It now checks the pause once and returns: a pause that did not land is reported through the log and the effect is left in place.LiveVideoCompositor.Video_Effects_RemoveAsyncis fixed the same way. - [Media Blocks SDK .Net] Fixed adding a video effect never returning when the pipeline is shutting down, and adding one to a paused pipeline waiting forever. The wait for playback to resume is now capped at thirty seconds; past it the effect is left for the next start and the wait is reported.
- [Media Blocks SDK .Net] Fixed a crash when changing a property of a video effect that is not applied to the running pipeline — one added while playback was paused or stopped, with at least one other effect already active. The property setter threw an exception instead of doing nothing.
- [Media Blocks SDK .Net] Fixed an effect being applied twice to a running pipeline, leaving a duplicate filter that could no longer be updated or removed, and an effect coming back after being removed when it had been re-added under the same name.
2026.8.14¶
- [Video Capture SDK .Net] / [Media Player SDK .Net] Fixed a GStreamer error when removing a video effect (grayscale, balance, and the other live filters) from a paused capture or player pipeline.
- [Video Capture SDK .Net] / [Media Player SDK .Net] Fixed video stopping after removing an image overlay, overlay manager, pan/zoom, or LUT effect at runtime.
- [Media Player SDK .Net] Fixed audio going silent after removing an audio effect during file playback.
- [Media Player SDK .Net] / [Media Blocks SDK .Net] Fixed a hang when removing pitch, compressor, loudnorm, or similar multi-element audio effects from a live pipeline.
- [Media Blocks SDK .Net] Fixed a crash when disposing an
AudioEffectsBlockthat still had effects in the public list. - [Video Capture SDK .Net] / [Media Blocks SDK .Net] Fixed MP4 recordings that could not be played back after stopping a paused capture (
VideoCaptureCoreX/MediaBlocksPipeline). Start → Pause → Stop (without Resume) left a non-zero file with nomoovindex. Stopping a paused capture now finalizes the file. - [Media Blocks SDK .Net] RTSP sources can send their own GET_PARAMETER keep-alive. Set
RTSPSourceSettings.ForceCustomKeepAlive(or the same flag onRTSPRAWSourceSettings) to replace the default RTSP keep-alive with a GET_PARAMETER every 30 seconds. Off by default — use it if a camera drops the session under the built-in keep-alive. -
[Demos] The RTSP Preview demos now have a transport selector (Auto / TCP / UDP) and a Force custom keep-alive checkbox, so a camera that works in VLC but dies after a minute can be tried the same way without rebuilding.
-
[Media Blocks SDK .Net] Fixed the first line of an
OverlayManagerText(andOverlayManagerDateTime) disappearing whenYwas 0 or close to the top of the frame.XandYare the top-left corner of the text in pixels;(0, 0)is a valid position and the first line of a multiline string is fully visible there. Previously the coordinates were treated as the Cairo baseline, so a block placed at the origin had its first line clipped off the top of the picture. - [Media Player SDK .Net]
MediaPlayerCoreXnow has the same overlay manager as capture. SetVideo_Overlay_EnabledbeforeOpenAsync/PlayAsyncand useVideo_Overlay_AddwithOverlayManagerText(includingTextProvider). The overlay is drawn on the preview only — after the sample grabber and after any custom video outputs — so the file on disk, snapshots and exports are not modified. Overlays added once stay acrossStopand opening another file.
2026.8.13¶
- [Media Blocks SDK .Net]
OverlayManagerTextcan now build its text for every frame through the newTextProvidercallback. SetTextProviderto aFunc<TimeSpan, string>and it is asked for the text once per frame, receiving the frame timestamp counted from the pipeline start; returningnullfalls back toText. This is the supported way to overlay a live readout — sensor values, a clock, a frame counter, or a template mixing all three — without removing and re-adding the overlay or touching the pipeline. AssigningTextdirectly still works and is equally cheap: the text layout is cached on the element and re-measured only when the string, font or geometry actually changes, so an unchanged value costs nothing. The callback runs on the streaming thread while the overlay list is locked, so it must be short and must not block — calling back into a UI dispatcher from it can deadlock rather than merely drop a frame. A callback that throws is reported once throughOnErrorand is then not called again: the element falls back toTextfor the rest of the run, because retrying it would unwind an exception at the frame rate under that lock. AssignTextProvideragain to re-enable it — worth knowing if your callback can throw on its first frame, while the values it reads are still being initialised.OverlayManagerDateTimeinherits the property and substitutes its[DATETIME]token into whatever the callback returned. - [Media Blocks SDK .Net] Overlay elements are now up to twice as fast on multi-core machines. Cairo-based overlays render through
cairooverlay, which only accepts BGRx/BGRA/RGB16, so a YUV source pays for two full-frame colour conversions per frame — and those conversions were running single-threaded, which was not enough to sustain 1080p50 on many machines. The recording branch was the first to suffer, because a preview renderer silently drops late frames while an encoder writes whatever reaches it, so the preview looked fine and the recorded file did not. Measured on a 14-core machine at 1920x1080 NV12: 361 to 815 frames per second throughOverlayManagerBlock. AffectsOverlayManagerBlock,ImageOverlayCairoBlock,PanZoomBlock, the mouse-highlight overlay and the Android text overlay. - [Media Blocks SDK .Net] Fixed
StartTimeandEndTimeon overlay elements being ignored unless both were set. The visibility window was only applied when neither value wasTimeSpan.Zero, so the common case of "show this for the first ten seconds" — a zeroStartTimewith a realEndTime— left the element on screen for the whole session. Either bound now defines a window on its own, and anEndTimeofTimeSpan.Zeromeans the element has no end. The break is symmetric, so check both directions: an element with onlyEndTimeset used to stay visible for the whole session and now disappears at that moment, and an element with onlyStartTimeset used to be drawn from the first frame and is now hidden until that moment. If you set either value and relied on it being ignored, clear it. Frames that carry no timestamp at all — anappsrcfeeding unstamped buffers, for instance — are outside any window that can be judged, and every element is drawn on them. - [Media Blocks SDK .Net] RTCP is now on by default for RTSP sources.
RTSPSourceSettings.DoRTCPandRTSPRAWSourceSettings.DoRTCPdefaulted tofalse, and the value is always written to the underlying RTSP source — so no VisioForge application ever sent RTCP receiver reports unless it set the property itself. Many cameras and RTSP servers use those reports to tell that the client is still watching and tear the session down without them: the picture freezes on the last decoded frame and the stream ends a session timeout later, with nothing in between to explain it. The same omission also madeNTPSyncineffective, because the NTP mapping arrives in RTCP sender reports. Both properties now default totrue, which is also the default of the underlying GStreamer element. SetDoRTCP = falseexplicitly if you talk to an old server that cannot handle RTCP. - [Demos] Fixed the RTSP Preview demos building a second pipeline when Start was clicked twice. Connecting to a camera takes a few seconds, and nothing appears on screen while it happens, so a second click was easy to make — it created a second pipeline over the same
VideoViewand opened a second session to the same camera. The two fought over the preview window, one of them failed with "Failed to open window", and on a camera that serves a single session its teardown stopped the stream for the surviving pipeline too, leaving a frozen picture. The Start button is now disabled while a start is in progress, a pipeline abandoned by a failed start is released instead of leaking, and the demos now report the stream ending — including a camera dropping the session — in their log instead of leaving a still frame with no explanation. - [Media Blocks SDK .Net] A user-defined overlay element can now be drawn through the new
IOverlayManagerDrawableinterface.Video_Overlay_Addaccepts anyIOverlayManagerElement, but only the built-in element types were rendered, so a custom type was silently never drawn. An element that implementsIOverlayManagerDrawable.Drawnow receives the live Cairo context of the frame exactly likeOverlayManagerCallbackdoes. A custom type that implements neither the interface nor a built-in type is still not drawn, but is now reported once throughOnErrornaming the type instead of failing silently.
2026.8.7¶
- [Core] The BCL cryptography packages now match the framework you target instead of always being the .NET 10 line.
System.Security.Cryptography.Pkcs,System.Security.Cryptography.XmlandSystem.Formats.Asn1were pinned at 10.0.10 for every target framework, so a .NET 6, 7, 8 or 9 application referencing a VisioForge package was pulled onto the 10.0.x line whether or not it wanted to be there — and an application holding the 8.0.x servicing line got a version conflict it could not resolve, because our own assemblies were compiled againstSystem.Security.Cryptography.Pkcs, Version=10.0.0.0. A .NET 6, 7 or 8 application now resolves the 8.0.x line and .NET 9 the 9.0.x line; .NET 10, .NET Framework 4.7.2/4.8 and .NET Standard are unchanged at 10.0.10. .NET Framework 4.6.1, .NET Core 3.1 and .NET 5 move down to the 6.0.x line — that is the only line these three are supported on, and it is what gives them a realnet461/netcoreapp3.1build instead of anetstandardfallback, but 6.0.x is out of support and did not receive the 2026System.Security.Cryptography.Xmlfixes. If you target one of those three frameworks and that matters to you, add an explicitPackageReferencetoSystem.Security.Cryptography.Xml 10.0.10in your own project — expect a build warning with it, because 10.0.x states it does not support those frameworks and falls back to itsnetstandard2.0build. That warning is exactly the reason the SDK itself does not take 10.0.x there. Every other rung sits at a patched version (8.0.4, 9.0.19, 10.0.10), because those advisories are fixed in each branch separately. On .NET 6 and .NET 7 this also replaces anetstandard2.0fallback with the real framework build. - [Core]
System.Text.Encoding.CodePagesnow matches the framework you target as well — 6.0.1 on .NET Framework 4.6.1, .NET Core 3.1 and .NET 5, 8.0.0 on .NET 6 and .NET 7, and 10.0.6 unchanged on .NET 8 and newer, on .NET Framework 4.7.2/4.8 and on .NET Standard. Those older frameworks were previously handed the 10.0.6 package, which states it does not support them and gave them anetstandard2.0build; they now get one made for the framework they run on. This package carries no security advisory at any version. - [Core] Fixed
VisioForge.DotNet.Corenot declaring its dependency onSystem.Security.Cryptography.Pkcs. The package has needed it since 2026.2.19 — the licensing code verifies Authenticode signatures — but it was declared only from 2026.4.21 onwards, and only as a side effect of how the dependency graph happened to be built. If you are on a version between 2026.2.19 and 2026.4.18, the shipped assembly requiresSystem.Security.Cryptography.Pkcs 10.0.0.0with nothing in the package asking for it; add the package reference yourself or move to a current release. - [Demos] Fixed the Unity package's sample scenes logging three "The referenced script (Unknown) on this Behaviour is missing!" errors each in any project that does not use the Universal Render Pipeline and the Input System. The scenes were authored from a URP 2D template and carried a
Light2D, aUniversalAdditionalCameraDataand anInputSystemUIInputModulethat none of the samples use — the video is rendered into a uGUIRawImage, which needs no render pipeline and no input module. They now open cleanly on Built-in, URP and HDRP alike. - [Demos] Fixed the Unity RTSP and IP-camera samples printing a "Frame stall" warning the moment a stream starts, on the first connect and on every reconnect after it. The watchdog compared its timeout against the time since the last decoded frame, which is infinite before the first frame ever arrives and, after a drop, still points at the last frame of the previous session — so it fired seconds before the camera could deliver anything. The reported stall is now capped at the age of the current stream, and a camera that genuinely never delivers is still reported after the same timeout.
- [Core] Fixed the Avalonia
VideoViewreporting a black background even when one was set.GetBackgroundColor()only read immutable solid-color brushes, so the mutableSolidColorBrushthe control installs itself — and any colour a user assigns — always fell back to black, and that wrong colour fed the renderer as its clear colour. It now reads any solid-color brush, mutable or immutable.
2026.8.6¶
- [Core] Fixed video editing and video preview breaking on macOS.
VideoEditCoreXfailed every render that had a video track — any container, any codec — withInternal data stream error, while audio-only output still worked; andVideoRendererBlockfroze the pipeline on the first frame in any application without a Cocoa UI running on its main thread, such as a console tool, a background service or a test host. GStreamer picks several elements automatically by rank rather than by name, and the Metal elements' ranks put them ahead of the software ones, so they were selected in places they were never meant for — including as the mixer inside every video-editing timeline. They are now registered for explicit use only, and the Metal video renderer is used only when you give it a view to draw into.MetalVideoCompositor,MetalConvertScale,MetalVideoRendererSettingsand the other Metal wrappers are unaffected and still give you GPU rendering when you ask for it. - [Core] Fixed
VideoRendererBlock(pipeline, windowHandle)ignoring the window handle on Windows and macOS — only the Android and iOS paths read it, so elsewhere the renderer behaved as though no target window had been given and opened one of its own. On macOS this constructor now also defaults to the Metal renderer, which is the only one there that can draw into a handle you supply. Two consequences, both documented on the constructor: the handle must be anNSView*(not anNSWindow*), and your main thread must keep running a Cocoa run loop while the pipeline plays, because the Metal renderer attaches to the view on the main queue.
2026.8.5¶
- [Core] The SDK no longer brings a pre-release package into your dependency graph. SkiaSharp moves from
3.119.4-preview.1.1to the stable3.119.4, and Avalonia from 12.0.3 to 12.0.5 — the two had to move together, because Avalonia itself switched to the stable SkiaSharp in 12.0.4 and holding it back would have kept a preview build of the WebAssembly native assets in the graph. Restoring a VisioForge package used to pull those preview builds transitively, with no opt-in on your side and no warning: they simply appeared in your lock file and indotnet list package --include-transitive. That matters if you mirror packages into an internal feed that rejects pre-release versions, or if a policy scan flags them. Everything the SDK resolves is now a stable release. The SkiaSharp difference itself is confined to bundled native libraries (libexpat 2.7.5, libpng 1.6.58) — no API changed. - [Core] The Avalonia package no longer brings a nightly build of DialogHost.Avalonia with it.
VisioForge.DotNet.Core.UI.Avaloniauses MessageBox.Avalonia forShowMessageEx, and MessageBox.Avalonia 12.0.0 — still its newest release — depends onDialogHost.Avalonia 0.12.1-nightly.0.1, so that nightly landed in the dependency graph of every application referencing our Avalonia package. DialogHost is now pinned to the stable 0.12.3. No API or behaviour change on our side. - [Core]
VisioForge.DotNet.Core.AI.Whispernow requires .NET 8 or newer. Seven builds are gone from the package —net5.0,net5.0-windows,net6.0,net6.0-windows,net7.0,net7.0-windowsandnet7.0-windows10.0.19041.0— so a WinUI or WPF head on one of those is affected as much as a plain console project.net8.0,net9.0,net10.0and their Windows, Android, iOS, macOS and Mac Catalyst variants are unchanged. Speech-to-text runs on Whisper.net, which now depends onMicrosoft.Extensions.AI.Abstractionsand through it onSystem.Text.Json10, andSystem.Text.Json10 states that it does not support and has not been tested on anything below .NET 8 — so those seven builds could only have shipped in a configuration Microsoft declares untested. .NET 5, 6 and 7 are themselves all out of support. If you reference this package from any .NET 5, 6 or 7 project, retarget it tonet8.0or later — keeping the same platform suffix if it has one; no code changes are needed. Only this package is affected — every other VisioForge package keeps its full framework list, down to .NET Framework 4.6.1. - [Core] The macOS native package now ships the SRT and WebRTC GStreamer plugins. Six plugins —
libgstsrt.dylib,libgstsrtp.dylib,libgstwebrtc.dylib,libgstrswebrtc.dylib,libgstwebrtcdsp.dylibandlibgstwebrtchttp.dylib— and the three libraries they load against (libgstwebrtc-1.0.0.dylib,libgstwebrtcnice-1.0.0.dylib,libsrt.1.5.3.dylib) were built and kept current but never packaged, so on macOS any pipeline using SRT or WebRTC failed to find its element, while identical code worked on Mac Catalyst, whose package has carried them all along.VisioForge.CrossPlatform.Core.macOS.Addsnow ships the same 58 files as its Mac Catalyst counterpart.
2026.8.1¶
- [Demos] Fixed several shipped samples referencing outdated packages. The macOS and Mac Catalyst native packages in the demo projects were six months behind the published versions, a
net472demo pinned aSystem.Resources.Extensionsbuild meant for .NET 8 and newer, and the Virtual Camera and WebM redistributables were pinned to 2023-era releases. If you copied a demo project as a starting point, its package references were older than the SDK you installed. - [Core] Security: updated
System.Security.Cryptography.Xmlto 10.0.10, closing five advisories that affected the version shipped before it — CVE-2026-47304, a bypass of XML encryption protections rated 8.1, and four denial-of-service issues rated 7.5.System.Security.Cryptography.PkcsandSystem.Formats.Asn1moved to 10.0.10 with it. The SDK does not call these APIs itself; they are reached through WCF, which ONVIF device communication uses. No action is needed on your side beyond taking the new package — but a security scan run against the previous release will have flagged it. - [Core] Fixed a random process crash while GStreamer objects were being released. On any platform, an application could die with an access violation (
0xC0000005on Windows,SIGSEGVon macOS) on a background thread, with no error, no exception and nothing in the log to connect it to what the application had been doing — the crash landed long after the code that caused it. The SDK now checks that a native object is still alive before releasing it, and when it is not, writes one line naming the type instead of taking the process down. - [Core] API change:
VisioForge.GStreamer.API.CustomAPI.g_signal_connect,g_signal_connect_dataandg_signal_handler_disconnectnow useUIntPtrfor the GLib signal handler id instead ofuint. The id is agulong, which is 64-bit on macOS, Linux, iOS and Android, so the previous declaration truncated it. These are low-level interop helpers; if you call them directly, change the variable holding the handler id toUIntPtr. - [Media Blocks SDK .Net] The SDK no longer takes ownership of the elements a decoder builds while playing a file. Playing any file made the SDK hold a native reference to every element inside
uridecodebin— parsers, demuxers, queues, several hundred per playback — and those references were given back only later, on a background thread, so the elements stayed alive past the pipeline that owned them. This is the same ownership mistake behind the render-time crash fixed below, on the playback path; measured on a four-class test run, the number of such references dropped by 78%. Affects every engine that plays or captures through a file or URL source. - [Core] Fixed an error or warning on the pipeline bus tearing down the bus handler. In
VideoEditCoreXandSimplePlayerCoreX, an error message that carried no source element raised aNullReferenceExceptioninside the handler, so that message and every message after it was lost — including the error you needed to see. A state-change message with no source could also be mistaken for one from the pipeline itself while the pipeline was being torn down. - [Video Edit SDK .Net] Fixed a process crash after rendering with
VideoEditCoreX. An application that rendered several timelines in one session could die with an access violation on a background thread, typically long after the render had finished and the objects involved had been released. Rendering to WMV made it most likely, but the underlying cause affected any render. Applications that create and destroyVideoEditCoreXrepeatedly — batch converters, render services — were the most exposed. - [Core] Fixed
Debug_Modewriting an empty log file. With debug logging enabled, the log was buffered and never flushed when the engine was disposed, so a short session produced an empty file and a longer one lost everything after the last automatic flush — exactly the log you are asked for when reporting a problem. The file also stayed locked for the life of the process, so it could not be read or deleted. AffectsVideoCaptureCoreX,MediaPlayerCoreX,SimplePlayerCoreX,VideoEditCoreXandMediaBlocksPipeline. - [Core] Fixed the same empty log file when the engine was disposed with
await using. The fix above covered the synchronousDispose()only, soMediaPlayerCoreXandSimplePlayerCoreXreleased asynchronously — the form most applications use — still produced an empty or truncated log and still held the file open.SimplePlayerCoreX.DisposeAsyncis also safe to call twice now, and on all three engines a failure during teardown no longer swallows the log, which is precisely the case you need it for. - [Media Blocks SDK .Net] Fixed open-vocabulary detection exhausting memory on Apple hardware.
OpenVocabularyDetectorBlockandObjectAnalyticsBlockwith an open-vocabulary detector could consume every gigabyte the machine had and bring it down rather than produce a detection. ONNX Runtime cannot map OWLv2 or Grounding DINO onto CoreML in one piece — it splits them into 126 and 255 separately compiled models — soProvider = Autonow selects the CPU for these two model families on Apple hardware and leaves every other AI block unchanged. SettingProvidertoCoreMLby name still does what you ask; it is not recommended for these models. On the CPU provider the memory retained after a detector is disposed also drops by about 2.4 GB on the same models, with no change to inference time. - [Media Blocks SDK .Net] Fixed a crash while tearing down
ObjectAnalyticsBlockwith an open-vocabulary detector. Disposing the block while a frame was still being analysed could free the inference session underneath the analysis and abort the process. - [Core] Fixed Media Foundation H.264 and H.265 encoder settings being silently ignored. On a machine whose Media Foundation encoder does not advertise a given control - the property set differs by GPU, driver and machine - the SDK wrote the value anyway. Nothing threw, the call reported success, and the encoder quietly kept its default, so the same code produced different output on different machines with no way to tell. Settings the encoder cannot accept are now skipped, and each one is named in a warning. This covers encoders you build yourself (
HEVCEncoderBlock,H264EncoderBlock,CreateBlock()) and the AMD MA35D encoders and decoders. Encoding profiles -MP4Outputand the other render outputs - are not covered yet, so the original symptom can still occur there. - [Core] Fixed an instability while enumerating Decklink capture cards and outputs. Plugging a card in or out, or listing devices from more than one place at once, could leave the SDK using a device object it had already released — harmless in the log on a good day, a crash on a bad one.
- [Core] Fixed WASAPI2 audio capture breaking up under load and never recovering. From 2026.3.7, audio captured through a WASAPI2 device could develop artifacts that got worse over time and only cleared when the pipeline was restarted; the log filled with
Found N frames gapwarnings. The bundled GStreamer runtime was requesting a capture buffer of roughly 20 ms instead of the 200 ms it used to, so any brief stall lost audio at the driver. The buffer is back to its previous size on capture and playback alike, and theLowLatencysetting again means what it says. Affects Windows x86, x64 and ARM64. - [Core] Added
BufferTimeandLatencyTimetoWASAPI2AudioCaptureDeviceSourceSettings,WASAPIAudioCaptureDeviceSourceSettings,LoopbackAudioCaptureDeviceSourceSettings,WASAPIRendererSettingsandWASAPI2RendererSettings. They control how much audio the device buffers — raiseBufferTimeon machines that see brief CPU spikes, lower it when you need latency. Defaults are 200 ms and 10 ms, matching previous behaviour; set either toTimeSpan.Zeroto leave the underlying element untouched. - [Core] An audio renderer whose output plugin is missing from the deployment now reports a clear error instead of throwing a
NullReferenceExceptionout ofStartAsync. - [Core] Fixed the built-in HLS/DASH HTTP server never starting on Windows unless the application ran as administrator. With
Custom_HTTP_Server_Enabledset, the sink reported no error and the pipeline ran, but nothing was ever served — the server bindshttp://*:<port>/, which Windows refuses to a process without an elevated token unless a URL reservation exists, and the failure went no further than one line in the log. The server now falls back to the loopback prefixes — bothhttp://localhost:<port>/andhttp://127.0.0.1:<port>/, so a player on the same machine works whichever of the two it is given — and the log names thenetsh http add urlaclcommand to run once as administrator to reach the server from other devices. Elevated applications and machines that already have the reservation are unaffected, as are macOS and Linux. - [Core] Fixed an application that never exits after
DestroySDK(). The SDK runs the GStreamer main loop on a foreground thread, andDestroySDK()could return having failed to stop it: the request to stop was dropped whenever it arrived in the moment between that thread being created and it reaching the loop, and nothing checked afterwards. The process then stayed alive with no window, no error and nothing running — visible as an application that closes but keeps a process in the task list, or a console tool that never returns to the prompt.DestroySDK()now waits for the loop thread to actually finish before returning, and reports it in the log if it does not. - [Core] Fixed the WASAPI2 audio renderer going silent whenever
Volumewas below 1.0. The value was passed to the renderer as a whole number, so anything between 0.0 and 1.0 was rounded down to zero — settingVolume = 0.5produced silence rather than half volume. OnlyVolume = 1.0behaved as expected.
2026.7.27¶
- [Media Blocks SDK .Net] Fixed a stopped pipeline not resuming when it was started again — after
StopAsync(), aStartAsync()on the sameMediaBlocksPipelinewith the same blocks returnedtrueand then did nothing: a recorder wrote no bytes, a preview stayed black, and no error was reported. Stopping now keeps the blocks and the connections you made, and starting rebuilds the pipeline from them, so the same pipeline instance can be recorded, stopped and recorded again. You no longer have to recreate the pipeline and every block between runs (doing so still works). A sink filename changed between runs —SetFilenameOrURL— is picked up by the next run. - [Media Blocks SDK .Net] Fixed a group of blocks that stayed silent after a pipeline was restarted, each in the same way: the block reported a successful start and then produced nothing. OCR (
OcrBlock) and Data Matrix (DataMatrixDecoderBlock) stopped raising their detection events;UniversalDemuxBlock,UniversalAutoDemuxerBlockandUniversalDecoderBlockdelivered no data on the second run (the demuxer could also throw from a streaming thread);StreamSourceBlockcame up over a closed stream, and now also rewinds a seekable one so a restarted source plays from the beginning;PreEventRecordingBlockdropped every frame and then threw fromTriggerRecording(); both squeezeback blocks failed to rebuild. The bridge blocks silently lost theOnEOShandler you had attached at the first stop. - [Media Blocks SDK .Net]
MediaBlocksPipeline.ClearBlocks()now disposes the blocks it removes. Removing a block hands it back to nobody, and the stop path no longer disposes it, so keeping it alive leaked whatever it held — an inference session, an encoder, a device handle. Do not callClearBlocks()for blocks you mean to reuse; a stopped pipeline can simply be started again with the same blocks. - [Media Blocks SDK .Net] A stop no longer closes a file opened by
StreamSourceBlock(filename)for good: the file is released on every stop, as before, and reopened when the pipeline is started again. Stopping and then deleting, overwriting or re-recording to the same path keeps working. A stream you passed in yourself is still never closed by the block — it is yours. - [Media Blocks SDK .Net] Fixed a crash on Android when the video surface was recreated after the pipeline was stopped — rotating the device or returning from the background after
StopAsync()dereferenced the pipeline the stop had already released. - [Media Blocks SDK .Net] Fixed an intermittent crash while a pipeline was being stopped or restarted. Under a restart-heavy load the process aborted outright about one run in three, with no exception to catch — a bus message could still be in the middle of being handled when the stop released the pipeline underneath it. Stopping now waits for an in-flight bus message to finish before releasing anything, and gives up after two seconds rather than hanging.
- [Media Blocks SDK .Net] Fixed a family of latent memory-corruption defects around teardown and restart, in sample grabbers, renderers, sources, decoders, bridge blocks, effects and device enumeration. Nothing failed visibly: GStreamer's own type checks turned the affected calls into no-ops, so the symptom was warnings in the log rather than a crash — but the same code was one timing change away from a hard
AccessViolationException. Restarting a pipeline produces far fewerGST_IS_ELEMENT/GST_IS_PADwarnings; the remaining ones are being worked through. - [Media Blocks SDK .Net] Fixed removing a video or audio effect at runtime leaving the pipeline holding a released element. Every effect filter — 51 of the video ones and 15 of the audio ones — released its GStreamer element while still pointing its own input and output at it, so removing an effect, or clearing them all, worked on the surface while the next teardown reached through a dangling reference. As with the teardown defects above, GStreamer's type checks kept it to log warnings instead of a crash, but the memory was already gone.
- [Media Blocks SDK .Net] Fixed
UniversalTransformBlockreleasing its own pads on the first frame. The transform callback released the pads the block had published, so every later probe, unlink and teardown on that block used a dead reference.CustomMediaBlockdid the same to the pads its wrapped element owns, including the pad handed to it when a demuxer creates one. - [Core] Fixed a reference-counting error that corrupted GStreamer's encoder registry on Windows. Enumerating the available hardware encoders released a reference the SDK never held, on every encoder registered on the machine — audio ones included. GStreamer detected it, logged a warning per encoder and recovered, so nothing failed visibly, but the accounting was left inconsistent and a concurrent registry change could have turned that into a crash.
- [Media Blocks SDK .Net] Fixed Vorbis audio bitrate settings being ignored.
VorbisEncoderSettings.Bitrate,MaxBitrateandMinBitrateare documented as "-1 to disable", which is also their default, and that default was passed to the encoder as an out-of-range value. The encoder rejected the whole assignment and fell back to its own defaults, so a bitrate you set took effect only if you had also set the other two. Encoding profiles built from these settings carried the same invalid value. - [Media Blocks SDK .Net] Fixed the pipeline-graph debug helpers misbehaving once playback had finished.
Debug_GetPipeline()andDebug_SavePipeline()called after a stop — including the stop that happens on its own when a file reaches the end — wrote no graph and logged a GStreamer warning instead.Debug_GetPipeline()now returns an empty string, as documented, andDebug_SavePipeline()does nothing. The same applies toVideoCaptureCoreX.Debug_SavePipeline(). - [Video Capture SDK .Net] Fixed
Video_Source_GetResolutionAndFrameRateandAudio_Source_GetInfodamaging a running capture. Both released the source block's own pad, so calling either of these read-only queries while capturing left the source unusable. - [Video Capture SDK .Net] Fixed the second recording of a separate-capture output silently producing no file. With an output registered and the engine running,
StartCaptureAsync(index, filename)worked the first time and every later call returnedtruewhile writing nothing — the record button worked exactly once per application run. All subsequent recordings now write to the file passed toStartCaptureAsync, with the preview left untouched, which is what the API is for.
2026.7.26¶
- [Media Blocks SDK .Net] Added
AndroidUVCSourceBlock— capture from a USB (UVC) camera connected to an Android device over OTG, such as a webcam or a capture dongle. These cameras are invisible to the regularSystemVideoSourceBlock, because Android only exposes them through Camera2 on devices whose vendor ships the External Camera HAL (Samsung, among others, does not). Connected cameras are listed withAndroidUVCDevices.FindCameras(), access is requested withAndroidUVCDevices.RequestPermissionAsync(), and the requested resolution and frame rate are matched against the modes the camera advertises. Your app must declare and be grantedandroid.permission.CAMERA— Android refuses to hand a USB video device to an app without it, even though the Android camera API is not used. Unplugging the camera ends the stream, so the pipeline reports end-of-stream rather than stalling silently. Requires Android 9 (API 28) or later. Note that a camera enumerating at USB 2.0 speed offers markedly lower frame rates than on a desktop: a Logitech BRIO, for example, tops out at 1080p30 (MJPEG) with no 4K modes available at all. - [Video Capture SDK .Net] USB (UVC) cameras on Android can now be used with
VideoCaptureCoreX— assign anAndroidUVCSourceSettingstoVideo_Sourceand the camera works like any other source, so recording to MP4, network streaming, video effects and snapshots are all available. NewAndroidUVCDevices.GetModes()lists the resolutions, frame rates and formats you can actually pick from — formats the SDK cannot stream are left out — so you can offer the real choices instead of requesting a mode and silently getting the nearest one, andAndroidUVCSourceSettings.Formatasks for one of them. Two things to know: an unplugged camera is reported throughOnError, notOnStop- and only once the stream has been silent for a few seconds, so handle Android'sACTION_USB_DEVICE_DETACHEDbroadcast as well if your app needs to react the moment the cable comes out; and a camera with a built-in microphone also registers as a USB audio input that Android prefers for recording but that cannot be captured while the camera is streaming, so such a recording is video-only. Live capture should also set the newVideoCaptureCoreX.Video_Output_IsSync = false, which stops the bridge feeding an output pipeline from waiting on the clock - left synced it can fill its queue and stall the preview along with it.Audio_Output_IsSyncis the matching switch for the audio branch, so a capture with audio can hand both branches over on the same terms. - [Demos] Added a USB Camera Android sample showing live preview from a UVC camera attached over OTG, including the device and permission handling, in both a Media Blocks SDK and a Video Capture SDK version — the latter also records to MP4.
2026.7.24¶
- [Video Capture SDK .Net] Fixed Picture-in-Picture crashing on .NET 9 and .NET 10 —
VideoCaptureCoreterminated with an unrecoverableExecutionEngineExceptionatStart/StartAsyncas soon as a PiP source was added (the same code worked on .NET 8). Adding a PiP overlay now works on all supported .NET versions. - [Video Edit SDK .Net] Fixed the legacy FFMPEG output crashing at start on .NET 9 and .NET 10 with the same
ExecutionEngineException; it now works as it did on .NET 8. - [Media Blocks SDK .Net] [Video Capture SDK .Net] Fixed video missing or corrupted when streaming MPEG-TS over SRT (
SRTMPEGTSSinkBlock,SRTOutput). The MPEG-TS muxer now emits a full 1316-byte payload per buffer instead of one transport packet at a time, so SRT sends whole datagrams rather than seven times as many undersized ones. Receivers such as MediaMTX, ffmpeg or OBS no longer see an audio-only or truncated stream. The UDP, multi-UDP and RIST MPEG-TS outputs get the same alignment. - [Media Blocks SDK .Net] [Video Capture SDK .Net] Fixed corrupted video from the Apple (iOS / macOS / Mac Catalyst) H.264 hardware encoder.
AppleMediaH264EncoderSettings.AllowFrameReorderingwas enabled by default; the resulting B-frames left a large share of the encoded frames with a presentation timestamp earlier than their own decode timestamp, so MPEG-TS outputs (SRT, UDP, RIST) and MP4/MOV recordings played back torn or undecodable in MediaMTX, ffmpeg and VLC. RTMP/FLV happened to tolerate it, which is why streaming from iOS looked broken over SRT but fine over RTMP. The property now defaults tofalse; set it back totrueonly for offline encoding where you can verify the resulting timestamps. - [Media Blocks SDK .Net] [Video Capture SDK .Net] Fixed SRT and RIST output failing to start on macOS and Mac Catalyst when the Apple hardware H.264 encoder was used: the stream parser those outputs need to feed the MPEG-TS muxer was omitted on those platforms.
- [Media Blocks SDK .Net] [Video Capture SDK .Net] [Video Edit SDK .Net] Fixed MPEG-TS output producing an empty file when AAC audio was encoded with a software encoder (
voaacenc, used on macOS, Linux and iOS). The MPEG-TS muxer only accepts framed AAC, which those encoders do not advertise, so the audio never linked and the muxer waited on it instead of writing - the recording ended as a 0-byte.ts. AffectsMPEGTSSinkBlock/MPEGTSOutputand the SRT, UDP and RIST outputs built on them. - [Media Blocks SDK .Net] Fixed RTSP playback failing with "Failed to link RTSP pad: WasLinked" in
UniversalSourceBlockV2. When the source announced a pad it had already handed over - on reconnect, or when a server re-announced a stream - the block tried to link it a second time and reported the result as an error, ending the session. - [Media Blocks SDK .Net] Fixed DASH output never starting (
DASHSinkBlock): the sink requested its input pads without a name, whichdashsinkrejects because it takes the stream index from the pad name. No manifest or segments were written and the pipeline hung on start instead of reporting the failure. - [Media Blocks SDK .Net] Fixed text overlays rendering as empty boxes (▯▯▯) on iOS, Android and macOS — the SDK now sets up font resolution at startup, so
TextOverlayBlock, subtitle overlays and the trial watermark draw real glyphs instead of tofu. Fonts your app bundles are picked up automatically, and on iOS the SDK carries a fallback font so text renders even in an app that bundles none.
2026.7.22¶
- [Video Capture SDK .Net] Fixed RTSP / IP camera login and password being URL-encoded, which broke authentication for credentials containing special characters such as
&,@,%,?or spaces (e.g. a passwordpassword&@%!?Endwas sent to the camera aspassword%26%40%25!%3fEnd). Credentials are now used verbatim. Applies to both theRTSPSourceSettings(X engine) andIPCameraSourceSettings(VideoCaptureCore) sources. If you previously worked around this by storing the pre-encoded value on the device, revert it to the real password after upgrading. - [Core] MAUI apps now build cleanly for Android 16: the bundled HarfBuzzSharp native library is updated to a 16 KB page-size-aligned build, removing the
XA0141("Android 16 will require 16 KB page sizes") warning on Android app builds.
2026.7.21¶
- [Media Blocks SDK .Net] Added AMD Alveo MA35D hardware acceleration (via the AMD AMA Video SDK) on Linux: H.264, HEVC and AV1 encoders (
AMAH264EncoderSettings/AMAHEVCEncoderSettings/AMAAV1EncoderSettings), matching decoders, and anAMAScalerBlock. A specific MA35D card is selected with theDeviceproperty (-1auto-selects), so you can pin encoding/decoding to the accelerator rather than the host GPU. Requires the AMD AMA Video SDK (kernel driver + GStreamer plugins) to be installed.
2026.7.10¶
- [Media Blocks SDK .Net] Added
AudioEventDetectorBlock— on-device audio event detection that recognizes real-world sounds (siren, dog bark, glass break, alarm, music, speech, and hundreds more from the 521-class AudioSet ontology) in live or file audio using a YAMNet ONNX classifier. Audio passes through unchanged; detections are raised viaOnAudioEventwith a label, confidence, and start/end time, using score smoothing and hysteresis so one continuous sound is a single event rather than a burst of duplicates. Optional class allowlist and a live top-K scores event. Works inVideoCaptureCoreX/MediaPlayerCoreXviaAudio_Processing_AddBlock. - [Demos] Added an Audio Event Detection WPF sample (Media Blocks SDK): open a file or select a microphone, live event log with label/confidence/time, class-filter box, and threshold slider.
2026.7.9¶
- [Core] Video stream info now reports the pixel aspect ratio (
VideoStreamInfo.ParNumerator/ParDenominator) when the negotiated caps carry it, so anamorphic sources can be displayed at the correct proportions. - [Media Blocks SDK .Net] Fixed pipeline restart after a failed start: blocks no longer report themselves as built when their Build fails, so a retried start rebuilds them instead of running a half-built pipeline.
- [Media Blocks SDK .Net] File output blocks (M4A/MP4/MKV/AVI) now fail cleanly instead of throwing an unhandled exception when configured with an unsupported encoder, so the pipeline reports a normal start error you can handle.
- [Core] Fixed stale frame dimensions after a mid-stream resolution change in video frame grabbing: frame callbacks and snapshots kept reporting the old width/height/stride, so the frame data could be mis-read at the new size.
- [Media Blocks SDK .Net] Added AI auto-reframe (
AutoReframeBlock): converts landscape footage into vertical 9:16 (or 1:1, 4:5) video that dynamically crops around the detected subject with smooth, jitter-free tracking — ideal for Shorts/Reels/TikTok. - [Demos] Added an Auto Reframe WPF sample (Media Blocks SDK): open a landscape file, follow the subject in a side-by-side original/reframed preview (9:16, 1:1, or 4:5), configure smoothing, dead zone, detection interval, and the followed class, and optionally export the reframed output to MP4.
- [Media Blocks SDK .Net] Added on-device speaker diarization ("who spoke when"): the new
SpeakerDiarizationBlockanalyses the audio as it plays and, once the recording has finished, reports every speech turn with the speaker who made it. Diarization is inherently offline — a voice heard at minute 1 can only be matched to the same voice at minute 40 once the whole recording has been heard — so the turns are raised at end-of-stream (OnSpeakerSegment, orGetTimeline()in one piece); checkIsTimelineCompletebefore reading them. Pair it with speech-to-text viaDiarizedTranscriptBuilderfor a speaker-labeled transcript. Works withMediaPlayerCoreX/VideoCaptureCoreXand manual Media Blocks pipelines. SetNumSpeakerswhen you know the count, or leave it at-1and tuneClusterThreshold(a cosine distance — smaller yields more speakers). - [Media Blocks SDK .Net] Speaker diarization is multilingual: alongside the default English WeSpeaker voiceprint model you can select the Apache-2.0 3D-Speaker ERes2NetV2 embedding (
SpeakerDiarizationSettings.EmbeddingModel = ERes2NetV2Multilingual) for far better speaker separation on non-English or mixed-language audio. The feature front-end adapts to the chosen model automatically, so no other code changes are needed when you switch. - [Media Blocks SDK .Net] Fixed degraded speech-to-text accuracy on any source that is not already 16 kHz mono — that is, on essentially every camera, capture card, media file and RTSP stream. The audio front-end decimated to the 16 kHz the model needs without band-limiting first, so everything above 8 kHz folded back into the speech band and corrupted the features both Whisper and the voice-activity detector consume. The audio is now low-pass filtered before the rate conversion.
- [Media Blocks SDK .Net][Video Capture SDK .Net] Added PTZ auto-tracking — an ONVIF PTZ camera can now automatically follow a detected object.
PTZAutoTrackingControllerturns detections fromObjectAnalyticsBlock(orYOLOObjectDetectorBlock) into continuous pan/tilt/zoom commands with a configurable dead zone, sticky target tracking, a lost-target timeout (with optional return-to-preset), and command rate limiting. Target selection by largest object, first detected, tracker ID, or class label. Includes the new "PTZ Auto Tracking" WPF demo. - [Media Blocks SDK .Net][Video Capture SDK .Net] PTZ auto-tracking can now run an idle preset patrol — when no target reappears for a configurable delay, the camera cycles through a list of ONVIF presets (with a per-preset dwell time) until a new target is acquired, which immediately aborts the patrol and resumes tracking.
- [Demos] Added a PTZ Auto Tracking WPF sample for the Media Blocks SDK — the same ONVIF auto-tracking built on a low-level
MediaBlocksPipeline(RTSP source →ObjectAnalyticsBlock→ video renderer, withPTZAutoTrackingControllerdriving the camera). - [Media Blocks SDK .Net] Added
VideoStabilizationBlock— real-time video stabilization that removes camera shake by estimating global inter-frame motion (translation and rotation) with OpenCV optical flow, smoothing the camera trajectory, and warping each frame back onto the smoothed path. Configurable smoothing radius, crop/zoom ratio, and per-frame correction limits; all tunable live. Requires the OpenCV redistributable (Windows). - [Media Blocks SDK .Net][Video Capture SDK .Net][Media Player SDK .Net]
VideoStabilizationBlockcan now be used with the X engines: pass it toVideo_Processing_AddBlock()onVideoCaptureCoreXorMediaPlayerCoreXto stabilize a live camera or a playback stream, with live retuning throughApplySettings(). - [Demos] Added a Video Stabilization WPF sample (Media Blocks SDK): open a file, preview stabilized playback, record the stabilized result to MP4, and adjust the smoothing radius and crop ratio live.
- [Demos] Added a Video Stabilization Capture X WPF sample (Video Capture SDK X): stabilize a live camera with
VideoCaptureCoreXand tune the stabilizer while the capture runs. - [Demos] Added a Video Stabilization Camera WPF sample (Media Blocks SDK): stabilize a live camera with a hand-built
MediaBlocksPipeline(camera source → stabilizer → renderer), with live tuning.
2026.7.8¶
- [Video Edit SDK .Net] Fixed a native process crash (fail-fast) when rendering FLAC output from a timeline with more than one clip (or a gap before the audio clip) in
VideoEditCoreX. - [Video Capture SDK .Net] Fixed empty WMA audio-only recordings from the legacy
VideoCaptureCoreengine: the default WMA profile was variable-bitrate (VBR), which the WM ASF Writer cannot produce from a live capture source, so the file contained only an ASF header with no audio data. The default is now an equivalent constant-bitrate WMA profile. - [Core][Video Capture SDK .Net][Media Blocks SDK .Net] Fixed a 32-bit (x86) ABI bug that mis-sized the native
GMutexfield (as a pointer) in the GStreamer object layout, shifting every element's field offsets by 8 bytes on x86. This made the element pad list read as empty and caused a NullReferenceException crash whenever the video/audio sample grabber, snapshots, or a frame-processing block was used on 32-bit. Frame grabbing, snapshots, and per-frame processing now work correctly on x86 (x64 unaffected).
2026.7.6¶
- [Media Blocks SDK .Net] Fixed an intermittent "Unable to create sample grabber element" failure that could occur when starting several camera pipelines (e.g. multiple RTSP cameras) at the same time. Managed element construction is now thread-safe.
- [Media Blocks SDK .Net] Fixed a NullReferenceException crash in the video sample grabber (and related processing elements) that could occur on the streaming thread when a frame buffer was momentarily unavailable.
2026.7.3¶
- [Media Blocks SDK .Net] Added
PIIRedactionBlock— automatic on-video redaction of personally identifiable information: faces (YuNet), vehicle license plates (FastALPR detector), and on-screen text (PP-OCRv5 detection + recognition — recognition filters out the detector's non-text false positives — with an optional regex filter that redacts only matching text such as e-mails or phone numbers). Redaction styles: Gaussian blur, pixelate, and solid fill. Each category can be toggled live; regions are padded and held between detection cycles so PII stays covered through motion and detector flicker. Works inVideoCaptureCoreX/MediaPlayerCoreXviaVideo_Processing_AddBlock. - [Demos] Added a PII Redaction WPF sample (Media Blocks SDK): webcam, file, or RTSP source with live category/style switching.
- [Demos] Added Player PII Redaction X and Capture PII Redaction X samples (WPF and MAUI) — live face/plate/text redaction on
MediaPlayerCoreX(file playback) andVideoCaptureCoreX(camera) viaVideo_Processing_AddBlock.
2026.7.2¶
- [Media Blocks SDK .Net] Added an open-vocabulary object-detection block (
OpenVocabularyDetectorBlock) that detects objects from free-text prompts (OWLv2 / Grounding DINO) instead of a fixed class list, with prompts swappable at runtime. It can also driveObjectAnalyticsBlockas a detector for tripwire / zone analytics. - [Media Blocks SDK .Net] Added a Florence-2 vision-language block (
VLMBlock) for frame captioning, OCR, phrase grounding, and object detection. - [Media Blocks SDK .Net] Added a CLIP video-embedding block (
VideoEmbeddingBlock) with a semantic frame-search index, for natural-language search over indexed video. - [Media Blocks SDK .Net]
VideoEmbeddingBlockcan index a file at full decode speed with no dropped samples viaVideoEmbeddingSettings.BackpressureNoDrop(backpressures the pipeline instead of dropping frames when the encoder is busy). - [Media Blocks SDK .Net]
OpenVocabularyDetectorBlockconfidence and IoU thresholds can now be adjusted at runtime (SetConfidenceThreshold/SetIoUThreshold); the new value takes effect on the next frame without rebuilding the pipeline. - [Demos] Added three WPF samples: Open Vocabulary Detection, VLM Captioning, and Semantic Video Search.
- [Media Player SDK .Net] Added
MediaPlayerCoreX.Video_Renderer_IsSync— set it tofalseto run the video renderer without clock synchronization so a file is processed at full decode speed (for offline AI indexing / analysis) instead of in real time;null(default) keeps the automatic behavior. - [Demos] Added X-engine versions of the new AI samples (WPF and MAUI): Open Vocabulary Detection and VLM Captioning for both
VideoCaptureCoreX(camera) andMediaPlayerCoreX(file), plus Semantic Video Search forMediaPlayerCoreX. Each inserts the AI block through theVideo_Processing_AddBlockAPI.
2026.6.30¶
- [Demos] Added Face Recognition and OCR demos for the X engines, in both WPF and MAUI: Player Face Recognition X and Player OCR X (
MediaPlayerCoreX), plus Capture Face Recognition X and Capture OCR X (VideoCaptureCoreX). Each inserts the AI block through theVideo_Processing_AddBlockAPI — the face demos enroll people from photos and label them on the video; the OCR demos draw and log recognized text. - [Demos] Added a Capture Live Subtitles X WPF sample (
VideoCaptureCoreXwith on-device Whisper speech-to-text subtitles).
2026.6.29¶
- [Media Blocks SDK .Net] Speech-to-text (
SpeechToTextBlock) now always transcribes the full input losslessly — the source is paced to Whisper so no audio is ever dropped. The previous live drop-buffer mode and theSpeechToTextSettings.BackpressureWhenBusyoption were removed (the lossless behavior is now the only mode).
2026.6.27¶
- [Video Capture SDK .Net]
VideoCaptureCoreXcan now insert AI processing blocks — object detection, OCR, face recognition, license-plate recognition, object analytics, background removal, generic ONNX inference, and Whisper speech-to-text — directly into the capture pipeline throughVideo_Processing_AddBlock/Audio_Processing_AddBlock, with on-frame overlays and detection events. - [Media Player SDK .Net]
MediaPlayerCoreXgains the sameVideo_Processing_AddBlock/Audio_Processing_AddBlockAPI to run AI processing (object detection, OCR, speech-to-text, and more) on played files and streams. - [Demos] Added a Player AI Processing demo (WPF): plays a file in
MediaPlayerCoreXwith a YOLO object detector or a Whisper speech-to-text block inserted through the new processing-block API. - [Demos] Added four MAUI AI demos (Android/iOS/Mac Catalyst/Windows) for the new X-engine processing-block API: Player Object Detection X and Player Live Subtitles X (
MediaPlayerCoreX), plus Capture Object Detection X and Capture Live Subtitles X (VideoCaptureCoreX). - [Media Blocks SDK .Net] Fixed an
AccessViolationException("Attempted to read or write protected memory") that could crash the application when using text overlays (OverlayManagerBlock/OverlayManagerText) — most reliably reproduced by adding a text overlay right afterStartAsyncand then stopping. The font-enumeration path freed Pango-owned font objects it did not own, corrupting memory during a later garbage collection or pipeline shutdown. - [Media Blocks SDK .Net] Fixed a related intermittent fatal crash ("Attempt to execute managed code after the .NET runtime thread state has been destroyed") that could abort the process during text overlay or font enumeration when a background media thread was recycled, or at application exit. The available-fonts / monospace-detection path no longer attaches a managed callback to Pango's internal font map.
2026.6.24¶
- [Media Blocks SDK .Net] Fixed a rare crash during pipeline shutdown or garbage collection in applications with many active GStreamer objects, such as multi-camera RTSP capture with sample grabbers, bridges, and file outputs.
- [Media Blocks SDK .Net]
FaceRecognitionBlock— enrolling a face from a photo that carries an EXIF orientation tag (typical of phone camera shots) now works; the image is rotated upright before detection instead of reporting "no face found". - [Demos] Added a Face Recognition Uno demo (Uno Platform): live camera 1:N face recognition with on-frame name/box overlay, photo enrollment, and switchable SFace / AuraFace embedding models. Android-focused.
- [Demos] The Face Recognition demos (WPF and CLI) now let you pick the embedding model: SFace (128-D) or AuraFace (512-D, ArcFace family, Apache-2.0) — a higher-accuracy, commercially licensed 512-D embedder downloaded on demand. The CLI adds an
--embedding sface|aurafaceswitch. - [Demos] Face Recognition WPF demo: switching the embedding model now automatically rebuilds the gallery from the enrolled photos, so changing models no longer makes every face read as Unknown (embeddings from different models are not comparable).
- [Demos] Face Recognition MAUI demo: added the same SFace/AuraFace embedder selection and automatic gallery rebuild, plus a video-file source with a seek bar and a real-time / max-speed playback toggle (in addition to the live camera).
2026.6.23¶
- [Media Blocks SDK .Net] Unity samples now use Unity's default Enter Play Mode behavior (Domain + Scene Reload); disabling Domain Reload is no longer required. The SDK survives the Editor's Play/Stop and script-recompile domain reloads via a built-in reload guard.
2026.6.21¶
- [Video Capture SDK X .Net] Added Android audio playback capture support to
VideoCaptureCoreX— assignAndroidAudioPlaybackCaptureSourceSettingstoAudio_Sourceto record the audio played by other apps (system AudioPlaybackCapture API, Android 10 / API 29+, on top of aMediaProjectiontoken) straight to a file. Includes a new native Android "Audio Playback Capture" demo built onVideoCaptureCoreXthat records another app's audio to an.m4afile. Only apps that allow playback capture (usage MEDIA/GAME/UNKNOWN and not opted out) can be captured.
2026.6.20¶
- [Media Blocks SDK .Net]
VideoSampleGrabberBlocknow works as a terminal block: if you leave its output unconnected (e.g. you only pollGetLastFrameAsSKBitmap()or handleOnVideoFrameBuffer), the block self-terminates so frames keep flowing. Previously a grabber with an unconnected output stalled after the first frame, so every snapshot returned the same initial image. - [Media Blocks SDK .Net]
VideoSampleGrabberBlock.GetLastFrameAsSKBitmap()andGetLastFrameAsBitmap()now returnnullwhen no frame has been captured yet, instead of throwing aNullReferenceException. - [Media Blocks SDK .Net] Setting
VideoSampleGrabberBlock.SaveLastFrame = falsenow discards the cached frame, so toggling it back on later never hands back a stale frame captured during an earlier session. - [Media Blocks SDK .Net]
KLVParsernow reads MISB KLV packets larger than 127 bytes. Standard MISB ST 0601 metadata uses BER long-form lengths, and the parser previously threw on the common 1- and 2-byte long-form lengths — so real-world packets failed to parse. All BER length forms are now decoded correctly.
2026.6.19¶
- [Media Blocks SDK .Net] Added Android audio playback capture — the new
AndroidAudioPlaybackCaptureSourceBlockrecords the audio played by other apps using the system AudioPlaybackCapture API (Android 10 / API 29+) on top of aMediaProjectiontoken, with a configurable format and usage filter (AndroidAudioPlaybackCaptureSourceSettings). Includes a new native Android "Audio Playback Capture" demo that records another app's audio to an.m4afile. Only apps that allow playback capture (usage MEDIA/GAME/UNKNOWN and not opted out) can be captured. - [Media Blocks SDK .Net] Speech-to-text (
SpeechToTextBlock) gains a lossless file-transcription mode: setSpeechToTextSettings.BackpressureWhenBusy = trueto pace a file source to the transcription engine so no audio is dropped and the pipeline position tracks the transcription frontier — ideal for transcribing a file as fast as the engine allows without losing speech. The newSpeechToTextBlock.RequestStop()lets you stop promptly mid-file, and anOnEndOfStreamevent fires when transcription finishes.
2026.6.18¶
- [Media Blocks SDK .Net] Fixed WMV/ASF output where the video stream was written with a roughly 1000-hour timestamp offset while audio started at zero — players saw a broken duration and the video and audio never shared a timeline. WMV/ASF files now have correctly aligned, overlapping video and audio timestamps.
- [Media Blocks SDK .Net] Fixed MP4 recordings produced from a still/image source (
ImageVideoSourceBlock, live mode) ending up unreadable ("moov atom not found") — a live image source now finalizes its file correctly on stop. - [Media Blocks SDK .Net] VP9 WebM output now uses a real-time-capable speed/quality default:
VP9EncoderSettings.CPUUseddefaults to4instead of0. The previous slowest/highest-quality default could not keep up with a live source, so the recorded video track could be truncated to about a second while audio ran the full length. SetCPUUsed = 0to restore maximum quality for offline encoding. - [Media Blocks SDK .Net] The rav1e AV1 encoder (
RAV1EEncoderSettings) now defaults to the fastest speed preset (SpeedPreset = 10) instead of6. rav1e is a quality-oriented, very slow software encoder; the previous default could encode well under real time (~1 fps at 720p), stalling live and short captures. LowerSpeedPresetfor higher quality in offline encoding where throughput does not matter.
2026.6.14¶
- [Media Blocks SDK .Net] The AI blocks —
YOLOObjectDetectorBlock,OcrBlock, object analytics, ANPR,BackgroundRemovalBlock(VisioForge.DotNet.Core.AI) andSpeechToTextBlock(VisioForge.DotNet.Core.AI.Whisper) — now build and run cross-platform on Linux, macOS, iOS, and Android, including .NET MAUI, in addition to Windows. - [Media Blocks SDK .Net] On-device speech-to-text (
SpeechToTextBlock, Whisper + Silero VAD) now runs on iOS and Android. - [Demos] Added three .NET MAUI sample apps: YOLO Object Detection, OCR Text Recognition, and Live Subtitles (on-device Whisper speech-to-text). The existing Live Subtitles console sample is now cross-platform (Windows, Linux, macOS).
- [Media Blocks SDK .Net] Fixed a crash that could occur when stopping live speech-to-text with
SpeechToTextBlockconfigured withEnableVad = false(fixed-window mode) — stopping the pipeline at end-of-stream while a transcription was in progress could terminate the process. Transcription of the in-progress window now completes cleanly during shutdown. - [Media Blocks SDK .Net]
SpeechToTextSettings.FixedWindowSecondsis now clamped to 1–30 s andSileroVadSettings.MaxSpeechMsno longer accepts "0 = unlimited" (a non-positive value falls back to the 15 s cap), so a single transcription window — and the time a stop waits for it to finish — stays bounded.
2026.6.13¶
- [Media Blocks SDK .Net] Added live speech-to-text / subtitles — the new
SpeechToTextBlock(in the newVisioForge.DotNet.Core.AI.Whisperpackage) transcribes the audio stream in real time with Whisper (Whisper.net / GGML) on a background worker, gated by Silero VAD so silence is skipped and not mis-transcribed. Audio passes through unchanged. It raisesOnSpeechRecognized, can auto-render captions onto video viaSubtitleRenderer+OverlayManagerBlock, and can write.srt/.vttside-car files. Runs fully on-device (CPU or NVIDIA CUDA); Whisper and Silero models are downloaded at runtime. Includes a new WPF Live Subtitles demo. - [Media Blocks SDK .Net] Added AI background removal (matting) — the new
BackgroundRemovalBlockruns an ONNX segmentation model (for example MODNet) to estimate a per-pixel foreground mask and replaces the background in real time with a blur of the original, a solid color, a static image, or transparency. Includes a new WPF Background Removal demo. The background is composited on every frame, so running the model less often (frame skipping) lowers CPU/GPU load without flicker.
2026.6.11¶
- [Media Blocks SDK .Net] Added Object Analytics — multi-object tracking with stable IDs, directed tripwire line crossing (In/Out counts), and polygon zone occupancy on top of ONNX object detection. Includes a turnkey
ObjectAnalyticsBlock, a pure C# analytics API (ByteTracker,LineZone,PolygonZone), overlay rendering with traces and counters, a new analytics mode in the YOLO Object Detection demo, and separate Tripwire and Polygon Zone demo applications.
2026.6.8¶
- [Video Capture SDK .Net] Updated the bundled FFmpeg DirectShow source and encoder filters to FFmpeg 8.1.1, with refreshed codec libraries (VP8/VP9, Opus, Vorbis, Speex, SRT) and current OpenSSL — bringing newer format support and upstream security and stability fixes to FFmpeg-based capture and output.
2026.6.7¶
- [Media Blocks SDK .Net] Fixed a crash when reusing a
TSAnalyzerBlockacross runs: after the block is stopped, analyzing a second transport stream with the same instance in a new pipeline now works instead of failing during rebuild. - [Media Blocks SDK .Net] Fixed MPEG-TS output with KLV metadata aborting (no valid file produced) when a video frame arrived with an out-of-order/duplicate timestamp — the muxer now keeps the stream writable, so KLV-bearing transport streams record reliably.
- [Core] Fixed native memory steadily growing while reading media information for many different files in sequence with
MediaInfoReaderX; per-file discovery resources are now released after each read.
2026.6.6¶
- [Media Player SDK .Net] New "Modern Player" MAUI demo. A from-scratch cross-platform sample (Android, iOS, macCatalyst, Windows) built on
MediaPlayerCoreXwith a dark glassmorphism UI, a YouTube-style seek preview (a thumbnail popup follows the scrub bar — generated in the background from the opened file), a live video + audio effects drawer (brightness/contrast/saturation/hue, gamma, blur/sharpen, grayscale, edge, deinterlace, color presets, flip/rotate, 3D-LUT; plus gain, pitch, 10-band equalizer, reverb, echo, true-bass, and karaoke), frame snapshot, playback-speed control, and volume/mute. - [Media Player SDK .Net] [Media Blocks SDK .Net] Fixed opening local media files by absolute file path on Android, iOS, macOS, and Linux. A path starting with
/(the form returned by the native file pickers) previously failed with a URI-format error;MediaPlayerCoreX.OpenAsync(string),MediaInfoReaderX, andUniversalSourceSettings.CreateAsync(string)now open such files correctly. Windows paths were unaffected. - [Media Blocks SDK .Net] OCR — text recognition: new
OcrBlockrecognizes text in any video or image source using a multi-stage PaddleOCR (PP-OCRv5) ONNX pipeline — text detection, automatic 180° orientation handling, and text-line recognition. Runs on CPU or GPU (DirectML on Windows, CoreML on Apple, CUDA) and is fully cross-platform (Windows/Linux/macOS/Android). It raises the recognized regions per frame (text, confidence, and the text polygon) and can optionally draw the boxes and recognized text directly into the video. Works with the permissive Apache-2.0 PP-OCRv5 mobile models (100+ languages available); the models ship with the sample, not the package. - [Media Blocks SDK .Net] ANPR — license plate recognition: new
LicensePlateRecognizerBlockreads vehicle number plates from a live stream or file using a specialized two-stage pipeline — a dedicated license-plate detector locates each plate, then a plate-specific OCR model (a global head covering the USA and 90+ countries, or a European head) reads its characters. Recognition runs on a background thread so live video never stalls; recognized plates (text, confidence, bounding box) are raised per frame and optionally drawn over the video. Cross-platform and GPU-accelerated (DirectML / CUDA / CoreML). The MIT-licensed models ship with the sample, not the package.
2026.6.4¶
- [Media Blocks SDK .Net] AI inference package renamed: the AI/ONNX inference package is now published as
VisioForge.DotNet.Core.AI(previouslyVisioForge.DotNet.Core.ONNX). Update yourPackageReferenceto the new id — the API and namespaces of the inference blocks are unchanged. - [Media Blocks SDK .Net] Object detection: more models, permissive default.
YOLOObjectDetectorBlocknow decodes three model families via the newYoloDetectorSettings.Modelproperty — YOLOX and RT-DETR / D-FINE (both Apache-2.0) in addition to YOLOv8/v11. Each family's frame preprocessing (resize mode, normalization, channel order) and the model's input size are applied automatically, so you only pick the family and the.onnxfile. The Object Detection demo now ships a ready-to-run Apache-2.0 model (YOLOX-nano) and works out of the box without any third-party model download. RT-DETR / D-FINE detectors are end-to-end (NMS-free). - [Media Blocks SDK .Net] TS analyzer — ETSI TR 101 290 monitoring:
TSAnalyzerBlocknow reports a structured TR 101 290 Priority 1/2/3 check list (sync loss, sync-byte errors, PAT/PMT/PID errors, continuity-count errors, transport errors, CRC errors, PCR/PTS errors, and SI/SDT/EIT/TDT errors), each with its priority, error count, and pass/fail status — turning the block into a broadcast-grade transport-stream monitor. - [Media Blocks SDK .Net] TS analyzer — service information: the report now exposes per-program SDT service names, service provider, and service type, the network name, and the stream UTC time (TDT/TOT), so programs show up as their real service name instead of just a program number.
- [Media Blocks SDK .Net] TS analyzer — audio language: elementary-stream entries now carry the ISO 639 audio language parsed from the PMT descriptors.
- [Media Blocks SDK .Net] TS analyzer — scrambling detection: per-PID and per-program scrambling state is now reported (transport-scrambling-control and free_CA_mode), along with a scrambled-packet count.
- [Media Blocks SDK .Net] TS analyzer — null and effective bitrate: the report adds the null-packet count, the null (stuffing) bitrate, and the effective (useful) bitrate, plus per-PID instantaneous and peak bitrate alongside the existing cumulative average.
- [Media Blocks SDK .Net] TS analyzer — PCR timing and PTS/DTS: PCR statistics now include maximum jitter and PCR repetition errors, and the report tracks PTS/DTS presence per PID and audio/video synchronization offset.
- [Media Blocks SDK .Net] TS analyzer — codec details: video elementary streams now report parsed codec details (resolution, frame rate, profile, level, chroma format, and display aspect ratio) for H.264, HEVC, and MPEG-2. Frame rate and aspect ratio are reported from the MPEG-1/2 sequence header.
- [Media Blocks SDK .Net] TS analyzer — optional EPG: when enabled, the analyzer parses EIT events (event id, start time, duration, name, description) and exposes them as an EPG event list. The new analysis options (service info, EPG, scrambling, TR 101 290, PTS/DTS, codec details) are configurable on
TSAnalyzerSettings. The WPF and console demos display all of the new information. - [Video Capture SDK .Net] Fixed audio capture failing to start with certain WDM capture cards (for example the Viewcast Osprey 460E) when the device was selected by its device path — the device enumerated correctly but capture aborted with an "audio output pin is null" error. Such devices now bind reliably.
- [Media Blocks SDK .Net] Fixed a
MediaBlocksPipelinebecoming unusable after a media file played to its end. Once a source reached End-of-Stream, the nextStartAsync()was permanently rejected with "Already starting or start in progress." and the pipeline could not be restarted without recreating it — for example when switching from a finished file back to a live camera. Playback now shuts down cleanly at end-of-stream exactly like an explicitStopAsync()(sources stopped, resources released), so the same pipeline can be started again.
2026.6.3¶
- [Media Blocks SDK .Net] MPEG-TS analyzer: new
TSAnalyzerBlockanalyzes a transport stream and reports the program/service line-up (PAT/PMT/PSI), the per-PID stream types and codecs, per-PID and total bitrate, continuity-counter errors, and PCR timing (interval min/avg/max and discontinuity count). It accepts a raw MPEG-TS byte stream from a file, UDP, or SRT source and can run terminal (Input) or inline passthrough (InputOutput); subscribe toOnAnalysisUpdatedfor periodic snapshots or callGetReport(). New WPF and console demos ("TS Analyzer Demo", "TS Analyzer CLI") show file and live UDP/SRT analysis. - [Media Blocks SDK .Net] Raw MPEG-TS UDP source: new
UDPRAWMPEGTSSourceBlockreceives a live UDP unicast or multicast transport stream and exposes the untouched MPEG-TS byte stream without demuxing — for analysis or passthrough remuxing/recording. The advertised packet size is configurable viaUDPRAWMPEGTSSourceSettings.PacketSize(188 by default, or 192 for M2TS-style streams). - [Media Blocks SDK .Net] Split-recording segment events:
MP4SinkBlock,MPEGTSSinkBlock, andMP4OutputBlocknow raiseOnSegmentCreatedandOnSegmentClosedwhen configured for split recording (MP4SplitSinkSettings/MPEGTSSplitSinkSettings). The arguments carry the segment file path, fragment index, and timing (running time, plus start offset and duration on close) — so you can be notified when a segment file is finished and, for example, rename it to include its start/end time. - [Media Blocks SDK .Net] Custom split-segment file names: the same blocks add an
OnSegmentFileNameRequestedevent, raised just before each new segment file is created, letting you supply a custom file name (for example one that embeds the segment start date/time). Leave it unset to keep the default name from the location pattern. - [Media Blocks SDK .Net] New AI inference blocks:
OnnxInferenceBlockruns any ONNX Runtime model over the live video frames and raises an event with the raw model outputs, whileYOLOObjectDetectorBlockperforms YOLOv8/v11 object detection, draws bounding boxes and labels directly on the video (label text auto-scales to the frame resolution so it stays readable on 720p/1080p/4K, or pin a fixed size viaYoloDetectorSettings.LabelFontSize), and raises a detections event (with class, confidence, and box for each object). Both support frame skipping to tune throughput. On Windows the package uses the DirectML ONNX Runtime build, so inference runs on any DirectX 12 GPU (NVIDIA, AMD, or Intel) out of the box; the execution provider defaults toAuto, which picks the fastest available backend (DirectML/CUDA/CoreML) and transparently falls back to the CPU. UseOnnxInferenceEngine.GetAvailableProviders()to detect what is available and the newActiveProviderproperty on either block to see which provider engaged. TheVisioForge.DotNet.Core.ONNXpackage targets the full SDK framework matrix (.NET Framework 4.6.1 through .NET 10); inference requires a 64-bit (x64 or ARM64) ONNX Runtime native build.
2026.6.2¶
- [Video Capture SDK .Net] Fixed KLV metadata progressively drifting out of sync with the video (about 2 seconds per source loop) on the receiving side when restreaming a looping KLV-bearing MPEG-TS via
UDP_FFMPEG_EXE. KLV and video now stay aligned across source loop boundaries. - [Video Capture SDK .Net] Unity: new VideoCaptureCoreX samples — local webcam preview + MP4 recording (Windows, macOS) and IP/RTSP camera viewing (Windows, Android, macOS, iOS).
- [Video Edit SDK .Net] Unity: new VideoEditCoreX sample — combine clips, apply effects, preview the timeline in Unity, and render to MP4.
2026.5.31¶
- [Media Blocks SDK .Net] New
UDPRAWSourceBlock: receives a live UDP stream (MPEG-TS, RTP, or raw elementary) and exposes the parsed, still-encoded media without decoding — ideal for recording or remuxing without re-encoding. MPEG-TS feeds are auto-detected; RTP and raw modes let you set the codec, RTP payload type, and a multicast address. It exposes all common video and audio codecs (video: H264, H265, VP8, VP9, AV1, MPEG-2, MJPEG; audio: AAC, MP3/MPEG audio, AC-3, Opus, FLAC); RTP can also carry audio on a separate port (AudioPort/AudioCodec). A codec without a dedicated parser is passed through unchanged rather than dropped, so a connected recorder/muxer is never starved. - [Demos] New WPF "UDP RAW Capture Demo" (Media Blocks SDK .Net): records a live UDP H264/H265 feed to MP4 files without re-encoding, with selectable transport (Auto / MPEG-TS / RTP / raw), starting a new file on a configurable interval and splitting on key-frames so no data is lost between files, while previewing the stream.
- [Media Player SDK .Net] Unity: new MediaPlayerCoreX sample — play files and network URLs with seek, pause and volume, rendered into a Unity
Texture2D.
2026.5.29¶
- [Media Blocks SDK .Net] Unity 6 (.NET Standard 2.1) build flavor: the managed SDK now ships as a single
netstandard2.1assembly compatible with Unity's IL2CPP backend (Api Compatibility Level = .NET Standard 2.1). This lets Unity projects target the SDK without requiring the .NET Framework 4.x compatibility surface. The existing net48 Unity package remains supported. - [Media Blocks SDK .Net] Unity macOS Standalone player support (Universal arm64 + x86_64): the Unity 6 ns2.1
.unitypackagenow ships a third platform flavor for macOS Standalone (in addition to Windows and Android). Includes pre-built P/Invoke for macOS.dylibnames, the bundled CrossPlatform.Core.macOS native runtime (GStreamer dylibs +libgioopensslTLS backend +ca-certificates.crt), and a one-timeConfigure()bootstrap that prunes any system / homebrew GStreamer fromDYLD_LIBRARY_PATHbefore the loader runs. - [Core] New API:
VisioForgeX.StopMainLoop()— explicit teardown of the internal GLib main loop independent ofDestroySDK(), for scenarios that need to release the loop without tearing the SDK down.
2026.5.22¶
- [Demos] Unity
.unitypackagedistribution: the Unity 6 (net48) integration now ships as a single self-contained.unitypackage - [Demos] New Unity 6 (net48) samples:
SimplePlayer(file playback) andRTSPViewer(live RTSP camera) render aMediaBlocksPipelineinto a UnityRawImagevia a reusableVisioForgeVideoViewcomponent (Stretch / Letterbox / Crop). The bundled native + managed runtime is set up automatically; a step-by-step setup guide is included.
2026.5.20¶
- [Media Blocks SDK .Net] Fix: native memory leak in
OverlayManagerFilterandPanZoomFilteron iOS/AOT builds.
2026.5.19¶
- [Media Blocks SDK .Net] Fix:
CVMotionCellsBlock,CVFaceDetectBlock,CVHandDetectBlock,CVTemplateMatchBlock— event subscriptions added afterStartAsyncsometimes were silently dropped. - [Media Blocks SDK .Net] Fix:
CVMotionCellsSettings.GapandPostNoMotionare now rounded and clamped to the ranges accepted by the underlyingmotioncellselement (Gap→[1, 60]s,PostNoMotion→[0, 180]s). Previously sub-second values truncated to0and were silently rejected. - [Media Blocks SDK .Net] Docs:
CVMotionCellsSettings.GridSizeXML-doc clarified that the minimum is 8x8 (constraint of the underlyingmotioncellselement); smaller values are silently rejected.
2026.5.18¶
- [Media Blocks SDK .Net] New API:
SRTSinkSettings.PreResolveHostnameandSRTSourceSettings.PreResolveHostname(bool, defaultfalse). When set totrue, the SDK resolves any DNS hostname in the SRT URI to a literal IPv4 on the managed side (viaSystem.Net.Dns) before handing the URI to the native code.
2026.5.16¶
- [Core] Public-API XML documentation is now validated for correct syntax across the shipped NuGet packages.
2026.5.15¶
- [Core] Added
D3D11ComposableWPF renderer mode: a pure FrameworkElement video panel built on a D3D11 shared texture +D3DImagebridge that composes natively with the WPF visual tree (transforms, opacity, z-order, rounded clips) and keeps frames GPU-resident end-to-end. New type:D3D11ComposablePanel. - [Core] Added true-peak (dBTP) metering per ITU-R BS.1770-4: new
TruePeakComputer(4× polyphase FIR oversampling, per-channel running peak, NaN/Inf-safe) andVUMeterXData.TruePeak[]channel array fired alongside the existing sample-peak/RMS data. - [Core] Added
VolumeMeterLEDWPF control: segmented LED-bar VU meter with broadcast-style green/yellow/red zones, optional peak-hold marker (configurable fall time), optional dB scale labels, optional RMS overlay bar, horizontal/vertical orientation. - [Core] NuGet packages now ship XML documentation generated from real summaries for the full public API surface (previously the doc files were empty).
2026.5.14¶
- [Avalonia] Updated Avalonia, Avalonia.Desktop, Avalonia.Fonts.Inter, Avalonia.Themes.Fluent from 12.0.1 to 12.0.3.
- [WinForms] Resolve issue with WinForms designer when using
VideoViewin .Net Framework 4.x projects - [Dependencies] Closed two transitive security advisories: pinned
System.Drawing.Commonper-TFM on bare/cross-platformnetN.0(was 5.0.1 via DlibDotNet — GHSA-rxg9-xrhp-64gj, critical) and added explicitSharpCompress 0.48.1CPM pin to lift the transitive floor from MongoDB.Driver (was 0.30.1 — GHSA-6c8g-7p36-r338, moderate); bumped MongoDB.Driver 3.8.0 → 3.8.1. - [Breaking]
VisioForge.Core.CVDandVisioForge.Core.FaceAIassemblies are no longer strong-named. The underlyingDlibDotNetdependency is unsigned, so the strong-name chain was already broken at runtime; the<SignAssembly>flag was dropped to silence CS8002. Consumers that referenced these assemblies by fully-qualified strong name (PublicKeyToken=...) or used[InternalsVisibleTo("VisioForge.Core.CVD, PublicKey=...")]must remove the strong-name assertion when upgrading.
2026.5.10¶
- [Core]
CustomMixerSourceBlock: reliability and throughput improvements under heavy load.
2026.5.8¶
- [Dependencies] Upgraded MongoDB.Driver.GridFS 2.30.0 to MongoDB.Driver 3.8.0; pinned Snappier 1.3.1 to resolve NU1903 high-severity vulnerability (GHSA-pggp-6c3x-2xmx)
2026.5.2¶
- [Core] Breaking change: licensing APIs now accept only raw certificate bytes. Removed file-path and stream-based certificate setters across shared licensing, public SDK wrappers, legacy Windows wrappers, tests, and licensing docs. Applications must load
.vflicensefiles into memory and callSetLicenseCertificateAsync(byte[]). - [Core]
AudioMixerBlock:AudioMixerSettings.IgnoreInactivePadsis now opt-in (defaultfalse). The 2026.4.30 release briefly forced ittrue, which broke single-input mixers — silent live audio and corrupted MP4 output. Multi-stream consumers (MediaPlayerCoreXadditional audio streams,LiveVideoCompositor, andAudioMixerSourceSettings-based multi-source capture) now opt in explicitly. If you wired a multi-streamAudioMixerBlockon 2026.4.30–2026.5.1 and relied on the implicittrue, setAudioMixerSettings.IgnoreInactivePads = trueexplicitly.
2026.4.25¶
- [Core] Fixed WinForms designer exception on
VideoViewin net472 demos — SkiaSharp 3 migration regression - [Core] Added transitive
SkiaSharp.NativeAssets.Linuxdependency for bare cross-platform TFMs (netcoreapp3.1,net5.0–net10.0) so consumers publishing tolinux-x64/arm64no longer need to add the package manually; mainSkiaSharpalready covers Win32/macOS/iOS/Android/MacCatalyst/tvOS via per-TFM nuspec groups - [Avalonia] Migrated SDK and all 28 demos from Avalonia 11.3.8 to 12.0.1: replaced
Avalonia.DiagnosticswithAvaloniaUI.DiagnosticsSupport 2.2.1, switched toReactiveUI.Avalonia 12.0.1, updatedRxApp.MainThreadScheduler→RxSchedulers.MainThreadScheduler(ReactiveUI 23.x), newUseReactiveUI(_ => { })signature, moved AndroidCustomizeAppBuilderfromMainActivityto newMainApplication : AvaloniaAndroidApplication<App>, migratedSaveFileDialog/OpenFileDialog/FileDialogFiltertoIStorageProvider.SaveFilePickerAsync/OpenFilePickerAsyncin 4 demos. SkiaSharp pinned to 3.119.3-preview.1.1 (required by Avalonia.Skia 12).
2026.4.23¶
- [NuGet] Extracted Intel Quick Sync Video (QSV) plugin (
gstqsv.dll) fromVisioForge.CrossPlatform.Core.Windows.x64/x86into new optional packagesVisioForge.CrossPlatform.Core.Windows.Intel.x64andVisioForge.CrossPlatform.Core.Windows.Intel.x86; each depends on the corresponding base Core package - [Video Capture SDK .Net] Fixed FFMPEG.exe pipe output argument ordering so resize/aspect options are emitted after all inputs, including KLV metadata pipe input
2026.4.21¶
- [Core] Added
AutoAV1EncoderSettings: auto-selecting AV1 encoder that walks AMF → NVENC → QSV → SVT-AV1 viaEncoderRuntimeTracker, mirroringAutoH264EncoderSettings/AutoHEVCEncoderSettings; AV1 sessions now participate in per-runtime slot accounting - [Core] Added typed
AV1Encoder.CanCreateSession(IAV1EncoderSettings, out string)probe so AV1 runtime selection can detect driver rejections before wiring a pipeline - [Core] Added
MFH264EncoderSettings,D3D12H264EncoderSettings,D3D12HEVCEncoderSettings— alternative Windows runtimes (mfh264enc,d3d12h264enc,d3d12h265enc) with independent per-adapter session counters for bypassing per-runtime caps (e.g., AMD iGPU 2-session ceiling) - [Core] Added
AutoH264EncoderSettings/AutoHEVCEncoderSettings: auto-selecting encoder that probes runtimes in order (AMF → NVENC → QSV → MF → D3D12 → software), tracks in-flight sessions viaEncoderRuntimeTracker, and falls back when a runtime's cap is reached - [Demo] Added
Encoder Concurrency TestWPF demo (Media Blocks SDK): spawn multiple source→encoder→decoder→renderer pipelines with configurable resolution, frame rate, encoder runtime, and adapter to exercise concurrent-session limits end-to-end
2026.4.18¶
- [Media Blocks SDK] UniversalSourceBlock: added
VideoFlipRotateoption for automatic video orientation correction using image-orientation metadata - [Core] VOAACEncoderSettings deprecated in favor of
AVENCAACEncoderSettings - [Core] RTSPXOutput: now accepts any
IAACEncoderSettings, not just VOAAC - [Core] MediaInfoReaderCore: preserves image-orientation flip metadata during media info reading
- [Core] H264Encoder: fixed thread-safety issue in KeyFrameDetected callback
- [iOS] PhotoGalleryHelper: requests
PHAccessLevel.AddOnlyfor iOS 26 compatibility - [Android] GStreamer Android NuGet rebuilt with zbar barcode plugin, bumped to 2026.4.18
- [Platform] macOS demos migrated from net9.0-macos to net10.0-macos
- [Dependencies] Uno.Sdk bumped 6.4.24 → 6.5.31
- [Media Blocks SDK] LiveVideoCompositor V2: added
OnRenderStatisticsevent withActualFps,ConfiguredFps,FramesDelivered, andLastFrameTimestamppayload for detecting when the compositor falls behind the configured frame rate under heavy load - [Media Blocks SDK] LiveVideoCompositor V1 (
VisioForge.Core.LiveVideoCompositor) marked[Obsolete]— migrate toVisioForge.Core.LiveVideoCompositorV2(identical class names, single-lineusingswap); V1 will be removed in a future release - [Demos] WPF LVC Demo and MAUI LVC Demo show the real vs configured output FPS in the UI; WinForms Video Mixer Player migrated from V1 to V2
2026.4.11¶
- [Media Player SDK X] Added
Play_PauseAtFirstFrameproperty to MediaPlayerCoreX — pauses at the first rendered frame for preview/thumbnail scenarios, matching the existing MediaPlayerCore API - [Core] Migrated SkiaSharp from 2.88.9 to 3.119.2 — updated text rendering to SKFont API, replaced SKFilterQuality with SKSamplingOptions, switched SVG library from SkiaSharp.Svg to Svg.Skia
- [UI] Updated SkiaSharp.Views.WPF and SkiaSharp.Views.Maui.Controls to 3.119.2; WPF skins now use DrawImage with high-quality Mitchell resampling
2026.4.8¶
- [Android] Added live camera switching (SwitchCamera) to SystemVideoSourceBlock — switches between front/back cameras without recreating the GStreamer pipeline, preserving resolution and frame rate
- [Video Capture SDK X] Added Video_Source_SwitchCamera for live camera switching on Android without pipeline restart
- [Video Capture SDK X] Added Video_Renderer_IsSync and Audio_Renderer_IsSync properties (default false) for lower-latency live preview
- [Android] New NuGet native version v2026.4.1
2026.3.27¶
- [Core] Fixed UNC path media info reading failure:
MediaInfoReaderAltnow correctly handles SDK initialization guard, null caps inOnPadAdded, and falls through toMediaInfoReaderXon failure.IsSambaURL()extended to detectfile://host/pathUNC URIs.OpenAsyncusesuri.LocalPathfor correct Windows UNC path.
2026.3.18¶
- [Media Blocks SDK .Net] Fixed missed context menu issue in WPF VideoView
2026.3.17¶
- [Media Blocks SDK .Net] Added UDPSinkBlock and MultiUDPSinkBlock for raw UDP streaming output with single and multi-destination support
- [Media Blocks SDK .Net] Added UDPMPEGTSSinkBlock and MultiUDPMPEGTSSinkBlock for MPEG-TS multiplexed UDP streaming with single and multi-destination support
- [Media Blocks SDK .Net] Added UDPSinkSettings, MultiUDPSinkSettings, and UDPSinkSettingsBase for UDP sink configuration with IPv6 support and URL parsing
- [Media Blocks SDK .Net] Added UDP MPEG-TS streamer demo (screen capture to UDP output)
2026.3.11¶
- [Core] Device enumeration: Blackmagic ATEM and Web Presenter devices now appear in regular video/audio device lists instead of being filtered as Decklink hardware. These devices use standard USB/UVC drivers, not the Decklink SDK. Applies to both DirectShow and GStreamer enumeration paths.
- [Core] RTSP info reader: Added audio channel count and sample rate parsing from SDP rtpmap and GStreamer pad caps.
2026.2.16¶
- [Media Blocks SDK .Net] Added PreEventRecordingBlock for circular buffer (pre-event) video recording with configurable buffer duration, keyframe-aware drain, and automatic post-event stop
- [Video Capture SDK .Net] VideoCaptureCoreX: Added pre-event recording API with TriggerPreEventRecording, ExtendPreEventRecording, StopPreEventRecording, and state query methods
- [Video Capture SDK .Net] VideoCaptureCoreX: Added PreEventRecordingOutput for configuring circular buffer recording with MP4, MPEG-TS, and MKV container support
2026.2.12¶
- [Media Blocks SDK .Net] Added OnNetworkSourceDisconnect event for detecting network source disconnections (RTSP, HTTP, SRT, NDI, RTMP, etc.) with detailed error information and source URI
2026.2.11¶
- [Media Player SDK .Net], [Media Blocks SDK .Net] Fixed audio effects pipeline routing
2026.2.10¶
- [Core] Added UNC (SMB/Samba) network path support for file sources across all X-engines, fixing File.Exists() failures on network shares
- [Media Blocks SDK .Net], [Video Capture SDK .Net] Added mouse click highlight support for screen capture with auto-subscribe/unsubscribe, manual click input, and real-time settings update
2026.2.8¶
- [Media Blocks SDK .Net] Added OverlayManagerImageSequence: image sequence overlay with per-frame durations, looping, position/size animation, fade effects, and easing support
- [Media Blocks SDK .Net] Added ImageSequenceItem data class for defining image sequence frames
- [Media Blocks SDK .Net] OverlayManagerBlock: Added convenience methods for image sequence overlays (Video_Overlay_AddImageSequence, UpdateImageSequencePosition, AnimateImageSequence, ImageSequenceFadeIn/Out)
- [Core] Extracted OverlayManagerEasingHelper: shared easing functions for all overlay animation types (Image, Fade, Pan, Squeezeback, ImageSequence)
2026.2.4¶
- [Media Blocks SDK .Net] Added H264PushSourceBlock for pushing raw H.264 encoded data into a decoding pipeline, with automatic AVC-to-byte-stream conversion and PTS rebasing
- [Core] Added RtspDescribeClient: lightweight cross-platform RTSP DESCRIBE client for fast stream discovery (~100-200ms), with SDP parsing and Basic/Digest auth support
- [Core] RTSPSourceSettings: Added fast RTSP discovery path using RtspDescribeClient
- [Core] RTSPRAWSourceSettings: Added fast RTSP discovery path using RtspDescribeClient
- [Core] UniversalSourceSettings: Added fast RTSP discovery path for rtsp:// and rtsps:// URIs
2026.2.2¶
- [Core] VideoCaptureDeviceInfo: Extended Windows device path population to support Media Foundation (MF) devices in addition to KS
- [Core] VideoCaptureDeviceInfo: Fixed pre-existing bug where V4L2 device path validation checked wrong variable
- [Core] VideoCaptureDeviceSourceSettings: Added FindByDevicePath() static methods for restoring saved camera profiles by device path
- [Core] DeviceEnumerator: Added FindVideoSourceByDevicePathAsync() method for looking up devices by path
- [Media Blocks SDK .Net] Added RIST (Reliable Internet Stream Transport) MPEG-TS sink output support
- [Media Blocks SDK .Net] Added WebRTC WHIP (WebRTC-HTTP Ingestion Protocol) output support
- [Video Capture SDK .Net] Added WebRTC WHIP streaming output
- [Video Capture SDK .Net] Added RIST streaming output
2026.1.16¶
- [Media Blocks SDK .Net] BridgeVideoSourceSettings: Added DoTimestamp property to enable fresh timestamp generation for cross-pipeline scenarios
2026.1.15¶
- [Media Blocks SDK .Net] DecklinkVideoSinkSettings: Made Mode parameter required in constructor to prevent frame rate mismatch issues (was defaulting to Unknown mode causing unexpected 23.98fps output)
- [Media Blocks SDK .Net] DecklinkVideoSinkSettings: Made DeviceNumber and Mode properties read-only for immutability
- [Core] DecklinkVideoOutputDialog (WPF): Added Video Mode selector for configuring output frame rate
2026.1.12¶
- [Core] WPF VideoView: Fixed crash (System.ExecutionEngineException) when minimizing window during video overlay playback
2026.1.11¶
- [Media Blocks SDK .Net] RTSPSourceBlock: Fixed video freeze when audio capture is disabled for cameras with multiple audio streams
- [Media Blocks SDK .Net] RTSPRAWSourceBlock: Added fakesink handling for disabled audio streams to prevent pipeline stalls
- [Core] MediaInfoReaderCore: Added logging for discovered audio, video, and RTP streams
- [Core] MediaInfoReaderCore: Fixed excessive block size (5MB) being set for RTSP sources, improving discovery speed
2026.1.10¶
- [Video Capture SDK .Net] DSFFMPEGEXEPipeOutput: Fixed preview lag during video capture with optimized pipe handling and queue processing
- [Video Capture SDK .Net] FFMPEG EXE output: Added real-time encoding optimizations for VP8/VP9, fixed MJPEG quality mode, improved default H264MFSettings defaults
2026.1.6¶
- [Video Capture SDK .Net] VideoCaptureCoreX: Fixed video capture resolution issue when ResizeVideoEffect is applied
2025.12.12¶
- [Media Blocks SDK .Net] Added PitchBlock for audio pitch shifting with semitone control (-12 to +12 range)
- [Media Player SDK X .Net] CDGSource: Added pitch shifting support with EnablePitchShifting option and real-time PitchSemitones control
- [Media Player SDK X .Net / Media Blocks SDK .Net] CDGSourceSettings: Added ZIP archive support for karaoke files (MP3+CDG pairs inside ZIP)
2025.11.8¶
- [Media Blocks SDK .Net] OverlayManagerVideo and OverlayManagerDecklinkVideo: Changed AudioOutput property type from MediaBlock to AudioOutputDeviceInfo for direct audio device selection. Audio is now handled internally via AudioRenderer with automatic channel conversion support.
2025.11.4¶
- .Net 10 support for all SDKs
2025.11.3¶
- WPF VideoView update: Added RotationAngle, RotateCrop, and RotationStretch properties to support rotated video rendering
2025.11.1¶
- [Media Blocks SDK .Net] Add synchronized overlay group support for OverlayManagerBlock
2025.10.10¶
- [Windows SDKs] Updated VideoEffectRotate with no-crop option
2025.10.6¶
🚀 Major Feature: Ultra-Low Latency RTSP Streaming¶
- [Media Blocks SDK .Net] Revolutionary low latency mode for RTSP sources achieving 60-120ms total latency (10-14x improvement over default 1-2 seconds)
- Added
RTSPSourceSettings.LowLatencyModeproperty for one-line enablement of optimized streaming - Automatic pipeline optimization: RTSP source (80ms), queue buffers (10-20ms), and renderer sync control
- GStreamer integration:
latency=80ms,buffer-mode=0, queuemax-size-buffers=2withleaky=downstream -
Perfect for real-time surveillance, security systems, live monitoring, and interactive video applications
-
[Media Blocks SDK .Net] Enhanced RTSPSourceBlock with comprehensive low latency configuration
- Added
RTSPBufferModeenum with 5 modes (None, Auto, Slave, Buffer, Synced) for fine-grained jitter buffer control - Added
RTSPNTPTimeSourceenum (NTP, RunningTime, Clock) for NTP timestamp synchronization in multi-camera scenarios - New properties:
LowLatencyMode,BufferMode,DropOnLatency,NTPSync,NTPTimeSource -
Optimized
QueueElementwith automatic low latency configuration (2 frame max, leaky downstream mode) -
[Video Capture SDK X .Net] Full low latency mode support for RTSP sources
- Compatible with
VideoCaptureCoreXengine across all platforms - Same simple API:
RTSPSourceSettings.LowLatencyMode = true -
Works seamlessly with IP Capture demo and RTSP MultiView demo
-
[Cross-Platform Support] Low latency RTSP streaming now available on all platforms:
- Windows (WPF, WinForms, Console, Blazor)
- macOS (MAUI, Console)
- Linux (Console, WPF with Mono)
- Android (MAUI, Native)
-
iOS (MAUI)
-
[Demo Applications] Updated 6 demos with low latency mode UI controls:
- Media Blocks SDK: RTSP Preview Demo (WPF), RTSP MultiView Demo (WinForms), MAUI RTSPViewer, Android RTSP Client
- Video Capture SDK X: IP Capture (WPF), RTSP MultiView Demo (WinForms)
-
All demos include easy-to-use checkboxes or default-enabled low latency for optimal user experience
-
[Documentation] Official help documentation updated with a low-latency section and best practices.
-
[Testing] Validated on real IP cameras across all platforms. Performance benchmarks: Windows (85ms), macOS (95ms), Linux (80ms), Android (110ms), iOS (100ms).
-
[Backward Compatibility] 100% backward compatible implementation:
- Default behavior unchanged - existing code works without modification
- Low latency mode is opt-in via explicit property
- No performance impact when not using low latency mode
- Queue optimization only applied when
LowLatencyMode=true
2025.10.3¶
- [Media Blocks SDK .Net] Added DASH (Dynamic Adaptive Streaming over HTTP) sink support with DASHSinkBlock and DASHOutput classes
- [Media Blocks SDK .Net] Added UniversalSourceBlockV2 with improved memory usage and performance
- [X-engines] Fixed uvch264src not starting on Linux by properly selecting the appropriate source pad based on video format (vidsrc for H264, vfsrc for raw/MJPEG)
2025.9.5¶
- [Video Fingerprinting SDK] Improved support for flipped videos
2025.9.3¶
- [Media Blocks SDK .Net] Added DataMatrix barcode support using DataMatrixDecoderBlock block
2025.9.1¶
- [Video Fingerprinting SDK] Improved support for flipped videos
2025.8.9¶
- [Video Capture SDK .Net] VideoCaptureCoreX: Resolved issue with Snapshot_GetSK call on Android (wrong colorspace)
2025.8.6¶
- [X-engines] Updated RTSP RAW source block. Added WaitForKeyframe and SyncAudioWithKeyframe properties. Block can wait for keyframes because some cameras may not send them as first frames.
2025.8.4¶
- [X-engines] Added NDI source support in Live Video Compositor
2025.8.2¶
- [ALL] New ONVIF manager code in VisioForge.Core.ONVIFX. Full implementation of various ONVIF services including Device Management, Media v1/v2, PTZ, Events, Imaging, Analytics, Recording, and Replay services.
2025.8.1¶
- [Media Player SDK] Added PauseOnStop property to MediaPlayerCoreX
2025.6.30¶
- [X-engines] Added animated GIF support to
ImageVideoSourceBlock/ImageVideoSourceSettingsclasses - [X-engines] Resolved issues with delayed file start in Live Video Compositor
- [X-engines] Update video mixer API to use GUIDs instead of integer indexes for video sources
2025.6.27¶
- [Video Capture SDK] Resolved issue with RTSP Low Latency engine with some cameras
2025.6.5¶
- [X-engines] Resolved issue with NDI sources playback without audio streams
2025.6.3¶
- [X-engines] Updated GenICam source support for USB Vision cameras. Added GenTL source support.
2025.6.2¶
- [X-engines] Added deinterlace support for interlaced Decklink video sources
2025.6.1¶
- [Live Video Compositor] Resolved issue with file sources paused on start, and resumed with error
2025.5.1¶
- [ALL] Update NuGet dependency packages to the latest versions
- [X-engines] Resolved issue with RTMP network streaming to a custom server
2025.4.8¶
- [ALL] Added Absolute Move API to the
ONVIFDeviceXclass. You can use this API to move the ONVIF camera to the specified absolute position.
2025.2.24¶
- [X-engine] By default, Media Foundation device enumeration is disabled. You can enable it using the
DeviceEnumerator.Shared.IsEnumerateMediaFoundationDevicesproperty.
2025.2.18¶
- [Media Player SDK.Net] Added loop support for the cross-platform engine.
- [ALL] Updated RTSP-X engine output, fixed crash issue with RTSP output and VLC player frequent reconnects
- [X-engines] Changed face detector support to use IFaceDetector interface
- [Live Video Compositor] Fixed registration issues with custom video view attached to video input
2025.2.9¶
- [X-engines] Updated NDI connection speed
2025.2.4¶
- [X-engines] RTSP Server Media Block and RTSPServerOutput added to Video Capture SDK. You can use the RTSPServerBlock to create an RTSP server and stream video and audio to it.
2025.2.1¶
- [X-engines] Added NVENC and AMF AV1 encoders support
2025.1.25¶
- [Windows] Resolved HTTPS issue with the not loaded SSL certificates
2025.1.22¶
- [Windows] Resolved issue with missed ONVIF sources while enumerating on PC with multiple network interfaces
- [Media Blocks SDK .Net] Added the
OnEOSevent toMediaBlockPadclass. You can use this event to get the EOS (End of Stream) event from the media block. It can be useful if you have several file sources with a different duration and you need to stop the pipeline when the first source ends. - [Media Blocks SDK .Net] Added the
SendEOSmethod toMediaBlocksPipelineclass. You can use this method to send the EOS (End of Stream) event to the pipeline.
2025.1.18¶
- [NuGet]
VisioForge.Core.UI.Apple,VisioForge.Core.UI.Android, andVisioForge.Core.UI.WinUIpackages are merged into theVisioForge.DotNet.Corepackage. All namespaces are the same. - [Media Blocks SDK .Net] Added the
ZOrderproperty toLVCVideoInputandLVCVideoAudioInputclasses. You can use this property to set the Z-order for the video input.
2025.1.14¶
- [NuGet]
VisioForge.Core.UI.WPFandVisioForge.Core.UI.WinFormspackages are merged into theVisioForge.DotNet.Corepackage. In WPF projects you have to update the XAML code if the assembly names are used. All namespaces are the same.
2025.1.11¶
- [Video Capture SDK .Net] Resolved QSV H264 FFMPEG encoder issue with the wrong symbols in parameters
2025.1.7¶
- [Cross-platform] Added
libcamerasource support for Linux/Raspberry Pi.
2025.1.5¶
- [Cross-platform] Improved previous frame playback in Media Player SDK .Net (Cross-platform engine)
2025.1.4¶
- [Cross-platform] Resolved issue with AMD AMF plugin initialization
2025.1.1¶
- [Cross-platform] Resolved memory leak in
OverlayManagerImage
2025.1.0¶
- [Cross-platform] Updated Live Video Compositor engine. Improved Decklink support for input and output. Improved performance. The new engine classes are located in the
VisioForge.Core.LiveVideoCompositorV2namespace.
2025.0.29¶
- [Cross-platform] Default video renderer on Windows has been changed to DirectX 11
2025.0.17¶
- [Media Blocks SDK .Net] Added libCamera source support (can be used on Raspberry Pi)
2025.0.16¶
- [Media Blocks SDK .Net] Resolved issue with adding several AudioRendererBlocks to the pipeline
2025.0.14¶
- [Media Blocks SDK .Net] Added the "PushJPEGSourceSettings" class to configure the JPEG source for the "PushSourceBlock". You can use this class to set the JPEG source settings for the "PushSourceBlock". Also "video-from-images" sample added.
2025.0.7¶
- [ALL] Resolved window capture issues in cross-platform SDKs
- [Media Blocks SDK .Net] Added the Bridge Source Switch sample
2025.0.5¶
- [iOS] Resolved issues with playback speed for some video files
- [iOS] Added iOS Simulator support for all SDKs. Camera source is not supported in the simulator.
2025.0.3¶
- [MacOS] Resolved wrong stride issue for vertical camera videos on MacOS
- [Video Capture SDK .Net] Resolved background color issue for the scrolling text overlay
2025.0¶
- [ALL] .Net 9 support
- [Media Blocks SDK .Net] Added
AVIOutputBlockto save video and audio streams to the AVI file format - [Media Blocks SDK .Net]
TeeBlockconstructor now accepts the media type as a parameter - [Video Capture SDK .Net] Added
Video_CaptureDevice_SetDefaultandAudio_CaptureDevice_SetDefaultmethods to theVideoCaptureCoreclass. You can use this method to set the default video and audio capture devices - [Cross-platform] Improved
Metalvideo rendering performance on Apple devices - [All] Improved performance of common video processing operations in Windows classic SDKs
- [CV] Added DNN face detectors for the
Media Blocks SDK .NetandVideo Capture SDK .Net - [Mobile] Improved AOT compatibility for iOS and Android
- [WinUI] Improved performance of the
WinUIvideo rendering - [Media Blocks SDK .Net] Added the
GetLastFrameAsSKBitmapandGetLastFrameAsBitmapmethods toVideoSampleGrabberBlockto get the last frame as aSkiaSharp.SKBitmaporSystem.Drawing.Bitmap - [Video Capture SDK .Net]
VideoCaptureCore: Added theAddFakeAudioSourceproperty toFFMPEGEXEOutput. TheNetwork_Streaming_Audio_Enabledproperty ofVideoCaptureCoreshould be set to false to use this fake audio. - [ALL] Improved WinUI (and MAUI on Windows) VideoView performance
- [Video Capture SDK .Net]
VideoCaptureCore: Added thePIP_Video_CaptureDevice_CameraControl_API to control the camera settings for the Picture-in-Picture mode - [X-engines] Added the headers support for the HTTP sources created using the
HTTPSourceSettingsclass - [X-engines] Updated Avalonia samples, with projects for macOS, Linux, and Windows
- [X-engines] Added NuGet redist packages for macOS and MacCatalyst (including MAUI)
- [Video Capture SDK .Net]
VideoCaptureCore: Added device path support forPIP_Video_CaptureDevice_CameraControlAPI - [Video Capture SDK .Net]
VideoCaptureCore: Added theFFMPEG_MaxLoadTimeoutproperty for IP camera sources. It allows you to set the maximum time to wait for the FFMPEG source to load the stream - [X-engines] Updated Linux support for
ALSA,PulseAudioandPipeWireaudio devices - [X-engines] Updated Linux support for
V4L2devices - [X-engines] Avalonia samples has be changed to a modern 1-project structure
- [X-engines] Resolved issue with
MAUIcrashes on Windows afterSkiaSharpupdate - [X-engines] Resolved issue with
TextureViewcrashes on Android inMAUIapplications - [X-engines] Resolved playback issue for http sources using the
UniversalSourceBlock - [X-engines] Added Mobile Streamer sample for Android
- [X-engines] Added
OverlayManagerBlocksupport for Android (now it's available for all platforms) - [Video Capture SDK .Net]
VideoCaptureCoreX: AddedCustomVideoProcessor/CustomAudioProcessorproperties for all output formats. You can use these properties to set custom video/audio processing blocks for the output format. - [Media Blocks SDK .Net] Added the
KeyFrameDetectorBlockto detect key frames in video streams (H264, H265, VP8, VP9, AV1, etc.) - [Media Blocks SDK .Net] Fixed licensing issue for the
LiveVideoCompositorclass
15.10.0¶
- [Windows] Updated window capture API to capture only the specified parent window by default. Added the
UpdateHotkeymethod to theWindowCaptureFormclass to update the hotkey for the window capture form. - [X-engines] Better AOT compatibility for default MAUI settings in iOS.
- [Media Blocks SDK .Net] Added the
DNNFaceDetectorBlockto detect faces and blur/pixelate them using OpenCV and DNN models. - [Media Blocks SDK .Net] Added the
MKVOutputBlockto save video and audio streams to the MKV file format. - [X-engines] Better support for video source size dynamic changing in MAUI applications.
- [X-engines] Resolved an issue with two or more VU meters in the same pipeline.
- [X-engines] Resolved volume/mute error issue with audio mixer in Live Video Compositor engine.
- [X-engines] The
Spinnakersource forFLIR/Teledynecameras is included in the main package and no longer requires an additional plugin. - [Video Capture SDK .Net] Resolved the issue with the
SeparateCaptureAPI if noVideoViewwas used. - [X-engines] The
MediaBlocksPipelineconstructor no longer has theliveparameter. For more customizable pipelines, video and audio renderers got theIsSyncproperty (trueby default). - [X-engines] Resolved
VideoViewTXcrash in MAUI Android applications. - [X-engines]
IVideoEncoderinterface added to theMPEG2VideoEncoderclass. It allows the use ofMPEG2VideoEncoderwithMPEGTSOutput,AVIOutput, and other output classes. - [X-engines] Resolved the issue with window capture using the
ScreenCaptureD3D11SourceSettingsclass. If the rectangle was incorrect or not specified, it caused an error. - [X-engines]
Metalrenderer was added to SDK for Apple devices and used by default for iOS and MAUI. - [Media Blocks SDK .Net] Added the MAUI Screen Capture sample.
- [Video Capture SDK .Net] VideoCaptureCore: Added the
VLC_CustomDefaultFrameRateproperty toIPCameraSourceSettingsto set a custom frame rate for the VLC IP camera source if the source does not provide the correct frame rate. - [Media Blocks SDK .Net]
RTSPSourceBlock: If the RTSP source has audio but you've disabled the audio stream inRTSPSourceSettings, SDK will add a null renderer automatically to prevent warnings. - [ALL] Resolved issue with
VideoFrameX.ToBitmap()call (wrong color space) - [Windows] Updated KLV support in MPEG-TS output
- [Windows] Resolved MediaPlayerCore serialization issue
- [ALL] Video renderer settings class no longer contains background color. Use the VideoView background color property instead.
- [X-engines] Updated GStreamer libraries
- [X-engines] Resolved video rendering issues on Android and iOS
- [X-engines] iOS crash fixed during VideoViewGL usage
- [X-engines] Added default AAC encoder for iOS
- [X-engines] iOS camera source update for high frame rate support
- [Windows] Updated VLC source - improved file loading speed
- [Media Blocks SDK .Net]: Added the
UniversalDemuxBlockallows to demux video and audio streams from a file in MP4, MKV, AVI, MOV, TS, VOB, FLV, OGG, and WebM formats - [Windows] Resolved FFMPEG stability issues
- [X-engines] Resolved issue with loopback audio source using VideoCaptureCoreX and audio capture to file
- [X-engines] Added SRT source and sink support in Media Blocks SDK .Net and Video Capture SDK .Net
- [Video Capture SDK .Net] VideoCaptureCore: The
IP_Camera_ONVIF_ListSourcesAsyncExmethod got an overload version with a callback for a more responsible UI - [X-engines] RTSP source compatibility update
- [X-engines]
Breaking API change. Starting with this update, the SDK usesIAudioRendererSettingsinterface implementations for audio output configuration. WASAPI output got the custom configuration classes. Output_AudioDevice properties ofVideoCaptureCoreX/MediaPlayerCoreXtype have been changed toIAudioRendererSettings. You can create theAudioRendererSettingsclass instance fromAudioOutputDeviceInfousing the default constructor. - [X-engines] Resolved problem with missed Media Foundation sources during device enumeration
- [X-engines] Resolved RTSP source problems with audio connection in some situations
- [X-engines] Added the RTSP Preview Demo to Media Blocks SDK .Net
- [Windows] FFMPEG outputs and source updated to FFMPEG v7.0.
- [X-engines] Fixed rare crashes in RTSP source when camera information is not available for some reason (network issue)
- [X-engines] Resolved an issue with
WASAPI/WASAPI2audio renderer usage - [X-engines] Resolved an issue with the audio loopback audio source on Windows
- [X-engines] Improved iOS video rendering performance and stability
- [X-engines] Added AWS S3 Sink output for Media Blocks SDK .Net
- [X-engines] Added Allied Vision USB3/GigE cameras support in Media Blocks SDK .Net and Video Capture SDK .Net
15.9¶
- [X-engines] Resolved wrong aspect ratio with video resize effect/block
- [X-engines] Updated GStreamer redist
- [X-engines] Added Basler USB3/GigE cameras support in Media Blocks SDK .Net and Video Capture SDK .Net
- [Video Edit SDK .Net] VideoEditCoreX: The TextOverlay class changed to use SkiaSharp-based font settings. Additionally, you can set the custom font file name or configure all rendering parameters using custom SKPaint.
- [Windows] Added Stream support in
MediaInfoReader. You can get the video/audio file information from a stream (DB, network, memory, etc.). - [X-engines] Updated Live Video Compositor engine, which improved support of the file sources
- [Video Capture SDK .Net] Added camera-covered detector into the
Computer Vision Demoand theVisioForge.Core.CVpackage - [X-engines] Added API to get snapshots from video files using MediaInfoReaderX: GetFileSnapshotBitmap, GetFileSnapshotSKBitmap, GetFileSnapshotRGB
- [X-engines] iOS support in MAUI samples
- [X-engines] Resolved memory leak issue for RTSP sources
- [Media Player SDK .Net] MediaPlayerCore: Added support for data streams in video files using the FFMPEG source engine. Add the OnDataFrameBuffer event to get data frames (KLV or other) from the video file.
- [Video Capture SDK .Net] VideoCaptureCore: Added support for data streams in video files using the IP Capture FFMPEG source engine. Add the OnDataFrameBuffer event to get data frames (KLV or other) from the MPEG-TS UDP network stream or other supported source.
- [Video Capture SDK .Net] VideoCaptureCore: Added the FFMPEG_CustomOptions property to the IPCameraSourceSettings class. This property allows you to set custom FFMPEG options for the IP camera source
- [Windows] Fixed the hang problem with the FFMPEG source when a network connection is lost
- [Media Blocks SDK .Net] Added RTSP MultiView in Sync Demo
- [X-engines] Added support for FLIR/Teledyne cameras (USB3Vision/GigE) using the Spinnaker SDK
- [Video Edit SDK .Net] VideoEditCoreX: Added support for .Net Stream usage as an input source
- The IAsyncDisposable interface was added to all SDK's core classes. The
DisposeAsynccall should be used to dispose of the core objects using async methods. - [Video Capture SDK .Net] VideoCaptureCoreX: Resolved issues with Android video capture (sometimes started only one time)
- [Media Blocks SDK .Net] Added HLS streaming sample
- [Video Capture SDK .Net] VideoCaptureCore: Resolved crash if the
multiscreenis enabled and screens added as window's handles (WinForms) - [X-engines] Improved MAUI video rendering speed
- [X-engines] Resolved MAUI media playback issues (decoding) in MAUI Android
- [X-engines] Resolved an issue with the H264 webcam sources (sometimes not connected)
- [X-engines] Resolved an issue with audio stream playback in the Live VideoCompositor engine
- [Media Blocks SDK .Net] Resolved a bad audio issue while mixing using the Live Video Compositor engine
- [Media Blocks SDK .Net] Added Decklink output and file source into the Live Video Compositor sample
- [Media Player SDK .Net] MediaPlayerCore: Added growing MPEG-TS file support for the VLC engine. You can play growing MPEG-TS files while it's recorded
15.8¶
- [X-engines] [API breaking change] DeviceEnumerator can now be used only by using
DeviceEnumerator.Sharedproperty. One enumerator per app is required. DeviceEnumerator objects used by API have been removed - [X-engines] [API breaking change] Android Activity is not required anymore to create SDK engines
- [X-engines] [API breaking change] X-engines require additional initialization and de-initialization steps. To initialize SDK, use the
VisioForge.Core.VisioForgeX.InitSDK()call. To de-initialize SDK, use theVisioForge.Core.VisioForgeX.DestroySDK()call. You need to initialize SDK before any SDK class usage and de-initialize SDK before the application exits. - [Windows] Improved MAUI video rendering performance in Windows
- [Windows] Added a mouse highlight for screen capture sources
- [Windows] Resolved a CallbackOnCollectedDelegate call issue with the BasicWindow class
- [Avalonia] Resolved an issue with Avalonia VideoView resize
- [X-engines] Added the StartPosition and StopPosition properties to UniversalSourceSettings. You can use these properties to set the start and stop positions for the file source.
- [ALL] Resolved the issue with passwords with special characters used for RTSP sources
- [ALL] Resolved the rare video flip issue with the Virtual Camera SDK engine
- [ALL] The VisioForge MJPEG Decoder filter was removed from the SDK's NuGet packages. You can optionally add it to your project by file copying or COM registration deployment.
- [X-engines] Fixed memory leak in the OverlayManager
- [Media Blocks SDK .Net] Resolved issue with the VideoSampleGrabberBlock, SetLastFrame option
- [Video Capture SDK .Net] VideoCaptureCoreX: WASAPI and WASAPI2 audio sources can be used now with the VideoCaptureCoreX engine
- [X-engines] DeviceEnumerator got events to notify about devices added/removed: OnVideoSourceAdded, OnVideoSourceRemoved, OnAudioSourceAdded, OnAudioSourceRemoved, OnAudioSinkAdded, OnAudioSinkRemoved
- [X-engines] Added custom error handler support for MediaBlocks, VideoCaptureCoreX, and MediaPlayerCoreX engines. Use the IMediaBlocksPipelineCustomErrorHandler interface and the SetCustomErrorHandler method to set a custom error handler.
- [Video Capture SDK .Net] VideoCaptureCoreX: Resolved issue with incorrect device index error for KS video sources (Windows)
- [Video Capture SDK .Net] VideoCaptureCore: Added Virtual_Camera_Output_AlternativeAudioFilterName property to set a custom audio filter for the Virtual Camera SDK output
- [Video Edit SDK .Net] VideoEditCore: Added Virtual_Camera_Output_AlternativeAudioFilterName property to set a custom audio filter for the Virtual Camera SDK output
- [Media Player SDK .Net] MediaPlayerCore: Added Virtual_Camera_Output_AlternativeAudioFilterName property to set a custom audio filter for the Virtual Camera SDK output
- [Video Capture SDK .Net] VideoCaptureCoreX: Added NDI streaming support and sample app.
- [Media Blocks SDK .Net] Added the BufferSink block to get video/audio frames from the pipeline
- [Media Blocks SDK .Net] Added the CustomMediaBlock class to create custom media blocks for any GStreamer element
- [Media Blocks SDK .Net] Added the UpdateChannel method to update the channel of the bridge source or sink
- [Media Player SDK .Net] MediaPlayerCore: Updated Tempo effect.
- [X-engines] Updated device enumerator. Removed unwanted firewall dialog when listing NDI sources.
- [X-engines] Fixed an issue with the video mixer when adding/removing video sources.
- [Media Blocks SDK .Net] Added VideoCropBlock and VideoAspectRatioCropBlock blocks to crop video frames.
- [Media Blocks SDK .Net] Resolved wrong frame rate issue with VideoRateBlock.
- [All] Resolved an issue with the Tempo audio effect.
- [Video Capture SDK .Net] VideoCaptureCore: Added WASAPI audio renderer support for the VideoCaptureCore engine.
15.7¶
- [ALL] .Net 8 support
- [Video Capture SDK .Net] VideoCaptureCore: Fixed problem with the OnNetworkSourceDisconnect event being called twice.
- [X-engines] Added the MPEG-2 video encoder.
- [X-engines] Added the MP2 audio encoder.
- [X-engines] Resolved Decklink enumeration issues.
- [X-engines] Default VP8/VP9 settings changed to live recording.
- [X-engines] Added DNxHD video encoder support.
- [Video Capture SDK .Net] VideoCaptureCoreX: Fixed problem with audio source format setting (regression).
- [Video Capture SDK .Net] VideoCaptureCoreX: Resolved WPF native rendering issue with a pop-up window.
- [All] Avalonia 11.0.5 support.
- [Video Capture SDK .Net] VideoCaptureCoreX: Resolved licensing issues.
- [Video Capture SDK .Net] VideoCaptureCore: Start/StartAsync method will return false if the video capture device is already used by another application.
- [All] Updated VLC source (libVLC 3.0.19).
- [All] Updated FFMPEG sources and encoders. Resolved issue with missed MSVC dependencies.
- [Video Capture SDK] Updated ONVIF engine.
- [Cross-platform SDKs] Updated Decklink source. Resolved the issue with the incorrect device name.
- [All] SkiaSharp security updates.
- [Cross-platform SDKs] Updated Overlay Manager. Added OverlayManagerDateTime class to draw current date time and custom text.
- [Cross-platform SDKs] Updated OverlayManagerImage. Resolved issue with System.Drawing.Bitmap usage.
- [ALL] VideoCaptureCore: Resolved rare crash issue with WinUI VideoView
- [Video Capture SDK .Net] VideoCaptureCore: Updated FFMPEG.exe output. Improved support of x264 and x265 encoders of custom FFMPEG builds.
15.6¶
- [Video Capture SDK .Net] VideoCaptureCore: Improved video crop performance on modern CPUs
- [ALL] VideoCaptureCore, MediaPlayerCore, VideoEditCore: Added the static CreateAsync method that can be used instead of the constructor to create engines without UI lag.
- [Video Capture SDK .Net] VideoCaptureCore: Resolved issues with video crop.
- [Video Capture SDK .Net] VideoCaptureCoreX: Added video overlays API. The Overlay Manager Demo shows how to use it.
- [Video Capture SDK .Net] Improved HW encoder detection. If you have several GPUs, sometimes only the major GPU can be used for video encoding.
- [Cross-platform SDKs] Updated Avalonia VideoView. Resolved issue with VideoView recreation.
- [Media Player SDK .Net] MediaPlayerCoreX: Resolved startup issue with the Android version of the MediaPlayerCoreX engine.
- [Media Player SDK .Net] MediaPlayerCore: Video_Stream_Index property has been replaced with Video_Stream_Select/Video_Stream_SelectAsync methods.
- [Media Player SDK .Net] MediaPlayerCoreX: Added Video_Stream_Select method.
- [Video Capture SDK .Net] VideoCaptureCore: Network_Streaming_WMV_Maximum_Clients property moved to WMVOutput class. You can set the maximum number of clients for network WMV output.
- [All] Updated WPF rendering. Improved performance for 4K and 8K videos.
- [Video Capture SDK .Net] VideoCaptureCoreX: Resolved issue with multiple outputs used.
- [Video Capture SDK .Net] VideoCaptureCoreX: Resolved issue with OnAudioFrameBuffer event.
- [Video Capture SDK .Net] Decklink source changed to improve startup speed. The Decklink_CaptureDevices method has been replaced by async Decklink_CaptureDevicesAsync.
- [Media Player SDK .Net] MediaPlayerCoreX: Added Custom_Video_Outputs/Custom_Audio_Outputs properties to set custom video/audio renderers
- [Media Player SDK .Net] MediaPlayerCoreX: Added Decklink Output Player Demo (WPF)
- [Video Edit SDK .Net] Added Multiple Audio Tracks Demo (WPF)
- [Video Edit SDK .Net] Updated MP4 output for multiple audio tracks
- [Cross-platform SDKs] Updated device enumerator
- [Video Capture SDK .Net] Resolved issue with VU meter in cross-platform engine
- [Cross-platform SDKs] Resolved issue with VU Meter (event not fired)
- [Media Player SDK .Net] Updated memory playback
- [ALL] Added IAsyncDisposable interface support for cross-platform core classes. It should be used to dispose of the core objects in async methods.
- [Video Capture SDK .Net] Added madVR support for mutiscreen
- [Video Capture SDK .Net] Resolved NDI enumerating issue in the VideoCaptureCore engine
- [Media Player SDK .Net] Added madVR Demo
- [Video Capture SDK .Net] Added madVR Demo
- [ALL] Resolved madVR issues in all SDKs
- [Media Blocks SDK .Net] Added NDI Source demo
- [Video Capture SDK .Net] Added NDI support for cross-platform engine
- [ALL] Resolve the "image not found" issue with the WinUI NuGet package
- [Media Blocks SDK .Net/Media Player SDK .Net (cross-platform)] Added MP3+CDG Karaoke Player demo
- [Media Blocks SDK .Net] Added CDGSourceBlock for MP3+CDG karaoke files playback
- [ALL] Improved madVR support
- WinUI VideoView updated to fix issues during audio file playback
- [Video Capture SDK .Net] Improved VNC source support for the VideoCaptureCoreX engine.
- [Video Capture SDK .Net] Added VNC source support for the VideoCaptureCoreX engine. You can use VNCSourceSettings class to configure Video_Source.
- [Media Blocks SDK .Net] Added VNC source support. You can use the VNCSourceBlock class as a video source block.
- [Video Capture SDK .Net] Video_Resize property has been changed to IVideoResizeSettings type. You can use the VideoResizeSettings class to perform classic resize the same as before or use MaxineUpscaleSettings/MaxineSuperResSettings to perform AI resizing on Nvidia GPU using Nvidia Maxine SDK (SDK or SDK models are required to deploy).
- [ALL] Resolved issues with NDI source detection in the local network
- [ALL] Added KLVParser class to read and decode data from KLV binary files.
- [ALL] Added KLVFileSink block. You can export KLV data from MPEG-TS files.
- [Media Blocks SDK .Net] Added KLV demo.
- [Video Capture SDK .Net] Added MJPEG network streamer.
- [ALL] Added WASAPI 2 support.
- [Media Blocks SDK .Net] Updated Video Effects API. Added Grayscale media block.
- [Media Blocks SDK .Net] Added Live Video Compositor API and sample.
- [ALL] Updated Avalonia VideoView control. Resolved issues with video playback on Windows on HighDPI displays.
- [Video Capture SDK .Net] Added CustomVideoFrameRate property to MFOutput. You can set a custom frame rate if your source provides an incorrect frame rate (IP camera, for example).
- [Video Capture SDK .Net] Updated NVENC encoder. Resolved issue with high-definition video capture.
- [Video Capture SDK .Net] Resolved issue with TV Tuning on Avermedia devices
- [Media Blocks SDK .Net] Added OpenCV blocks: CVDewarp, CVDilate, CVEdgeDetect, CVEqualizeHistogram, CVErode, CVFaceBlur, CVFaceDetect, CVHandDetect, CVLaplace, CVMotionCells, CVSmooth, CVSobel, CVTemplateMatch, CVTextOverlay, CVTracker
- [CV] Resolved the issue with wrong face coordinates.
- [CV, Media Blocks SDK .Net] Added Face Detector block.
- [Media Blocks SDK .Net] Added rav1e AV1 video encoder.
- [Media Blocks SDK .Net] Added GIF video encoder.
- [Media Blocks SDK .Net] Added NDI Sink and NDI source blocks.
- [ALL] Resolved NDI SDK detection issues.
- [Media Blocks SDK .Net] Updated Speex encoder.
- [Media Blocks SDK .Net] Updated Video Mixer block.
- [ALL] Added Save/Load methods for output format to serialize into JSON.
- [Media Blocks SDK .Net] Added MJPEG HTTP Live streaming sink block.
- [ALL] Resolved MP4 HW QSV H264 regression.
- [ALL] WinForms and WPF VideoView stability updates.
- [Media Player SDK .Net] Removed FilenamesOrURL legacy property. Please use the
PlaylistAPI instead. - [Media Blocks SDK .Net] Added fade-in/out feature for image overlay block.
- [ALL] Telemetry update
- [ALL] SDKs updated to use the
ObservableCollectioninstead of theListin public API. - [ALL] Updated MP4 HW output. Improved NVENC performance.
- [Media Blocks SDK .Net] Added Video Compositor sample.
- [Media Blocks SDK .Net] Added YouTubeSink and FacebookLiveSink blocks with custom YouTube/Facebook configurations. The
RTMPSinkcan stream to YouTube/Facebook in the same way as before. - [Media Blocks SDK .Net] Added SqueezeBack video mixer block.
- [ALL] Updated scrolling text logo. We've added the Preload method to render a text overlay before playback.
- [ALL] Updated scrolling text logo (performance)
- [Media Blocks SDK .Net] Updated Decklink sink blocks
- [ALL] Resolved crashes with a text logo with a custom resolution
- [Media Blocks SDK .Net] Added Intel QuickSync H264, HEVC, VP9, and MJPEG encoders support.
- [Video Edit SDK .Net] Added FastEdit_ExtractAudioStreamAsync method to extract the audio stream from the video file.
- [Video Edit SDK .Net] Added "Audio Extractor" WinForms sample.
- [Media Blocks SDK .Net] Updated MP4SinkBlock. The sink can split output files by duration, file size, or timecode. Use MP4SplitSinkSettings instead of MP4SinkSettings to configure.
- [Video Capture SDK .Net] Added the OnMJPEGLowLatencyRAWFrame event that fired when the MJPEG low latency engine received a RAW frame from a camera.
- [Media Blocks SDK .Net] Added VideoEffectsBlock to use video effects, available in Windows SDKs
- [Media Blocks SDK .Net] Updated Decklink source
- [Media Blocks SDK .Net] Added Decklink Demo (WPF)
- [ALL] Resolved the DeinterlaceBlend video effect crash
- [ALL] Used 3rd-party libraries moved to VisioForge.Libs.External assembly/NuGet
- [ALL] Added Nvidia Maxine Video Effects SDK (BETA) and sample app for Media Player SDK .Net and Video Capture SDK .Net
- [Video Capture SDK .Net] Added Decklink_Input_GetVideoFramesCount/Decklink_Input_GetVideoFramesCountAsync API to get total and dropped frames for the Decklink source
- [ALL] VisioForge HW encoders update
15.5¶
- .Net 7 support
- Added NetworkDisconnect event support to MJPEG Low Latency IP camera engine
- Added Linux support for the VideoEditCoreX-based demos
- Added OnRTSPLowLatencyRAWFrame event to get RAW frames from RTSP stream, using RTSP Low Latency engine
- Added AutoTransitions property to the VideoEditCoreX engine
- System.Drawing.Rectangle and System.Drawing.Size types are replaced by VisioForge.Types.Rectangle and VisioForge.Types.Size in all crossplatform APIs
- MAUI samples (BETA) are added
- Improved compatibility with Snap Camera for MP4 HW encoding
- Online licensing updated
- Added Camera Light demo
- Added segments support in Media Player SDK .Net (Cross-platform engine)
- Added Playlist API in Media Player SDK .Net (Windows-only engine)
- Resolved issues with the "rtsp_source_create_audio_resampler" call in the RTSP Low Latency engine in Video Capture SDK .Net (Windows-only engine)
- Added support for multiple Decklink outputs in Video Capture SDK .Net and Video Edit SDK .Net (Windows-only engine)
- Resolved issues with the reverse playback engine in Media Player SDK .Net (Windows-only engine)
- ONVIFControl and other ONVIF-related APIs are available for all platforms
- API breaking change: the frame rate changed from double to VideoFrameRate in all APIs
- Added GPU HW decoding for VLC engine
- Resolved issue with WPF HighDPI apps that use EVR
- Resolved issue with MediaPlayerCore.Video_Renderer_SetCustomWindowHandle method
- Added previous frame playback in Media Player SDK .Net (Cross-platform engine)
- Added WPF Screen Capture Demo to Media Blocks SDK .Net
15.4¶
- Resolved an issue with ignored Play_PauseAtFirstFrame property
- Updated HighDPI support in WinForms samples
- Resolved an issue with HighDPI support for the Direct2D video renderer
- Added additional API to ONVIFControl class: GetDeviceCapabilities, GetMediaEndpoints
- Resolved forced reencoding issue with FFMPEG files joining without reencoding
- Sentry update
- Added video interpolation settings for Zoom and Pan video effects
- Added GtkSharp UI framework support for video rendering
- FastEdit API has been changed to async
- Resolved screen flip issue with Video_Effects_AllowMultipleStreams property of Video Capture SDK .Net core
- Updated RTSP MultiView demo (added GPU decoding, added RAW stream access)
- Added OnLoop event into Media Player SDK .Net
- Added Loop feature into Media Blocks SDK .Net
- Avalonia VideoView was downgraded to 0.10.12 because of Avalonia UI problems with NativeControl
- Added File Encryptor demo for Video Edit SDK .Net
15.3¶
- App start-up time improved for PCs with Decklink cards
- NDI SDK v5 support
- Resolved an issue with MKV Legacy output (wrong cast exception).
- Zoom and pan effects performance optimizations
- Added basic Media Blocks API (WIP)
- Added HLS network streaming to Video Edit SDK .Net
- Added Rotate property to WPF VideoView. You can rotate the video by 90, 180, or 270 degrees. Also, you can use the GetImageLayer() method to get the Image layer and apply custom transforms
- API change - FilterHelpers renamed to FilterDialogHelper
- VisioForge.Types and VisioForge.MediaFramework assemblies merged into VisioForge.Core
- UI classes moved to VisioForge.Core.UI.* assemblies and independent NuGet packages
- VisioForge.Types renamed to VisioForge.Core.Types
- VisioForge.Core no longer depends on the Windows Forms framework
15.2¶
- Added HorizontalAlignment and VerticalAlignment properties to the text and image logos
- Updated ONVIF support, resolved an issue with username and password specified in URL but not specified in source settings
- Resolved an issue with the FFMPEG.exe output dialog
- Resolved an issue with the separate capture in a service applications
- SDK migrated to System.Text.Json from NewtonsoftJson
- Updated DirectCapture output for IP cameras
- Video processing performance optimizations
- IPCameraSourceSettings.URL property type changed from string to a
System.Uri - Added DirectCapture ASF output for IP cameras
15.1¶
- Disabled Sentry debug messages in the console
- Added Icecast streaming
- VideoStreamInfo.FrameRate property type changed to VideoFrameRate (with numerator and denominator) from double
- Updated WPF VideoView, resolved the issue for IP camera stream playback
- API breaking change:
VisioForge.Controls,VisioForge.Controls.UI,VisioForge.Controls.UI.Dialogs, andVisioForge.Toolsassemblies are merged inside theVisioForge.Coreassembly - Audio effect API now uses string name instead of index
- Added Android support in Media Player SDK .Net
- Added a new GStreamer-based cross-platform engine to support Windows and other platforms within the v15 development cycle
15.0¶
- Added StatusOverlay property for VideoCapture class. Assign the
TextStatusOverlayobject to this property to add text status overlay, for example, to show "Connecting..." text during IP camera connecting. - RTSP Live555 IP camera engine has been removed. Please use RTSP Low Latency or FFMPEG engines.
- Resolved SDK_Version possible issue.
- Added Settings_Load API. You can load the settings file saved by Settings_JSON. Be sure that device names are correct.
- Resolved issue with an exception if separate capture started before Start/StartAsync method call.
- RTP support for the VLC source engine.
- API breaking change: SDK_State property has been removed. We do not have TRIAL and FULL SDK versions anymore.
- API breaking change: DirectShow_Filters_Show_Dialog, DirectShow_Filters_Has_Dialog, Audio_Codec_HasDialog, Audio_Codec_ShowDialog, Video_Codec_HasDialog, Video_Codec_ShowDialog, Filter_Supported_LAV, Filter_Exists_MatroskaMuxer, Filter_Exists_OGGMuxer, Filter_Exists_VorbisEncoder, Filter_Supported_EVR, Filter_Supported_VMR9 and Filter_Supported_NVENC has been moved to VisioForge.Tools.FilterHelpers class.
- The
VFAudioStreamInfo/VFVideoStreamInfoclasses use theTimespanfor the duration. - Decklink types from VisioForge.Types assembly moved to VisioForge.Types.Decklink namespace.
- Telemetry updated.
- Custom redist loader updated.
- NDI update.
- API breaking change: The
Statusproperty was renamed to theState. The property type isPlaybackStatein all SDKs. - API breaking change: UI controls split into Core (VideoCaptureCore, MediaPlayerCore, VideoEditCore) and VideoView.
- API breaking change: Video_CaptureDevice... properties merged into Video_CaptureDevice property of VideoCaptureSource type.
- API breaking change: Audio_CaptureDevice... properties merged into Audio_CaptureDevice property of AudioCaptureSource type.
- API breaking change: In the Media Player SDK, the
Source_StreamAPI properties were merged into theSource_MemoryStreamproperty of theMemoryStreamSourcetype - Updated DVD playback
- Updated FFMPEG source
- API breaking change: Media Player SDK types moved from VisioForge.Types namespace to VisioForge.Types.MediaPlayer
- API breaking change: Video Capture SDK types moved from VisioForge.Types namespace to VisioForge.Types.VideoCapture
- API breaking change: Video Edit SDK types moved from VisioForge.Types namespace to "VisioForge.Types.VideoEdit"
- API breaking change: Output types moved from VisioForge.Types namespace to VisioForge.Types.Output
- API breaking change: Video Effects types moved from VisioForge.Types namespace to VisioForge.Types.VideoEffects
- API breaking change: Audio Effects types moved from VisioForge.Types namespace to VisioForge.Types.AudioEffects
- API breaking change: Event types moved from VisioForge.Types namespace to VisioForge.Types.Events
- Added Video_Renderer_SetCustomWindowHandle method to set custom video renderer by Win32 window/control HWND handle
14.4¶
- Windows 11 support
- Telemetry update
- Resolved issues with Picture-in-Picture in 2x2 mode
- Resolved issues with MJPEG Low Latency source in .Net 5/.Net 6/.Net Core 3.1
- Resolved issue with UDP network streaming for Decklink source
- VFMP4v11Output renamed to VFMP4HWOutput
- Added Microsoft H265 encoder support
- Added Intel QuickSync H265 encoder support
- Added OnDecklinkInputDisconnected/OnDecklinkInputReconnected events
- Updated Decklink output
- Resolved issues with Separate capture for MP4 HW, MOV, MPEG-TS, and MKVv2 outputs
- Added Video_CaptureDevice_CustomPinName property. You can use this property to set a custom output pin name for a video capture device with several output video pins
- Custom redist configuration updated
- Updated IP camera RTSP Low Latency engine
14.3¶
- An issue with Video Resize filter creation for NuGet redists has been resolved
- Telemetry update
- Updated VFDirectCaptureMP4Output output
- .Net 6 (preview) support
- Nvidia CUDA removed. NVENC is a modern alternative and is available for H264/HEVC encoding.
- IP camera MJPEG Low Latency engine has been updated
- The NDI source listing has been updated
- Improved ONVIF support
- Added .Net Core 3.1 support for RTSP Low Latency source engine
- Resolved issues with Picture-in-Picture for 2x2 mode
- Split project and solutions by independent files for .Net Framework 4.7.2, .Net Core 3.1, .Net 5 and .Net 6
14.2¶
- An issue with audio stream capture with enabled Virtual Camera SDK output was resolved
- VFMP4v8v10Output was replaced with VFMP4Output
- The "CanStart" method was added for Video_CaptureDevices items. The method returns true if the device can start and is not used exclusively in another app
- Added async/await API to the ONVIFControl
- An issue with wrong ColorKey processing in the Text Overlay video effect was resolved
- Added forced frame rate support for the RTSP Low Latency IP camera source
- MP4v11 AMD encoders were updated
- The timestamp issue that happened during the MP4v11 separate capture pause/resume was resolved
- FFMPEG.exe network streaming update
- FFMPEG output was updated to the latest FFMPEG version
- VC++ redist is no longer required to be installed. VC++ linking changed to static (except optional XIPH output)
- Many base DirectShow filters moved to the VisioForge_BaseFilters module
14.1¶
- Added WPF VideoView control. You can push video frames from the OnVideoFrameBuffer event to control to render them
- Correct default transparency value for a text logo
- ONVIF support added to .Net 5 / .Net Core 3.1 builds
- Added IP_Camera_ONVIF_ListSourcesAsync method to discover ONVIF cameras in the local network
- (BREAKING API CHANGE) Changed video capture device API for frame rates enumerating to support modern 4K cameras
- Updated MJPEG Decoder (improved performance)
- Removed MP4 v8 legacy encoders
- INotifyPropertyChanged support in WinForms/WPF wrappers to provide MVVM application support
- Resolved issue with RTMPS streaming to Facebook
- IP camera source added to the TimeShift demo
- Added separate output support for MOV
- Added fast-start FFMPEG flag for MP4v11 output that used FFMPEG MP4 muxer
- Added GPU decoding for the IP Camera source in demo applications
- Added CustomRedist_DisableDialog property to disable the redist message dialog
- Removed Kinect assemblies and demos. Please contact us if you still need Kinect packages
- MP4v10 default profile has been changed to Baseline / 5.0 for better browser compatibility
14.0¶
- .Net 5.0 support
- Resolved issue with not visible Decklink sources in NuGet SDK version
- Resolved issue with device added/removed notifier
- Added alternative NDI source in Video Capture SDK .Net
- Added NDI streaming (server) in Video Capture SDK .Net
- Resolved Separate Capture usage issue for NuGet deployment
- Resolved issue with merged text/image logos
- Updated device notifier
- Added CameraPowerLineControl class to control webcam power line frequency option
- Legacy audio effects have been removed.
- Removed HTTP_FFMPEG, RTSP_UDP_FFMPEG, RTSP_TCP_FFMPEG and RTSP_HTTP_FFMPEG from VFIPSource enumeration. You can use the Auto_FFMPEG value
- Updated HLS server. Correct error reporting about used port
- Added NDI streaming (server) in Video Edit SDK .Net
- Added NDI streaming (server) in Media Player SDK .Net
- Added IP_Camera_CheckAvailable method in Video Capture SDK .Net
- Updated FFMPEG Source filter, more supported codecs, and added GPU decoding
12.1¶
- Migrated to .Net 4.6
- Added Debug_DisableMessageDialogs property to disable error dialog if OnError event is not implemented.
- Fixed issue with resizing on the pause for WPF controls.
- Updated ONVIF engine in Video Capture SDK .Net
- Updated What You Hear source in Video Capture SDK .Net
- Added OnPause/OnResume events
- Updated YouTube demo in Media Player SDK .Net
- Improved support of webcams with integrated H264 encoder in Video Capture SDK .Net
- Updated VLC source
- Removed unwanted warning in MP4 v11 output
- One installer for TRIAL and FULL versions
- Same NuGet packages for TRIAL and FULL versions
- .Net Core NuGet packaged merged with .Net Framework package
- Added NuGet redists. Deployment was never so simple!
12.0¶
- Async / await API for all SDKs
- Breaking API change: All time-related API now uses TimeSpan instead of long (milliseconds)
- Tag reader/writer - correct logo loading for some video formats
- Removed legacy DirectX 9 video effects
- Fixed audio conversion progress issue in Video Edit SDK .Net
- Improved .Net Core compatibility
- Virtual Camera SDK output added to Media Player SDK .Net (as one of the video renderers)
- NewTek NDI devices support added to Video Capture SDK .Net as a new engine for IP cameras
- Added Video_Effects_MergeImageLogos and Video_Effects_MergeTextLogos properties. If you have three or more logos, you can set these properties to true to optimize video effects' performance
- Added playlist type option for HLS network streaming
- Added integrated lightweight HTTP server for HLS network streaming
- Added VR 360° video support in Media Player SDK .Net
- Improved DirectX 11 video processing
- Added MPEG-TS AAC-only no video support for MPEG-TS output
- Improved What You Hear audio source
- Several new demo applications
- Improved MP4 v11 output
- Separate capture for MP4 v11 can split files without frame lose
- Many minor bugfixes
- .Net Core assemblies updated to .Net Core 3.1 LTS
- Updated demos repository on GitHub
11.4¶
- Added ASP.Net MVC video conversion demo app to Video Edit SDK .Net
- Alternative OSD implementation to handle Windows 10 changes
- Updated GPU video effects
- Updated memory source in Media Player SDK .Net
- Updated OSD API
- Resolved issues with video encryption using binary keys
- Update screen capture demos for Video Capture SDK .Net, added window selection to capture. You can capture any window, including windows in the background
- Mosaic effect added for Computer Vision demo in Video Capture SDK .Net
- Added Multiple IP Cameras Demo (WPF) in Video Capture SDK .Net
- Added custom video resize option for MP4v11 output
- Merge module (MSM) redists added to all SDKs
- Updated FFMPEG.exe output using pipes instead of virtual devices
- Resolved issue with PIP custom output resolution option in Video Capture SDK .Net
- Resolved issue with file lock using LAV engine in Media Player SDK .Net
- Added DirectX11-based GPU video processing
11.3¶
- Resolved issue with audio renderer connection if Virtual Camera SDK output enabled in Video Capture SDK
- Improved subtitles support with autoloading in Media Player SDK .Net
- Updated audio fade-in/fade-out effects
- Added MIDI and KAR files support in Media Player SDK .Net
- Added CDG karaoke files support (and new demo application) in Media Player SDK .Net
- Added Async playback in Media Player SDK .Net
- Updated integrated JSON serializer
- Added optional GPU decoding in Media Player SDK .Net. Available decoding engines: DXVA2, Direct3D 11, nVidia CUVID, Intel QuickSync
- Added .Net Core 3.0 support, including WinForms and WPF demo apps (Windows only)
11.2¶
- Added Loop property to Video Edit SDK .Net
- Updated audio enhancer
- Updated RTSP Low Latency source
- Resolved crop issue for Decklink source
- Added property to use TCP or UDP in RTSP Low Latency engine
- Deployment without COM registration and admin rights for Video Edit SDK and Media Player SDK (BETA)
- Updated video mixer with improved performance
- Added YouTube playback code snippet
- Added method to move OSD
11.1¶
- Fixed seeking issue with some MP4 files in Video Edit SDK
- Fixed stretch/letterbox issue in the WPF version of all SDKs
- Fixed issue with an equalizer on sample rate 16000 or less
- Fixed problem with sample grabber for DirectShow source in Media Player SDK
- Fixed encrypted files playback in Media Player SDK
- Added DVDInfoReader class to read info about DVD files
- Resolved issue with wrong file name in OnSeparateCaptureStopped event
- Improved barcode detection quality for rotated images
- The minimal .Net Framework version is .Net 4.5 now
- Improved YouTube playback in Media Player SDK. Added OnYouTubeVideoPlayback event to select video quality for playback
- Added the
Play_PauseAtFirstFrameproperty to the Media Player SDK .Net. If true playback will be paused on the first frame - Multiple screen support in Screen Capture demo in Video Capture SDK .Net
- Resolved issue with network stream playback in Media Player SDK .Net WPF applications
- Added low latency HTTP MJPEG stream playback (IP cameras or other sources) in Video Capture SDK .Net
- Added Fake Audio Source DirectShow filter, which produces a tone signal
- Updated Computer Vision demo in Video Capture SDK .Net
- Added Frame_GetCurrentFromRenderer method to all SDKs. Using this method, you can get the currently rendered video frame directly from the video renderer.
- Added low latency RTSP source playback in Video Capture SDK .Net
11.0¶
- Fixed bug with MP4 v11 output, custom GOP settings
- Updated MJPEG Decoder
- Fixed bug with MP4 v11 output. Added Windows 7 full support
- OnStop event of Video Edit SDK returns a successful status
- Video Capture SDK Main Demo update - multiscreen can automatically use connected external displays
- Media Player SDK Main Demo update - multiscreen can automatically use connected external displays
- Added fade-in / fade-out for text logo
- Updated Decklink output
- Video Edit SDK can fast-cut files from network sources (HTTP/HTTPS)
- Added Computer Vision demo, with cars/pedestrian counter and face/eyes/nose/mouth detector/tracker
- Updated MP4 output to use alternative muxer that provides constant frame rate
- Added MPEG-TS output
- Added MOV output