예제 #1
0
        private bool ForceWaitForNewFrame(int lastFrameCount, float timeoutMs)
        {
            bool result = false;

            // Wait for the frame to change, or timeout to happen (for the case that there is no new frame for this time)
            System.DateTime startTime      = System.DateTime.Now;
            int             iterationCount = 0;

            while (Control != null && (System.DateTime.Now - startTime).TotalMilliseconds < (double)timeoutMs)
            {
                m_Player.Update();

                // TODO: check if Seeking has completed!  Then we don't have to wait

                // If frame has changed we can continue
                // NOTE: this will never happen because GL.IssuePlugin.Event is never called in this loop
                if (lastFrameCount != TextureProducer.GetTextureFrameCount())
                {
                    result = true;
                    break;
                }

                iterationCount++;

                // NOTE: we tried to add Sleep for 1ms but it was very slow, so switched to this time based method which burns more CPU but about double the speed
                // NOTE: had to add the Sleep back in as after too many iterations (over 1000000) of GL.IssuePluginEvent Unity seems to lock up
                // NOTE: seems that GL.IssuePluginEvent can't be called if we're stuck in a while loop and they just stack up
                //System.Threading.Thread.Sleep(0);
            }

            m_Player.Render();

            return(result);
        }
예제 #2
0
        void OnGUI()
        {
            if (m_Info != null && m_DebugGui)
            {
                GUI.depth  = -1;
                GUI.matrix = Matrix4x4.TRS(new Vector3(m_GuiPositionX, 10f, 0f), Quaternion.identity, new Vector3(s_GuiScale, s_GuiScale, 1.0f));

                GUILayout.BeginVertical("box", GUILayout.MaxWidth(s_GuiWidth));
                GUILayout.Label(System.IO.Path.GetFileName(m_VideoPath));
                GUILayout.Label("Dimensions: " + m_Info.GetVideoWidth() + " x " + m_Info.GetVideoHeight());
                GUILayout.Label("Time: " + (m_Control.GetCurrentTimeMs() * 0.001f).ToString("F1") + "s / " + (m_Info.GetDurationMs() * 0.001f).ToString("F1") + "s");
                GUILayout.Label("Rate: " + m_Info.GetVideoPlaybackRate().ToString("F2") + "Hz");

                if (TextureProducer != null && TextureProducer.GetTexture() != null)
                {
                    // Show texture without and with alpha blending
                    GUILayout.BeginHorizontal();
                    Rect r1 = GUILayoutUtility.GetRect(32f, 32f);
                    GUILayout.Space(8f);
                    Rect r2 = GUILayoutUtility.GetRect(32f, 32f);
                    if (TextureProducer.RequiresVerticalFlip())
                    {
                        GUIUtility.ScaleAroundPivot(new Vector2(1f, -1f), new Vector2(0, r1.y + (r1.height / 2)));
                    }
                    GUI.DrawTexture(r1, TextureProducer.GetTexture(), ScaleMode.ScaleToFit, false);
                    GUI.DrawTexture(r2, TextureProducer.GetTexture(), ScaleMode.ScaleToFit, true);
                    GUILayout.FlexibleSpace();
                    GUILayout.EndHorizontal();
                }
                GUILayout.EndVertical();
            }
        }
예제 #3
0
		private void OnGUI()
		{
			if (m_Info != null && m_DebugGui)
			{
				GUI.depth = -1000;
				GUI.matrix = Matrix4x4.TRS(new Vector3((float)m_GuiPositionX, 10f, 0f), Quaternion.identity, new Vector3(1.5f, 1.5f, 1f));
				GUILayout.BeginVertical("box", GUILayout.MaxWidth(180f));
				GUILayout.Label(Path.GetFileName(m_VideoPath));
				GUILayout.Label("Dimensions: " + m_Info.GetVideoWidth() + "x" + m_Info.GetVideoHeight() + "@" + m_Info.GetVideoFrameRate().ToString("F2"));
				GUILayout.Label("Time: " + (m_Control.GetCurrentTimeMs() * 0.001f).ToString("F1") + "s / " + (m_Info.GetDurationMs() * 0.001f).ToString("F1") + "s");
				GUILayout.Label("Rate: " + m_Info.GetVideoDisplayRate().ToString("F2") + "Hz");
				if (TextureProducer != null && TextureProducer.GetTexture() != null)
				{
					GUILayout.BeginHorizontal();
					Rect rect = GUILayoutUtility.GetRect(32f, 32f);
					GUILayout.Space(8f);
					Rect rect2 = GUILayoutUtility.GetRect(32f, 32f);
					Matrix4x4 matrix = GUI.matrix;
					if (TextureProducer.RequiresVerticalFlip())
					{
						GUIUtility.ScaleAroundPivot(new Vector2(1f, -1f), new Vector2(0f, rect.y + rect.height / 2f));
					}
					GUI.DrawTexture(rect, TextureProducer.GetTexture(), ScaleMode.ScaleToFit, alphaBlend: false);
					GUI.DrawTexture(rect2, TextureProducer.GetTexture(), ScaleMode.ScaleToFit, alphaBlend: true);
					GUI.matrix = matrix;
					GUILayout.FlexibleSpace();
					GUILayout.EndHorizontal();
				}
				GUILayout.EndVertical();
			}
		}
