private void UpdateFrameSyncDebugging() { int frameCount = TextureProducer.GetTextureFrameCount(); if (frameCount == _lastFrameCount) { _sameFrameCount++; } else { _sameFrameCount = 1; } _lastFrameCount = frameCount; }
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; }
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); }
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); }
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; } } }
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; } } }