public override void Update()
        {
            Native.Update(_playerInstance);
            UpdateTracks();
            UpdateTextCue();

            _lastError = (ErrorCode)Native.GetLastErrorCode(_playerInstance);

            UpdateTimeRanges();
            UpdateSubtitles();
            Update_Textures();
            UpdateDisplayFrameRate();

            if (!_isMediaLoaded)
            {
                if (HasVideo() && _eyeTextures[0].texture != null)
                {
                    Native.VideoTrack videoTrack;
                    if (Native.GetActiveVideoTrackInfo(_playerInstance, out videoTrack))
                    {
                        Helper.LogInfo("Using playback path: " + _playerDescription + " (" + videoTrack.frameWidth + "x" + videoTrack.frameHeight + "@" + videoTrack.frameRate.ToString("F2") + ")");
                        _isMediaLoaded = true;
                    }
                }
                else if (HasAudio() && !HasVideo())
                {
                    Helper.LogInfo("Using playback path: " + _playerDescription);
                    _isMediaLoaded = true;
                }
            }
        }
Ejemplo n.º 2
0
        public override void Update()
        {
            if (AVPPlayerUpdate(_player))
            {
                IssuePluginEvent(AVPPluginEventType.PlayerRender);
            }
            _lastError = AVPPlayerGetLastError(_player);
            UpdateTexture();

            // Check for meta data to become available
            if (!_isMetaDataReady)
            {
                if (AVPPlayerHasMetaData(_player) || CanPlay())
                {
                    // MOZ - had to move this outside of HasVideo check
                    _isMetaDataReady = true;

                    if (HasVideo())
                    {
                        if (_width > 0 && _height > 0)
                        {
                            if (Mathf.Max(_width, _height) > SystemInfo.maxTextureSize)
                            {
                                Debug.LogError("[AVProVideo] Video dimensions larger than maxTextureSize");
                            }
                        }
                        _playerDescription = "AVFoundation";
                        Helper.LogInfo("Using playback path: " + _playerDescription + " (" + _width + "x" + _height + "@" + GetVideoFrameRate().ToString("F2") + ")");
                    }
                    else if (HasAudio())
                    {
                    }
                }
            }
        }
        void OnApplicationPause(bool pauseStatus)
        {
#if !(UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN)
//			Debug.Log("OnApplicationPause: pauseStatus: " + pauseStatus);

            if (pauseStatus)
            {
                if (_pauseMediaOnAppPause)
                {
                    if (Control != null && Control.IsPlaying())
                    {
                        _wasPlayingOnPause = true;
#if !UNITY_IPHONE
                        Control.Pause();
#endif
                        Helper.LogInfo("OnApplicationPause: pausing video");
                    }
                }
            }
            else
            {
                if (_playMediaOnAppUnpause)
                {
                    // Catch coming back from power off state when no lock screen
                    OnApplicationFocus(true);
                }
            }
#endif
        }
Ejemplo n.º 4
0
        public void UpdateTexture()
        {
            IntPtr        native;
            int           width;
            int           height;
            TextureFormat format;
            bool          flipped;

            if (AVPPlayerGetTexture(_player, out native, out width, out height, out format, out flipped))
            {
                if (_texture == null || _texture.width != width || _texture.height != height || _texture.format != format)
                {
                    Helper.LogInfo("CreateExternalTexture(" + width + ", " + height + ", " + format + ", false, false, " + native + ")");
                    _texture = Texture2D.CreateExternalTexture(width, height, format, /*mipmap*/ false, /*linear*/ false, native);
                    _width   = width;
                    _height  = height;
                }
                else
                {
                    _texture.UpdateExternalTexture(native);
                }

                _flipped = flipped;
            }
        }
Ejemplo n.º 5
0
        public AndroidMediaPlayer(bool useFastOesPath, bool showPosterFrame, Android.VideoApi api, bool enable360Audio, Audio360ChannelMode channelMode, bool preferSoftware)
        {
            m_API = api;
            // Create a java-size video class up front
            m_Video = s_Interface.Call <AndroidJavaObject>("CreatePlayer", (int)m_API, useFastOesPath, enable360Audio, (int)channelMode, preferSoftware);

            if (m_Video != null)
            {
                m_Method_SetHeadRotation         = AndroidJNIHelper.GetMethodID(m_Video.GetRawClass(), "SetHeadRotation", "(FFFF)V", false);
                m_Method_SetFocusProps           = AndroidJNIHelper.GetMethodID(m_Video.GetRawClass(), "SetFocusProps", "(FF)V", false);
                m_Method_SetFocusEnabled         = AndroidJNIHelper.GetMethodID(m_Video.GetRawClass(), "SetFocusEnabled", "(Z)V", false);
                m_Method_SetFocusRotation        = AndroidJNIHelper.GetMethodID(m_Video.GetRawClass(), "SetFocusRotation", "(FFFF)V", false);
                m_Method_GetCurrentTimeMs        = AndroidJNIHelper.GetMethodID(m_Video.GetRawClass(), "GetCurrentTimeMs", "()J", false);
                m_Method_GetSourceVideoFrameRate = AndroidJNIHelper.GetMethodID(m_Video.GetRawClass(), "GetSourceVideoFrameRate", "()F", false);
                m_Method_IsPlaying   = AndroidJNIHelper.GetMethodID(m_Video.GetRawClass(), "IsPlaying", "()Z", false);
                m_Method_IsPaused    = AndroidJNIHelper.GetMethodID(m_Video.GetRawClass(), "IsPaused", "()Z", false);
                m_Method_IsFinished  = AndroidJNIHelper.GetMethodID(m_Video.GetRawClass(), "IsFinished", "()Z", false);
                m_Method_IsSeeking   = AndroidJNIHelper.GetMethodID(m_Video.GetRawClass(), "IsSeeking", "()Z", false);
                m_Method_IsBuffering = AndroidJNIHelper.GetMethodID(m_Video.GetRawClass(), "IsBuffering", "()Z", false);
                m_Method_IsLooping   = AndroidJNIHelper.GetMethodID(m_Video.GetRawClass(), "IsLooping", "()Z", false);
                m_Method_HasVideo    = AndroidJNIHelper.GetMethodID(m_Video.GetRawClass(), "HasVideo", "()Z", false);
                m_Method_HasAudio    = AndroidJNIHelper.GetMethodID(m_Video.GetRawClass(), "HasAudio", "()Z", false);

                m_iPlayerIndex = m_Video.Call <int>("GetPlayerIndex");
                Helper.LogInfo("Creating player " + m_iPlayerIndex);
                //Debug.Log( "AVPro: useFastOesPath: " + useFastOesPath );
                SetOptions(useFastOesPath, showPosterFrame);

                // Initialise renderer, on the render thread
                AndroidMediaPlayer.IssuePluginEvent(Native.AVPPluginEvent.PlayerSetup, m_iPlayerIndex);
            }
        }
        private bool StartOpenMediaFromBufferInternal(ulong length)
        {
            bool result = false;

            // Open the video file
            if (_controlInterface != null)
            {
                CloseMedia();

                _isMediaOpened            = true;
                _autoPlayOnStartTriggered = !_autoPlayOnStart;

                Helper.LogInfo("Starting Opening buffer of length " + length, this);

                if (!_controlInterface.StartOpenMediaFromBuffer(length))
                {
                    Debug.LogError("[AVProVideo] Failed to start open video from buffer", this);
                    if (GetCurrentPlatformOptions() != PlatformOptionsWindows || PlatformOptionsWindows.videoApi != Windows.VideoApi.DirectShow)
                    {
                        Debug.LogError("[AVProVideo] Loading from buffer is currently only supported in Windows when using the DirectShow API");
                    }
                }
                else
                {
                    SetPlaybackOptions();
                    result = true;
                    StartRenderCoroutine();
                }
            }
            return(result);
        }
