1.0.0
First stable release. The receive pipeline is now a single, tunable FFmpeg user-space engine feeding the Media Foundation virtual camera through shared memory.
Added
- FFmpeg receive path (now the only one). The app decodes the RTSP stream in user space with FFmpeg (
RTCamNative/FfmpegRtspSource— d3d11va hardware decode when available, else software, with low-latency demux options and a resync-to-live latency cap) and streams NV12 frames to the Frame Server through a frame shared-memory channel (Shared/VCamFrameChannel.h, triple-buffered, seqlock, created by the Frame Server viaFrameChannelReaderand written by the app viaFrameChannelWriter). The Frame Server reads those frames inMediaStream::RequestSampleand shows the synthetic frame when the app producer's heartbeat goes stale. FFmpeg (LGPL, dynamic, decode-only) is provided by vcpkg manifest mode with vcpkg as a git submodule atexternal/vcpkg(version pinned via the baseline); its DLLs are app-locally deployed into the build output and bundled by the MSI — no manual setup for the end user. - The live preview is now FFmpeg-based too (
RTCamNative/FfmpegPreviewPlayer): the same decode core renders NV12→BGRA into the WinForms panel with a double-buffered GDI path. It inherits the latency cap, so a fast/misbehaving source no longer drifts the way the old Media Foundation preview did. - Live Frame-Server stats channel (cross-process shared memory,
Shared/VCamStats.h): RX/render/declined fps and copy cost, surfaced in the app's diagnostics bar while the virtual camera is running. The GPU-decode indicator comes from the app producer (VCam_IsFfmpegProducerHardware), shown asFFmpeg HW/FFmpeg SW. - Selectable RTSP transport, with a live view of the one actually in use. Settings → Network offers Auto (UDP, TCP fallback) / UDP only / TCP only. In Auto the decode loop drives the fallback itself — it opens with an explicit UDP transport first and, if an attempt connects but carries no frame within the socket timeout, flips to TCP on the next attempt — so the connection panel shows the real transport (
UDP/TCP) rather than just the request. Exposed to the UI viaVCam_GetActiveTransport(producer) andGetActiveTransport(preview). - FFmpeg fine-tuning in Settings (process-wide, applied on the next connection): hardware-decode on/off (force software decode when a d3d11va driver misbehaves), socket timeout, RTP reorder-buffer depth, and the resync-to-live latency-cap threshold. Persisted in
Settingsand pushed to the native engine throughVirtualCameraWrapper.ApplyEngineSettings. - Diagnostic frame-counter overlay (Settings, off by default): burns a per-frame counter into every delivered frame (real and synthetic) so the actual consumer-side frame rate is visible on the video itself.
- Settings dialog strings localized in all four supported languages (Italian, English, Spanish, German).
Removed
- The Media Foundation receive engine, entirely. The Frame Server no longer opens the RTSP source itself:
RtspSessionManagerandRtspReaderCallback(in-processIMFSourceReader+ DXVA GPU zero-copy) were removed, as was the Media Foundation preview player (VideoPlayer/VideoReaderCbk/CSourceOpenMonitor). The engine selector (Settings → "Motore di ricezione",Settings.VideoEngine,MF_VCAM_ENGINEattribute,VCamConfig.engine) is gone — there is a single FFmpeg receive path. The virtual camera itself stays Media Foundation; only the source of its pixels changed. As a consequence the camera is live only while the app is running (the decode happens in the app process); this was previously the FFmpeg-mode trade-off and is now the only behaviour.
Changed
deploy_vcam.ps1now copies the built DLL toC:\Projects\RTVirtualCamera(override with-DeployDir) before registering it, instead of registering directly from the repo build output underC:\Users\...— fixesE_ACCESSDENIEDonIMFVirtualCamera::Start(Frame Server runs as Local Service, which cannot access the user profile).VCamMediaSource::SetupCameraSettingsclamps an implausible RTSP-declared frame rate (>60fps) to 30fps, instead of trusting it forMediaStreampacing.MediaStream::RequestSampletracks how many deliveries re-serve the same frame as the previous one (declinedFrames, count only) instead of leavingrenderedFramesindistinguishable from genuinely new frames. (An attempt at actually declining these re-serves viaMF_E_SAMPLEALLOCATOR_EMPTYwas reverted — it destabilized the Frame Server's own retry timing on real hardware.)- Default RTSP transport is now UDP with automatic TCP fallback (previously hardcoded TCP); a small RTP reorder buffer keeps UDP usable without shredding the picture on minor packet reordering.
- Frame Server sample delivery reworked to an async two-queue design, decoupling the RTSP receive cadence from the consumer's
RequestSamplepolling. - Trace output is off by default in production. ETW (
WINTRACE) and the app file log (DebugLog) are gated behind runtime environment variables (RTVCAM_TRACEmachine-wide for the Frame Server,RTVCAM_LOGfor the app), read once and cached; when disabled they pay no formatting or file-I/O cost andWINTRACEskipsEventRegisterentirely. - MSI (
Setup) no longer builds in Debug configurations (Release only).