예제 #4
0
		private Texture ExtractFrame(float timeSeconds = -1f, bool accurateSeek = true, int timeoutMs = 1000)
		{
			Texture result = null;
			if (m_Control != null)
			{
				if (timeSeconds >= 0f)
				{
					Pause();
					float num = timeSeconds * 1000f;
					if (TextureProducer.GetTexture() != null && m_Control.GetCurrentTimeMs() == num)
					{
						result = TextureProducer.GetTexture();
					}
					else
					{
						int textureFrameCount = TextureProducer.GetTextureFrameCount();
						if (accurateSeek)
						{
							m_Control.Seek(num);
						}
						else
						{
							m_Control.SeekFast(num);
						}
						ForceWaitForNewFrame(textureFrameCount, (float)timeoutMs);
						result = TextureProducer.GetTexture();
					}
				}
				else
				{
					result = TextureProducer.GetTexture();
				}
			}
			return result;
		}
예제 #5
0
		public Texture2D ExtractFrame(Texture2D target, float timeSeconds = -1f, bool accurateSeek = true, int timeoutMs = 1000)
		{
			Texture2D result = target;
			Texture texture = ExtractFrame(timeSeconds, accurateSeek, timeoutMs);
			if (texture != null)
			{
				result = Helper.GetReadableTexture(texture, TextureProducer.RequiresVerticalFlip(), target);
			}
			return result;
		}
예제 #6
0
    //		private IEnumerator ExtractFrameCoroutine(Texture2D target, ProcessExtractedFrame callback, float timeSeconds = -1f, bool accurateSeek = true, int timeoutMs = 1000, int timeThresholdMs = 100)
    //		{
    //#if REAL_ANDROID || UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN || UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX || UNITY_IOS || UNITY_TVOS
    //			Texture2D result = target;

    //			Texture frame = null;

    //			if (m_Control != null)
    //			{
    //				if (timeSeconds >= 0f)
    //				{
    //					Pause();

    //					float seekTimeMs = timeSeconds * 1000f;

    //					// If the right frame is already available (or close enough) just grab it
    //					if (TextureProducer.GetTexture() != null && (Mathf.Abs(m_Control.GetCurrentTimeMs() - seekTimeMs) < timeThresholdMs))
    //					{
    //						frame = TextureProducer.GetTexture();
    //					}
    //					else
    //					{
    //						int preSeekFrameCount = m_Texture.GetTextureFrameCount();

    //						// Seek to the frame
    //						if (accurateSeek)
    //						{
    //							m_Control.Seek(seekTimeMs);
    //						}
    //						else
    //						{
    //							m_Control.SeekFast(seekTimeMs);
    //						}

    //						// Wait for the new frame to arrive
    //						if (!m_Control.WaitForNextFrame(GetDummyCamera(), preSeekFrameCount))
    //						{
    //							// If WaitForNextFrame fails (e.g. in android single threaded), we run the below code to asynchronously wait for the frame
    //							int currFc = TextureProducer.GetTextureFrameCount();
    //							int iterations = 0;
    //							int maxIterations = 50;

    //							//+1 as often there will be an extra frame produced after pause (so we need to wait for the second frame instead)
    //							while((currFc + 1) >= TextureProducer.GetTextureFrameCount() && iterations++ < maxIterations)
    //							{
    //								yield return null;
    //							}
    //						}
    //						frame = TextureProducer.GetTexture();
    //					}
    //				}
    //				else
    //				{
    //					frame = TextureProducer.GetTexture();
    //				}
    //			}
    //			if (frame != null)
    //			{
    //				result = Helper.GetReadableTexture(frame, TextureProducer.RequiresVerticalFlip(), Helper.GetOrientation(Info.GetTextureTransform()), target);
    //			}
    //#else
    //			Texture2D result = ExtractFrame(target, timeSeconds, accurateSeek, timeoutMs, timeThresholdMs);
    //#endif
    //			callback(result);

    //			yield return null;
    //		}

    //public void ExtractFrameAsync(Texture2D target, ProcessExtractedFrame callback, float timeSeconds = -1f, bool accurateSeek = true, int timeoutMs = 1000, int timeThresholdMs = 100)
    //{
    //	StartCoroutine(ExtractFrameCoroutine(target, callback, timeSeconds, accurateSeek, timeoutMs, timeThresholdMs));
    //}

    // "target" can be null or you can pass in an existing texture.
    public Texture2D ExtractFrame(Texture2D target, float timeSeconds = -1f, bool accurateSeek = true, int timeoutMs = 1000, int timeThresholdMs = 100)
    {
        Texture2D result = target;

        // Extract frames returns the interal frame of the video player
        Texture frame = ExtractFrame(timeSeconds, accurateSeek, timeoutMs, timeThresholdMs);
        if (frame != null)
        {
            result = DBD.Moudle.AVPro.Helper.GetReadableTexture(frame, TextureProducer.RequiresVerticalFlip(), DBD.Moudle.AVPro.Helper.GetOrientation(Info.GetTextureTransform()), target);
        }

        return result;
    }