Ejemplo n.º 7
0
        public void OnApplicationQuit()
        {
            if (s_GlobalStartup)
            {
                Helper.LogInfo("Shutdown");

                // Clean up any open media players
                MediaPlayer[] players = Resources.FindObjectsOfTypeAll <MediaPlayer>();
                if (players != null && players.Length > 0)
                {
                    for (int i = 0; i < players.Length; i++)
                    {
                        players[i].CloseVideo();
                    }
                }

#if UNITY_EDITOR
#if UNITY_EDITOR_WIN
                WindowsMediaPlayer.DeinitPlatform();
#endif
#else
#if (UNITY_STANDALONE_WIN)
                WindowsMediaPlayer.DeinitPlatform();
#endif
#endif
                s_GlobalStartup = false;
            }
        }
Ejemplo n.º 8
0
        protected void Initialise()
        {
            BaseMediaPlayer mediaPlayer = CreatePlatformMediaPlayer();

            if (mediaPlayer != null)
            {
                // Set-up interface
                m_Control = mediaPlayer;
                m_Texture = mediaPlayer;
                m_Info    = mediaPlayer;
                m_Player  = mediaPlayer;
                m_Dispose = mediaPlayer;

                if (!s_GlobalStartup)
                {
#if UNITY_5
                    Helper.LogInfo(string.Format("Initialising AVPro Video (script v{0} plugin v{1}) on {2}/{3} (MT {4})", Helper.ScriptVersion, mediaPlayer.GetVersion(), SystemInfo.graphicsDeviceName, SystemInfo.graphicsDeviceVersion, SystemInfo.graphicsMultiThreaded));
#else
                    Helper.LogInfo(string.Format("Initialising AVPro Video (script v{0} plugin v{1}) on {2}/{3}", Helper.ScriptVersion, mediaPlayer.GetVersion(), SystemInfo.graphicsDeviceName, SystemInfo.graphicsDeviceVersion));
#endif

#if AVPROVIDEO_BETA_SUPPORT_TIMESCALE
                    Debug.LogWarning("[AVProVideo] TimeScale support used.  This could affect performance when changing Time.timeScale or Time.captureFramerate.  This feature is useful for supporting video capture system that adjust time scale during capturing.");
#endif
                    s_GlobalStartup = true;
                }
            }
        }
Ejemplo n.º 9
0
        private bool OpenVideoFromFile()
        {
            bool result = false;

            // Open the video file
            if (m_Control != null)
            {
                CloseVideo();

                m_VideoOpened                = true;
                m_AutoStartTriggered         = !m_AutoStart;
                m_EventFired_MetaDataReady   = false;
                m_EventFired_ReadyToPlay     = false;
                m_EventFired_Started         = false;
                m_EventFired_FirstFrameReady = false;

                // Potentially override the file location
                long   fileOffset = GetPlatformFileOffset();
                string fullPath   = GetPlatformFilePath(GetPlatform(), ref m_VideoPath, ref m_VideoLocation);

                if (!string.IsNullOrEmpty(m_VideoPath))
                {
                    bool checkForFileExist = true;
                    if (fullPath.Contains("://"))
                    {
                        checkForFileExist = false;
                    }
#if (UNITY_ANDROID)
                    checkForFileExist = false;
#endif

                    if (checkForFileExist && !System.IO.File.Exists(fullPath))
                    {
                        Debug.LogError("[AVProVideo] File not found: " + fullPath, this);
                    }
                    else
                    {
                        Helper.LogInfo("Opening " + fullPath + " (offset " + fileOffset + ")", this);

                        if (!m_Control.OpenVideoFromFile(fullPath, fileOffset))
                        {
                            Debug.LogError("[AVProVideo] Failed to open " + fullPath, this);
                        }
                        else
                        {
                            SetPlaybackOptions();
                            result = true;
                            StartRenderCoroutine();
                        }
                    }
                }
                else
                {
                    Debug.LogError("[AVProVideo] No file path specified", this);
                }
            }
            return(result);
        }
