### UnityCapture MonoBehaviour Setup Source: https://context7.com/schellingb/unitycapture/llms.txt This C# script demonstrates how to set up the `UnityCapture` MonoBehaviour component on a Camera. It configures capture settings like device, resize mode, and mirroring. The component automatically handles texture sending via `OnRenderImage`. ```csharp // --- Inspector-configurable fields // // CaptureDevice : ECaptureDevice — which registered device slot to send to (Device1–Device10) // ResizeMode : EResizeMode — Disabled | LinearResize // Timeout : int (ms) — frames to wait before reporting "Unity stopped" (default 1000) // MirrorMode : EMirrorMode — Disabled | MirrorHorizontally // DoubleBuffering: bool — adds 1 frame latency but improves throughput on fast renders // EnableVSync : bool — overrides QualitySettings.vSyncCount on Awake // TargetFrameRate: int — overrides Application.targetFrameRate on Awake (default 60) // HideWarnings : bool — suppresses non-fatal log warnings // Minimal setup: attach this script to your main Camera in the Inspector. // All fields have sensible defaults. Device1 / no resize / no mirror / 1000 ms timeout. using UnityEngine; [RequireComponent(typeof(Camera))] public class MyCameraCapture : MonoBehaviour { // Reference the built-in UnityCapture component placed on the same camera, OR // configure it directly in the Inspector with the settings below. void Start() { var cap = gameObject.AddComponent(); cap.CaptureDevice = UnityCapture.ECaptureDevice.CaptureDevice1; cap.ResizeMode = UnityCapture.EResizeMode.Disabled; cap.MirrorMode = UnityCapture.EMirrorMode.Disabled; cap.Timeout = 1000; // ms cap.DoubleBuffering = false; cap.EnableVSync = false; cap.TargetFrameRate = 60; cap.HideWarnings = false; } } // The component handles OnRenderImage internally: // void OnRenderImage(RenderTexture source, RenderTexture destination) // { // Graphics.Blit(source, destination); // ECaptureSendResult result = CaptureInterface.SendTexture(source, Timeout, DoubleBuffering, ResizeMode, MirrorMode); // // logs warnings/errors based on result code // } ``` -------------------------------- ### Create Unity Capture Instance Source: https://context7.com/schellingb/unitycapture/llms.txt Creates a capture instance bound to a specific capture device slot. Returns an opaque pointer used by other functions. ```cpp UnityCaptureInstance* CaptureCreateInstance(int CapNum); ``` -------------------------------- ### OBS Configuration for Alpha Capture Source: https://context7.com/schellingb/unitycapture/llms.txt Configuration steps for OBS to capture Unity with alpha channel support. Ensure the resolution in OBS matches the Unity Game tab. ```text // OBS configuration for alpha capture: // Source: Video Capture Device → "Unity Video Capture" // Resolution: Custom → 1920x1080 (must match Unity Game tab resolution exactly) // Video Format: ARGB ``` -------------------------------- ### Configure Multiple Cameras with ECaptureDevice Source: https://context7.com/schellingb/unitycapture/llms.txt Use ECaptureDevice to map C# device indices to underlying capture numbers for sending multiple camera feeds to separate virtual capture devices. Ensure cameras render to independent RenderTextures. ```csharp // Enum values: // CaptureDevice1 = 0 (default; corresponds to "Unity Video Capture" in device list) // CaptureDevice2 = 1 (corresponds to "Unity Video Capture #2") // ... // CaptureDevice10 = 9 // Multi-camera example: send two cameras to two separate capture devices public class MultiCamCapture : MonoBehaviour { public Camera cam1, cam2; UnityCapture.Interface iface1, iface2; void Awake() { // Render each camera to its own RenderTexture so their outputs are independent cam1.targetTexture = new RenderTexture(1920, 1080, 24); cam2.targetTexture = new RenderTexture(1920, 1080, 24); iface1 = new UnityCapture.Interface(UnityCapture.ECaptureDevice.CaptureDevice1); iface2 = new UnityCapture.Interface(UnityCapture.ECaptureDevice.CaptureDevice2); } void LateUpdate() { // Called after all cameras have finished rendering this frame iface1.SendTexture(cam1.targetTexture); iface2.SendTexture(cam2.targetTexture); } void OnDestroy() { iface1.Close(); iface2.Close(); } } ``` -------------------------------- ### Register Unity Capture Filter Source: https://context7.com/schellingb/unitycapture/llms.txt Use these batch scripts to register the DirectShow filter DLLs with Windows. They handle UAC elevation automatically. Manual registration commands are also provided. ```bat :: Register a single capture device (default — "Unity Video Capture") Install\Install.bat ``` ```bat :: Register multiple capture devices (prompts for a count) Install\InstallMultipleDevices.bat ``` ```bat :: Register with a custom device name (prompts for a name) Install\InstallCustomName.bat ``` ```bat :: Unregister all devices Install\Uninstall.bat ``` ```bat :: Manual registration — equivalent to Install.bat regsvr32 "Install\UnityCaptureFilter32.dll" ``` ```bat regsvr32 "Install\UnityCaptureFilter64.dll" ``` ```bat :: Register 4 capture devices manually regsvr32 "Install\UnityCaptureFilter64.dll" "/i:UnityCaptureDevices=4" ``` ```bat :: Register with custom name manually regsvr32 "Install\UnityCaptureFilter64.dll" "/i:UnityCaptureName=My Game Camera" ``` -------------------------------- ### Capture Custom Textures with UnityCapture.Interface Source: https://context7.com/schellingb/unitycapture/llms.txt Use this class to send arbitrary Texture objects, such as procedurally generated textures or textures from secondary cameras, directly to the capture device. Ensure the interface is closed when no longer needed to release native resources. ```csharp using UnityEngine; public class CustomTextureCapture : MonoBehaviour { UnityCapture.Interface captureInterface; Texture2D tex; void Start() { // Create an interface to capture device slot 1 (index 0) captureInterface = new UnityCapture.Interface(UnityCapture.ECaptureDevice.CaptureDevice1); tex = new Texture2D(1920, 1080, TextureFormat.ARGB32, false); } void Update() { // Fill tex with your data here, then: tex.Apply(); UnityCapture.ECaptureSendResult result = captureInterface.SendTexture( tex, timeout: 1000, DoubleBuffering: false, ResizeMode: UnityCapture.EResizeMode.Disabled, MirrorMode: UnityCapture.EMirrorMode.Disabled ); switch (result) { case UnityCapture.ECaptureSendResult.SUCCESS: break; // frame delivered case UnityCapture.ECaptureSendResult.WARNING_FRAMESKIP: Debug.LogWarning("Frame was skipped by the capture device"); break; case UnityCapture.ECaptureSendResult.WARNING_CAPTUREINACTIVE: Debug.LogWarning("No receiving application has opened the capture device yet"); break; case UnityCapture.ECaptureSendResult.ERROR_UNSUPPORTEDGRAPHICSDEVICE: Debug.LogError("Only Direct3D 11 is supported"); break; case UnityCapture.ECaptureSendResult.ERROR_TOOLARGERESOLUTION: Debug.LogError("Resolution exceeds 3840×2160 maximum"); break; case UnityCapture.ECaptureSendResult.ERROR_TEXTUREFORMAT: Debug.LogError("Unsupported texture format — use ARGB32 (non-HDR) or ARGB Half / FP16 (HDR)"); break; case UnityCapture.ECaptureSendResult.ERROR_READTEXTURE: Debug.LogError("GPU texture readback failed"); break; case UnityCapture.ECaptureSendResult.ERROR_INVALIDCAPTUREINSTANCEPTR: Debug.LogError("Interface was already closed"); break; } } void OnDestroy() { captureInterface.Close(); // releases the native instance } } ``` -------------------------------- ### UnityCapturePlugin Exports Source: https://context7.com/schellingb/unitycapture/llms.txt These C-exported functions are the primary interface for capturing content from Unity. They are intended to be called via P/Invoke from C#. ```APIDOC ## CaptureCreateInstance ### Description Creates a capture instance bound to a specific capture device slot. ### Parameters - **CapNum** (int) - The 0-based index of the capture device. ### Returns An opaque pointer representing the capture instance, used by other functions. ``` ```APIDOC ## CaptureDeleteInstance ### Description Releases all resources associated with a capture instance. ### Parameters - **c** (UnityCaptureInstance*) - The opaque pointer to the capture instance returned by `CaptureCreateInstance`. ``` ```APIDOC ## CaptureSendTexture ### Description Copies a D3D11 render texture into shared memory for inter-process transfer. ### Parameters - **c** (UnityCaptureInstance*) - The instance returned by `CaptureCreateInstance`. - **TextureNativePtr** (void*) - The native pointer to the D3D11 texture (ID3D11Texture2D*). - **Timeout** (int) - The timeout in milliseconds before a "Unity stopped" state is triggered on the filter side. - **UseDoubleBuffering** (bool) - If true, allocates a second staging texture to prevent GPU pipeline stalls. - **ResizeMode** (SharedImageMemory::EResizeMode) - Specifies the resizing mode: `RESIZEMODE_DISABLED` or `RESIZEMODE_LINEAR` for filter-side scaling. - **MirrorMode** (SharedImageMemory::EMirrorMode) - Specifies the mirroring mode: `MIRRORMODE_DISABLED` or `MIRRORMODE_HORIZONTALLY`. - **IsLinearColorSpace** (bool) - True if Unity's active color space is Linear, affecting FP16 gamma. ### Returns An integer indicating the result: `RET_SUCCESS` (0), `RET_WARNING_FRAMESKIP` (1), `RET_WARNING_CAPTUREINACTIVE` (2), or `RET_ERROR_*` (100-104). ``` ```APIDOC ## UnitySetGraphicsDevice ### Description Sets the graphics device information for the Unity plugin. This is called automatically by Unity. ### Parameters - **device** (void*) - Pointer to the graphics device. - **deviceType** (int) - The type of the graphics device. - **eventType** (int) - The event type related to the graphics device. ``` -------------------------------- ### Set Unity Graphics Device Source: https://context7.com/schellingb/unitycapture/llms.txt Exports a function for Unity's plugin infrastructure to automatically set the graphics device and type. Only D3D11 is supported. ```cpp void UnitySetGraphicsDevice(void* device, int deviceType, int eventType); ``` -------------------------------- ### Configure Horizontal Flip with EMirrorMode Source: https://context7.com/schellingb/unitycapture/llms.txt Apply EMirrorMode.MirrorHorizontally to flip the output image left-to-right within the DirectShow filter. This is useful for webcam-style mirroring, but it's preferable to handle this in the receiving application if possible. ```csharp // EMirrorMode.Disabled (default) — no mirroring // EMirrorMode.MirrorHorizontally — each row is reversed in-place after colour conversion var cap = gameObject.GetComponent(); cap.MirrorMode = UnityCapture.EMirrorMode.MirrorHorizontally; ``` -------------------------------- ### SharedImageMemory Sender Usage Source: https://context7.com/schellingb/unitycapture/llms.txt Demonstrates the sender-side usage of the SharedImageMemory class to send image data. Checks if the receiver is ready before sending and handles different send results. ```cpp // Sender side (plugin): SharedImageMemory sender(0); // device 0 if (sender.SendIsReady()) { // returns false if no receiver has opened the mapping yet ESendResult r = sender.Send(width, height, stride, dataSize, FORMAT_UINT8, RESIZEMODE_DISABLED, MIRRORMODE_DISABLED, 1000, pixelBuffer); // SENDRES_OK — consumed by filter // SENDRES_WARN_FRAMESKIP — filter was not ready (no WantFrame event was pending) // SENDRES_TOOLARGE — dataSize > maxSize } ``` -------------------------------- ### SendTexture Method Signature and Usage Source: https://context7.com/schellingb/unitycapture/llms.txt This method pushes a frame to the DirectShow filter, accepting any Texture subclass. Note that DoubleBuffering: true adds 1 frame of latency but can reduce GPU stalls. Supported texture formats are ARGB32 (non-HDR) and ARGB Half/FP16 (HDR), with a maximum resolution of 3840x2160. ```csharp // Texture formats accepted by the native plugin: // DXGI_FORMAT_R8G8B8A8_UNORM / _UNORM_SRGB / _UINT / _TYPELESS → FORMAT_UINT8 (non-HDR) // DXGI_FORMAT_R16G16B16A16_FLOAT / _TYPELESS → FORMAT_FP16 (HDR) // Maximum supported resolution: // 3840 × 2160 (MAX_SHARED_IMAGE_SIZE = 3840 * 2160 * 4 * sizeof(short)) RenderTexture rt = new RenderTexture(1280, 720, 24); rt.format = RenderTextureFormat.ARGB32; // non-HDR — best performance UnityCapture.Interface iface = new UnityCapture.Interface(UnityCapture.ECaptureDevice.CaptureDevice1); ECaptureSendResult r = iface.SendTexture(rt, timeout: 500, DoubleBuffering: true); // DoubleBuffering: true → adds 1 frame latency, reduces GPU stalls on fast machines ``` -------------------------------- ### Handle SendTexture Results with ECaptureSendResult Source: https://context7.com/schellingb/unitycapture/llms.txt Implement logic to handle the return codes from SendTexture using ECaptureSendResult. Differentiate between successful frames, warnings (like frame skips), and errors (like unsupported graphics devices or invalid parameters). ```csharp // SUCCESS = 0 Frame written to shared memory and picked up by the filter. // WARNING_FRAMESKIP = 1 Frame written but the filter had not yet consumed the previous // one (capture app is slower than Unity render rate). // WARNING_CAPTUREINACTIVE = 2 No receiving application has opened the virtual camera yet // (filter's shared memory not open). // ERROR_UNSUPPORTEDGRAPHICSDEVICE = 100 Unity is not using Direct3D 11 backend. // ERROR_PARAMETER = 101 Null instance or null texture pointer passed. // ERROR_TOOLARGERESOLUTION = 102 Pixel data exceeds MAX_SHARED_IMAGE_SIZE (> 4K RGBA16). // ERROR_TEXTUREFORMAT = 103 D3D11 format is neither RGBA8 nor RGBA16F. // ERROR_READTEXTURE = 104 D3D11 Map() failed when reading the staging texture. // ERROR_INVALIDCAPTUREINSTANCEPTR = 200 Interface.Close() was already called. void HandleResult(UnityCapture.ECaptureSendResult r) { if (r == UnityCapture.ECaptureSendResult.SUCCESS) return; bool isWarning = (int)r < 100; bool isError = (int)r >= 100; if (isWarning && !hideWarnings) Debug.LogWarning($"[UnityCapture] Warning: {r}"); else if (isError) Debug.LogError($"[UnityCapture] Error: {r}"); } ``` -------------------------------- ### Error Display Modes Configuration Source: https://context7.com/schellingb/unitycapture/llms.txt Overview of error display modes for the Unity Capture filter when frames are not being sent. These modes are configurable via the 'Configure Video' properties. ```text // Note: the first 5 frames always display as EDM_BLACK regardless of the configured mode, // to avoid a flash of the error pattern during startup. // "Display FPS" checkbox: overlays the current capture frame-rate in green text // at the top-left corner of the output image. ``` -------------------------------- ### SharedImageMemory Protocol Source: https://context7.com/schellingb/unitycapture/llms.txt Details of the inter-process shared memory protocol used by UnityCapturePlugin and UnityCaptureFilter. ```APIDOC ## SharedImageMemory Sender (Plugin Side) ### Description Used by the plugin to send captured frames over shared memory. ### Usage ```cpp SharedImageMemory sender(0); // device 0 if (sender.SendIsReady()) { // returns false if no receiver has opened the mapping yet ESendResult r = sender.Send(width, height, stride, dataSize, FORMAT_UINT8, RESIZEMODE_DISABLED, MIRRORMODE_DISABLED, 1000, pixelBuffer); // SENDRES_OK — consumed by filter // SENDRES_WARN_FRAMESKIP — filter was not ready (no WantFrame event was pending) // SENDRES_TOOLARGE — dataSize > maxSize } ``` ### Parameters for `sender.Send` - **width** (int) - Pixel width of the frame. - **height** (int) - Pixel height of the frame. - **stride** (int) - Row stride in pixels. - **dataSize** (size_t) - Size of the pixel data in bytes. - **format** (EFormat) - Pixel format (e.g., `FORMAT_UINT8`, `FORMAT_FP16_GAMMA`, `FORMAT_FP16_LINEAR`). - **resizemode** (EResizeMode) - Resizing mode (`RESIZEMODE_DISABLED`, `RESIZEMODE_LINEAR`). - **mirrormode** (EMirrorMode) - Mirroring mode (`MIRRORMODE_DISABLED`, `MIRRORMODE_HORIZONTALLY`). - **timeout** (int) - Timeout in milliseconds. - **pixelBuffer** (const uint8_t*) - Pointer to the raw pixel data. ``` ```APIDOC ## SharedImageMemory Receiver (Filter Side) ### Description Used by the filter to receive captured frames from shared memory. ### Usage ```cpp SharedImageMemory receiver(0); EReceiveResult r = receiver.Receive( [](int w, int h, int stride, EFormat fmt, EResizeMode rm, EMirrorMode mm, int timeout, uint8_t* buf, void* ctx) { // convert buf (RGBA) → DirectShow sample buffer (BGR/BGRA) }, &myProcessState ); // RECEIVERES_CAPTUREINACTIVE — width==0, Unity never started // RECEIVERES_NEWFRAME — fresh frame arrived within RECEIVE_MAX_WAIT (200 ms) // RECEIVERES_OLDFRAME — no new frame; stale data reused (timeout counting begins) ``` ### Parameters for `receiver.Receive` - **callback** (function pointer) - A function to process the received frame data. It receives width, height, stride, format, resize mode, mirror mode, timeout, buffer pointer, and context. - **ctx** (void*) - User-defined context pointer passed to the callback. ``` -------------------------------- ### UnityCapture.Interface.SendTexture Source: https://context7.com/schellingb/unitycapture/llms.txt The SendTexture method allows you to push a frame to the DirectShow filter by accepting any Texture subclass. It internally calls the native plugin's CaptureSendTexture function via P/Invoke, passing the D3D11 native pointer. ```APIDOC ## Interface.SendTexture - Method Signature The single method on `UnityCapture.Interface` that pushes a frame to the DirectShow filter. Accepts any `Texture` subclass (including `Texture2D` and `RenderTexture`). Internally calls `CaptureSendTexture` in the native plugin via P/Invoke and passes the D3D11 native pointer. ```csharp // Signature: // public ECaptureSendResult SendTexture( // Texture Source, // int Timeout = 1000, // bool DoubleBuffering = false, // EResizeMode ResizeMode = EResizeMode.Disabled, // EMirrorMode MirrorMode = EMirrorMode.Disabled // ) // Texture formats accepted by the native plugin: // DXGI_FORMAT_R8G8B8A8_UNORM / _UNORM_SRGB / _UINT / _TYPELESS -> FORMAT_UINT8 (non-HDR) // DXGI_FORMAT_R16G16B16A16_FLOAT / _TYPELESS -> FORMAT_FP16 (HDR) // Maximum supported resolution: // 3840 × 2160 (MAX_SHARED_IMAGE_SIZE = 3840 * 2160 * 4 * sizeof(short)) RenderTexture rt = new RenderTexture(1280, 720, 24); rt.format = RenderTextureFormat.ARGB32; // non-HDR - best performance UnityCapture.Interface iface = new UnityCapture.Interface(UnityCapture.ECaptureDevice.CaptureDevice1); ECaptureSendResult r = iface.SendTexture(rt, timeout: 500, DoubleBuffering: true); // DoubleBuffering: true -> adds 1 frame latency, reduces GPU stalls on fast machines ``` ``` -------------------------------- ### Configure Resolution Mismatch Handling with EResizeMode Source: https://context7.com/schellingb/unitycapture/llms.txt Set EResizeMode to control how the DirectShow filter handles differences between Unity's render resolution and the receiving application's requested resolution. 'Disabled' is recommended to avoid scaling artifacts and potential frame skipping. ```csharp // EResizeMode.Disabled (default) — no scaling; filter shows an error pattern with text // describing both resolutions and asking the user to match them. // EResizeMode.LinearResize — the filter scales the image using nearest-neighbour bilinear // sampling. Can introduce frame skipping on slower machines. // Width of the capture output must be a multiple of 4. // Recommended: leave Disabled and configure the receiving application to match Unity's resolution. // In OBS: Video Capture Device → Properties → Resolution → type "1280x720" manually. var cap = gameObject.GetComponent(); cap.ResizeMode = UnityCapture.EResizeMode.Disabled; // safest option ``` -------------------------------- ### ECaptureDevice Enum Source: https://context7.com/schellingb/unitycapture/llms.txt Maps C# device index to the underlying SharedImageMemory capture number, allowing selection of up to 10 devices. ```APIDOC ## ECaptureDevice Enum Maps the C# device index to the underlying `SharedImageMemory` capture number. Up to 10 devices (CaptureDevice1–CaptureDevice10) can be addressed from Unity, corresponding to the number of filter instances registered with `InstallMultipleDevices.bat`. ### Enum Values: - `CaptureDevice1` = 0 (default; corresponds to "Unity Video Capture" in device list) - `CaptureDevice2` = 1 (corresponds to "Unity Video Capture #2") - ... - `CaptureDevice10` = 9 ### Example Usage: ```csharp // Multi-camera example: send two cameras to two separate capture devices public class MultiCamCapture : MonoBehaviour { public Camera cam1, cam2; UnityCapture.Interface iface1, iface2; void Awake() { // Render each camera to its own RenderTexture so their outputs are independent cam1.targetTexture = new RenderTexture(1920, 1080, 24); cam2.targetTexture = new RenderTexture(1920, 1080, 24); iface1 = new UnityCapture.Interface(UnityCapture.ECaptureDevice.CaptureDevice1); iface2 = new UnityCapture.Interface(UnityCapture.ECaptureDevice.CaptureDevice2); } void LateUpdate() { // Called after all cameras have finished rendering this frame iface1.SendTexture(cam1.targetTexture); iface2.SendTexture(cam2.targetTexture); } void OnDestroy() { iface1.Close(); iface2.Close(); } } ``` ``` -------------------------------- ### Send Texture via Shared Memory Source: https://context7.com/schellingb/unitycapture/llms.txt Copies a D3D11 render texture into shared memory for inter-process communication. Configure resizing, mirroring, and color space. Handles timeouts and optional double buffering to prevent GPU stalls. ```cpp int CaptureSendTexture( UnityCaptureInstance* c, void* TextureNativePtr, int Timeout, bool UseDoubleBuffering, SharedImageMemory::EResizeMode ResizeMode, SharedImageMemory::EMirrorMode MirrorMode, bool IsLinearColorSpace ); ``` -------------------------------- ### Shared Image Memory Header Structure Source: https://context7.com/schellingb/unitycapture/llms.txt Defines the layout of the SharedMemHeader at the beginning of the file mapping for inter-process shared memory communication. Includes metadata like size, dimensions, format, and flags. ```cpp struct SharedMemHeader { DWORD maxSize; // set to MAX_SHARED_IMAGE_SIZE by the receiver on first open int width; // pixel width of the current frame int height; // pixel height of the current frame int stride; // row stride in pixels (may differ from width due to D3D11 pitch) int format; // EFormat: FORMAT_UINT8=0, FORMAT_FP16_GAMMA=1, FORMAT_FP16_LINEAR=2 int resizemode; // EResizeMode: 0=disabled, 1=linear int mirrormode; // EMirrorMode: 0=disabled, 1=horizontally int timeout; // milliseconds uint8_t data[1]; // raw pixel bytes follow immediately (up to MAX_SHARED_IMAGE_SIZE) }; ``` -------------------------------- ### Delete Unity Capture Instance Source: https://context7.com/schellingb/unitycapture/llms.txt Releases all resources associated with a capture instance, including staging textures and SharedImageMemory sender. ```cpp void CaptureDeleteInstance(UnityCaptureInstance* c); ``` -------------------------------- ### EMirrorMode Enum Source: https://context7.com/schellingb/unitycapture/llms.txt Applies a horizontal flip to the output image within the DirectShow filter, useful for webcam-style mirroring. ```APIDOC ## EMirrorMode Enum Mirrors the output image left-to-right inside the DirectShow filter (multi-threaded). Useful for webcam-style "mirror" display. Prefer handling this in the receiving application when possible to avoid extra CPU work on the Unity side. ### Enum Values: - `EMirrorMode.Disabled` (default) — no mirroring - `EMirrorMode.MirrorHorizontally` — each row is reversed in-place after colour conversion ### Example Usage: ```csharp var cap = gameObject.GetComponent(); cap.MirrorMode = UnityCapture.EMirrorMode.MirrorHorizontally; ``` ``` -------------------------------- ### SharedImageMemory Receiver Usage Source: https://context7.com/schellingb/unitycapture/llms.txt Illustrates the receiver-side usage of the SharedImageMemory class to receive image data. It processes incoming frames using a callback function and handles different receive results, including inactive captures and stale frames. ```cpp // Receiver side (filter, runs in streaming thread): SharedImageMemory receiver(0); EReceiveResult r = receiver.Receive( [](int w, int h, int stride, EFormat fmt, EResizeMode rm, EMirrorMode mm, int timeout, uint8_t* buf, void* ctx) { // convert buf (RGBA) → DirectShow sample buffer (BGR/BGRA) }, &myProcessState ); // RECEIVERES_CAPTUREINACTIVE — width==0, Unity never started // RECEIVERES_NEWFRAME — fresh frame arrived within RECEIVE_MAX_WAIT (200 ms) // RECEIVERES_OLDFRAME — no new frame; stale data reused (timeout counting begins) ``` -------------------------------- ### ECaptureSendResult Enum Source: https://context7.com/schellingb/unitycapture/llms.txt Defines the return codes for the `SendTexture` method, indicating the success or failure of delivering a frame. ```APIDOC ## ECaptureSendResult Enum Every call to `SendTexture` returns one of these values. Warnings are non-fatal; errors indicate the frame was not delivered. ### Enum Values: - `SUCCESS` = 0: Frame written to shared memory and picked up by the filter. - `WARNING_FRAMESKIP` = 1: Frame written but the filter had not yet consumed the previous one (capture app is slower than Unity render rate). - `WARNING_CAPTUREINACTIVE` = 2: No receiving application has opened the virtual camera yet (filter's shared memory not open). - `ERROR_UNSUPPORTEDGRAPHICSDEVICE` = 100: Unity is not using Direct3D 11 backend. - `ERROR_PARAMETER` = 101: Null instance or null texture pointer passed. - `ERROR_TOOLARGERESOLUTION` = 102: Pixel data exceeds MAX_SHARED_IMAGE_SIZE (> 4K RGBA16). - `ERROR_TEXTUREFORMAT` = 103: D3D11 format is neither RGBA8 nor RGBA16F. - `ERROR_READTEXTURE` = 104: D3D11 Map() failed when reading the staging texture. - `ERROR_INVALIDCAPTUREINSTANCEPTR` = 200: Interface.Close() was already called. ### Example Usage: ```csharp void HandleResult(UnityCapture.ECaptureSendResult r) { if (r == UnityCapture.ECaptureSendResult.SUCCESS) return; bool isWarning = (int)r < 100; bool isError = (int)r >= 100; if (isWarning && !hideWarnings) Debug.LogWarning($"[UnityCapture] Warning: {r}"); else if (isError) Debug.LogError($"[UnityCapture] Error: {r}"); } ``` ``` -------------------------------- ### EResizeMode Enum Source: https://context7.com/schellingb/unitycapture/llms.txt Controls how the DirectShow filter handles resolution mismatches between Unity's render output and the receiving application's requested resolution. ```APIDOC ## EResizeMode Enum Controls what the DirectShow filter does when Unity's render resolution differs from the resolution requested by the receiving application. ### Enum Values: - `EResizeMode.Disabled` (default) — no scaling; filter shows an error pattern with text describing both resolutions and asking the user to match them. - `EResizeMode.LinearResize` — the filter scales the image using nearest-neighbour bilinear sampling. Can introduce frame skipping on slower machines. Width of the capture output must be a multiple of 4. ### Recommendation: Leave `Disabled` and configure the receiving application to match Unity's resolution. For example, in OBS: Video Capture Device → Properties → Resolution → type "1280x720" manually. ### Example Usage: ```csharp var cap = gameObject.GetComponent(); cap.ResizeMode = UnityCapture.EResizeMode.Disabled; // safest option ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.