123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- using UnityEngine;
- //-----------------------------------------------------------------------------
- // Copyright 2015-2022 RenderHeads Ltd. All rights reserved.
- //-----------------------------------------------------------------------------
- namespace RenderHeads.Media.AVProVideo
- {
- public partial class MediaPlayer : MonoBehaviour
- {
- #region Support for Time Scale
- #if AVPROVIDEO_BETA_SUPPORT_TIMESCALE
- // Adjust this value to get faster performance but may drop frames.
- // Wait longer to ensure there is enough time for frames to process
- private const float TimeScaleTimeoutMs = 20f;
- private bool _timeScaleIsControlling;
- private double _timeScaleVideoTime;
- 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;
- }
- }
- }
- #endif
- #endregion // Support for Time Scale
- }
- }
|