예제 #7
0
		private void UpdateFrameSyncDebugging()
		{
			int frameCount = TextureProducer.GetTextureFrameCount();
			if (frameCount == _lastFrameCount)
			{
				_sameFrameCount++;
			}
			else
			{
				_sameFrameCount = 1;
			}
			_lastFrameCount = frameCount;
		}
예제 #8
0
		// "target" can be null or you can pass in an existing texture.
		public Texture2D ExtractFrame(Texture2D target, float timeSeconds = -1f, bool accurateSeek = true, int timeoutMs = 1000)
		{
			Texture2D result = target;

			// Extract frames returns the interal frame of the video player
			Texture frame = ExtractFrame(timeSeconds, accurateSeek, timeoutMs);
			if (frame != null)
			{
				result = Helper.GetReadableTexture(frame, TextureProducer.RequiresVerticalFlip(), target);
			}

			return result;
		}
예제 #9
0
		private bool ForceWaitForNewFrame(int lastFrameCount, float timeoutMs)
		{
			bool result = false;
			DateTime now = DateTime.Now;
			int num = 0;
			while (Control != null && (DateTime.Now - now).TotalMilliseconds < (double)timeoutMs)
			{
				m_Player.Update();
				if (lastFrameCount != TextureProducer.GetTextureFrameCount())
				{
					result = true;
					break;
				}
				num++;
			}
			m_Player.Render();
			return result;
		}
예제 #10
0
        private Texture ExtractFrame(float timeSeconds = -1f, bool accurateSeek = true, int timeoutMs = 1000)
        {
            Texture result = null;

            if (m_Control != null)
            {
                if (timeSeconds >= 0f)
                {
                    Pause();

                    float seekTimeMs = timeSeconds * 1000f;

                    // If the frame is already avaiable just grab it
                    if (TextureProducer.GetTexture() != null && m_Control.GetCurrentTimeMs() == seekTimeMs)
                    {
                        result = TextureProducer.GetTexture();
                    }
                    else
                    {
                        // Store frame count before seek
                        int frameCount = TextureProducer.GetTextureFrameCount();

                        // Seek to the frame
                        if (accurateSeek)
                        {
                            m_Control.Seek(seekTimeMs);
                        }
                        else
                        {
                            m_Control.SeekFast(seekTimeMs);
                        }

                        // Wait for frame to change
                        ForceWaitForNewFrame(frameCount, timeoutMs);
                        result = TextureProducer.GetTexture();
                    }
                }
                else
                {
                    result = TextureProducer.GetTexture();
                }
            }
            return(result);
        }
예제 #11
0
        private Texture ExtractFrame(double timeSeconds = -1.0, bool accurateSeek = true, int timeoutMs = 1000, int timeThresholdMs = 100)
        {
            Texture result = null;

            if (_controlInterface != null)
            {
                if (timeSeconds >= 0f)
                {
                    Pause();

                    // If the right frame is already available (or close enough) just grab it
                    if (TextureProducer.GetTexture() != null && (System.Math.Abs(_controlInterface.GetCurrentTime() - timeSeconds) < (timeThresholdMs / 1000.0)))
                    {
                        result = TextureProducer.GetTexture();
                    }
                    else
                    {
                        // Store frame count before seek
                        int frameCount = TextureProducer.GetTextureFrameCount();

                        // Seek to the frame
                        if (accurateSeek)
                        {
                            _controlInterface.Seek(timeSeconds);
                        }
                        else
                        {
                            _controlInterface.SeekFast(timeSeconds);
                        }

                        // Wait for frame to change
                        ForceWaitForNewFrame(frameCount, timeoutMs);
                        result = TextureProducer.GetTexture();
                    }
                }
                else
                {
                    result = TextureProducer.GetTexture();
                }
            }
            return(result);
        }
