> ## Documentation Index
> Fetch the complete documentation index at: https://docs.liv.tv/llms.txt
> Use this file to discover all available pages before exploring further.

# Encoding

> How the LIV Camera Kit (LCK) SDK handles video encoding in Unreal Engine, including the encoder interface, Windows Media Foundation and Android MediaCodec implementations, and performance tuning.

## Encoder Architecture

The LCK SDK uses a platform-abstracted encoder interface with hardware-accelerated implementations.

```
┌─────────────────────────────────────────┐
│           ILCKEncoder                   │
│      (Abstract Interface)               │
└────────────────┬────────────────────────┘
                 │
    ┌────────────┴────────────┐
    │                         │
┌───▼───────────────┐   ┌────▼──────────────┐
│ FLCKWindowsEncoder│   │ FLCKAndroidEncoder│
│ (MediaFoundation) │   │  (MediaCodec)     │
└───────────────────┘   └───────────────────┘
```

## ILCKEncoder Interface

```cpp theme={null}
class ILCKEncoder : public TSharedFromThis<ILCKEncoder, ESPMode::ThreadSafe>, public FRunnable
{
public:
    virtual bool Open() noexcept = 0;
    virtual bool IsEncoding() const noexcept = 0;
    virtual void EncodeTexture(FTextureRHIRef& Texture, float TimeSeconds) = 0;
    virtual void EncodeAudio(TArrayView<float> PCMData) = 0;
    virtual void Save(TFunction<void(float)> OnProgress) = 0;
    [[nodiscard]] virtual float GetAudioTime() const noexcept = 0;
};
```

<Note>
  `ILCKEncoder` extends both `TSharedFromThis<ILCKEncoder, ESPMode::ThreadSafe>` and `FRunnable` — encoding runs on a dedicated background thread.
  Texture encoding uses `FTextureRHIRef` for direct GPU access, not `UTextureRenderTarget2D`.
</Note>

## ILCKEncoderFactory

Factory interface for creating platform-specific encoders.

```cpp theme={null}
class ILCKEncoderFactory : public IModularFeature,
                           public TSharedFromThis<ILCKEncoderFactory, ESPMode::ThreadSafe>
{
public:
    static FName GetModularFeatureName() noexcept;

    [[nodiscard]] virtual const FString& GetEncoderName() const noexcept = 0;
    [[nodiscard]] virtual TSharedPtr<ILCKEncoder, ESPMode::ThreadSafe> CreateEncoder(
        uint32 Width, uint32 Height, uint32 VideoBitrate,
        uint32 Framerate, uint32 Samplerate, uint32 AudioBitrate) const noexcept = 0;
};
```

### Encoder Selection

Encoders register via Unreal's modular feature system and are discovered at runtime:

```cpp theme={null}
// 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, ESPMode::ThreadSafe> Encoder = Factory->CreateEncoder(
        1920, 1080, 12000000, 60, 48000, 256000
    );
}
```

***

## Platform Implementations

<Tabs>
  <Tab title="Windows">
    ### 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

    ```cpp theme={null}
    // 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+
  </Tab>

  <Tab title="Android">
    ### FLCKAndroidEncoder

    Uses Android MediaCodec for hardware-accelerated encoding.

    **Features:**

    * Hardware acceleration via SoC
    * H.264 encoding
    * AAC audio encoding
    * Vulkan texture interop

    **Requirements:**

    * Android 10+ (API 29+)
    * Vulkan **required** (OpenGL ES not supported)
    * Hardware codec support

    ```cpp theme={null}
    // Android encoder automatically selected on Android platform
    // Vulkan must be enabled — OpenGL ES is not supported
    ```

    **Tested Devices:**

    * Meta Quest 2, Quest 3, Quest Pro
    * Samsung Galaxy S10+
    * Pixel 4+
  </Tab>
</Tabs>

***

## Encoding Pipeline

<Steps>
  <Step title="Frame Capture">
    Scene capture component renders to render target texture
  </Step>

  <Step title="Texture Transfer">
    GPU texture data transferred to encoder (zero-copy when possible)
  </Step>

  <Step title="Video Encoding">
    Hardware encoder compresses frame to H.264
  </Step>

  <Step title="Audio Mixing">
    FLCKAudioMix combines audio sources
  </Step>

  <Step title="Audio Encoding">
    PCM audio encoded to AAC
  </Step>

  <Step title="Muxing">
    Video and audio streams combined into MP4 container
  </Step>
</Steps>

***

## Performance Considerations

### Frame Timing

```cpp theme={null}
// 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       |

<Warning>
  High resolutions increase memory pressure significantly. Monitor memory usage on mobile VR devices.
</Warning>

### Thread Safety

* `EncodeTexture()` must be called from game thread
* `EncodeAudio()` is safe from any thread
* Internal encoding runs on dedicated worker threads

***

## Error Handling

```cpp theme={null}
// 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
```

***

## Output Format

| Property       | Value            |
| -------------- | ---------------- |
| Container      | MP4 (fragmented) |
| Video Codec    | H.264 / AVC      |
| Video Profile  | High             |
| Audio Codec    | AAC-LC           |
| Audio Channels | Stereo (2)       |

<Tip>
  Output files are saved to the platform's standard video/gallery location on Android, or to the project's Saved folder on desktop.
</Tip>
