/*----------------------------------------------------------------
// 多 RawImage + 多 Decoder、同时只播一路时:共用一份 UI 材质,仅当前激活 Decoder 写贴图与参数。
//----------------------------------------------------------------*/
using UnityEngine;
///
/// 与多个 配合:全组共用一个 实例,
/// 任意时刻只有 指定的那一路会把它赋到自己的 RawImage 并更新 Y/U/V。
/// 要求:各解码器的 与控制器上配置的 Shared Alpha Type 一致(同一套 Shader)。
///
public class LeviathanVideoSharedMaterialController : MonoBehaviour
{
private static Shader FindShaderForAlphaType(LeviathanVideoDecoderBase.PlayAlphaType alphaType)
{
string name = alphaType switch
{
LeviathanVideoDecoderBase.PlayAlphaType.RightSide => "LeviathanVideo/YUV420P_Alpha_Right",
LeviathanVideoDecoderBase.PlayAlphaType.BottomSide => "LeviathanVideo/YUV420P_Alpha_Bottom",
LeviathanVideoDecoderBase.PlayAlphaType.ChromaKey => "LeviathanVideo/YUV420P_ChromaKey",
_ => "LeviathanVideo/YUV420P",
};
return Shader.Find(name);
}
[SerializeField]
[Tooltip("共用材质使用的 Alpha/Shader 类型,须与各 Decoder 的 Alpha Type 一致")]
private LeviathanVideoDecoderBase.PlayAlphaType _sharedAlphaType = LeviathanVideoDecoderBase.PlayAlphaType.ChromaKey;
[SerializeField]
[Tooltip("可选:用工程里的材质做模板 Instantiate;为空则按 Shared Alpha Type 从 Shader 创建")]
private Material _materialTemplate;
private Material _sharedMaterial;
private LeviathanVideoDecoder _activeDecoder;
/// 当前独占共用材质的解码器;无则为 null。
public LeviathanVideoDecoder ActiveDecoder => _activeDecoder;
/// 共用材质实例(只读,勿在外部 Dispose)。
public Material SharedMaterial
{
get
{
EnsureSharedMaterial();
return _sharedMaterial;
}
}
private void EnsureSharedMaterial()
{
if (_sharedMaterial != null)
return;
if (_materialTemplate != null)
{
_sharedMaterial = new Material(_materialTemplate);
return;
}
var sh = FindShaderForAlphaType(_sharedAlphaType);
if (sh == null)
{
LeviathanLogConfig.LogError(nameof(LeviathanVideoSharedMaterialController),
$"无法创建共用材质:Shader 未找到(AlphaType={_sharedAlphaType})");
return;
}
_sharedMaterial = new Material(sh);
}
///
/// 将共用材质交给指定解码器;可选停止上一路。
///
/// 若为 null,则仅解绑当前路并清空激活项
/// 为 true 时对上一路调用
public void ActivateDecoder(LeviathanVideoDecoder decoder, bool stopPreviousDecoder = true)
{
EnsureSharedMaterial();
if (_sharedMaterial == null)
return;
if (_activeDecoder == decoder)
{
if (decoder != null)
decoder.RefreshSharedMaterialDisplay();
return;
}
if (_activeDecoder != null)
{
if (stopPreviousDecoder)
_activeDecoder.Stop();
_activeDecoder.UnbindSharedMaterialController();
_activeDecoder = null;
}
if (decoder == null)
return;
if (decoder.AlphaType != _sharedAlphaType)
{
LeviathanLogConfig.LogError(nameof(LeviathanVideoSharedMaterialController),
$"ActivateDecoder: 解码器 AlphaType={decoder.AlphaType} 与控制器 {_sharedAlphaType} 不一致,拒绝绑定。请统一 Inspector 中的 Alpha Type。");
return;
}
_activeDecoder = decoder;
_activeDecoder.BindToSharedMaterialController(this, _sharedMaterial);
_activeDecoder.RefreshSharedMaterialDisplay();
}
/// 解绑当前解码器并停止播放(共用材质仍保留在控制器上)。
public void DeactivateCurrent(bool stopDecoder = true)
{
if (_activeDecoder == null)
return;
if (stopDecoder)
_activeDecoder.Stop();
_activeDecoder.UnbindSharedMaterialController();
_activeDecoder = null;
}
private void OnDestroy()
{
if (_activeDecoder != null)
{
_activeDecoder.UnbindSharedMaterialController();
_activeDecoder = null;
}
if (_sharedMaterial != null)
{
Destroy(_sharedMaterial);
_sharedMaterial = null;
}
}
///
/// 解码器销毁或主动 时调用,清除激活引用。
///
public void NotifyDecoderReleased(LeviathanVideoDecoder decoder)
{
if (_activeDecoder == decoder)
_activeDecoder = null;
}
}