Shared contract
On Apple platforms, TRTC custom preprocess commonly uses OpenGL textures; Agora / LiveKit more often deliver
CVPixelBuffer. Both work — do not mix both modes on one engine instance.
Shared: process texture
Shared: process CVPixelBuffer (NV12 sketch)
Agora / LiveKit callbacks often use NV12. Take plane pointers and strides from theCVPixelBuffer; how you write back into the vendor frame varies by SDK version.
externalContext = NO. Credentials: Subscription, Auth & License.
TRTC (Tencent)
Hook:setLocalVideoProcessDelegete:pixelFormat:bufferType: (official spelling Delegete). Use TRTCVideoPixelFormat_Texture_2D and TRTCVideoBufferType_Texture.
Implement TRTCVideoFrameDelegate: create the engine in onGLContextCreated; set dstFrame.textureId in onProcessVideoFrame:dstFrame:; nil the engine in onGLContextDestory.
FacebetterPlugin.processTexture).
Agora
Hook:AgoraRtcEngineKit.setVideoFrameDelegate: (Video SDK 4.x). On iOS, captured frames are usually CVPixelBuffer (textureBuf / format 12), not an Android-style GL_TEXTURE_2D id.
You need to:
- Return ReadWrite from
getVideoFrameProcessMode - Take the
CVPixelBufferinonCapture:sourceType:(or olderonCaptureVideoFrame) - Feed it via
createWithNV12:/createWithBGRA:, then write the result back intoAgoraOutputVideoFrame
setVideoFrameDelegate:nil and nil beautyEngine before tearing down the engine.
LiveKit
Hook: implement SwiftVideoProcessor, transform in process(frame:), return the new frame (or nil to drop). Pass processor: when creating the camera track, or set track.processor later.
BackgroundBlurVideoProcessor. Custom capturers can run Facebetter before frames enter the encoder.

