Help with AEGP_RenderAndCheckOutLayerFrame_Async?
class AsyncRenderManager
{
public:
AsyncRenderManager() {}
// Method to initiate async rendering with an optional custom callback
void renderAsync(LayerRenderOptionsPtr optionsH, std::function<void(WorldPtr)> callbackF)
{
auto callbackPtr = new std::function<void(WorldPtr)>(callbackF);
auto ret = std::async(std::launch::async, [optionsH, callbackPtr]() {
RenderSuite().renderAndCheckoutLayerFrameAsync(optionsH, callback,
reinterpret_cast<AEGP_AsyncFrameRequestRefcon>(callbackPtr));
});
}
// Existing static callback method remains unchanged
static A_Err callback(AEGP_AsyncRequestId request_id, A_Boolean was_canceled, A_Err error,
AEGP_FrameReceiptH receiptH, AEGP_AsyncFrameRequestRefcon refconP0)
{
auto callbackPtr = reinterpret_cast<std::function<void(WorldPtr)> *>(refconP0);
if (callbackPtr && *callbackPtr)
{
FrameReceiptPtr ptr = std::make_shared<AEGP_FrameReceiptH>(receiptH);
auto world = RenderSuite().getReceiptWorld(ptr);
(*callbackPtr)(world);
delete callbackPtr;
}
return error;
}
};
And my version of Grabba:
void saveFrame(int i, LayerRenderOptionsPtr layerRenderOptions) {
LayerRenderOptionsSuite().setTime(layerRenderOptions, FramesToTime(i)); // Set the time of the layer render options
AsyncRenderManager rmanager; // Create an instance of the AsyncRenderManager class
rmanager.renderAsync(layerRenderOptions, [i](WorldPtr world) { // Call the renderAsync method with a lambda function
if (world) {
std::string folder = "C:\\Users\\tjerf\\Downloads\\pdf_output\\New folder\\";
auto data = Image::data(world); // Get the image data from the world
Image::saveImage(folder + "\\frame" + std::to_string(i) + ".png", "png", data); // Save the image to disk
}
});
}
void GrabbaCommand::execute() {
try {
auto layer = Layer::activeLayer(); // Get the active layer
auto duration = layer->duration(); // Get the duration of the layer
auto framerate = layer->parentComp()->frameRate(); // Get the frame rate of the composition
int numframes = static_cast<int>(std::round(duration * framerate)); // Calculate the number of frames
auto layerRenderOptions = LayerRenderOptionsSuite().newFromLayer(layer->getLayer()); // Create a new LayerRenderOptions object
// Prepare a vector of futures to hold the results of async operations
std::vector<std::future<void>> futures;
for (int i = 0; i < numframes; ++i) { // Loop through each frame
// Capture 'i' by value to ensure each thread gets the correct frame number
auto future = std::async(std::launch::async, [i, &layerRenderOptions]() {
saveFrame(i, layerRenderOptions);
});
futures.push_back(std::move(future)); // Move the future into the vector
}
// Wait for all async operations to complete
for (auto& future : futures) {
future.wait(); // Wait for the future to complete
}
}
catch (const std::exception& e) {
App::Alert(e.what()); // Display the exception message
}
catch (...) {
App::Alert("An unknown error occurred.");
}
}
