textureId. Hook Facebetter in the vendor’s custom preprocess callback, run ImageFrame::CreateWithI420 (or NV12) → ProcessImage, then write planes back.
Shares the same C++ API as Linux. Basics: Implement Beauty. Room join / publish belong in the vendor’s docs.
Shared contract
Shared: process I420 and write planes back
TRTC (Tencent)
Windows / desktop C++: custom preprocess uses Buffer, not Texture. Newer SDKs useenableLocalVideoCustomProcess + setLocalVideoCustomProcessCallback (older setLocalVideoProcessCallback is deprecated — check your version).
Use pixel format I420 and buffer type Buffer. In onProcessVideoFrame, process srcFrame and fill dstFrame.
Tencent docs: mobile can use Texture; PC supports Buffer only. Do not follow the Android
Texture_2D path on Windows.Agora
Hook:IRtcEngine::registerVideoFrameObserver (C++ Video SDK 4.x). Windows typically yields YUV420 / I420.
- Return
PROCESS_MODE_READ_WRITEfromgetVideoFrameProcessMode - In
onCaptureVideoFrame, runProcessI420InPlaceonyBuffer/uBuffer/vBuffer - Return
trueso the SDK keeps the frame
IRtcEngine, then engine.reset().
LiveKit
On desktop, the usual pattern is a custom video source: capture / process yourself, then push frames into LiveKit (C++ client or your bridge) — not the mobileVideoProcessor texture callback.
Recommended pipeline:
- Capture frames (camera / DXGI / etc.)
CreateWithI420/CreateWithRGBA→ProcessImage- Wrap the output as a LiveKit / WebRTC frame and push into
VideoSource/RTCVideoSource

