MediaPlayerEditor_Debug.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. using UnityEngine;
  2. using UnityEditor;
  3. //-----------------------------------------------------------------------------
  4. // Copyright 2015-2021 RenderHeads Ltd. All rights reserved.
  5. //-----------------------------------------------------------------------------
  6. namespace RenderHeads.Media.AVProVideo.Editor
  7. {
  8. /// <summary>
  9. /// Editor for the MediaPlayer component
  10. /// </summary>
  11. public partial class MediaPlayerEditor : UnityEditor.Editor
  12. {
  13. private static bool _allowDeveloperMode = false;
  14. private static bool _showUltraOptions = true;
  15. private AnimCollapseSection _sectionDevModeState;
  16. private AnimCollapseSection _sectionDevModeTexture;
  17. private AnimCollapseSection _sectionDevModeHapNotchLCDecoder;
  18. private AnimCollapseSection _sectionDevModeBufferedFrames;
  19. private AnimCollapseSection _sectionDevModePlaybackQuality;
  20. private static readonly GUIContent _guiTextMetaData = new GUIContent("MetaData");
  21. private static readonly GUIContent _guiTextPaused = new GUIContent("Paused");
  22. private static readonly GUIContent _guiTextPlaying = new GUIContent("Playing");
  23. private static readonly GUIContent _guiTextSeeking = new GUIContent("Seeking");
  24. private static readonly GUIContent _guiTextBuffering = new GUIContent("Buffering");
  25. private static readonly GUIContent _guiTextStalled = new GUIContent("Stalled");
  26. private static readonly GUIContent _guiTextFinished = new GUIContent("Finished");
  27. private static readonly GUIContent _guiTextTimeColon= new GUIContent("Time: ");
  28. private static readonly GUIContent _guiTextFrameColon = new GUIContent("Frame: ");
  29. private static readonly GUIContent _guiTextFrameDec = new GUIContent("<");
  30. private static readonly GUIContent _guiTextFrameInc = new GUIContent(">");
  31. private static readonly GUIContent _guiTextSelectTexture = new GUIContent("Select Texture");
  32. private static readonly GUIContent _guiTextSaveFramePNG = new GUIContent("Save Frame PNG");
  33. private static readonly GUIContent _guiTextSaveFrameEXR = new GUIContent("Save Frame EXR");
  34. private static readonly GUIContent _guiTextDecodeStats = new GUIContent("Decode Stats");
  35. private static readonly GUIContent _guiTextParallelFrames = new GUIContent("Parallel Frames");
  36. private static readonly GUIContent _guiTextDecodedFrames = new GUIContent("Decoded Frames");
  37. private static readonly GUIContent _guiTextDroppedFrames = new GUIContent("Dropped Frames");
  38. private static readonly GUIContent _guiTextBufferedFrames = new GUIContent("Buffered Frames");
  39. private static readonly GUIContent _guiTextFreeFrames = new GUIContent("Free Frames");
  40. //private static readonly GUIContent _guiTextDisplayTimestamp = new GUIContent("Display Timstamp");
  41. //private static readonly GUIContent _guiTextMinTimestamp = new GUIContent("Min Timstamp");
  42. //private static readonly GUIContent _guiTextMaxTimestamp = new GUIContent("Max Timstamp");
  43. private static readonly GUIContent _guiTextFlush = new GUIContent("Flush");
  44. private static readonly GUIContent _guiTextReset = new GUIContent("Reset");
  45. private void OnInspectorGUI_DevMode_State()
  46. {
  47. MediaPlayer mediaPlayer = (this.target) as MediaPlayer;
  48. if (mediaPlayer.Control != null)
  49. {
  50. // State
  51. GUIStyle style = GUI.skin.button;
  52. using (HorizontalFlowScope flow = new HorizontalFlowScope(Screen.width))
  53. {
  54. flow.AddItem(_guiTextMetaData, style);
  55. GUI.color = mediaPlayer.Control.HasMetaData() ? Color.green : Color.white;
  56. GUILayout.Toggle(true, _guiTextMetaData, style);
  57. flow.AddItem(_guiTextPaused, style);
  58. GUI.color = mediaPlayer.Control.IsPaused() ? Color.green : Color.white;
  59. GUILayout.Toggle(true, _guiTextPaused, style);
  60. flow.AddItem(_guiTextPlaying, style);
  61. GUI.color = mediaPlayer.Control.IsPlaying() ? Color.green : Color.white;
  62. GUILayout.Toggle(true, _guiTextPlaying, style);
  63. flow.AddItem(_guiTextSeeking, style);
  64. GUI.color = mediaPlayer.Control.IsSeeking() ? Color.green : Color.white;
  65. GUILayout.Toggle(true, _guiTextSeeking, style);
  66. flow.AddItem(_guiTextBuffering, style);
  67. GUI.color = mediaPlayer.Control.IsBuffering() ? Color.green : Color.white;
  68. GUILayout.Toggle(true, _guiTextBuffering, style);
  69. flow.AddItem(_guiTextStalled, style);
  70. GUI.color = mediaPlayer.Info.IsPlaybackStalled() ? Color.green : Color.white;
  71. GUILayout.Toggle(true, _guiTextStalled, style);
  72. flow.AddItem(_guiTextFinished, style);
  73. GUI.color = mediaPlayer.Control.IsFinished() ? Color.green : Color.white;
  74. GUILayout.Toggle(true, _guiTextFinished, style);
  75. }
  76. GUI.color = Color.white;
  77. // Time, FPS, Frame stepping
  78. GUILayout.BeginHorizontal();
  79. GUILayout.Label(_guiTextTimeColon);
  80. GUILayout.Label(mediaPlayer.Control.GetCurrentTime().ToString());
  81. GUILayout.FlexibleSpace();
  82. GUILayout.Label(_guiTextFrameColon);
  83. GUILayout.Label(mediaPlayer.Control.GetCurrentTimeFrames().ToString());
  84. EditorGUI.BeginDisabledGroup(mediaPlayer.Info.GetVideoFrameRate() <= 0f);
  85. if (GUILayout.Button(_guiTextFrameDec))
  86. {
  87. mediaPlayer.Control.SeekToFrameRelative(-1);
  88. }
  89. if (GUILayout.Button(_guiTextFrameInc))
  90. {
  91. mediaPlayer.Control.SeekToFrameRelative(1);
  92. }
  93. EditorGUI.EndDisabledGroup();
  94. GUILayout.EndHorizontal();
  95. }
  96. }
  97. private void OnInspectorGUI_DevMode_Texture()
  98. {
  99. MediaPlayer mediaPlayer = (this.target) as MediaPlayer;
  100. if (mediaPlayer.Control != null)
  101. {
  102. // Raw texture preview
  103. if (mediaPlayer.TextureProducer != null)
  104. {
  105. GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
  106. GUILayout.FlexibleSpace();
  107. for (int i = 0; i < mediaPlayer.TextureProducer.GetTextureCount(); i++)
  108. {
  109. Texture texture = mediaPlayer.TextureProducer.GetTexture(i);
  110. if (texture != null)
  111. {
  112. GUILayout.BeginVertical();
  113. Rect textureRect = GUILayoutUtility.GetRect(128f, 128f);
  114. if (Event.current.type == EventType.Repaint)
  115. {
  116. GUI.color = Color.gray;
  117. EditorGUI.DrawTextureTransparent(textureRect, Texture2D.blackTexture, ScaleMode.StretchToFill);
  118. GUI.color = Color.white;
  119. }
  120. GUI.DrawTexture(textureRect, texture, ScaleMode.ScaleToFit, false);
  121. GUILayout.Label(texture.width + "x" + texture.height + " ");
  122. if (GUILayout.Button(_guiTextSelectTexture, GUILayout.ExpandWidth(false)))
  123. {
  124. Selection.activeObject = texture;
  125. }
  126. GUILayout.EndVertical();
  127. }
  128. }
  129. GUILayout.FlexibleSpace();
  130. GUILayout.EndHorizontal();
  131. GUILayout.Label("Updates: " + mediaPlayer.TextureProducer.GetTextureFrameCount());
  132. GUILayout.Label("TimeStamp: " + mediaPlayer.TextureProducer.GetTextureTimeStamp());
  133. GUILayout.BeginHorizontal();
  134. if (GUILayout.Button(_guiTextSaveFramePNG, GUILayout.ExpandWidth(true)))
  135. {
  136. mediaPlayer.SaveFrameToPng();
  137. }
  138. if (GUILayout.Button(_guiTextSaveFrameEXR, GUILayout.ExpandWidth(true)))
  139. {
  140. mediaPlayer.SaveFrameToExr();
  141. }
  142. GUILayout.EndHorizontal();
  143. }
  144. }
  145. }
  146. private void OnInspectorGUI_DevMode_HapNotchLCDecoder()
  147. {
  148. MediaPlayer mediaPlayer = (this.target) as MediaPlayer;
  149. if (mediaPlayer.Info != null)
  150. {
  151. int activeDecodeThreadCount = 0;
  152. int decodedFrameCount = 0;
  153. int droppedFrameCount = 0;
  154. if (mediaPlayer.Info.GetDecoderPerformance(ref activeDecodeThreadCount, ref decodedFrameCount, ref droppedFrameCount))
  155. {
  156. GUILayout.Label(_guiTextDecodeStats);
  157. EditorGUI.indentLevel++;
  158. EditorGUILayout.Slider(_guiTextParallelFrames, activeDecodeThreadCount, 0f, mediaPlayer.PlatformOptionsWindows.parallelFrameCount);
  159. EditorGUILayout.Slider(_guiTextDecodedFrames, decodedFrameCount, 0f, mediaPlayer.PlatformOptionsWindows.prerollFrameCount * 2);
  160. EditorGUILayout.IntField(_guiTextDroppedFrames, droppedFrameCount);
  161. EditorGUI.indentLevel--;
  162. }
  163. }
  164. }
  165. private float _lastBufferedFrameCount;
  166. private float _lastFreeFrameCount;
  167. private void OnInspectorGUI_DevMode_BufferedFrames()
  168. {
  169. MediaPlayer mediaPlayer = (this.target) as MediaPlayer;
  170. if (mediaPlayer.Control != null)
  171. {
  172. IBufferedDisplay bufferedDisplay = mediaPlayer.BufferedDisplay;
  173. if (bufferedDisplay != null)
  174. {
  175. BufferedFramesState state = bufferedDisplay.GetBufferedFramesState();
  176. GUILayout.BeginHorizontal();
  177. EditorGUILayout.PrefixLabel(_guiTextBufferedFrames);
  178. Rect progressRect = EditorGUILayout.GetControlRect(false, EditorGUIUtility.singleLineHeight);
  179. EditorGUI.ProgressBar(progressRect, _lastBufferedFrameCount, state.bufferedFrameCount.ToString());
  180. GUILayout.EndHorizontal();
  181. GUILayout.BeginHorizontal();
  182. EditorGUILayout.PrefixLabel(_guiTextFreeFrames);
  183. progressRect = EditorGUILayout.GetControlRect(false, EditorGUIUtility.singleLineHeight);
  184. EditorGUI.ProgressBar(progressRect, _lastFreeFrameCount, state.freeFrameCount.ToString());
  185. GUILayout.EndHorizontal();
  186. _lastBufferedFrameCount = Mathf.MoveTowards(_lastBufferedFrameCount, state.bufferedFrameCount / 12f, Time.deltaTime);
  187. _lastFreeFrameCount = Mathf.MoveTowards(_lastFreeFrameCount, state.freeFrameCount / 12f, Time.deltaTime);
  188. //EditorGUILayout.LabelField(_guiTextDisplayTimestamp, new GUIContent(mediaPlayer.TextureProducer.GetTextureTimeStamp().ToString() + " " + (mediaPlayer.TextureProducer.GetTextureTimeStamp() / Helper.SecondsToHNS).ToString() + "s"));
  189. //EditorGUILayout.LabelField(_guiTextMinTimestamp, new GUIContent(state.minTimeStamp.ToString() + " " + (state.minTimeStamp / Helper.SecondsToHNS).ToString() + "s"));
  190. //EditorGUILayout.LabelField(_guiTextMaxTimestamp, new GUIContent(state.maxTimeStamp.ToString() + " " + (state.maxTimeStamp / Helper.SecondsToHNS).ToString() + "s"));
  191. if (GUILayout.Button(_guiTextFlush))
  192. {
  193. // Seek causes a flush
  194. mediaPlayer.Control.Seek(mediaPlayer.Control.GetCurrentTime());
  195. }
  196. }
  197. }
  198. }
  199. private void OnInspectorGUI_DevMode_PresentationQuality()
  200. {
  201. MediaPlayer mediaPlayer = (this.target) as MediaPlayer;
  202. if (mediaPlayer.Info != null)
  203. {
  204. PlaybackQualityStats stats = mediaPlayer.Info.GetPlaybackQualityStats();
  205. //stats.LogIssues = true;
  206. stats.LogIssues = EditorGUILayout.Toggle("Log Issues", stats.LogIssues);
  207. GUILayout.Label("Video", EditorStyles.boldLabel);
  208. EditorGUI.indentLevel++;
  209. EditorGUILayout.LabelField("Skipped Frames", stats.SkippedFrames.ToString());
  210. GUILayout.BeginHorizontal();
  211. EditorGUILayout.LabelField("Duplicate Frames", stats.DuplicateFrames.ToString());
  212. GUILayout.Label(stats.VSyncStatus);
  213. GUILayout.EndHorizontal();
  214. EditorGUILayout.LabelField("Perfect Frames", (stats.PerfectFramesT * 100f).ToString("F2") + "%");
  215. EditorGUI.indentLevel--;
  216. GUILayout.Label("Unity", EditorStyles.boldLabel);
  217. EditorGUI.indentLevel++;
  218. EditorGUILayout.LabelField("Dropped Frames", stats.UnityDroppedFrames.ToString());
  219. EditorGUI.indentLevel--;
  220. if (GUILayout.Button(_guiTextReset))
  221. {
  222. stats.Reset();
  223. }
  224. }
  225. }
  226. private void OnInspectorGUI_Debug()
  227. {
  228. MediaPlayer mediaPlayer = (this.target) as MediaPlayer;
  229. IMediaInfo info = mediaPlayer.Info;
  230. if (info != null)
  231. {
  232. AnimCollapseSection.Show(_sectionDevModeState);
  233. AnimCollapseSection.Show(_sectionDevModeTexture);
  234. AnimCollapseSection.Show(_sectionDevModePlaybackQuality);
  235. }
  236. if (info != null)
  237. {
  238. #if UNITY_EDITOR_WIN
  239. if (mediaPlayer.PlatformOptionsWindows.useHapNotchLC)
  240. {
  241. AnimCollapseSection.Show(_sectionDevModeHapNotchLCDecoder);
  242. }
  243. if (mediaPlayer.PlatformOptionsWindows.bufferedFrameSelection != BufferedFrameSelectionMode.None)
  244. {
  245. AnimCollapseSection.Show(_sectionDevModeBufferedFrames);
  246. }
  247. #endif
  248. }
  249. else
  250. {
  251. GUILayout.Label("No media loaded");
  252. }
  253. }
  254. }
  255. }