Ejemplo n.º 10
0
        public override void Render()
        {
            if (m_Video != null)
            {
                //GL.InvalidateState();
                AndroidMediaPlayer.IssuePluginEvent(AVPPluginEvent.PlayerUpdate, m_iPlayerIndex);
                //GL.InvalidateState();

                // Check if we can create the texture
                // Scan for a change in resolution
                if (m_Texture != null)
                {
                    int newWidth  = m_Video.Call <int>("GetWidth");
                    int newHeight = m_Video.Call <int>("GetHeight");
                    if (newWidth != m_Width || newHeight != m_Height)
                    {
                        m_Texture       = null;
                        m_TextureHandle = 0;
                    }
                }
                int textureHandle = m_Video.Call <int>("GetTextureHandle");
                if (textureHandle > 0 && textureHandle != m_TextureHandle)
                {
                    int newWidth  = m_Video.Call <int>("GetWidth");
                    int newHeight = m_Video.Call <int>("GetHeight");

                    if (Mathf.Max(newWidth, newHeight) > SystemInfo.maxTextureSize)
                    {
                        m_Width         = newWidth;
                        m_Height        = newHeight;
                        m_TextureHandle = textureHandle;
                        Debug.LogError("[AVProVideo] Video dimensions larger than maxTextureSize");
                    }
                    else if (newWidth > 0 && newHeight > 0)
                    {
                        m_Width         = newWidth;
                        m_Height        = newHeight;
                        m_TextureHandle = textureHandle;

                        _playerDescription = "MediaPlayer";
                        Helper.LogInfo("Using playback path: " + _playerDescription + " (" + m_Width + "x" + m_Height + "@" + GetVideoFrameRate().ToString("F2") + ")");

                        m_Texture = Texture2D.CreateExternalTexture(m_Width, m_Height, TextureFormat.RGBA32, false, false, new System.IntPtr(textureHandle));
                        if (m_Texture != null)
                        {
                            ApplyTextureProperties(m_Texture);
                        }
                        Helper.LogInfo("Texture ID: " + textureHandle);
                    }
                }
                if (m_DurationMs == 0.0f)
                {
                    m_DurationMs = (float)(m_Video.Call <long>("GetDurationMs"));
//					if( m_DurationMs > 0.0f ) { Helper.LogInfo("Duration: " + m_DurationMs); }
                }
            }
        }
 private void AddEvent(MediaPlayerEvent.EventType et)
 {
     Helper.LogInfo("[MediaPlayer] Event: " + et.ToString(), this);
     _eventLog.Enqueue(et.ToString());
     if (_eventLog.Count > 5)
     {
         _eventLog.Dequeue();
         _eventTimer = 1f;
     }
 }
Ejemplo n.º 12
0
		private bool OpenVideoFromFile()
		{
			bool result = false;
			if (m_Control != null)
			{
				CloseVideo();
				m_VideoOpened = true;
				m_AutoStartTriggered = !m_AutoStart;
				m_EventFired_MetaDataReady = false;
				m_EventFired_ReadyToPlay = false;
				m_EventFired_Started = false;
				m_EventFired_FirstFrameReady = false;
				long platformFileOffset = GetPlatformFileOffset();
				string platformFilePath = GetPlatformFilePath(GetPlatform(), ref m_VideoPath, ref m_VideoLocation);
				if (!string.IsNullOrEmpty(m_VideoPath))
				{
					bool flag = true;
					if (platformFilePath.Contains("://"))
					{
						flag = false;
					}
					if (flag && !File.Exists(platformFilePath))
					{
						Debug.LogError("[AVProVideo] File not found: " + platformFilePath, this);
					}
					else
					{
						Helper.LogInfo("Opening " + platformFilePath + " (offset " + platformFileOffset + ")", this);
						if (!m_Control.OpenVideoFromFile(platformFilePath, platformFileOffset))
						{
							Debug.LogError("[AVProVideo] Failed to open " + platformFilePath, this);
						}
						else
						{
							SetPlaybackOptions();
							result = true;
							StartRenderCoroutine();
						}
					}
				}
				else
				{
					Debug.LogError("[AVProVideo] No file path specified", this);
				}
			}
			return result;
		}
Ejemplo n.º 13
0
		private void OnApplicationQuit()
		{
			if (s_GlobalStartup)
			{
				Helper.LogInfo("Shutdown");
				MediaPlayer[] array = Resources.FindObjectsOfTypeAll<MediaPlayer>();
				if (array != null && array.Length > 0)
				{
					for (int i = 0; i < array.Length; i++)
					{
						array[i].CloseVideo();
					}
				}
				WindowsMediaPlayer.DeinitPlatform();
				s_GlobalStartup = false;
			}
		}
Ejemplo n.º 14
0
		protected void Initialise()
		{
			BaseMediaPlayer baseMediaPlayer = CreatePlatformMediaPlayer();
			if (baseMediaPlayer != null)
			{
				m_Control = baseMediaPlayer;
				m_Texture = baseMediaPlayer;
				m_Info = baseMediaPlayer;
				m_Player = baseMediaPlayer;
				m_Dispose = baseMediaPlayer;
				if (!s_GlobalStartup)
				{
					Helper.LogInfo(string.Format("Initialising AVPro Video (script v{0} plugin v{1}) on {2}/{3} (MT {4})", "1.5.8", baseMediaPlayer.GetVersion(), SystemInfo.graphicsDeviceName, SystemInfo.graphicsDeviceVersion, SystemInfo.graphicsMultiThreaded));
					s_GlobalStartup = true;
				}
			}
		}
        void OnApplicationFocus(bool focusStatus)
        {
#if !(UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN)
//			Debug.Log("OnApplicationFocus: focusStatus: " + focusStatus);

            if (focusStatus)
            {
                if (Control != null && _wasPlayingOnPause)
                {
                    _wasPlayingOnPause = false;
                    Control.Play();

                    Helper.LogInfo("OnApplicationFocus: playing video again");
                }
            }
#endif
        }
Ejemplo n.º 16
0
        public AndroidMediaPlayer(bool useFastOesPath, bool showPosterFrame, Android.VideoApi api, bool enable360Audio, Audio360ChannelMode channelMode)
        {
            m_API = api;
            // Create a java-size video class up front
            m_Video = s_Interface.Call <AndroidJavaObject>("CreatePlayer", (int)m_API, enable360Audio, (int)channelMode);

            if (m_Video != null)
            {
                m_iPlayerIndex = m_Video.Call <int>("GetPlayerIndex");
                Helper.LogInfo("Creating player " + m_iPlayerIndex);
                //Debug.Log( "AVPro: useFastOesPath: " + useFastOesPath );
                SetOptions(useFastOesPath, showPosterFrame);

                // Initialise renderer, on the render thread
                AndroidMediaPlayer.IssuePluginEvent(Native.AVPPluginEvent.PlayerSetup, m_iPlayerIndex);
            }
        }
