RecordingSession.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. using System;
  2. using UnityEngine;
  3. namespace UnityEditor.Recorder
  4. {
  5. public class RecordingSession : IDisposable
  6. {
  7. public Recorder recorder;
  8. internal GameObject recorderGameObject;
  9. internal RecorderComponent recorderComponent;
  10. int m_FrameIndex = 0;
  11. int m_InitialFrame = 0;
  12. int m_FirstRecordedFrameCount = -1;
  13. float m_FPSTimeStart;
  14. float m_FPSNextTimeStart;
  15. int m_FPSNextFrameCount;
  16. internal bool prepareFrameCalled { get; private set; }
  17. internal double currentFrameStartTS { get; private set; }
  18. internal double recordingStartTS { get; private set; }
  19. internal DateTime sessionStartTS { get; private set; }
  20. public RecorderSettings settings
  21. {
  22. get { return recorder.settings; }
  23. }
  24. internal bool isRecording
  25. {
  26. get { return recorder.Recording; }
  27. }
  28. public int frameIndex
  29. {
  30. get { return m_FrameIndex; }
  31. }
  32. internal int RecordedFrameSpan
  33. {
  34. get { return m_FirstRecordedFrameCount == -1 ? 0 : Time.renderedFrameCount - m_FirstRecordedFrameCount; }
  35. }
  36. public float recorderTime
  37. {
  38. get { return (float)(currentFrameStartTS - settings.StartTime); }
  39. }
  40. static void AllowInBackgroundMode()
  41. {
  42. if (!Application.runInBackground)
  43. {
  44. Application.runInBackground = true;
  45. if (RecorderOptions.VerboseMode)
  46. Debug.Log("Recording sessions is enabling Application.runInBackground!");
  47. }
  48. }
  49. internal bool SessionCreated()
  50. {
  51. try
  52. {
  53. AllowInBackgroundMode();
  54. recordingStartTS = (Time.time / (Mathf.Approximately(Time.timeScale, 0f)? 1f : Time.timeScale));
  55. sessionStartTS = DateTime.Now;
  56. recorder.SessionCreated(this);
  57. prepareFrameCalled = false;
  58. return true;
  59. }
  60. catch (Exception ex)
  61. {
  62. Debug.LogException(ex);
  63. return false;
  64. }
  65. }
  66. internal bool BeginRecording()
  67. {
  68. try
  69. {
  70. if (!settings.IsPlatformSupported)
  71. {
  72. Debug.LogError(string.Format("Recorder {0} does not support current platform", recorder.GetType().Name));
  73. return false;
  74. }
  75. AllowInBackgroundMode();
  76. recordingStartTS = (Time.time / (Mathf.Approximately(Time.timeScale, 0f) ? 1f : Time.timeScale));
  77. recorder.SignalInputsOfStage(ERecordingSessionStage.BeginRecording, this);
  78. if (!recorder.BeginRecording(this))
  79. return false;
  80. m_InitialFrame = Time.renderedFrameCount;
  81. m_FPSTimeStart = Time.unscaledTime;
  82. return true;
  83. }
  84. catch (Exception ex)
  85. {
  86. Debug.LogException(ex);
  87. return false;
  88. }
  89. }
  90. internal void EndRecording()
  91. {
  92. if (!isRecording)
  93. return;
  94. try
  95. {
  96. recorder.SignalInputsOfStage(ERecordingSessionStage.EndRecording, this);
  97. recorder.EndRecording(this);
  98. }
  99. catch (Exception ex)
  100. {
  101. Debug.LogException(ex);
  102. }
  103. }
  104. internal void RecordFrame()
  105. {
  106. try
  107. {
  108. recorder.SignalInputsOfStage(ERecordingSessionStage.NewFrameReady, this);
  109. if (!recorder.SkipFrame(this))
  110. {
  111. recorder.RecordFrame(this);
  112. recorder.RecordedFramesCount++;
  113. if (recorder.RecordedFramesCount == 1)
  114. m_FirstRecordedFrameCount = Time.renderedFrameCount;
  115. }
  116. recorder.SignalInputsOfStage(ERecordingSessionStage.FrameDone, this);
  117. }
  118. catch (Exception ex)
  119. {
  120. Debug.LogException(ex);
  121. }
  122. // Note: This is not great when multiple recorders are simultaneously active...
  123. if (settings.FrameRatePlayback == FrameRatePlayback.Variable ||
  124. settings.FrameRatePlayback == FrameRatePlayback.Constant && recorder.settings.CapFrameRate)
  125. {
  126. var frameCount = Time.renderedFrameCount - m_InitialFrame;
  127. var frameLen = 1.0f / recorder.settings.FrameRate;
  128. var elapsed = Time.unscaledTime - m_FPSTimeStart;
  129. var target = frameLen * (frameCount + 1);
  130. var sleep = (int)((target - elapsed) * 1000);
  131. if (sleep > 2)
  132. {
  133. if (RecorderOptions.VerboseMode)
  134. Debug.Log(string.Format("Recording session info => dT: {0:F1}s, Target dT: {1:F1}s, Retarding: {2}ms, fps: {3:F1}", elapsed, target, sleep, frameCount / elapsed));
  135. System.Threading.Thread.Sleep(Math.Min(sleep, 1000));
  136. }
  137. else if (sleep < -frameLen)
  138. m_InitialFrame--;
  139. else if (RecorderOptions.VerboseMode)
  140. Debug.Log(string.Format("Recording session info => fps: {0:F1}", frameCount / elapsed));
  141. // reset every 30 frames
  142. if (frameCount % 50 == 49)
  143. {
  144. m_FPSNextTimeStart = Time.unscaledTime;
  145. m_FPSNextFrameCount = Time.renderedFrameCount;
  146. }
  147. if (frameCount % 100 == 99)
  148. {
  149. m_FPSTimeStart = m_FPSNextTimeStart;
  150. m_InitialFrame = m_FPSNextFrameCount;
  151. }
  152. }
  153. m_FrameIndex++;
  154. }
  155. internal void PrepareNewFrame()
  156. {
  157. try
  158. {
  159. AllowInBackgroundMode();
  160. currentFrameStartTS = (Time.time / (Mathf.Approximately(Time.timeScale, 0f) ? 1f : Time.timeScale)) - recordingStartTS;
  161. recorder.SignalInputsOfStage(ERecordingSessionStage.NewFrameStarting, this);
  162. recorder.PrepareNewFrame(this);
  163. prepareFrameCalled = true;
  164. }
  165. catch (Exception ex)
  166. {
  167. Debug.LogException(ex);
  168. }
  169. }
  170. public void Dispose()
  171. {
  172. if (recorder != null)
  173. {
  174. EndRecording();
  175. UnityHelpers.Destroy(recorder);
  176. }
  177. }
  178. }
  179. }