PostProcessor.hh 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. #ifndef POSTPROCESSOR_HH
  2. #define POSTPROCESSOR_HH
  3. #include "VideoLayer.hh"
  4. #include "Schedulable.hh"
  5. #include "EmuTime.hh"
  6. #include <memory>
  7. namespace openmsx {
  8. class AviRecorder;
  9. class CliComm;
  10. class Deflicker;
  11. class DeinterlacedFrame;
  12. class Display;
  13. class DoubledFrame;
  14. class EventDistributor;
  15. class FrameSource;
  16. class RawFrame;
  17. class RenderSettings;
  18. class SuperImposedFrame;
  19. /** Abstract base class for post processors.
  20. * A post processor builds the frame that is displayed from the MSX frame,
  21. * while applying effects such as scalers, noise etc.
  22. * TODO: With some refactoring, it would be possible to move much or even all
  23. * of the post processing code here instead of in the subclasses.
  24. */
  25. class PostProcessor : public VideoLayer, private Schedulable
  26. {
  27. public:
  28. ~PostProcessor() override;
  29. /** Sets up the "abcdFrame" variables for a new frame.
  30. * TODO: The point of passing the finished frame in and the new workFrame
  31. * out is to be able to split off the scaler application as a
  32. * separate class.
  33. * @param finishedFrame Frame that has just become available.
  34. * @param time The moment in time the frame becomes available. Used to
  35. * calculate the framerate for recording (depends on
  36. * PAL/NTSC, frameskip).
  37. * @return RawFrame object that can be used for building the next frame.
  38. */
  39. virtual std::unique_ptr<RawFrame> rotateFrames(
  40. std::unique_ptr<RawFrame> finishedFrame, EmuTime::param time);
  41. /** Set the Video frame on which to superimpose the 'normal' output of
  42. * this PostProcessor. Superimpose is done (preferably) after the
  43. * normal output is scaled. IOW the video frame is (preferably) left
  44. * unchanged, though exceptions are e.g. scalers that render
  45. * scanlines, those are preferably also visible in the video frame.
  46. */
  47. void setSuperimposeVideoFrame(const RawFrame* videoSource) {
  48. superImposeVideoFrame = videoSource;
  49. }
  50. /** Set the VDP frame on which to superimpose the 'normal' output of
  51. * this PostProcessor. This is similar to the method above, except
  52. * that now the superimposing is done before scaling. IOW both frames
  53. * get scaled.
  54. */
  55. void setSuperimposeVdpFrame(const FrameSource* vdpSource) {
  56. superImposeVdpFrame = vdpSource;
  57. }
  58. /** Start/stop recording.
  59. * @param recorder_ Finished frames should be pushed to this
  60. * AviRecorder. Can also be nullptr, meaning
  61. * recording is stopped.
  62. */
  63. void setRecorder(AviRecorder* recorder_) { recorder = recorder_; }
  64. /** Is recording active.
  65. * ATM used to keep frameskip constant during recording.
  66. */
  67. bool isRecording() const { return recorder != nullptr; }
  68. /** Get the number of bits per pixel for the pixels in these frames.
  69. * @return Possible values are 15, 16 or 32
  70. */
  71. unsigned getBpp() const;
  72. /** Get the frame that would be displayed. E.g. so that it can be
  73. * superimposed over the output of another PostProcessor, see
  74. * setSuperimposeVdpFrame().
  75. */
  76. FrameSource* getPaintFrame() const { return paintFrame; }
  77. // VideoLayer
  78. void takeRawScreenShot(unsigned height, const std::string& filename) override;
  79. CliComm& getCliComm();
  80. protected:
  81. /** Returns the maximum width for lines [y..y+step).
  82. */
  83. static unsigned getLineWidth(FrameSource* frame, unsigned y, unsigned step);
  84. PostProcessor(
  85. MSXMotherBoard& motherBoard, Display& display,
  86. OutputSurface& screen, const std::string& videoSource,
  87. unsigned maxWidth, unsigned height, bool canDoInterlace);
  88. /** Render settings */
  89. RenderSettings& renderSettings;
  90. /** The surface which is visible to the user. */
  91. OutputSurface& screen;
  92. /** The last 4 fully rendered (unscaled) MSX frames. */
  93. std::unique_ptr<RawFrame> lastFrames[4];
  94. /** Combined the last two frames in a deinterlaced frame. */
  95. std::unique_ptr<DeinterlacedFrame> deinterlacedFrame;
  96. /** Each line of the last frame twice, to get double vertical resolution. */
  97. std::unique_ptr<DoubledFrame> interlacedFrame;
  98. /** Combine the last 4 frames into one 'flicker-free' frame. */
  99. std::unique_ptr<Deflicker> deflicker;
  100. /** Result of superimposing 2 frames. */
  101. std::unique_ptr<SuperImposedFrame> superImposedFrame;
  102. /** Represents a frame as it should be displayed.
  103. * This can be simply a RawFrame or two RawFrames combined in a
  104. * DeinterlacedFrame or DoubledFrame.
  105. */
  106. FrameSource* paintFrame;
  107. /** Video recorder, nullptr when not recording. */
  108. AviRecorder* recorder;
  109. /** Video frame on which to superimpose the (VDP) output.
  110. * nullptr when not superimposing. */
  111. const RawFrame* superImposeVideoFrame;
  112. const FrameSource* superImposeVdpFrame;
  113. int interleaveCount; // for interleave-black-frame
  114. int lastFramesCount; // How many items in lastFrames[] are up-to-date
  115. int maxWidth; // we lazily create RawFrame objects in lastFrames[]
  116. int height; // these two vars remember how big those should be
  117. private:
  118. // Schedulable
  119. void executeUntil(EmuTime::param time) override;
  120. Display& display;
  121. /** Laserdisc cannot do interlace (better: the current implementation
  122. * is not interlaced). In that case some internal stuff can be done
  123. * with less buffers.
  124. */
  125. const bool canDoInterlace;
  126. EmuTime lastRotate;
  127. EventDistributor& eventDistributor;
  128. };
  129. } // namespace openmsx
  130. #endif // POSTPROCESSOR_HH