Ejemplo n.º 17
0
        public AndroidMediaPlayer(bool useFastOesPath, bool showPosterFrame, Android.VideoApi api, bool enable360Audio, Audio360ChannelMode channelMode, bool preferSoftware)
        {
#if UNITY_5 || UNITY_5_4_OR_NEWER
            Debug.Assert(s_Interface != null);
            Debug.Assert(s_bInitialised);
#endif
            m_API = api;
            // Create a java-size video class up front
            m_Video = s_Interface.Call <AndroidJavaObject>("CreatePlayer", (int)m_API, useFastOesPath, enable360Audio, (int)channelMode, preferSoftware);

            if (m_Video != null)
            {
                m_Method_Update                  = GetMethod("Update", "()V");
                m_Method_SetHeadRotation         = GetMethod("SetHeadRotation", "(FFFF)V");
                m_Method_SetFocusProps           = GetMethod("SetFocusProps", "(FF)V");
                m_Method_SetFocusEnabled         = GetMethod("SetFocusEnabled", "(Z)V");
                m_Method_SetFocusRotation        = GetMethod("SetFocusRotation", "(FFFF)V");
                m_Method_GetCurrentTimeMs        = GetMethod("GetCurrentTimeMs", "()J");
                m_Method_GetSourceVideoFrameRate = GetMethod("GetSourceVideoFrameRate", "()F");
                m_Method_IsPlaying               = GetMethod("IsPlaying", "()Z");
                m_Method_IsPaused                = GetMethod("IsPaused", "()Z");
                m_Method_IsFinished              = GetMethod("IsFinished", "()Z");
                m_Method_IsSeeking               = GetMethod("IsSeeking", "()Z");
                m_Method_IsBuffering             = GetMethod("IsBuffering", "()Z");
                m_Method_IsLooping               = GetMethod("IsLooping", "()Z");
                m_Method_HasVideo                = GetMethod("HasVideo", "()Z");
                m_Method_HasAudio                = GetMethod("HasAudio", "()Z");

                m_iPlayerIndex = m_Video.Call <int>("GetPlayerIndex");
                Helper.LogInfo("Creating player " + m_iPlayerIndex);
                Debug.Log("AVPro: useFastOesPath: " + useFastOesPath);
                SetOptions(useFastOesPath, showPosterFrame);

                // Initialise renderer, on the render thread
                AndroidMediaPlayer.IssuePluginEvent(Native.AVPPluginEvent.PlayerSetup, m_iPlayerIndex);
            }
            else
            {
                Debug.LogError("[AVProVideo] Failed to create player instance");
            }
        }
Ejemplo n.º 18
0
        public void OnApplicationPause(bool pauseStatus)
        {
#if !(UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN)
//			Debug.Log("OnApplicationPause: pauseStatus: " + pauseStatus);

            if (pauseStatus)
            {
                if (m_Control != null && m_Control.IsPlaying())
                {
                    m_WasPlayingOnPause = true;
                    m_Control.Pause();

                    Helper.LogInfo("OnApplicationPause: pausing video");
                }
            }
            else
            {
                // Catch coming back from power off state when no lock screen
                OnApplicationFocus(true);
            }
#endif
        }
Ejemplo n.º 19
0
        public override void Render()
        {
            if (m_Video != null)
            {
                if (m_UseFastOesPath)
                {
                    // This is needed for at least Unity 5.5.0, otherwise it just renders black in OES mode
                    GL.InvalidateState();
                }
                AndroidMediaPlayer.IssuePluginEvent(Native.AVPPluginEvent.PlayerUpdate, m_iPlayerIndex);
                if (m_UseFastOesPath)
                {
                    GL.InvalidateState();
                }

                // Check if we can create the texture
                // Scan for a change in resolution
                int newWidth  = -1;
                int newHeight = -1;
                if (m_Texture != null)
                {
#if DLL_METHODS
                    newWidth  = Native._GetWidth(m_iPlayerIndex);
                    newHeight = Native._GetHeight(m_iPlayerIndex);
#else
                    newWidth  = m_Video.Call <int>("GetWidth");
                    newHeight = m_Video.Call <int>("GetHeight");
#endif
                    if (newWidth != m_Width || newHeight != m_Height)
                    {
                        m_Texture       = null;
                        m_TextureHandle = 0;
                    }
                }
#if DLL_METHODS
                int textureHandle = Native._GetTextureHandle(m_iPlayerIndex);
#else
                int textureHandle = m_Video.Call <int>("GetTextureHandle");
#endif
                if (textureHandle != 0 && textureHandle != m_TextureHandle)
                {
                    // Already got? (from above)
                    if (newWidth == -1 || newHeight == -1)
                    {
#if DLL_METHODS
                        newWidth  = Native._GetWidth(m_iPlayerIndex);
                        newHeight = Native._GetHeight(m_iPlayerIndex);
#else
                        newWidth  = m_Video.Call <int>("GetWidth");
                        newHeight = m_Video.Call <int>("GetHeight");
#endif
                    }

                    if (Mathf.Max(newWidth, newHeight) > SystemInfo.maxTextureSize)
                    {
                        m_Width         = newWidth;
                        m_Height        = newHeight;
                        m_TextureHandle = textureHandle;
                        Debug.LogError("[AVProVideo] Video dimensions larger than maxTextureSize");
                    }
                    else if (newWidth > 0 && newHeight > 0)
                    {
                        m_Width         = newWidth;
                        m_Height        = newHeight;
                        m_TextureHandle = textureHandle;

                        switch (m_API)
                        {
                        case Android.VideoApi.MediaPlayer:
                            _playerDescription = "MediaPlayer";
                            break;

                        case Android.VideoApi.ExoPlayer:
                            _playerDescription = "ExoPlayer";
                            break;

                        default:
                            _playerDescription = "UnknownPlayer";
                            break;
                        }

                        Helper.LogInfo("Using playback path: " + _playerDescription + " (" + m_Width + "x" + m_Height + "@" + GetVideoFrameRate().ToString("F2") + ")");

                        // NOTE: From Unity 5.4.x when using OES textures, an error "OPENGL NATIVE PLUG-IN ERROR: GL_INVALID_OPERATION: Operation illegal in current state" will be logged.
                        // We assume this is because we're passing in TextureFormat.RGBA32 which isn't the true texture format.  This error should be safe to ignore.
                        m_Texture = Texture2D.CreateExternalTexture(m_Width, m_Height, TextureFormat.RGBA32, false, false, new System.IntPtr(textureHandle));
                        if (m_Texture != null)
                        {
                            ApplyTextureProperties(m_Texture);
                        }
                        Helper.LogInfo("Texture ID: " + textureHandle);
                    }
                }

#if AVPROVIDEO_FIXREGRESSION_TEXTUREQUALITY_UNITY542
                // In Unity 5.4.2 and above the video texture turns black when changing the TextureQuality in the Quality Settings
                // The code below gets around this issue.  A bug report has been sent to Unity.  So far we have tested and replicated the
                // "bug" in Windows only, but a user has reported it in Android too.
                // Texture.GetNativeTexturePtr() must sync with the rendering thread, so this is a large performance hit!
                if (_textureQuality != QualitySettings.masterTextureLimit)
                {
                    if (m_Texture != null && textureHandle > 0 && m_Texture.GetNativeTexturePtr() == System.IntPtr.Zero)
                    {
                        //Debug.Log("RECREATING");
                        m_Texture.UpdateExternalTexture(new System.IntPtr(textureHandle));
                    }

                    _textureQuality = QualitySettings.masterTextureLimit;
                }
#endif
            }
        }
        public bool EnableSubtitles(MediaPath mediaPath)
        {
            bool result = false;

            if (_subtitlesInterface != null)
            {
                if (mediaPath != null && !string.IsNullOrEmpty(mediaPath.Path))
                {
                    string fullPath = mediaPath.GetResolvedFullPath();

                    bool checkForFileExist = true;
                    if (fullPath.Contains("://"))
                    {
                        checkForFileExist = false;
                    }
#if (!UNITY_EDITOR && UNITY_ANDROID)
                    checkForFileExist = false;
#endif

                    if (checkForFileExist && !System.IO.File.Exists(fullPath))
                    {
                        Debug.LogError("[AVProVideo] Subtitle file not found: " + fullPath, this);
                    }
                    else
                    {
                        Helper.LogInfo("Opening subtitles " + fullPath, this);

                        _previousSubtitleIndex = -1;

                        try
                        {
                            if (fullPath.Contains("://"))
                            {
                                // Use coroutine and WWW class for loading
                                if (_loadSubtitlesRoutine != null)
                                {
                                    StopCoroutine(_loadSubtitlesRoutine);
                                    _loadSubtitlesRoutine = null;
                                }
                                _loadSubtitlesRoutine = StartCoroutine(LoadSubtitlesCoroutine(fullPath, mediaPath));
                            }
                            else
                            {
                                // Load directly from file
                                string subtitleData = System.IO.File.ReadAllText(fullPath);
                                if (_subtitlesInterface.LoadSubtitlesSRT(subtitleData))
                                {
                                    _subtitlePath      = mediaPath;
                                    _sideloadSubtitles = false;
                                    result             = true;
                                }
                                else
                                {
                                    Debug.LogError("[AVProVideo] Failed to load subtitles" + fullPath, this);
                                }
                            }
                        }
                        catch (System.Exception e)
                        {
                            Debug.LogError("[AVProVideo] Failed to load subtitles " + fullPath, this);
                            Debug.LogException(e, this);
                        }
                    }
                }
                else
                {
                    Debug.LogError("[AVProVideo] No subtitle file path specified", this);
                }
            }
            else
            {
                _queueSubtitlePath = mediaPath;
            }

            return(result);
        }
