Files
video-orchestra/godot-project/scripts/VideoOrchestraManager.cs

186 lines
5.2 KiB
C#

using Godot;
using System;
using VideoOrchestra.Platform;
namespace VideoOrchestra
{
/// <summary>
/// Main VP9 multi-stream video decoder manager for Godot Engine
/// Handles simultaneous decoding of up to 3 VP9 video streams with alpha channels
/// Supports Windows (Media Foundation), Android (MediaCodec), iOS/macOS (VideoToolbox)
/// </summary>
public partial class VideoOrchestraManager : Node
{
private const int MAX_STREAMS = 3;
// Platform decoder interface
private IVP9PlatformDecoder _platformDecoder;
private VP9PlatformInfo _platformInfo;
private bool _initialized = false;
// Stream configuration
[Export] public int StreamWidth { get; set; } = 1920;
[Export] public int StreamHeight { get; set; } = 1080;
[Export] public bool UseHardwareDecoding { get; set; } = true;
[Export] public bool ShowPlatformInfo { get; set; } = true;
// Events
[Signal] public delegate void StreamDecodedEventHandler(int streamId);
[Signal] public delegate void DecoderErrorEventHandler(int streamId, string error);
[Signal] public delegate void DecoderInitializedEventHandler(string platformName, bool hardwareEnabled);
public override void _Ready()
{
InitializePlatformDecoder();
}
private void InitializePlatformDecoder()
{
try
{
// Get platform information
_platformInfo = VP9PlatformFactory.GetPlatformInfo();
if (ShowPlatformInfo)
{
GD.Print($"VP9 Platform Info: {_platformInfo}");
}
// Create platform-specific decoder
_platformDecoder = VP9PlatformFactory.CreateDecoder(UseHardwareDecoding);
if (_platformDecoder == null)
{
GD.PrintErr("Failed to create platform decoder");
return;
}
// Initialize the decoder
_initialized = _platformDecoder.Initialize(StreamWidth, StreamHeight, UseHardwareDecoding);
if (_initialized)
{
bool hardwareEnabled = UseHardwareDecoding && _platformDecoder.IsHardwareDecodingSupported;
GD.Print($"VP9 Orchestra initialized: {StreamWidth}x{StreamHeight} on {_platformDecoder.PlatformName}");
GD.Print($"Hardware acceleration: {(hardwareEnabled ? "Enabled" : "Disabled")}");
EmitSignal(SignalName.DecoderInitialized, _platformDecoder.PlatformName, hardwareEnabled);
}
else
{
GD.PrintErr($"Failed to initialize {_platformDecoder.PlatformName} VP9 decoder");
}
}
catch (PlatformNotSupportedException ex)
{
GD.PrintErr($"Platform not supported: {ex.Message}");
}
catch (Exception ex)
{
GD.PrintErr($"Error initializing VP9 decoder: {ex.Message}");
}
}
/// <summary>
/// Decode a VP9 frame for the specified stream
/// </summary>
/// <param name="frameData">VP9 encoded frame data</param>
/// <param name="streamId">Stream identifier (0-2)</param>
/// <returns>True if decoding succeeded</returns>
public bool DecodeFrame(byte[] frameData, int streamId)
{
if (!_initialized || streamId < 0 || streamId >= MAX_STREAMS || _platformDecoder == null)
{
return false;
}
try
{
bool success = _platformDecoder.DecodeFrame(frameData, streamId);
if (success)
{
EmitSignal(SignalName.StreamDecoded, streamId);
}
else
{
EmitSignal(SignalName.DecoderError, streamId, "Decode failed");
}
return success;
}
catch (VP9DecoderException vpEx)
{
GD.PrintErr($"VP9 decoder error: {vpEx.Message}");
EmitSignal(SignalName.DecoderError, streamId, vpEx.Message);
return false;
}
catch (Exception ex)
{
GD.PrintErr($"Error decoding frame for stream {streamId}: {ex.Message}");
EmitSignal(SignalName.DecoderError, streamId, ex.Message);
return false;
}
}
/// <summary>
/// Get the decoded texture for the specified stream
/// </summary>
/// <param name="streamId">Stream identifier (0-2)</param>
/// <returns>ImageTexture containing decoded frame, or null if not available</returns>
public ImageTexture GetStreamTexture(int streamId)
{
if (!_initialized || streamId < 0 || streamId >= MAX_STREAMS || _platformDecoder == null)
{
return null;
}
return _platformDecoder.GetDecodedTexture(streamId);
}
/// <summary>
/// Get platform-specific native texture ID for the specified stream
/// </summary>
/// <param name="streamId">Stream identifier (0-2)</param>
/// <returns>Native texture ID (OpenGL/DirectX/Metal), or 0 if not available</returns>
public uint GetNativeTextureId(int streamId)
{
if (!_initialized || streamId < 0 || streamId >= MAX_STREAMS || _platformDecoder == null)
{
return 0;
}
return _platformDecoder.GetNativeTextureId(streamId);
}
/// <summary>
/// Get current platform information
/// </summary>
/// <returns>VP9 platform capabilities information</returns>
public VP9PlatformInfo GetPlatformInfo()
{
return _platformInfo;
}
/// <summary>
/// Get current decoder status
/// </summary>
/// <returns>Current decoder status</returns>
public VP9DecoderStatus GetDecoderStatus()
{
return _platformDecoder?.GetStatus() ?? VP9DecoderStatus.Uninitialized;
}
public override void _ExitTree()
{
if (_platformDecoder != null)
{
_platformDecoder.Dispose();
_platformDecoder = null;
}
_initialized = false;
}
}
}