PrimarylessVideoSender class
Application-owned video stream, such as GUI panel content, that exists before any receiver connects and is delivered to every receiver that requests its stream id.
Namespace: Quaternar.Qaros · Assembly: Quaternar.Qaros.dll
public sealed class PrimarylessVideoSender : IDisposable
Implements: IDisposable
Remarks
Unlike RenderSender, which answers one target's render request and hands
out poses and FOVs to render with, this sender carries an arbitrary layout and no render
metadata. Use RenderSender for remote-rendered content shown in an app
volume, this one for video the application produces on its own.
Frame cycle: PrimarylessVideoSender.TryBeginFrame until it returns true, write the frame
(PrimarylessVideoSender.GetCpuFrame, PrimarylessVideoSender.GetD3D11Frame, PrimarylessVideoSender.GetOpenGlFrame or
PrimarylessVideoSender.GetVulkanFrame, matching the sender's graphics API), then
PrimarylessVideoSender.ShowFrame. The frame exists from creation and may be inspected outside a
cycle; its contents and synchronization may be written only inside one. Its texture
handles stay stable until a layout change, so they can be cached between cycles.
Methods
| Member | Description |
|---|---|
| GetStreamId() | |
| TryBeginFrame() | Non-blocking: true when a frame cycle was begun for the receivers ready at this moment; false when no cycle exists yet, so poll again later. |
| GetLayout() | |
| ChangeLayout(VideoFrameLayout) | Replaces the frame layout. The new frame resources are created synchronously on the calling thread; if that fails, the previous layout and frame stay usable. |
| GetCpuFrame() | |
| GetD3D11Frame() | |
| GetOpenGlFrame() | Requires a library built with QAR_ENABLE_OPENGL (otherwise EntryPointNotFoundException). |
| GetVulkanFrame() | Sender-owned Vulkan frame; requires a library built with QAR_ENABLE_VULKAN (otherwise EntryPointNotFoundException). Valid until the next call or this sender's disposal. |
| ShowFrame() | Sends the written frame to the receivers reserved by PrimarylessVideoSender.TryBeginFrame and ends the cycle. |
| Dispose() | Closes the stream to every receiver, draining frames still being sent first. |
GetStreamId
public Result<StreamId> GetStreamId()
TryBeginFrame
Non-blocking: true when a frame cycle was begun for the receivers ready at this moment; false when no cycle exists yet, so poll again later.
public Result<bool> TryBeginFrame()
Remarks
Receivers that become ready afterwards get the next cycle. Recoverable failures, to
keep polling through: StatusCode.MediaStreamingNoActiveTransfers while
no receiver is connected (the normal state before the first one requests the
stream), StatusCode.MediaStreamingStreamIsPaused while every receiver
has paused it, and StatusCode.MediaStreamingStreamIsReconnecting while
every receiver is reconnecting. Calling it again before PrimarylessVideoSender.ShowFrame fails
with StatusCode.LogicError: only one cycle may be open.
GetLayout
public Result<VideoFrameLayout> GetLayout()
Returns: Result<VideoFrameLayout>
ChangeLayout
Replaces the frame layout. The new frame resources are created synchronously on the calling thread; if that fails, the previous layout and frame stay usable.
public Result<Unit> ChangeLayout(VideoFrameLayout layout)
Parameters
| Name | Type | Description |
|---|---|---|
layout | VideoFrameLayout |
Exceptions
| Exception | Condition |
|---|---|
| ArgumentNullException | layout is null. |
Remarks
Texture handles cached from an earlier frame do not survive a successful change: fetch the frame again.
GetCpuFrame
public Result<VideoFrameCpu> GetCpuFrame()
Returns: Result<VideoFrameCpu>
GetD3D11Frame
public Result<VideoFrameD3D11> GetD3D11Frame()
Returns: Result<VideoFrameD3D11>
GetOpenGlFrame
Requires a library built with QAR_ENABLE_OPENGL (otherwise EntryPointNotFoundException).
public Result<VideoFrameOpenGl> GetOpenGlFrame()
Returns: Result<VideoFrameOpenGl>
GetVulkanFrame
Sender-owned Vulkan frame; requires a library built with QAR_ENABLE_VULKAN
(otherwise EntryPointNotFoundException). Valid until the next
call or this sender's disposal.
public Result<VideoFrameVulkan> GetVulkanFrame()
Returns: Result<VideoFrameVulkan>
Remarks
Inside a frame cycle, record on it the layout and queue family each image was left in
(VideoFrameVulkan.SetTextureState) and the synchronization the rendering
signals (VideoFrameVulkan.SetSynchronization) before
PrimarylessVideoSender.ShowFrame. PrimarylessVideoSender.ShowFrame fails with
StatusCode.LogicError when this was not called in the current cycle.
ShowFrame
Sends the written frame to the receivers reserved by PrimarylessVideoSender.TryBeginFrame and
ends the cycle.
public Result<Unit> ShowFrame()
Remarks
Succeeds when at least one reserved receiver got the frame; fails with
StatusCode.MediaStreamingNoActiveTransfers when all of them were lost
before delivery.
Dispose
Closes the stream to every receiver, draining frames still being sent first.
public void Dispose()