Ejemplo n.º 21
0
        //public override void SetAudioDeviceName(string name)
        //{
        //}

        public override void Update()
        {
            Native.Update(_instance);
            _lastError = (ErrorCode)Native.GetLastErrorCode(_instance);

            if (_queueSetAudioTrackIndex >= 0 && _hasAudio)
            {
                // We have to queue the setting of the audio track, as doing it from the UI can result in a crash (for some unknown reason)
                Native.SetAudioTrack(_instance, _queueSetAudioTrackIndex);
                _queueSetAudioTrackIndex = -1;
            }

            // Update network buffering
            {
                _bufferedTimeRangeCount = Native.GetBufferedRanges(_instance, _bufferedTimeRanges, _bufferedTimeRanges.Length / 2);
                if (_bufferedTimeRangeCount > (_bufferedTimeRanges.Length / 2))
                {
                    _bufferedTimeRanges     = new float[_bufferedTimeRangeCount * 2];
                    _bufferedTimeRangeCount = Native.GetBufferedRanges(_instance, _bufferedTimeRanges, _bufferedTimeRanges.Length / 2);
                }
            }

            UpdateSubtitles();

            if (!_canPlay)
            {
                if (!_hasMetaData)
                {
                    if (Native.HasMetaData(_instance))
                    {
                        if (Native.HasVideo(_instance))
                        {
                            _width     = Native.GetWidth(_instance);
                            _height    = Native.GetHeight(_instance);
                            _frameRate = Native.GetFrameRate(_instance);

                            // Sometimes the dimensions aren't available yet, in which case fail and poll them again next loop
                            if (_width > 0 && _height > 0)
                            {
                                _hasVideo = true;

                                // Note: If the Unity editor Build platform isn't set to Windows then maxTextureSize will not be correct
                                if (Mathf.Max(_width, _height) > SystemInfo.maxTextureSize

                                    // If we're running in the editor it may be emulating another platform
                                    // in which case maxTextureSize won't be correct, so ignore it.
                                                                #if UNITY_EDITOR
                                    && !SystemInfo.graphicsDeviceName.ToLower().Contains("emulated")
                                                                #endif
                                    )
                                {
                                    Debug.LogError(string.Format("[AVProVideo] Video dimensions ({0}x{1}) larger than maxTextureSize ({2} for current build target)", _width, _height, SystemInfo.maxTextureSize));
                                    _width    = _height = 0;
                                    _hasVideo = false;
                                }
                            }

                            if (_hasVideo)
                            {
                                if (Native.HasAudio(_instance))
                                {
                                    _hasAudio = true;
                                }
                            }
                        }
                        else
                        {
                            if (Native.HasAudio(_instance))
                            {
                                _hasAudio = true;
                            }
                        }

                        if (_hasVideo || _hasAudio)
                        {
                            _hasMetaData = true;
                        }

                        _playerDescription        = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(Native.GetPlayerDescription(_instance));
                        _supportsLinearColorSpace = !_playerDescription.Contains("MF-MediaEngine-Hardware");
                        Helper.LogInfo("Using playback path: " + _playerDescription + " (" + _width + "x" + _height + "@" + GetVideoFrameRate().ToString("F2") + ")");
                        if (_hasVideo)
                        {
                            OnTextureSizeChanged();
                        }
                    }
                }
                if (_hasMetaData)
                {
                    _canPlay = Native.CanPlay(_instance);
                }
            }

#if UNITY_WSA
            // NOTE: I think this issue has been resolved now as of version 1.5.24.
            // The issue was caused by functions returning booleans incorrectly (4 bytes vs 1)
            // and as been resolved by specifying the return type during marshalling..
            // Still we'll keep this code here until after more testing.

            // WSA has an issue where it can load the audio track first and the video track later
            // Here we try to handle this case and get the video track information when it arrives
            if (_hasAudio && !_hasVideo)
            {
                _width     = Native.GetWidth(_instance);
                _height    = Native.GetHeight(_instance);
                _frameRate = Native.GetFrameRate(_instance);

                if (_width > 0 && _height > 0)
                {
                    _hasVideo = true;
                    OnTextureSizeChanged();
                }
            }
#endif

            if (_hasVideo)
            {
                System.IntPtr newPtr = Native.GetTexturePointer(_instance);

                // Check for texture recreation (due to device loss or change in texture size)
                if (_texture != null && _nativeTexture != System.IntPtr.Zero && _nativeTexture != newPtr)
                {
                    _width  = Native.GetWidth(_instance);
                    _height = Native.GetHeight(_instance);

                    if (newPtr == System.IntPtr.Zero || (_width != _texture.width || _height != _texture.height))
                    {
                        if (_width != _texture.width || _height != _texture.height)
                        {
                            Helper.LogInfo("Texture size changed: " + _width + " X " + _height);
                            OnTextureSizeChanged();
                        }

                        _nativeTexture = System.IntPtr.Zero;
                        Texture2D.Destroy(_texture);
                        _texture = null;
                    }
                    else if (_nativeTexture != newPtr)
                    {
                        _texture.UpdateExternalTexture(newPtr);
                        _nativeTexture = newPtr;
                    }
                }

#if AVPROVIDEO_FIXREGRESSION_TEXTUREQUALITY_UNITY542
                // In Unity 5.4.2 and above the video texture turns black when changing the TextureQuality in the Quality Settings
                // The code below gets around this issue.  A bug report has been sent to Unity.  So far we have tested and replicated the
                // "bug" in Windows only, but a user has reported it in Android too.
                // Texture.GetNativeTexturePtr() must sync with the rendering thread, so this is a large performance hit!
                if (_textureQuality != QualitySettings.masterTextureLimit)
                {
                    if (_texture != null && _nativeTexture != System.IntPtr.Zero && _texture.GetNativeTexturePtr() == System.IntPtr.Zero)
                    {
                        //Debug.Log("RECREATING");
                        _texture.UpdateExternalTexture(_nativeTexture);
                    }

                    _textureQuality = QualitySettings.masterTextureLimit;
                }
#endif

                // Check if a new texture has to be created
                if (_texture == null && _width > 0 && _height > 0 && newPtr != System.IntPtr.Zero)
                {
                    _isTextureTopDown = Native.IsTextureTopDown(_instance);
                    bool isLinear = (!_supportsLinearColorSpace && QualitySettings.activeColorSpace == ColorSpace.Linear);
                    _texture = Texture2D.CreateExternalTexture(_width, _height, TextureFormat.RGBA32, _useTextureMips, isLinear, newPtr);
                    if (_texture != null)
                    {
                        _texture.name  = "AVProVideo";
                        _nativeTexture = newPtr;
                        ApplyTextureProperties(_texture);
                    }
                    else
                    {
                        Debug.LogError("[AVProVideo] Failed to create texture");
                    }
                }
            }
        }