예제 #12
0
        private void UpdateTimeScale()
        {
            if (Time.timeScale != 1f || Time.captureFramerate != 0)
            {
                if (Control.IsPlaying())
                {
                    Control.Pause();
                    _timeScaleIsControlling = true;
                    _timeScaleVideoTime     = Control.GetCurrentTimeMs();
                }

                if (_timeScaleIsControlling)
                {
                    int frameCount = TextureProducer.GetTextureFrameCount();

                    // Progress time
                    _timeScaleVideoTime += (Time.deltaTime * 1000f);

                    // Handle looping
                    if (m_Loop && _timeScaleVideoTime >= Info.GetDurationMs())
                    {
                        _timeScaleVideoTime = 0f;
                    }

                    // Seek
                    Control.Seek(_timeScaleVideoTime);

                    // Wait for frame to change
                    ForceWaitForNewFrame(frameCount, TimeScaleTimeoutMs);
                }
            }
            else
            {
                // Restore playback when timeScale becomes 1
                if (_timeScaleIsControlling)
                {
                    Control.Play();
                    _timeScaleIsControlling = false;
                }
            }
        }
예제 #13
0
        private IEnumerator ExtractFrameCoroutine(Texture2D target, ProcessExtractedFrame callback, double timeSeconds = -1.0, bool accurateSeek = true, int timeoutMs = 1000, int timeThresholdMs = 100)
        {
#if (!UNITY_EDITOR && UNITY_ANDROID) || UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN || UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX || UNITY_IOS || UNITY_TVOS
            Texture2D result = target;

            Texture frame = null;

            if (_controlInterface != null)
            {
                if (timeSeconds >= 0f)
                {
                    Pause();

                    // If the right frame is already available (or close enough) just grab it
                    if (TextureProducer.GetTexture() != null && (System.Math.Abs(_controlInterface.GetCurrentTime() - timeSeconds) < (timeThresholdMs / 1000.0)))
                    {
                        frame = TextureProducer.GetTexture();
                    }
                    else
                    {
                        int preSeekFrameCount = _textureInterface.GetTextureFrameCount();

                        // Seek to the frame
                        if (accurateSeek)
                        {
                            _controlInterface.Seek(timeSeconds);
                        }
                        else
                        {
                            _controlInterface.SeekFast(timeSeconds);
                        }

                        // Wait for the new frame to arrive
                        if (!_controlInterface.WaitForNextFrame(GetDummyCamera(), preSeekFrameCount))
                        {
                            // If WaitForNextFrame fails (e.g. in android single threaded), we run the below code to asynchronously wait for the frame
                            int currFc        = TextureProducer.GetTextureFrameCount();
                            int iterations    = 0;
                            int maxIterations = 50;

                            //+1 as often there will be an extra frame produced after pause (so we need to wait for the second frame instead)
                            while ((currFc + 1) >= TextureProducer.GetTextureFrameCount() && iterations++ < maxIterations)
                            {
                                yield return(null);
                            }
                        }
                        frame = TextureProducer.GetTexture();
                    }
                }
                else
                {
                    frame = TextureProducer.GetTexture();
                }
            }
            if (frame != null)
            {
                result = Helper.GetReadableTexture(frame, TextureProducer.RequiresVerticalFlip(), Helper.GetOrientation(Info.GetTextureTransform()), target);
            }
#else
            Texture2D result = ExtractFrame(target, timeSeconds, accurateSeek, timeoutMs, timeThresholdMs);
#endif
            callback(result);

            yield return(null);
        }
        private void UpdateTimeScale()
        {
            if (Time.timeScale != 1f || Time.captureFramerate != 0)
            {
                if (_controlInterface.IsPlaying())
                {
                    _controlInterface.Pause();
                    _timeScaleIsControlling = true;
                    _timeScaleVideoTime     = _controlInterface.GetCurrentTime();
                }

                if (_timeScaleIsControlling)
                {
                    // Progress time
                    _timeScaleVideoTime += Time.deltaTime;

                    // Handle looping
                    if (_controlInterface.IsLooping() && _timeScaleVideoTime >= Info.GetDuration())
                    {
                        // TODO: really we should seek to (_timeScaleVideoTime % Info.GetDuration())
                        _timeScaleVideoTime = 0.0;
                    }

                    int preSeekFrameCount = TextureProducer.GetTextureFrameCount();

                    // Seek to the new time
                    {
                        double preSeekTime = Control.GetCurrentTime();

                        // Seek
                        _controlInterface.Seek(_timeScaleVideoTime);

                        // Early out, if after the seek the time hasn't changed, the seek was probably too small to go to the next frame.
                        // TODO: This behaviour may be different on other platforms (not Windows) and needs more testing.
                        if (Mathf.Approximately((float)preSeekTime, (float)_controlInterface.GetCurrentTime()))
                        {
                            return;
                        }
                    }

                    // Wait for the new frame to arrive
                    if (!_controlInterface.WaitForNextFrame(GetDummyCamera(), preSeekFrameCount))
                    {
                        // If WaitForNextFrame fails (e.g. in android single threaded), we run the below code to asynchronously wait for the frame
                        System.DateTime startTime      = System.DateTime.Now;
                        int             lastFrameCount = TextureProducer.GetTextureFrameCount();

                        while (_controlInterface != null && (System.DateTime.Now - startTime).TotalMilliseconds < (double)TimeScaleTimeoutMs)
                        {
                            _playerInterface.Update();
                            _playerInterface.Render();
                            GetDummyCamera().Render();
                            if (lastFrameCount != TextureProducer.GetTextureFrameCount())
                            {
                                break;
                            }
                        }
                    }
                }
            }
            else
            {
                // Restore playback when timeScale becomes 1
                if (_timeScaleIsControlling)
                {
                    _controlInterface.Play();
                    _timeScaleIsControlling = false;
                }
            }
        }
