Skip to main content

What Problem Does This Solve?

ILCKEncoder abstracts platform-specific video encoding so you don’t have to:
  • Windows uses Media Foundation
  • Android uses NDK MediaCodec
  • Quest uses Vulkan texture interop
The interface lets LCK support multiple platforms with a single API. Most developers never interact with this directly—ULCKService handles it all.

When to Use This

Read this if:
  • Building a custom encoder (very advanced)
  • Debugging encoding issues
  • Understanding LCK’s internal architecture
  • Extending LCK to new platforms
Skip this if: You’re just using LCK for recording. Use ULCKService instead.

Interface Definition


Encoder Factory

Encoders are discovered and created via Unreal’s modular features system:

Finding an Encoder at Runtime


Platform Implementations

Windows: FLCKWindowsEncoder

Technologies:
  • IMFSinkWriter — MP4 muxing
  • IMFTransform — H.264 video encoding
  • IMFMediaType — AAC audio encoding
  • Direct3D 11 texture interop
Key features:
  • Hardware-accelerated encoding via GPU
  • Triple-buffered texture pool (avoids GPU stalls)
  • Async encoding thread
  • Supports DX11 render targets
Error handling example:
Triple-buffered texture pool:

Android: FLCKAndroidEncoder

Technologies:
  • AMediaCodec — H.264/AAC hardware encoding
  • AMediaMuxer — MP4 container
  • Vulkan/EGL texture interop
  • Android Hardware Buffer
Key features:
  • Hardware-accelerated encoding on Quest
  • Vulkan texture export via EGL
  • Low-latency pipeline
  • Direct write to device storage
Vulkan interop flow:
Why Vulkan interop is critical:
  • Quest uses Vulkan for rendering
  • CPU readback would be too slow (kills performance)
  • EGL interop lets encoder access GPU memory directly
  • This is why LCKVulkan module must load at EarliestPossible phase

Data Flow


Audio Encoding

Audio flows from audio sources → mixer → encoder:

Thread Safety

Encoding runs on a dedicated background thread:
Why threading matters:
  • Encoding is CPU-intensive
  • Running on game thread would cause stuttering
  • Background thread keeps game smooth
  • Queue-based design prevents race conditions

Creating a Custom Encoder

This is advanced usage. Most developers should use the built-in platform encoders. Only create a custom encoder if:
  • You need a different codec (HEVC, VP9)
  • You need a different container (WebM, AVI)
  • You’re porting LCK to a new platform

Step 1: Implement ILCKEncoder


Step 2: Create Factory


Step 3: Register via Modular Features


Debugging Encoder Issues

Enable Verbose Logging

What you’ll see:

Common Encoder Errors

Windows:
Fix: H.264 codec not installed (rare on Windows 10/11)
Android:
Fix: Unsupported resolution or bitrate for device
Vulkan interop:
Fix: Ensure LCKVulkan module loads at EarliestPossible phase

Key Takeaways

Platform abstraction — One interface, multiple implementations
Modular features — Runtime encoder discovery and creation
Triple buffering — Prevents GPU stalls on texture readback
Background thread — Encoding doesn’t block game thread
Most devs don’t need this — Use ULCKService for recording