Ejemplo n.º 22
0
        public override void Render()
        {
            if (m_Video != null)
            {
                //GL.InvalidateState();
                AndroidMediaPlayer.IssuePluginEvent(Native.AVPPluginEvent.PlayerUpdate, m_iPlayerIndex);
                //GL.InvalidateState();

                // Check if we can create the texture
                // Scan for a change in resolution
                int newWidth  = -1;
                int newHeight = -1;
                if (m_Texture != null)
                {
#if DLL_METHODS
                    newWidth  = Native._GetWidth(m_iPlayerIndex);
                    newHeight = Native._GetHeight(m_iPlayerIndex);
#else
                    newWidth  = m_Video.Call <int>("GetWidth");
                    newHeight = m_Video.Call <int>("GetHeight");
#endif
                    if (newWidth != m_Width || newHeight != m_Height)
                    {
                        m_Texture       = null;
                        m_TextureHandle = 0;
                    }
                }
#if DLL_METHODS
                int textureHandle = Native._GetTextureHandle(m_iPlayerIndex);
#else
                int textureHandle = m_Video.Call <int>("GetTextureHandle");
#endif
                if (textureHandle > 0 && textureHandle != m_TextureHandle)
                {
                    // Already got? (from above)
                    if (newWidth == -1 || newHeight == -1)
                    {
#if DLL_METHODS
                        newWidth  = Native._GetWidth(m_iPlayerIndex);
                        newHeight = Native._GetHeight(m_iPlayerIndex);
#else
                        newWidth  = m_Video.Call <int>("GetWidth");
                        newHeight = m_Video.Call <int>("GetHeight");
#endif
                    }

                    if (Mathf.Max(newWidth, newHeight) > SystemInfo.maxTextureSize)
                    {
                        m_Width         = newWidth;
                        m_Height        = newHeight;
                        m_TextureHandle = textureHandle;
                        Debug.LogError("[AVProVideo] Video dimensions larger than maxTextureSize");
                    }
                    else if (newWidth > 0 && newHeight > 0)
                    {
                        m_Width         = newWidth;
                        m_Height        = newHeight;
                        m_TextureHandle = textureHandle;

                        _playerDescription = "MediaPlayer";
                        Helper.LogInfo("Using playback path: " + _playerDescription + " (" + m_Width + "x" + m_Height + "@" + GetVideoFrameRate().ToString("F2") + ")");

                        // NOTE: From Unity 5.4.x when using OES textures, an error "OPENGL NATIVE PLUG-IN ERROR: GL_INVALID_OPERATION: Operation illegal in current state" will be logged.
                        // We assume this is because we're passing in TextureFormat.RGBA32 which isn't the true texture format.  This error should be safe to ignore.
                        m_Texture = Texture2D.CreateExternalTexture(m_Width, m_Height, TextureFormat.RGBA32, false, false, new System.IntPtr(textureHandle));
                        if (m_Texture != null)
                        {
                            ApplyTextureProperties(m_Texture);
                        }
                        Helper.LogInfo("Texture ID: " + textureHandle);
                    }
                }

#if UNITY_5_4_OR_NEWER
                // In Unity 5.4.2 and above the vidoe texture turns black when changing the TextureQuality in the Quality Settings
                // The code below gets around this issue.  A bug report has been sent to Unity.  So far we have tested and replicated the
                // "bug" in Windows only, but a user has reported it in Android too
                if (m_Texture != null && textureHandle > 0 && m_Texture.GetNativeTexturePtr() == System.IntPtr.Zero)
                {
                    //Debug.Log("RECREATING");
                    m_Texture.UpdateExternalTexture(new System.IntPtr(textureHandle));
                }
#endif

                if (m_DurationMs == 0.0f)
                {
#if DLL_METHODS
                    m_DurationMs = (float)(Native._GetDuration(m_iPlayerIndex));
#else
                    m_DurationMs = (float)(m_Video.Call <long>("GetDurationMs"));
#endif
//					if( m_DurationMs > 0.0f ) { Helper.LogInfo("Duration: " + m_DurationMs); }
                }
            }
        }