예제 #15
0
        public void OnGUI()
        {
            if (m_Info != null && m_DebugGui)
            {
                GUI.depth  = s_GuiDepth;
                GUI.matrix = Matrix4x4.TRS(new Vector3(m_GuiPositionX, 10f, 0f), Quaternion.identity, new Vector3(s_GuiScale, s_GuiScale, 1.0f));

                GUILayout.BeginVertical("box", GUILayout.MaxWidth(s_GuiWidth));
                GUILayout.Label(System.IO.Path.GetFileName(m_VideoPath));
                GUILayout.Label("Dimensions: " + m_Info.GetVideoWidth() + "x" + m_Info.GetVideoHeight() + "@" + m_Info.GetVideoFrameRate().ToString("F2"));
                GUILayout.Label("Time: " + (m_Control.GetCurrentTimeMs() * 0.001f).ToString("F1") + "s / " + (m_Info.GetDurationMs() * 0.001f).ToString("F1") + "s");
                GUILayout.Label("Rate: " + m_Info.GetVideoDisplayRate().ToString("F2") + "Hz");

                if (TextureProducer != null && TextureProducer.GetTexture() != null)
                {
                    // Show texture without and with alpha blending
                    GUILayout.BeginHorizontal();
                    Rect r1 = GUILayoutUtility.GetRect(32f, 32f);
                    GUILayout.Space(8f);
                    Rect      r2         = GUILayoutUtility.GetRect(32f, 32f);
                    Matrix4x4 prevMatrix = GUI.matrix;
                    if (TextureProducer.RequiresVerticalFlip())
                    {
                        GUIUtility.ScaleAroundPivot(new Vector2(1f, -1f), new Vector2(0, r1.y + (r1.height / 2)));
                    }
                    GUI.DrawTexture(r1, TextureProducer.GetTexture(), ScaleMode.ScaleToFit, false);
                    GUI.DrawTexture(r2, TextureProducer.GetTexture(), ScaleMode.ScaleToFit, true);
                    GUI.matrix = prevMatrix;
                    GUILayout.FlexibleSpace();
                    GUILayout.EndHorizontal();
                }

#if AVPROVIDEO_DEBUG_DISPLAY_EVENTS
                // Dirty code to hack in an event monitor
                if (Event.current.type == EventType.Repaint)
                {
                    this.Events.RemoveListener(OnMediaPlayerEvent);
                    this.Events.AddListener(OnMediaPlayerEvent);
                    UpdateEventLogs();
                }

                if (_eventLog != null && _eventLog.Count > 0)
                {
                    GUILayout.Label("Recent Events: ");
                    GUILayout.BeginVertical("box");
                    int eventIndex = 0;
                    foreach (string eventString in _eventLog)
                    {
                        GUI.color = Color.white;
                        if (eventIndex == 0)
                        {
                            GUI.color = new Color(1f, 1f, 1f, _eventTimer);
                        }
                        GUILayout.Label(eventString);
                        eventIndex++;
                    }
                    GUILayout.EndVertical();
                    GUI.color = Color.white;
                }
#endif
                GUILayout.EndVertical();
            }
        }