307 lines
10 KiB
C++
307 lines
10 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "CoreTypes.h"
|
|
#include "MovieSceneCaptureProtocolBase.h"
|
|
#include "FrameGrabber.h"
|
|
#include "ImageWriteStream.h"
|
|
#include "UserDefinedCaptureProtocol.generated.h"
|
|
|
|
enum class EDesiredImageFormat : uint8;
|
|
struct FImagePixelData;
|
|
struct FImageWriteOptions;
|
|
struct ICaptureProtocolHost;
|
|
class UTexture;
|
|
|
|
/** Structure used as an identifier for a particular buffer within a capture. */
|
|
USTRUCT(BlueprintType)
|
|
struct FCapturedPixelsID
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
/** Convert this strream ID to a string */
|
|
FString ToString() const;
|
|
|
|
/** Map of identifiers to their values for this ID. */
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Capture)
|
|
TMap<FName, FName> Identifiers;
|
|
};
|
|
|
|
|
|
|
|
USTRUCT(BlueprintType)
|
|
struct FCapturedPixels
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
TSharedPtr<FImagePixelData, ESPMode::ThreadSafe> ImageData;
|
|
};
|
|
|
|
/**
|
|
* A blueprintable capture protocol that defines how to capture frames from the engine
|
|
*/
|
|
UCLASS(Abstract, Blueprintable, meta=(DisplayName="Capture Protocol"), MinimalAPI)
|
|
class UUserDefinedCaptureProtocol
|
|
: public UMovieSceneImageCaptureProtocolBase
|
|
{
|
|
public:
|
|
|
|
GENERATED_BODY()
|
|
|
|
MOVIESCENECAPTURE_API UUserDefinedCaptureProtocol(const FObjectInitializer& ObjInit);
|
|
|
|
protected:
|
|
|
|
/**
|
|
* Called before the capture process itself is ticked, before each frame is set up for capture
|
|
* Useful for any pre-frame set up or resetting the previous frame's state
|
|
*/
|
|
UFUNCTION(BlueprintImplementableEvent, Category=Capture)
|
|
MOVIESCENECAPTURE_API void OnPreTick();
|
|
|
|
/**
|
|
* Called after the capture process itself is ticked, after the frame is set up for capture, but before most actors have ticked
|
|
*/
|
|
UFUNCTION(BlueprintImplementableEvent, Category=Capture)
|
|
MOVIESCENECAPTURE_API void OnTick();
|
|
|
|
/**
|
|
* Called once at the start of the capture process, but before any warmup frames
|
|
* @return true if this protocol set up successfully, false otherwise
|
|
*/
|
|
UFUNCTION(BlueprintNativeEvent, Category=Capture)
|
|
MOVIESCENECAPTURE_API bool OnSetup();
|
|
virtual bool OnSetup_Implementation() { return true; }
|
|
|
|
/**
|
|
* Called when the capture process is warming up. Protocols may transition from either an initialized, or capturing state to warm-up
|
|
*/
|
|
UFUNCTION(BlueprintImplementableEvent, Category=Capture)
|
|
MOVIESCENECAPTURE_API void OnWarmUp();
|
|
|
|
/**
|
|
* Called when this protocol should start capturing frames
|
|
*/
|
|
UFUNCTION(BlueprintImplementableEvent, Category=Capture)
|
|
MOVIESCENECAPTURE_API void OnStartCapture();
|
|
|
|
/**
|
|
* Called when this protocol should capture the current frame
|
|
*/
|
|
UFUNCTION(BlueprintImplementableEvent, Category=Capture)
|
|
MOVIESCENECAPTURE_API void OnCaptureFrame();
|
|
|
|
/**
|
|
* Called when this protocol should temporarily stop capturing frames
|
|
*/
|
|
UFUNCTION(BlueprintImplementableEvent, Category=Capture)
|
|
MOVIESCENECAPTURE_API void OnPauseCapture();
|
|
|
|
/**
|
|
* Called when this protocol is going to be shut down - should not capture any more frames
|
|
*/
|
|
UFUNCTION(BlueprintImplementableEvent, Category=Capture)
|
|
MOVIESCENECAPTURE_API void OnBeginFinalize();
|
|
|
|
|
|
/**
|
|
* Called to check whether this protocol has finished any pending tasks, and can now be shut down
|
|
*/
|
|
UFUNCTION(BlueprintNativeEvent, Category=Capture)
|
|
MOVIESCENECAPTURE_API bool OnCanFinalize() const;
|
|
virtual bool OnCanFinalize_Implementation() const { return true; }
|
|
|
|
|
|
/**
|
|
* Called to complete finalization of this protocol
|
|
*/
|
|
UFUNCTION(BlueprintImplementableEvent, Category=Capture)
|
|
MOVIESCENECAPTURE_API void OnFinalize();
|
|
|
|
|
|
/**
|
|
* Called when pixels have been received for the specified stream name
|
|
*/
|
|
UFUNCTION(BlueprintImplementableEvent, Category=Capture)
|
|
MOVIESCENECAPTURE_API void OnPixelsReceived(const FCapturedPixels& Pixels, const FCapturedPixelsID& ID, FFrameMetrics FrameMetrics);
|
|
|
|
|
|
public:
|
|
|
|
/*
|
|
* Resolve the specified buffer and pass it directly to the specified handler when done (does not pass to any bound streams)
|
|
*
|
|
* @param Buffer The desired buffer to save
|
|
* @param BufferID The ID of this buffer that is passed to the pixel handler (e.g. a composition pass name).
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category=Capture)
|
|
MOVIESCENECAPTURE_API void ResolveBuffer(UTexture* Buffer, const FCapturedPixelsID& BufferID);
|
|
|
|
|
|
/**
|
|
* Instruct this protocol to start capturing LDR final pixels (including slate widgets and burn-ins)
|
|
*
|
|
* @param StreamID The identifier to use for the final pixels buffer
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category=Capture)
|
|
MOVIESCENECAPTURE_API void StartCapturingFinalPixels(const FCapturedPixelsID& StreamID);
|
|
|
|
|
|
/**
|
|
* Instruct this protocol to stop capturing LDR final pixels
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category=Capture)
|
|
MOVIESCENECAPTURE_API void StopCapturingFinalPixels();
|
|
|
|
|
|
/**
|
|
* Generate a filename for the current frame
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category=Capture)
|
|
MOVIESCENECAPTURE_API virtual FString GenerateFilename(const FFrameMetrics& InFrameMetrics) const;
|
|
|
|
|
|
/**
|
|
* Access this protocol's current frame metrics
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category=Capture)
|
|
FFrameMetrics GetCurrentFrameMetrics() const
|
|
{
|
|
return CachedFrameMetrics;
|
|
}
|
|
|
|
public:
|
|
|
|
/**
|
|
* Called when image pixel data is ready to be processed
|
|
*/
|
|
MOVIESCENECAPTURE_API void OnPixelsReceivedImpl(const FCapturedPixels& Pixels, const FCapturedPixelsID& StreamID, FFrameMetrics FrameMetrics);
|
|
|
|
/**
|
|
* INTERNAL: Report that the protocol is dispatching the specified number of asynchronous tasks that need to be completed
|
|
* before this protocol can be finalized
|
|
*/
|
|
MOVIESCENECAPTURE_API void ReportOutstandingWork(int32 NumNewOperations);
|
|
|
|
protected:
|
|
|
|
/**~ Begin UMovieSceneCaptureProtocolBase implementation */
|
|
MOVIESCENECAPTURE_API virtual void PreTickImpl() override;
|
|
MOVIESCENECAPTURE_API virtual void TickImpl() override;
|
|
MOVIESCENECAPTURE_API virtual bool SetupImpl() override;
|
|
MOVIESCENECAPTURE_API virtual void WarmUpImpl() override;
|
|
MOVIESCENECAPTURE_API virtual bool StartCaptureImpl() override;
|
|
MOVIESCENECAPTURE_API virtual void CaptureFrameImpl(const FFrameMetrics& FrameMetrics) override;
|
|
MOVIESCENECAPTURE_API virtual void BeginFinalizeImpl() override;
|
|
MOVIESCENECAPTURE_API virtual bool HasFinishedProcessingImpl() const override;
|
|
MOVIESCENECAPTURE_API virtual void FinalizeImpl() override;
|
|
MOVIESCENECAPTURE_API virtual void AddFormatMappingsImpl(TMap<FString, FStringFormatArg>& FormatMappings) const override;
|
|
/**~ End UMovieSceneCaptureProtocolBase implementation */
|
|
|
|
/**~ Begin UObject implementation */
|
|
virtual UWorld* GetWorld() const override { return World; }
|
|
/**~ End UObject implementation */
|
|
|
|
protected:
|
|
|
|
/** World pointer assigned on Setup */
|
|
UPROPERTY(transient, BlueprintReadOnly, Category=Capture)
|
|
TObjectPtr<UWorld> World;
|
|
|
|
protected:
|
|
|
|
/** A frame grabber responsible for capturing LDR final pixels from the viewport when requested */
|
|
TUniquePtr<FFrameGrabber> FinalPixelsFrameGrabber;
|
|
|
|
/** A running count of the number of currently pending async operations */
|
|
TAtomic<int32> NumOutstandingOperations;
|
|
|
|
/** Frame metrics cached for the current frame */
|
|
FFrameMetrics CachedFrameMetrics;
|
|
|
|
/** The ID of the final pixel stream cached from StartCapturingFinalPixels */
|
|
FCapturedPixelsID FinalPixelsID;
|
|
|
|
/** Transient stream ID used only during filename generation */
|
|
const FCapturedPixelsID* CurrentStreamID;
|
|
};
|
|
|
|
|
|
/**
|
|
* A blueprintable capture protocol tailored to capturing and exporting frames as images
|
|
*/
|
|
UCLASS(Abstract, config=EditorPerProjectUserSettings, Blueprintable, meta=(DisplayName="Capture Protocol"), MinimalAPI)
|
|
class UUserDefinedImageCaptureProtocol
|
|
: public UUserDefinedCaptureProtocol
|
|
{
|
|
public:
|
|
|
|
GENERATED_BODY()
|
|
|
|
MOVIESCENECAPTURE_API UUserDefinedImageCaptureProtocol(const FObjectInitializer& ObjInit);
|
|
|
|
/** The image format to save as */
|
|
UPROPERTY(config, BlueprintReadWrite, EditAnywhere, Category=Capture)
|
|
EDesiredImageFormat Format;
|
|
|
|
/** Whether to save images with compression or not. Not supported for bitmaps. */
|
|
UPROPERTY(config, BlueprintReadWrite, EditAnywhere, Category=Capture, meta=(InlineEditConditionToggle))
|
|
bool bEnableCompression;
|
|
|
|
/** The compression quality for the image type. For EXRs, 0 = Default ZIP compression, 1 = No compression, PNGs and JPEGs expect a value between 0 and 100*/
|
|
UPROPERTY(config, BlueprintReadWrite, EditAnywhere, Category=Capture, meta=(EditCondition=bEnableCompression))
|
|
int32 CompressionQuality;
|
|
|
|
public:
|
|
|
|
|
|
/*
|
|
* Generate a filename for the specified buffer using this protocol's file name formatter
|
|
*
|
|
* @param Buffer The desired buffer to generate a filename for
|
|
* @param StreamID The ID of the stream for this buffer (e.g. a composition pass name)
|
|
* @return A fully qualified file name
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category=Capture)
|
|
MOVIESCENECAPTURE_API FString GenerateFilenameForBuffer(UTexture* Buffer, const FCapturedPixelsID& StreamID);
|
|
|
|
|
|
/*
|
|
* Generate a filename for the current frame using this protocol's file name formatter
|
|
*
|
|
* @return A fully qualified file name for the current frame number
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category=Capture)
|
|
MOVIESCENECAPTURE_API FString GenerateFilenameForCurrentFrame();
|
|
|
|
|
|
/*
|
|
* Generate a filename for the current frame using this protocol's file name formatter
|
|
*
|
|
* @return A fully qualified file name for the current frame number
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category=Capture)
|
|
MOVIESCENECAPTURE_API void WriteImageToDisk(const FCapturedPixels& PixelData, const FCapturedPixelsID& StreamID, const FFrameMetrics& FrameMetrics, bool bCopyImageData = false);
|
|
|
|
protected:
|
|
|
|
/**~ Begin UMovieSceneCaptureProtocolBase implementation */
|
|
MOVIESCENECAPTURE_API virtual void OnReleaseConfigImpl(FMovieSceneCaptureSettings& InSettings) override;
|
|
MOVIESCENECAPTURE_API virtual void OnLoadConfigImpl(FMovieSceneCaptureSettings& InSettings) override;
|
|
/**~ End UMovieSceneCaptureProtocolBase implementation */
|
|
|
|
public:
|
|
|
|
/**
|
|
* Called on the main thread when an async operation dispatched from this class has completed (either successfully or otherwise)
|
|
*/
|
|
MOVIESCENECAPTURE_API void OnFileWritten();
|
|
|
|
private:
|
|
|
|
/**~ Begin UUserDefinedCaptureProtocol implementation */
|
|
MOVIESCENECAPTURE_API virtual FString GenerateFilename(const FFrameMetrics& InFrameMetrics) const override;
|
|
/**~ Begin UUserDefinedCaptureProtocol implementation */
|
|
};
|