Ejemplo n.º 23
0
        public override void Update()
        {
            Native.Update(_instance);
            _lastError = (ErrorCode)Native.GetLastErrorCode(_instance);

            if (_queueSetAudioTrackIndex >= 0 && _hasAudio)
            {
                // We have to queue the setting of the audio track, as doing it from the UI can result in a crash (for some unknown reason)
                Native.SetAudioTrack(_instance, _queueSetAudioTrackIndex);
                _queueSetAudioTrackIndex = -1;
            }

            // Update network buffering
            {
                _bufferedTimeRangeCount = Native.GetBufferedRanges(_instance, _bufferedTimeRanges, _bufferedTimeRanges.Length / 2);
                if (_bufferedTimeRangeCount > (_bufferedTimeRanges.Length / 2))
                {
                    _bufferedTimeRanges     = new float[_bufferedTimeRangeCount * 2];
                    _bufferedTimeRangeCount = Native.GetBufferedRanges(_instance, _bufferedTimeRanges, _bufferedTimeRanges.Length / 2);
                }
            }

            if (!_canPlay)
            {
                if (!_hasMetaData)
                {
                    if (Native.HasMetaData(_instance))
                    {
                        if (Native.HasVideo(_instance))
                        {
                            _width     = Native.GetWidth(_instance);
                            _height    = Native.GetHeight(_instance);
                            _frameRate = Native.GetFrameRate(_instance);

                            // Sometimes the dimensions aren't available yet, in which case fail and poll them again next loop
                            if (_width > 0 && _height > 0)
                            {
                                _hasVideo = true;

                                // Note: If the Unity editor Build platform isn't set to Windows then maxTextureSize will not be correct
                                if (Mathf.Max(_width, _height) > SystemInfo.maxTextureSize)
                                {
                                    Debug.LogError(string.Format("[AVProVideo] Video dimensions ({0}x{1}) larger than maxTextureSize ({2})", _width, _height, SystemInfo.maxTextureSize));
                                    _width    = _height = 0;
                                    _hasVideo = false;
                                }
                            }

                            if (_hasVideo)
                            {
                                if (Native.HasAudio(_instance))
                                {
                                    _hasAudio = true;
                                }
                            }
                        }
                        else
                        {
                            if (Native.HasAudio(_instance))
                            {
                                _hasAudio = true;
                            }
                        }

                        if (_hasVideo || _hasAudio)
                        {
                            _hasMetaData = true;
                        }

                        _playerDescription        = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(Native.GetPlayerDescription(_instance));
                        _supportsLinearColorSpace = !_playerDescription.Contains("MF-MediaEngine-Hardware");
                        Helper.LogInfo("Using playback path: " + _playerDescription + " (" + _width + "x" + _height + "@" + GetVideoFrameRate().ToString("F2") + ")");
                        if (_hasVideo)
                        {
                            OnTextureSizeChanged();
                        }
                    }
                }
                if (_hasMetaData)
                {
                    _canPlay = Native.CanPlay(_instance);
                }
            }

            if (_hasVideo)
            {
                System.IntPtr newPtr = Native.GetTexturePointer(_instance);

                // Check for texture recreation (due to device loss or change in texture size)
                if (_texture != null && _nativeTexture != System.IntPtr.Zero && _nativeTexture != newPtr)
                {
                    _width  = Native.GetWidth(_instance);
                    _height = Native.GetHeight(_instance);

                    if (newPtr == System.IntPtr.Zero || (_width != _texture.width || _height != _texture.height))
                    {
                        if (_width != _texture.width || _height != _texture.height)
                        {
                            Helper.LogInfo("Texture size changed: " + _width + " X " + _height);
                            OnTextureSizeChanged();
                        }

                        _nativeTexture = System.IntPtr.Zero;
                        Texture2D.Destroy(_texture);
                        _texture = null;
                    }
                    else if (_nativeTexture != newPtr)
                    {
                        _texture.UpdateExternalTexture(newPtr);
                        _nativeTexture = newPtr;
                    }
                }

#if UNITY_5_4_OR_NEWER
                // In Unity 5.4.2 and above the vidoe texture turns black when changing the TextureQuality in the Quality Settings
                // The code below gets around this issue.  A bug report has been sent to Unity.  So far we have tested and replicated the
                // "bug" in Windows only, but a user has reported it in Android too
                if (_texture != null && _nativeTexture != System.IntPtr.Zero && _texture.GetNativeTexturePtr() == System.IntPtr.Zero)
                {
                    //Debug.Log("RECREATING");
                    _texture.UpdateExternalTexture(_nativeTexture);
                }
#endif

                // Check if a new texture has to be created
                if (_texture == null && _width > 0 && _height > 0 && newPtr != System.IntPtr.Zero)
                {
                    _isTextureTopDown = Native.IsTextureTopDown(_instance);
                    _texture          = Texture2D.CreateExternalTexture(_width, _height, TextureFormat.RGBA32, false, false, newPtr);
                    if (_texture != null)
                    {
                        _nativeTexture = newPtr;
                        ApplyTextureProperties(_texture);
                    }
                    else
                    {
                        Debug.LogError("[AVProVideo] Failed to create texture");
                    }
                }
            }
        }
