/*---------------------------------------------------------------- // 多 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; } }