Encoder Architecture
The LCK SDK uses a platform-abstracted encoder interface with hardware-accelerated implementations.
┌─────────────────────────────────────────┐
│ ILCKEncoder │
│ (Abstract Interface) │
└────────────────┬────────────────────────┘
│
┌────────────┴────────────┐
│ │
┌───▼───────────────┐ ┌────▼──────────────┐
│ FLCKWindowsEncoder│ │ FLCKAndroidEncoder│
│ (MediaFoundation) │ │ (MediaCodec) │
└───────────────────┘ └───────────────────┘
ILCKEncoder Interface
class ILCKEncoder : public FRunnable
{
public:
virtual bool Open() = 0;
virtual bool IsEncoding() const = 0;
virtual void EncodeTexture(FTextureRHIRef& Texture, float TimeSeconds) = 0;
virtual void EncodeAudio(TArrayView<float> PCMData) = 0;
virtual void Save(TFunction<void(float)> ProgressCallback) = 0;
virtual float GetAudioTime() const = 0;
};
ILCKEncoder extends FRunnable — encoding runs on a dedicated background thread.
Texture encoding uses FTextureRHIRef for direct GPU access, not UTextureRenderTarget2D.
ILCKEncoderFactory
Factory interface for creating platform-specific encoders.
class ILCKEncoderFactory : public IModularFeature
{
public:
static FName GetModularFeatureName() { return TEXT("LCKEncoderFactory"); }
virtual FString GetEncoderName() const = 0;
virtual TSharedPtr<ILCKEncoder> CreateEncoder(
int32 Width, int32 Height, int32 VideoBitrate,
int32 Framerate, int32 Samplerate, int32 AudioBitrate) = 0;
};
Encoder Selection
Encoders register via Unreal’s modular feature system and are discovered at runtime:
// Find available encoder factory
auto& ModularFeatures = IModularFeatures::Get();
if (ModularFeatures.IsModularFeatureAvailable(ILCKEncoderFactory::GetModularFeatureName()))
{
ILCKEncoderFactory* Factory = &ModularFeatures.GetModularFeature<ILCKEncoderFactory>(
ILCKEncoderFactory::GetModularFeatureName()
);
// Create encoder with recording parameters
TSharedPtr<ILCKEncoder> Encoder = Factory->CreateEncoder(
1920, 1080, 8000000, 30, 48000, 256000
);
}
FLCKWindowsEncoder
Uses Windows Media Foundation for hardware-accelerated H.264 encoding.Features:
- Hardware acceleration via GPU
- H.264 Baseline to High profile
- AAC-LC audio encoding
- Direct GPU texture access
Requirements:
- Windows 10 or later
- DirectX 11 compatible GPU
- Media Foundation runtime
// Windows encoder automatically selected on Windows platform
// No additional configuration needed
Supported GPUs:
- NVIDIA GeForce GTX 600+
- AMD Radeon HD 7000+
- Intel HD Graphics 4000+
FLCKAndroidEncoder
Uses Android MediaCodec for hardware-accelerated encoding.Features:
- Hardware acceleration via SoC
- H.264 encoding
- AAC audio encoding
- Vulkan texture interop
Requirements:
- Android 8.0+ (API 26+)
- Vulkan support recommended
- Hardware codec support
// Android encoder automatically selected on Android platform
// Ensure Vulkan is enabled for best performance
Tested Devices:
- Meta Quest 2, Quest 3, Quest Pro
- Samsung Galaxy S10+
- Pixel 4+
Encoding Pipeline
Frame Capture
Scene capture component renders to render target texture
Texture Transfer
GPU texture data transferred to encoder (zero-copy when possible)
Video Encoding
Hardware encoder compresses frame to H.264
Audio Mixing
FLCKAudioMix combines audio sources
Audio Encoding
PCM audio encoded to AAC
Muxing
Video and audio streams combined into MP4 container
Frame Timing
// Encoder expects consistent frame timing
// Match capture rate to recording framerate
CaptureComponent->bCaptureEveryFrame = false;
// The subsystem handles frame timing internally
// based on configured framerate
Memory Usage
| Resolution | Approx. Memory |
|---|
| 720p | ~50 MB |
| 1080p | ~100 MB |
| 1440p | ~150 MB |
| 2160p | ~250 MB |
High resolutions increase memory pressure significantly. Monitor memory usage on mobile VR devices.
Thread Safety
EncodeTexture() must be called from game thread
EncodeAudio() is safe from any thread
- Internal encoding runs on dedicated worker threads
Error Handling
// Check encoder state before operations
if (!Encoder->IsEncoding())
{
if (!Encoder->Open())
{
UE_LOG(LogLCKEncoding, Error, TEXT("Failed to open encoder"));
// Handle initialization failure
}
}
// Monitor for encoding errors via logs
// LogLCKEncoding category reports encoder issues
| Property | Value |
|---|
| Container | MP4 (fragmented) |
| Video Codec | H.264 / AVC |
| Video Profile | Main (default) |
| Audio Codec | AAC-LC |
| Audio Channels | Stereo (2) |
Output files are saved to the platform’s standard video/gallery location on Android, or to the project’s Saved folder on desktop.