Ejemplo n.º 24
0
 public override void Update()
 {
     Native.Update(_instance);
     _lastError = (ErrorCode)Native.GetLastErrorCode(_instance);
     if (_queueSetAudioTrackIndex >= 0 && _hasAudio)
     {
         Native.SetAudioTrack(_instance, _queueSetAudioTrackIndex);
         _queueSetAudioTrackIndex = -1;
     }
     _bufferedTimeRangeCount = Native.GetBufferedRanges(_instance, _bufferedTimeRanges, _bufferedTimeRanges.Length / 2);
     if (_bufferedTimeRangeCount > _bufferedTimeRanges.Length / 2)
     {
         _bufferedTimeRanges     = new float[_bufferedTimeRangeCount * 2];
         _bufferedTimeRangeCount = Native.GetBufferedRanges(_instance, _bufferedTimeRanges, _bufferedTimeRanges.Length / 2);
     }
     if (!_canPlay)
     {
         if (!_hasMetaData && Native.HasMetaData(_instance))
         {
             if (Native.HasVideo(_instance))
             {
                 _width     = Native.GetWidth(_instance);
                 _height    = Native.GetHeight(_instance);
                 _frameRate = Native.GetFrameRate(_instance);
                 if (_width > 0 && _height > 0)
                 {
                     _hasVideo = true;
                     if (Mathf.Max(_width, _height) > SystemInfo.maxTextureSize)
                     {
                         Debug.LogError($"[AVProVideo] Video dimensions ({_width}x{_height}) larger than maxTextureSize ({SystemInfo.maxTextureSize})");
                         _width    = (_height = 0);
                         _hasVideo = false;
                     }
                 }
                 if (_hasVideo && Native.HasAudio(_instance))
                 {
                     _hasAudio = true;
                 }
             }
             else if (Native.HasAudio(_instance))
             {
                 _hasAudio = true;
             }
             if (_hasVideo || _hasAudio)
             {
                 _hasMetaData = true;
             }
             _playerDescription        = Marshal.PtrToStringAnsi(Native.GetPlayerDescription(_instance));
             _supportsLinearColorSpace = !_playerDescription.Contains("MF-MediaEngine-Hardware");
             Helper.LogInfo("Using playback path: " + _playerDescription + " (" + _width + "x" + _height + "@" + GetVideoFrameRate().ToString("F2") + ")");
             if (_hasVideo)
             {
                 OnTextureSizeChanged();
             }
         }
         if (_hasMetaData)
         {
             _canPlay = Native.CanPlay(_instance);
         }
     }
     if (_hasVideo)
     {
         IntPtr texturePointer = Native.GetTexturePointer(_instance);
         if (_texture != null && _nativeTexture != IntPtr.Zero && _nativeTexture != texturePointer)
         {
             _width  = Native.GetWidth(_instance);
             _height = Native.GetHeight(_instance);
             if (texturePointer == IntPtr.Zero || _width != _texture.width || _height != _texture.height)
             {
                 if (_width != _texture.width || _height != _texture.height)
                 {
                     Helper.LogInfo("Texture size changed: " + _width + " X " + _height);
                     OnTextureSizeChanged();
                 }
                 _nativeTexture = IntPtr.Zero;
                 UnityEngine.Object.Destroy(_texture);
                 _texture = null;
             }
             else if (_nativeTexture != texturePointer)
             {
                 _texture.UpdateExternalTexture(texturePointer);
                 _nativeTexture = texturePointer;
             }
         }
         if (_texture == null && _width > 0 && _height > 0 && texturePointer != IntPtr.Zero)
         {
             _isTextureTopDown = Native.IsTextureTopDown(_instance);
             _texture          = Texture2D.CreateExternalTexture(_width, _height, TextureFormat.RGBA32, /*mipmap:*/ false, /*linear:*/ false, texturePointer);
             if (_texture != null)
             {
                 _nativeTexture = texturePointer;
                 ApplyTextureProperties(_texture);
             }
             else
             {
                 Debug.LogError("[AVProVideo] Failed to create texture");
             }
         }
     }
 }
Ejemplo n.º 25
0
        public override void Update()
        {
            Native.Update(_instance);
            _lastError = (ErrorCode)Native.GetLastErrorCode(_instance);

            if (_queueSetAudioTrackIndex >= 0 && _hasAudio)
            {
                // We have to queue the setting of the audio track, as doing it from the UI can result in a crash (for some unknown reason)
                Native.SetAudioTrack(_instance, _queueSetAudioTrackIndex);
                _queueSetAudioTrackIndex = -1;
            }

            if (!_canPlay)
            {
                if (!_hasMetaData)
                {
                    if (Native.HasMetaData(_instance))
                    {
                        if (Native.HasVideo(_instance))
                        {
                            _width     = Native.GetWidth(_instance);
                            _height    = Native.GetHeight(_instance);
                            _frameRate = Native.GetFrameRate(_instance);

                            // Sometimes the dimensions aren't available yet, in which case fail and poll them again next loop
                            if (_width > 0 && _height > 0)
                            {
                                _hasVideo = true;

                                // Note: If the Unity editor Build platform isn't set to Windows then maxTextureSize will not be correct
                                if (Mathf.Max(_width, _height) > SystemInfo.maxTextureSize)
                                {
                                    Debug.LogError(string.Format("[AVProVideo] Video dimensions ({0}x{1}) larger than maxTextureSize ({2})", _width, _height, SystemInfo.maxTextureSize));
                                    _width    = _height = 0;
                                    _hasVideo = false;
                                }
                            }

                            if (_hasVideo)
                            {
                                if (Native.HasAudio(_instance))
                                {
                                    _hasAudio = true;
                                }
                            }
                        }
                        else
                        {
                            if (Native.HasAudio(_instance))
                            {
                                _hasAudio = true;
                            }
                        }

                        if (_hasVideo || _hasAudio)
                        {
                            _hasMetaData = true;
                        }

                        _playerDescription        = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(Native.GetPlayerDescription(_instance));
                        _supportsLinearColorSpace = !_playerDescription.Contains("MF-MediaEngine-Hardware");
                        Helper.LogInfo("Using playback path: " + _playerDescription + " (" + _width + "x" + _height + "@" + GetVideoFrameRate().ToString("F2") + ")");
                        if (_hasVideo)
                        {
                            OnTextureSizeChanged();
                        }
                    }
                }
                if (_hasMetaData)
                {
                    _canPlay = Native.CanPlay(_instance);
                }
            }

            if (_hasVideo)
            {
                System.IntPtr newPtr = Native.GetTexturePointer(_instance);

                // Check for texture recreation (due to device loss or change in texture size)
                if (_texture != null && _nativeTexture != System.IntPtr.Zero && _nativeTexture != newPtr)
                {
                    _width  = Native.GetWidth(_instance);
                    _height = Native.GetHeight(_instance);

                    if (newPtr == System.IntPtr.Zero || (_width != _texture.width || _height != _texture.height))
                    {
                        if (_width != _texture.width || _height != _texture.height)
                        {
                            Helper.LogInfo("Texture size changed: " + _width + " X " + _height);
                            OnTextureSizeChanged();
                        }

                        _nativeTexture = System.IntPtr.Zero;
                        Texture2D.Destroy(_texture);
                        _texture = null;
                    }
                    else if (_nativeTexture != newPtr)
                    {
                        _texture.UpdateExternalTexture(newPtr);
                        _nativeTexture = newPtr;
                    }
                }

                // Check if a new texture has to be created
                if (_texture == null && _width > 0 && _height > 0 && newPtr != System.IntPtr.Zero)
                {
                    _isTextureTopDown = Native.IsTextureTopDown(_instance);
                    _texture          = Texture2D.CreateExternalTexture(_width, _height, TextureFormat.RGBA32, false, false, newPtr);
                    if (_texture != null)
                    {
                        _nativeTexture = newPtr;
                        ApplyTextureProperties(_texture);
                    }
                    else
                    {
                        Debug.LogError("[AVProVideo] Failed to create texture");
                    }
                }
            }
        }