Files
ZHGD_Web/Assets/3rds/AVProVideo/Runtime/Scripts/Components/ResolveToRenderTexture.cs
2025-07-13 23:16:20 +08:00

131 lines
3.6 KiB
C#

using UnityEngine;
//-----------------------------------------------------------------------------
// Copyright 2019-2022 RenderHeads Ltd. All rights reserved.
//-----------------------------------------------------------------------------
namespace RenderHeads.Media.AVProVideo
{
/// Renders the video texture to a RenderTexture - either one provided by the user (external) or to an internal one.
/// The video frames can optionally be "resolved" to unpack packed alpha, display a single stereo eye, generate mip maps, and apply colorspace conversions
[AddComponentMenu("AVPro Video/Resolve To RenderTexture", 330)]
[HelpURL("https://www.renderheads.com/products/avpro-video/")]
public class ResolveToRenderTexture : MonoBehaviour
{
[SerializeField] MediaPlayer _mediaPlayer = null;
[SerializeField] VideoResolveOptions _options = VideoResolveOptions.Create();
[SerializeField] VideoRender.ResolveFlags _resolveFlags = (VideoRender.ResolveFlags.ColorspaceSRGB | VideoRender.ResolveFlags.Mipmaps | VideoRender.ResolveFlags.PackedAlpha | VideoRender.ResolveFlags.StereoLeft);
[SerializeField] RenderTexture _externalTexture = null;
private Material _materialResolve;
private bool _isMaterialSetup;
private bool _isMaterialDirty;
private RenderTexture _internalTexture;
private int _textureFrameCount = -1;
public MediaPlayer MediaPlayer
{
get { return _mediaPlayer; }
set { ChangeMediaPlayer(_mediaPlayer); }
}
public RenderTexture ExternalTexture
{
get
{
return _externalTexture;
}
set
{
_externalTexture = value;
}
}
public RenderTexture TargetTexture
{
get
{
if (_externalTexture == null) return _internalTexture;
return _externalTexture;
}
}
public void SetMaterialDirty()
{
_isMaterialDirty = true;
}
private void ChangeMediaPlayer(MediaPlayer mediaPlayer)
{
if (_mediaPlayer != mediaPlayer)
{
_mediaPlayer = mediaPlayer;
_textureFrameCount = -1;
_isMaterialSetup = false;
_isMaterialDirty = true;
Resolve();
}
}
void Start()
{
_materialResolve = VideoRender.CreateResolveMaterial();
VideoRender.SetupMaterialForMedia(_materialResolve, _mediaPlayer, -1);
}
void LateUpdate()
{
Debug.Assert(_mediaPlayer != null);
Resolve();
}
public void Resolve()
{
ITextureProducer textureProducer = _mediaPlayer.TextureProducer;
if (textureProducer != null && textureProducer.GetTexture())
{
if (!_isMaterialSetup)
{
VideoRender.SetupMaterialForMedia(_materialResolve, _mediaPlayer, -1);
_isMaterialSetup = true;
_isMaterialDirty = true;
}
if (_isMaterialDirty)
{
VideoRender.SetupResolveMaterial(_materialResolve, _options);
_isMaterialDirty = false;
}
int textureFrameCount = textureProducer.GetTextureFrameCount();
if (textureFrameCount != _textureFrameCount)
{
_internalTexture = VideoRender.ResolveVideoToRenderTexture(_materialResolve, _internalTexture, textureProducer, _resolveFlags);
_textureFrameCount = textureFrameCount;
if (_internalTexture && _externalTexture)
{
// NOTE: This blit can be removed once we can ResolveVideoToRenderTexture is made not to recreate textures
// NOTE: This blit probably doesn't do correct linear/srgb conversion if the colorspace settings differ, may have to use GL.sRGBWrite
Graphics.Blit(_internalTexture, _externalTexture);
}
}
}
}
void OnDisable()
{
if (_internalTexture)
{
RenderTexture.ReleaseTemporary(_internalTexture); _internalTexture = null;
}
}
void OnDestroy()
{
if (_materialResolve)
{
Destroy(_materialResolve); _materialResolve = null;
}
}
}
}