[FFmpeg-devel] [PATCH 2/3] avfilter/vf_geq: use per-thread state for expression evaluation
Marton Balint
cus at passwd.hu
Mon Dec 30 23:22:33 EET 2019
On Mon, 30 Dec 2019, Michael Niedermayer wrote:
> On Sun, Dec 29, 2019 at 05:03:55PM +0100, Marton Balint wrote:
>>
>>
>> On Sun, 29 Dec 2019, Michael Niedermayer wrote:
>>
>>> On Sat, Dec 28, 2019 at 03:46:24PM +0100, Marton Balint wrote:
>>>> Fixes ticket #7528.
>>>>
>>>> Signed-off-by: Marton Balint <cus at passwd.hu>
>>>> ---
>>>> libavfilter/vf_geq.c | 9 +++++++--
>>>> 1 file changed, 7 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/libavfilter/vf_geq.c b/libavfilter/vf_geq.c
>>>> index 2905efae24..417b92222d 100644
>>>> --- a/libavfilter/vf_geq.c
>>>> +++ b/libavfilter/vf_geq.c
>>>> @@ -377,6 +377,7 @@ static int slice_geq_filter(AVFilterContext *ctx, void *arg, int jobnr, int nb_j
>>>> int x, y;
>>>> uint8_t *ptr;
>>>> uint16_t *ptr16;
>>>> + AVExprState *state = av_expr_state_alloc();
>>>>
>>>> double values[VAR_VARS_NB];
>>>> values[VAR_W] = geq->values[VAR_W];
>>>> @@ -386,6 +387,9 @@ static int slice_geq_filter(AVFilterContext *ctx, void *arg, int jobnr, int nb_j
>>>> values[VAR_SH] = geq->values[VAR_SH];
>>>> values[VAR_T] = geq->values[VAR_T];
>>>>
>>>> + if (!state)
>>>> + return AVERROR(ENOMEM);
>>>> +
>>>> if (geq->bps == 8) {
>>>> for (y = slice_start; y < slice_end; y++) {
>>>> ptr = geq->dst + linesize * y;
>>>> @@ -393,7 +397,7 @@ static int slice_geq_filter(AVFilterContext *ctx, void *arg, int jobnr, int nb_j
>>>>
>>>> for (x = 0; x < width; x++) {
>>>> values[VAR_X] = x;
>>>> - ptr[x] = av_expr_eval(geq->e[plane], values, geq);
>>>> + ptr[x] = av_expr_eval2(geq->e[plane], state, values, geq);
>>>> }
>>>> ptr += linesize;
>>>> }
>>>> @@ -404,10 +408,11 @@ static int slice_geq_filter(AVFilterContext *ctx, void *arg, int jobnr, int nb_j
>>>> values[VAR_Y] = y;
>>>> for (x = 0; x < width; x++) {
>>>> values[VAR_X] = x;
>>>> - ptr16[x] = av_expr_eval(geq->e[plane], values, geq);
>>>> + ptr16[x] = av_expr_eval2(geq->e[plane], state, values, geq);
>>>> }
>>>> }
>>>> }
>>>> + av_expr_state_free(&state);
>>>
>>> a filter which adds random noise would get its seed reset on each frame and
>>> slice with this, unless iam missing something.
>>>
>>> The random values produced by random should be uncorrelatec between frame n and m when n!=m
>>
>> I guess I can make one AVExprState for each thread and keep them during the
>> lifetime of the filter. That would resolve the frame correlation, but not
>> the slice correlation.
>>
>> I don't see too many simple ways to deal with this:
>>
>> 1) accept slice correlation and keep the AVExprStates across executions
>>
>> 2) document that the number of filter threads has to be 1 if uncorrelated
>> random is required
>>
>> 3) initialize the state with the line number at the beginning of each line,
>> which is kind of ugly but would make the filter invariant of the thread
>> count used.
>>
>> Do you have something else in mind? Do you prefer any of these?
>
> for the purpose of random numbers we do not need dependancies accross
> slices or frames and we should have none
>
> It probably makes sense though that in the future each pixels evaluation
> can access the state of the previously evaluated touching pixels both
> temporal and spatial. Threading could then be done depending on where
> the depandancies are.
> This may introduce different slice evaluation orders (like in columns
> instead of rows or diagonally if both left and top state is accessed)
>
> But back to the subject,
>
> We could add a expression to initialize the state at the slice or line start,
> this could be used to set the state based on the line number, iam a bit
> undecided on this though, its not impossible to do ATM without changes
Yeah, it is doable right now by prepending the expression with this:
ifnot(X,st(0,Y));
So I don't think adding an extra expression for this is worth it.
Regards,
Marton
More information about the ffmpeg-devel
mailing list