SequenceBatchRenderDialog.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. // Description : A dialog for batch-rendering sequences
  9. #pragma once
  10. #include "AtomOutputFrameCapture.h"
  11. #include <AzFramework/StringFunc/StringFunc.h>
  12. #include <QDialog>
  13. #include <QFutureWatcher>
  14. #include <QTimer>
  15. #include <QValidator>
  16. #include <AzCore/std/containers/vector.h>
  17. class QStringListModel;
  18. namespace Ui
  19. {
  20. class SequenceBatchRenderDialog;
  21. }
  22. class CSequenceBatchRenderDialog
  23. : public QDialog
  24. , public IMovieListener
  25. {
  26. public:
  27. CSequenceBatchRenderDialog(float fps, QWidget* pParent = nullptr);
  28. virtual ~CSequenceBatchRenderDialog();
  29. void reject() override; // overriding so Qt doesn't cancel
  30. protected:
  31. void OnInitDialog();
  32. void OnAddRenderItem();
  33. void OnRemoveRenderItem();
  34. void OnClearRenderItems();
  35. void OnUpdateRenderItem();
  36. void OnLoadPreset();
  37. void OnSavePreset();
  38. void OnGo();
  39. void OnDone();
  40. void OnSequenceSelected();
  41. void OnRenderItemSelChange();
  42. void OnFPSEditChange();
  43. void OnDirectorChange(int itemIndex);
  44. void OnFPSChange(int itemIndex);
  45. void OnImageFormatChange();
  46. void OnResolutionSelected();
  47. void OnStartFrameChange();
  48. void OnEndFrameChange();
  49. void OnLoadBatch();
  50. void OnSaveBatch();
  51. void OnKickIdle();
  52. void OnCancelRender();
  53. void OnVarsChange();
  54. void OnFormatChange();
  55. void OnPrefixChange();
  56. void OnDisableDebugInfoChange();
  57. void OnCreateVideoChange();
  58. void SaveOutputOptions(const QString& pathname) const;
  59. bool LoadOutputOptions(const QString& pathname);
  60. QString m_ffmpegPluginStatusMsg;
  61. bool m_bFFMPEGCommandAvailable;
  62. float m_fpsForTimeToFrameConversion; // FPS setting in TrackView
  63. struct SRenderItem
  64. {
  65. IAnimSequence* pSequence;
  66. IAnimNode* pDirectorNode;
  67. Range frameRange;
  68. int resW, resH;
  69. int fps;
  70. QString seqName;
  71. QString folder;
  72. QString imageFormat;
  73. QString prefix;
  74. QStringList cvars;
  75. bool disableDebugInfo;
  76. bool bCreateVideo;
  77. SRenderItem()
  78. : pSequence(nullptr)
  79. , pDirectorNode(nullptr)
  80. , disableDebugInfo(false)
  81. , bCreateVideo(false) {}
  82. bool operator==(const SRenderItem& item) const
  83. {
  84. if (pSequence == item.pSequence
  85. && pDirectorNode == item.pDirectorNode
  86. && frameRange == item.frameRange
  87. && resW == item.resW
  88. && resH == item.resH
  89. && fps == item.fps
  90. && seqName == item.seqName
  91. && folder == item.folder
  92. && prefix == item.prefix
  93. && cvars == item.cvars
  94. && disableDebugInfo == item.disableDebugInfo
  95. && bCreateVideo == item.bCreateVideo
  96. && imageFormat == item.imageFormat)
  97. {
  98. return true;
  99. }
  100. return false;
  101. }
  102. };
  103. AZStd::vector<SRenderItem> m_renderItems;
  104. // Capture States
  105. enum class CaptureState
  106. {
  107. Idle,
  108. WarmingUpAfterResChange,
  109. EnteringGameMode,
  110. BeginPlayingSequence,
  111. Capturing,
  112. End,
  113. FFMPEGProcessing,
  114. Finalize
  115. };
  116. struct SRenderContext
  117. {
  118. int currentItemIndex = -1;
  119. float expectedTotalTime{};
  120. float spentTime{};
  121. int flagBU{};
  122. Range rangeBU;
  123. int cvarDisplayInfoBU{};
  124. int framesSpentInCurrentPhase{};
  125. IAnimNode* pActiveDirectorBU{};
  126. ICaptureKey captureOptions{};
  127. bool processingFFMPEG{};
  128. // Signals when an mpeg is finished being processed.
  129. QFutureWatcher<void> processingFFMPEGWatcher;
  130. // True if the user canceled a render.
  131. bool canceled{};
  132. // The sequence that triggered the CaptureState::Ending.
  133. IAnimSequence* endingSequence{};
  134. // Current capture state.
  135. CaptureState captureState = CaptureState::Idle;
  136. // Is an individual frame currently being captured.
  137. bool capturingFrame{};
  138. // Current frame being captured
  139. int frameNumber{};
  140. bool IsInRendering() const { return currentItemIndex >= 0; }
  141. SRenderContext() = default;
  142. };
  143. SRenderContext m_renderContext;
  144. // Custom validator to make sure the prefix is a valid part of a filename.
  145. class CPrefixValidator : public QValidator
  146. {
  147. public:
  148. CPrefixValidator(QObject* parent) : QValidator(parent) {}
  149. QValidator::State validate(QString& input, [[maybe_unused]] int& pos) const override
  150. {
  151. bool valid = input.isEmpty() || AzFramework::StringFunc::Path::IsValid(input.toUtf8().data());
  152. return valid ? QValidator::State::Acceptable : QValidator::State::Invalid;
  153. }
  154. };
  155. // Custom values from resolution/FPS combo boxes
  156. int m_customResW, m_customResH;
  157. int m_customFPS;
  158. void InitializeContext();
  159. void OnMovieEvent(IMovieListener::EMovieEvent event, IAnimSequence* pSequence) override;
  160. void CaptureItemStart();
  161. // Capture State Updates
  162. void OnUpdateWarmingUpAfterResChange();
  163. void OnUpdateEnteringGameMode();
  164. void OnUpdateBeginPlayingSequence();
  165. void OnUpdateCapturing();
  166. void OnUpdateEnd(IAnimSequence* pSequence);
  167. void OnUpdateFFMPEGProcessing();
  168. void OnUpdateFinalize();
  169. bool SetUpNewRenderItem(SRenderItem& item);
  170. void AddItem(const SRenderItem& item);
  171. QString GetCaptureItemString(const SRenderItem& item) const;
  172. protected slots:
  173. void OnKickIdleTimout();
  174. bool GetResolutionFromCustomResText(const char* customResText, int& retCustomWidth, int& retCustomHeight) const;
  175. private:
  176. void CheckForEnableUpdateButton();
  177. void StashActiveViewportResolution();
  178. void UpdateSpinnerProgressMessage(const char* description);
  179. void EnterCaptureState(CaptureState captureState);
  180. void SetEnableEditorIdleProcessing(bool enabled);
  181. void UpdateAtomOutputFrameCaptureView(const int width, const int height);
  182. QScopedPointer<Ui::SequenceBatchRenderDialog> m_ui;
  183. QStringListModel* m_renderListModel;
  184. QTimer m_renderTimer;
  185. bool m_editorIdleProcessingEnabled;
  186. int32 CV_TrackViewRenderOutputCapturing;
  187. QScopedPointer<CPrefixValidator> m_prefixValidator;
  188. TrackView::AtomOutputFrameCapture m_atomOutputFrameCapture;
  189. };