UP-Viagg-io/Viagg-io/Assets/Packages/AVProVideo/Runtime/Scripts/Components/MediaPlayer_TimeScale.cs

93 lines
2.9 KiB
C#
Executable File

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
}
}