| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706 | // UnityEngine.UI was moved to a package in 2019.2.0// Unfortunately no way to test for this across all Unity versions yet// You can set up the asmdef to reference the new package, but the package doesn't// existing in Unity 2017 etc, and it throws an error due to missing reference#define AVPRO_PACKAGE_UNITYUI#if (UNITY_2019_2_OR_NEWER && AVPRO_PACKAGE_UNITYUI) || (!UNITY_2019_2_OR_NEWER)#if UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX || UNITY_IOS || UNITY_TVOS	#define UNITY_PLATFORM_SUPPORTS_YPCBCR#endif#if UNITY_EDITOR || UNITY_STANDALONE_OSX || UNITY_STANDALONE_WIN || UNITY_IOS || UNITY_TVOS || UNITY_ANDROID || (UNITY_WEBGL && UNITY_2017_2_OR_NEWER)	#define UNITY_PLATFORM_SUPPORTS_LINEAR#endif#if (!UNITY_STANDALONE_WIN && !UNITY_EDITOR_WIN) && (UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX || UNITY_IOS || UNITY_TVOS || UNITY_ANDROID)	#define UNITY_PLATFORM_SUPPORTS_VIDEOTRANSFORM#endif#if (UNITY_EDITOR_WIN || (!UNITY_EDITOR && UNITY_STANDALONE_WIN))	#define UNITY_PLATFORM_SUPPORTS_VIDEOASPECTRATIO#endifusing System.Collections.Generic;using UnityEngine;using UnityEngine.UI;using UnityEngine.Serialization;//-----------------------------------------------------------------------------// Copyright 2015-2021 RenderHeads Ltd.  All rights reserved.//-----------------------------------------------------------------------------namespace RenderHeads.Media.AVProVideo{	/// <summary>	/// Displays the video from MediaPlayer component using uGUI	/// </summary>	[HelpURL("http://renderheads.com/products/avpro-video/")]	[AddComponentMenu("AVPro Video/Display uGUI", 200)]	//[ExecuteInEditMode]	public class DisplayUGUI : MaskableGraphic	{		[SerializeField] MediaPlayer _mediaPlayer;		public MediaPlayer Player		{			get { return _mediaPlayer; }			set { ChangeMediaPlayer(value); }		}		[Tooltip("Default texture to display when the video texture is preparing")]		[SerializeField] Texture _defaultTexture;		public Texture DefaultTexture		{			get { return _defaultTexture; }			set { if (_defaultTexture != value) { _defaultTexture = value; } }		}		[FormerlySerializedAs("m_UVRect")]		[SerializeField] Rect _uvRect = new Rect(0f, 0f, 1f, 1f);		public Rect UVRect		{			get { return _uvRect; }			set { _uvRect = value; }		}		[SerializeField] bool _setNativeSize = false;		public bool ApplyNativeSize		{			get { return _setNativeSize; }			set { _setNativeSize = value; }		}		[SerializeField] ScaleMode _scaleMode = ScaleMode.ScaleToFit;		public ScaleMode ScaleMode		{			get { return _scaleMode; }			set { _scaleMode = value; }		}		[SerializeField] bool _noDefaultDisplay = true;		public bool NoDefaultDisplay		{			get { return _noDefaultDisplay; }			set { _noDefaultDisplay = value; }		}		[SerializeField] bool _displayInEditor = true;		public bool DisplayInEditor		{			get { return _displayInEditor; }			set { _displayInEditor = value; }		}		private int _lastWidth;		private int _lastHeight;		private Orientation _lastOrientation;		private bool _flipY;		private Texture _lastTexture;		private static Shader _shaderStereoPacking;		private static Shader _shaderAlphaPacking;		private static Shader _shaderAndroidOES;		private static Shader _shaderAndroidOESAlphaPacking;		private bool _isUserMaterial = true;		private Material _material;		private List<UIVertex> _vertices = new List<UIVertex>(4);		private static List<int> QuadIndices = new List<int>(new int[] { 0, 1, 2, 2, 3, 0 });		protected override void Awake()		{			if (_mediaPlayer != null)			{				_mediaPlayer.Events.AddListener(OnMediaPlayerEvent);			}			base.Awake();		}		// Callback function to handle events		private void OnMediaPlayerEvent(MediaPlayer mp, MediaPlayerEvent.EventType et, ErrorCode errorCode)		{			switch (et)			{				case MediaPlayerEvent.EventType.FirstFrameReady:					if (_isUserMaterial && null != GetRequiredShader())					{						Debug.LogWarning("[AVProVideo] Custom material is being used but the video requires our internal shader for correct rendering.  Consider removing custom shader or modifying it for AVPro Video support.", this);					}					LateUpdate();					break;				case MediaPlayerEvent.EventType.PropertiesChanged:				case MediaPlayerEvent.EventType.ResolutionChanged:				case MediaPlayerEvent.EventType.Closing:					LateUpdate();					break;			}			// TODO: remove this, we're just doing this so we can make sure texture is correct when running in EDIT mode			LateUpdate();		}		private void ChangeMediaPlayer(MediaPlayer player)		{			if (_mediaPlayer != player)			{				if (_mediaPlayer != null)				{					_mediaPlayer.Events.RemoveListener(OnMediaPlayerEvent);				}				_mediaPlayer = player;				if (_mediaPlayer != null)				{					_mediaPlayer.Events.AddListener(OnMediaPlayerEvent);				}				LateUpdate();			}		}		private static Shader EnsureShader(Shader shader, string name)		{			if (shader == null)			{				shader = Shader.Find(name);				if (shader == null)				{					Debug.LogWarning("[AVProVideo] Missing shader " + name);				}			}			return shader;		}		private static Shader EnsureAlphaPackingShader()		{			_shaderAlphaPacking = EnsureShader(_shaderAlphaPacking, "AVProVideo/Internal/UI/Transparent Packed (stereo)");			return _shaderAlphaPacking;		}		private static Shader EnsureStereoPackingShader()		{			_shaderStereoPacking = EnsureShader(_shaderStereoPacking, "AVProVideo/Internal/UI/Stereo");			return _shaderStereoPacking;		}		private Shader EnsureAndroidOESShader()		{			_shaderAndroidOES = EnsureShader(_shaderAndroidOES, "AVProVideo/Internal/UI/Stereo - AndroidOES");			return _shaderAndroidOES;		}		private static Shader EnsureAndroidOESAlphaPackingShader()		{			_shaderAndroidOESAlphaPacking = EnsureShader(_shaderAndroidOESAlphaPacking, "AVProVideo/Internal/UI/Transparent Packed (stereo) - AndroidOES");			return _shaderAndroidOESAlphaPacking;		}				protected override void Start()		{			_isUserMaterial = (this.m_Material != null);			if (_isUserMaterial)			{				_material = new Material(this.material);				this.material = _material;			}			base.Start();		}		protected override void OnDestroy()		{			// Destroy existing material			if (_material != null)			{				this.material = null;#if UNITY_EDITOR				Material.DestroyImmediate(_material);#else				Material.Destroy(_material);#endif				_material = null;			}			ChangeMediaPlayer(null);			base.OnDestroy();		}		private Shader GetRequiredShader()		{			Shader result = null;			if (result == null && _mediaPlayer.TextureProducer != null)			{				switch (_mediaPlayer.TextureProducer.GetTextureStereoPacking())				{					case StereoPacking.None:						break;					case StereoPacking.LeftRight:					case StereoPacking.TopBottom:					case StereoPacking.TwoTextures:						result = EnsureStereoPackingShader();						break;				}				if (_mediaPlayer.TextureProducer.GetTextureTransparency() == TransparencyMode.Transparent)				{					result = EnsureAlphaPackingShader();				}				switch (_mediaPlayer.TextureProducer.GetTextureAlphaPacking())				{					case AlphaPacking.None:						break;					case AlphaPacking.LeftRight:					case AlphaPacking.TopBottom:						result = EnsureAlphaPackingShader();						break;				}			}#if UNITY_PLATFORM_SUPPORTS_LINEAR			if (result == null && _mediaPlayer.Info != null)			{				if (QualitySettings.activeColorSpace == ColorSpace.Linear && !_mediaPlayer.Info.PlayerSupportsLinearColorSpace())				{					result = EnsureAlphaPackingShader();				}			}#endif			if (result == null && _mediaPlayer.TextureProducer != null && _mediaPlayer.TextureProducer.GetTextureCount() == 2)			{				result = EnsureAlphaPackingShader();			}//			if (_mediaPlayer.TextureProducer != null && _mediaPlayer.IsUsingAndroidOESPath() && (_defaultTexture == null || _lastTexture != _defaultTexture ))			if (_mediaPlayer.TextureProducer != null && _mediaPlayer.IsUsingAndroidOESPath())			{				// This shader handles stereo too				result = EnsureAndroidOESShader();				if (_mediaPlayer.TextureProducer.GetTextureTransparency() == TransparencyMode.Transparent)				{					result = EnsureAndroidOESAlphaPackingShader();				}				switch (_mediaPlayer.TextureProducer.GetTextureAlphaPacking())				{					case AlphaPacking.None:						break;					case AlphaPacking.LeftRight:					case AlphaPacking.TopBottom:						result = EnsureAndroidOESAlphaPackingShader();						break;				}			}			return result;		}		/// <summary>		/// Returns the texture used to draw this Graphic.		/// </summary>		public override Texture mainTexture		{			get			{				Texture result = Texture2D.whiteTexture;				if (HasValidTexture())				{					Texture resamplerTex = _mediaPlayer.FrameResampler == null || _mediaPlayer.FrameResampler.OutputTexture == null ? null : _mediaPlayer.FrameResampler.OutputTexture[0];					result = _mediaPlayer.UseResampler ? resamplerTex : _mediaPlayer.TextureProducer.GetTexture();				}				else				{					if (_noDefaultDisplay)					{						result = null;					}					else if (_defaultTexture != null)					{						result = _defaultTexture;					}#if UNITY_EDITOR					if (result == null && _displayInEditor)					{						result = Resources.Load<Texture2D>("AVProVideoIcon");					}#endif				}				return result;			}		}		public bool HasValidTexture()		{			return (Application.isPlaying && _mediaPlayer != null && _mediaPlayer.TextureProducer != null && _mediaPlayer.TextureProducer.GetTexture() != null);		}		private void UpdateInternalMaterial()		{			if (_mediaPlayer != null)			{				// Get required shader				Shader currentShader = null;				if (_material != null)				{					currentShader = _material.shader;				}				Shader nextShader = GetRequiredShader();				// If the shader requirement has changed				if (currentShader != nextShader)				{					// Destroy existing material					if (_material != null)					{						this.material = null;#if UNITY_EDITOR						Material.DestroyImmediate(_material);#else						Material.Destroy(_material);#endif						_material = null;					}					// Create new material					if (nextShader != null)					{						_material = new Material(nextShader);					}				}				this.material = _material;			}		}		// We do a LateUpdate() to allow for any changes in the texture that may have happened in Update()		void LateUpdate()		{			if (_setNativeSize)			{				SetNativeSize();			}			if (_lastTexture != mainTexture)			{				_lastTexture = mainTexture;				SetVerticesDirty();				SetMaterialDirty();			}			if (HasValidTexture())			{				if (mainTexture != null)				{					Orientation orientation = Helper.GetOrientation(_mediaPlayer.Info.GetTextureTransform());					if (mainTexture.width != _lastWidth || mainTexture.height != _lastHeight || orientation != _lastOrientation)					{						_lastWidth = mainTexture.width;						_lastHeight = mainTexture.height;						_lastOrientation = orientation;						SetVerticesDirty();						SetMaterialDirty();					}				}			}			if (Application.isPlaying)			{				if (!_isUserMaterial)				{					UpdateInternalMaterial();				}			}			if (material != null && _mediaPlayer != null)			{				// TODO: only run when dirty				VideoRender.SetupMaterialForMedia(materialForRendering, _mediaPlayer);			}		}		/// <summary>		/// Texture to be used.		/// </summary>		public MediaPlayer CurrentMediaPlayer		{			get			{				return _mediaPlayer;			}			set			{				if (_mediaPlayer != value)				{					_mediaPlayer = value;					//SetVerticesDirty();					SetMaterialDirty();				}			}		}		/// <summary>		/// UV rectangle used by the texture.		/// </summary>		public Rect uvRect		{			get			{				return _uvRect;			}			set			{				if (_uvRect == value)				{					return;				}				_uvRect = value;				SetVerticesDirty();			}		}		/// <summary>		/// Adjust the scale of the Graphic to make it pixel-perfect.		/// </summary>		[ContextMenu("Set Native Size")]		public override void SetNativeSize()		{			Texture tex = mainTexture;			if (tex != null)			{				int w = Mathf.RoundToInt(tex.width * uvRect.width);				int h = Mathf.RoundToInt(tex.height * uvRect.height);				if (_mediaPlayer != null)				{#if UNITY_PLATFORM_SUPPORTS_VIDEOTRANSFORM && !(!UNITY_EDITOR && UNITY_ANDROID)					if (_mediaPlayer.Info != null)					{						Orientation ori = Helper.GetOrientation(_mediaPlayer.Info.GetTextureTransform());						if (ori == Orientation.Portrait || ori == Orientation.PortraitFlipped)						{							w = Mathf.RoundToInt(tex.height * uvRect.width);							h = Mathf.RoundToInt(tex.width * uvRect.height);						}					}#endif					if (_mediaPlayer.TextureProducer != null)					{						if (_mediaPlayer.TextureProducer.GetTextureAlphaPacking() == AlphaPacking.LeftRight ||							_mediaPlayer.TextureProducer.GetTextureStereoPacking() == StereoPacking.LeftRight)						{							w /= 2;						}						else if (_mediaPlayer.TextureProducer.GetTextureAlphaPacking() == AlphaPacking.TopBottom ||								 _mediaPlayer.TextureProducer.GetTextureStereoPacking() == StereoPacking.TopBottom)						{							h /= 2;						}					}				}				rectTransform.anchorMax = rectTransform.anchorMin;				rectTransform.sizeDelta = new Vector2(w, h);			}		}		protected override void OnPopulateMesh(VertexHelper vh)		{			vh.Clear();			_OnFillVBO(_vertices);			vh.AddUIVertexStream(_vertices, QuadIndices );		}		private void _OnFillVBO(List<UIVertex> vbo)		{			_flipY = false;			if (HasValidTexture())			{				_flipY = _mediaPlayer.TextureProducer.RequiresVerticalFlip();			}			Rect uvRect = _uvRect;			Vector4 v = GetDrawingDimensions(_scaleMode, ref uvRect);#if UNITY_PLATFORM_SUPPORTS_VIDEOTRANSFORM			Matrix4x4 m = Matrix4x4.identity;			if (HasValidTexture())			{				m = Helper.GetMatrixForOrientation(Helper.GetOrientation(_mediaPlayer.Info.GetTextureTransform()));			}#endif			vbo.Clear();			var vert = UIVertex.simpleVert;			vert.color = color;			vert.position = new Vector2(v.x, v.y);			vert.uv0 = new Vector2(uvRect.xMin, uvRect.yMin);			if (_flipY)			{				vert.uv0 = new Vector2(uvRect.xMin, 1.0f - uvRect.yMin);			}#if UNITY_PLATFORM_SUPPORTS_VIDEOTRANSFORM			vert.uv0 = m.MultiplyPoint3x4(vert.uv0);#endif			vbo.Add(vert);			vert.position = new Vector2(v.x, v.w);			vert.uv0 = new Vector2(uvRect.xMin, uvRect.yMax);			if (_flipY)			{				vert.uv0 = new Vector2(uvRect.xMin, 1.0f - uvRect.yMax);			}#if UNITY_PLATFORM_SUPPORTS_VIDEOTRANSFORM			vert.uv0 = m.MultiplyPoint3x4(vert.uv0);#endif			vbo.Add(vert);			vert.position = new Vector2(v.z, v.w);			vert.uv0 = new Vector2(uvRect.xMax, uvRect.yMax);			if (_flipY)			{				vert.uv0 = new Vector2(uvRect.xMax, 1.0f - uvRect.yMax);			}#if UNITY_PLATFORM_SUPPORTS_VIDEOTRANSFORM			vert.uv0 = m.MultiplyPoint3x4(vert.uv0);#endif			vbo.Add(vert);			vert.position = new Vector2(v.z, v.y);			vert.uv0 = new Vector2(uvRect.xMax, uvRect.yMin);			if (_flipY)			{				vert.uv0 = new Vector2(uvRect.xMax, 1.0f - uvRect.yMin);			}#if UNITY_PLATFORM_SUPPORTS_VIDEOTRANSFORM			vert.uv0 = m.MultiplyPoint3x4(vert.uv0);#endif			vbo.Add(vert);		}		private Vector4 GetDrawingDimensions(ScaleMode scaleMode, ref Rect uvRect)		{			Vector4 returnSize = Vector4.zero;			if (mainTexture != null)			{				var padding = Vector4.zero;				var textureSize = new Vector2(mainTexture.width, mainTexture.height);				{					// Adjust textureSize based on orientation#if UNITY_PLATFORM_SUPPORTS_VIDEOTRANSFORM && !(!UNITY_EDITOR && UNITY_ANDROID)					if (HasValidTexture())					{						Matrix4x4 m = Helper.GetMatrixForOrientation(Helper.GetOrientation(_mediaPlayer.Info.GetTextureTransform()));						textureSize = m.MultiplyVector(textureSize);						textureSize.x = Mathf.Abs(textureSize.x);						textureSize.y = Mathf.Abs(textureSize.y);					}#endif#if UNITY_PLATFORM_SUPPORTS_VIDEOASPECTRATIO					if (HasValidTexture())					{						float par = _mediaPlayer.TextureProducer.GetTexturePixelAspectRatio();						if (par > 0f)						{							if (par > 1f)							{								textureSize.x *= par;							}							else							{								textureSize.y /= par;							}						}					}#endif					// Adjust textureSize based on alpha/stereo packing					if (_mediaPlayer != null && _mediaPlayer.TextureProducer != null)					{						if (_mediaPlayer.TextureProducer.GetTextureAlphaPacking() == AlphaPacking.LeftRight ||							_mediaPlayer.TextureProducer.GetTextureStereoPacking() == StereoPacking.LeftRight)						{							textureSize.x /= 2;						}						else if (_mediaPlayer.TextureProducer.GetTextureAlphaPacking() == AlphaPacking.TopBottom ||								 _mediaPlayer.TextureProducer.GetTextureStereoPacking() == StereoPacking.TopBottom)						{							textureSize.y /= 2;						}					}				}				Rect r = GetPixelAdjustedRect();				// Fit the above textureSize into rectangle r				int spriteW = Mathf.RoundToInt( textureSize.x );				int spriteH = Mathf.RoundToInt( textureSize.y );				var size = new Vector4( padding.x / spriteW,										padding.y / spriteH,										(spriteW - padding.z) / spriteW,										(spriteH - padding.w) / spriteH );				{					if (textureSize.sqrMagnitude > 0.0f)					{						if (scaleMode == ScaleMode.ScaleToFit)						{							float spriteRatio = textureSize.x / textureSize.y;							float rectRatio = r.width / r.height;							if (spriteRatio > rectRatio)							{								float oldHeight = r.height;								r.height = r.width * (1.0f / spriteRatio);								r.y += (oldHeight - r.height) * rectTransform.pivot.y;							}							else							{								float oldWidth = r.width;								r.width = r.height * spriteRatio;								r.x += (oldWidth - r.width) * rectTransform.pivot.x;							}						}						else if (scaleMode == ScaleMode.ScaleAndCrop)						{							float aspectRatio = textureSize.x / textureSize.y;							float screenRatio = r.width / r.height;							if (screenRatio > aspectRatio)							{								float adjust = aspectRatio / screenRatio;								uvRect = new Rect(uvRect.xMin, (uvRect.yMin * adjust) + (1f - adjust) * 0.5f, uvRect.width, adjust * uvRect.height);							}							else							{								float adjust = screenRatio / aspectRatio;								uvRect = new Rect(uvRect.xMin * adjust + (0.5f - adjust * 0.5f), uvRect.yMin, adjust * uvRect.width, uvRect.height);							}						}					}				}				returnSize = new Vector4( r.x + r.width * size.x,										  r.y + r.height * size.y,										  r.x + r.width * size.z,										  r.y + r.height * size.w  );			}			return returnSize;		}	}}#endif
 |