Copy link to clipboard
Copied
Hi gang;
I would love some guidance here.
As we know, there are two ways to check out a layer. One is the old-fashioned way like so:
AEFX_CLR_STRUCT(checkoutLayer);
ERR(PF_CHECKOUT_PARAM(in_data,
SKELETON_CHECKOUTLAYER,
in_data->current_time,
in_data->time_step,
in_data->time_scale,
&checkoutColorLayer));
ERR(PF_CHECKIN_PARAM(in_data, &checkoutLayer));
The other, is the method used for SmartRender plugins where you check them out in PreRender like so:
ERR(extraP->cb->checkout_layer(in_dataP->effect_ref,
SKELETON_CHECKOUTLAYER,
SKELETON_CHECKOUTLAYER,
&req,
in_dataP->current_time,
in_dataP->time_step,
in_dataP->time_scale,
&in_result));
UnionLRect(&in_result.result_rect, &extraP->output->result_rect);
UnionLRect(&in_result.max_result_rect, &extraP->output->max_result_rect);
And then when we are ready to use it in SmartRender, we call it like this:
ERR(extraP->cb->checkout_layer_pixels(in_data->effect_ref, SKELETON_CHECKOUTLAYER, &checkoutLayer));
// And once finished:
ERR2(extraP->cb->checkin_layer_pixels(in_data->effect_ref, SKELETON_CHECKOUTLAYER));
Now, with the old fashioned method, it was easy to seek through the time during rendertime and grab whichever frame we wanted.
With the SmartRender method, it's trickier because we need to get those frames beforehand in the PreRender function and store them in checkout_idl.
This thread kind of discusses it but I still need clarification as my attempts haven't worked: https://community.adobe.com/t5/after-effects-discussions/checkout-previous-frame-in-smart-render/m-p...
Here are my questions. Let's say I want to checkout a layer over 100 frames. Let's say 0-100:
1 - In the header file, under ENUMS, if my ENUM is called SKELETON_CHECKOUTLAYER, do I need 100 of these or just one? I assume 1 because I don't want 100 checkout layer parameters. And we will modify the ID anyway, not the index, right?
2 - In the ParamsSetup, similarly, we only want 1 instance of it.
3 - In Pre-Render, we would have something like the following:
for (int i = 0; i < 100; i++)
{
ERR(extraP->cb->checkout_layer(in_dataP->effect_ref,
SKELETON_CHECKOUTLAYER,
SKELETON_CHECKOUTLAYER+i,
&req,
i * in_dataP->time_step,
in_dataP->time_step,
in_dataP->time_scale,
&checkoutColorLayer));
UnionLRect(&checkoutLayer.result_rect, &extraP->output->result_rect);
UnionLRect(&checkoutLayer.max_result_rect, &extraP->output->max_result_rect);
}
This should store the checkout layer at time 0 through to 100. I do not increase the parameter index because we don't want 100 parameter checkouts. Then in SmartRender, I can call that particular time like so (where timeindex is the time of the checked out layer):
ERR(extraP->cb->checkout_layer_pixels(in_data->effect_ref, SKELETON_CHECKOUTLAYER + timeindex, &checkoutColorLayer));
// And upon finishing:
ERR2(extraP->cb->checkin_layer_pixels(in_data->effect_ref, SKELETON_CHECKOUTLAYER + timeindex));
However, this is incorrect. I get a crash and an error: "Node received more checkout requests than expected."
Any suggestions on what I'm doing wrong here?
Thanks,
-Richard
Copy link to clipboard
Copied
Hi Rich
When checking out the layer pixels inside smart render you specify the index (not the time, you specified that in preRender), so if your code is like this it should be correct:
PF_EffectWorldPtr buffer;
for(int i = 0; i < 100; i++)
{
ERR(extra->cb->checkout_layer_pixels(in_data->effect_ref, CMB_INPUT + i, buffer));
// use / comp checked out buffer
ERR2(extra->cb->checkin_layer_pixels(in_data->effect_ref, CMB_INPUT + i));
}
Copy link to clipboard
Copied
i tihnk i see where you got things mixed up.
when using extraP->cb->checkout_layer, you specify the layer param index for the checkout, and you also pass some unique identifier.
the misconception is that this identifier has to do with the layer param index. it does not. on the sample projects the param index is used because it is unique in itself, but it's ablsoutely not required to be so.
if you're doing 100 checkouts, you need 100 unique identifiers. you need to use the same identifiers when eventually checking out the pixels and when cheking them back in again.
say your param index is 6. the unique identifier can indeed be 6 as well. it can also be 234967592.
the input layer is also checked out with param index 0, so except for 0 you can use any number.
if you have 2 layer params you'd like to check out with at 100 different times, you need to make sure the unique identifiers don't collide. for exmaple, if the param index for one is 6 and the other is 7, you can't do checkouts with 6+i and 7+i, as the nubers would overlap. instead, make a checkout counter, checkout the first param with indetifiers in the range of 1 -100 and the scond one with the range of 101-200. as long as in the redner function you know what identifier was associated with what sample so you could get what you expect, all is good.
Copy link to clipboard
Copied
Hi Shachar & James;
Thanks for your explanations. I now understand that the IDL doesn't have to match the param ID. I am getting conflicted info though because James says I should checkin with the param ID in SmartRender but Shachar, you say to check in with the IDL.
So factoring in your suggestions, this should be the correct structure?
// Let's define an IDL outside of the parameter index list so that it's unique and without conflict:
#define IDL 32768
// Now in pre-render we use unique IDL + i to save 100 instances of the checkout frame time (These are the idls used: 32768 + i = range of 32768 to 32868)
for (int i = 0; i < 100; i++)
{
ERR(extraP->cb->checkout_layer(in_dataP->effect_ref,
SKELETON_CHECKOUTLAYER,
IDL + i,
&req,
i * in_dataP->time_step,
in_dataP->time_step,
in_dataP->time_scale,
&checkoutLayer));
UnionLRect(&checkoutLayer.result_rect, &extraP->output->result_rect);
UnionLRect(&checkoutLayer.max_result_rect, &extraP->output->max_result_rect);
}
for (i = 0; i < 100; i++)
{
// Check out
ERR(extraP->cb->checkout_layer_pixels(in_data->effect_ref, IDL + i, &checkoutLayer));
// Check In
ERR2(extraP->cb->checkin_layer_pixels(in_data->effect_ref, IDL + i));
}
But alas, this still reports an error and crashes: Node received more checkout requests than expected.
In ENUMS, I only have one SKELETON_CHECKOUT param, not 100 of them. Similarly in ParamsSetup.
Sorry guys, this one is taking me a bit longer to grasp. Please bear with me. What is wrong with it?
-Richard
Copy link to clipboard
Copied
i don't see where james and i disagree on the checkin index. we both wrote it's the same index as used in the checkout.
anyways, check the status of err and err2 in pre-render. it's possible that a checkout fails and sets the err state to non 0. once set, the ERR and ERR2 macros skip the code inside them, so the pre-render checkouts might not be happening past the first error.
same goes for the render function. keep track of which checkouts succeeded, so you don't check in buffers that were never checked out.
Copy link to clipboard
Copied
Hi guys;
I have solved it.
For some reason, the checkout in SmartRender can be in a loop but the final checkin, should not. If I place the final checkin after my main program loop, it works correctly. This eliminates the Node received more checkout requests than expected. error and works as it should.
I am not entirely sure why and I will do more testing but I wanted to post it.
As always, I really appreciate both your help and I wouldn't have solved it without better understanding how the IDL works.
-Richard
Copy link to clipboard
Copied
honest to god, that makes no sense to me...
i would strongly suggest you investigate further becuase the actual problem may be lurking in the shadows it will manifest in some unexpected ways.
Copy link to clipboard
Copied
If you do ~100 buffer checkouts you'll likely run out of memory if they can't be checked in in that loop 😞
Copy link to clipboard
Copied
Yeah, I will run some tests to see what's going on.
I suppose one good way to test is to see if the ram usage skyrockets when I select the checkout layer and it does 100 checkouts.
I will test that and also try again to do the checkouts and checkins in the same loop iteration, despite it not having worked for me yet.
Rich