SequenceBatchRenderDialog.h 6.4 KB

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