diff mbox

[FFmpeg-devel] avfilter/vf_tonemap: add slice threading

Message ID 20190430100028.23305-1-onemda@gmail.com
State Accepted
Commit d3d1d5936fdc9a351d6d1aac8405292dfb14c831
Headers show

Commit Message

Paul B Mahol April 30, 2019, 10 a.m. UTC
Signed-off-by: Paul B Mahol <onemda@gmail.com>
---
 libavfilter/vf_tonemap.c | 39 ++++++++++++++++++++++++++++++++++-----
 1 file changed, 34 insertions(+), 5 deletions(-)

Comments

Vittorio Giovara April 30, 2019, 7:08 p.m. UTC | #1
On Tue, Apr 30, 2019 at 6:07 AM Paul B Mahol <onemda@gmail.com> wrote:

> Signed-off-by: Paul B Mahol <onemda@gmail.com>
> ---
>  libavfilter/vf_tonemap.c | 39 ++++++++++++++++++++++++++++++++++-----
>  1 file changed, 34 insertions(+), 5 deletions(-)
>
> diff --git a/libavfilter/vf_tonemap.c b/libavfilter/vf_tonemap.c
> index efd4af5466..d1728c8513 100644
> --- a/libavfilter/vf_tonemap.c
> +++ b/libavfilter/vf_tonemap.c
> @@ -191,10 +191,36 @@ static void tonemap(TonemapContext *s, AVFrame *out,
> const AVFrame *in,
>      *b_out *= sig / sig_orig;
>  }
>
> +typedef struct ThreadData {
> +    AVFrame *in, *out;
> +    const AVPixFmtDescriptor *desc;
> +    double peak;
> +} ThreadData;
> +
> +static int tonemap_slice(AVFilterContext *ctx, void *arg, int jobnr, int
> nb_jobs)
> +{
> +    TonemapContext *s = ctx->priv;
> +    ThreadData *td = arg;
> +    AVFrame *in = td->in;
> +    AVFrame *out = td->out;
> +    const AVPixFmtDescriptor *desc = td->desc;
> +    const int slice_start = (in->height * jobnr) / nb_jobs;
> +    const int slice_end = (in->height * (jobnr+1)) / nb_jobs;
> +    double peak = td->peak;
> +
> +    for (int y = slice_start; y < slice_end; y++)
> +        for (int x = 0; x < out->width; x++)
> +            tonemap(s, out, in, desc, x, y, peak);
> +
> +    return 0;
> +}
> +
>  static int filter_frame(AVFilterLink *link, AVFrame *in)
>  {
> -    TonemapContext *s = link->dst->priv;
> -    AVFilterLink *outlink = link->dst->outputs[0];
> +    AVFilterContext *ctx = link->dst;
> +    TonemapContext *s = ctx->priv;
> +    AVFilterLink *outlink = ctx->outputs[0];
> +    ThreadData td;
>      AVFrame *out;
>      const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format);
>      const AVPixFmtDescriptor *odesc =
> av_pix_fmt_desc_get(outlink->format);
> @@ -245,9 +271,11 @@ static int filter_frame(AVFilterLink *link, AVFrame
> *in)
>      }
>
>      /* do the tone map */
> -    for (y = 0; y < out->height; y++)
> -        for (x = 0; x < out->width; x++)
> -            tonemap(s, out, in, desc, x, y, peak);
> +    td.out = out;
> +    td.in = in;
> +    td.desc = desc;
> +    td.peak = peak;
> +    ctx->internal->execute(ctx, tonemap_slice, &td, NULL,
> FFMIN(in->height, ff_filter_get_nb_threads(ctx)));
>

why this FFMIN()?

     /* copy/generate alpha if needed */
>      if (desc->flags & AV_PIX_FMT_FLAG_ALPHA && odesc->flags &
> AV_PIX_FMT_FLAG_ALPHA) {
> @@ -315,4 +343,5 @@ AVFilter ff_vf_tonemap = {
>      .priv_class      = &tonemap_class,
>      .inputs          = tonemap_inputs,
>      .outputs         = tonemap_outputs,
> +    .flags           = AVFILTER_FLAG_SLICE_THREADS,
>  };
> --
>

lgtm
Paul B Mahol April 30, 2019, 8:18 p.m. UTC | #2
On 4/30/19, Vittorio Giovara <vittorio.giovara@gmail.com> wrote:
> On Tue, Apr 30, 2019 at 6:07 AM Paul B Mahol <onemda@gmail.com> wrote:
>
>> Signed-off-by: Paul B Mahol <onemda@gmail.com>
>> ---
>>  libavfilter/vf_tonemap.c | 39 ++++++++++++++++++++++++++++++++++-----
>>  1 file changed, 34 insertions(+), 5 deletions(-)
>>
>> diff --git a/libavfilter/vf_tonemap.c b/libavfilter/vf_tonemap.c
>> index efd4af5466..d1728c8513 100644
>> --- a/libavfilter/vf_tonemap.c
>> +++ b/libavfilter/vf_tonemap.c
>> @@ -191,10 +191,36 @@ static void tonemap(TonemapContext *s, AVFrame *out,
>> const AVFrame *in,
>>      *b_out *= sig / sig_orig;
>>  }
>>
>> +typedef struct ThreadData {
>> +    AVFrame *in, *out;
>> +    const AVPixFmtDescriptor *desc;
>> +    double peak;
>> +} ThreadData;
>> +
>> +static int tonemap_slice(AVFilterContext *ctx, void *arg, int jobnr, int
>> nb_jobs)
>> +{
>> +    TonemapContext *s = ctx->priv;
>> +    ThreadData *td = arg;
>> +    AVFrame *in = td->in;
>> +    AVFrame *out = td->out;
>> +    const AVPixFmtDescriptor *desc = td->desc;
>> +    const int slice_start = (in->height * jobnr) / nb_jobs;
>> +    const int slice_end = (in->height * (jobnr+1)) / nb_jobs;
>> +    double peak = td->peak;
>> +
>> +    for (int y = slice_start; y < slice_end; y++)
>> +        for (int x = 0; x < out->width; x++)
>> +            tonemap(s, out, in, desc, x, y, peak);
>> +
>> +    return 0;
>> +}
>> +
>>  static int filter_frame(AVFilterLink *link, AVFrame *in)
>>  {
>> -    TonemapContext *s = link->dst->priv;
>> -    AVFilterLink *outlink = link->dst->outputs[0];
>> +    AVFilterContext *ctx = link->dst;
>> +    TonemapContext *s = ctx->priv;
>> +    AVFilterLink *outlink = ctx->outputs[0];
>> +    ThreadData td;
>>      AVFrame *out;
>>      const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format);
>>      const AVPixFmtDescriptor *odesc =
>> av_pix_fmt_desc_get(outlink->format);
>> @@ -245,9 +271,11 @@ static int filter_frame(AVFilterLink *link, AVFrame
>> *in)
>>      }
>>
>>      /* do the tone map */
>> -    for (y = 0; y < out->height; y++)
>> -        for (x = 0; x < out->width; x++)
>> -            tonemap(s, out, in, desc, x, y, peak);
>> +    td.out = out;
>> +    td.in = in;
>> +    td.desc = desc;
>> +    td.peak = peak;
>> +    ctx->internal->execute(ctx, tonemap_slice, &td, NULL,
>> FFMIN(in->height, ff_filter_get_nb_threads(ctx)));
>>
>
> why this FFMIN()?

So that it does not break up if user set number of threads more than height.

>
>      /* copy/generate alpha if needed */
>>      if (desc->flags & AV_PIX_FMT_FLAG_ALPHA && odesc->flags &
>> AV_PIX_FMT_FLAG_ALPHA) {
>> @@ -315,4 +343,5 @@ AVFilter ff_vf_tonemap = {
>>      .priv_class      = &tonemap_class,
>>      .inputs          = tonemap_inputs,
>>      .outputs         = tonemap_outputs,
>> +    .flags           = AVFILTER_FLAG_SLICE_THREADS,
>>  };
>> --
>>
>
> lgtm
> --
> Vittorio
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
diff mbox

Patch

diff --git a/libavfilter/vf_tonemap.c b/libavfilter/vf_tonemap.c
index efd4af5466..d1728c8513 100644
--- a/libavfilter/vf_tonemap.c
+++ b/libavfilter/vf_tonemap.c
@@ -191,10 +191,36 @@  static void tonemap(TonemapContext *s, AVFrame *out, const AVFrame *in,
     *b_out *= sig / sig_orig;
 }
 
+typedef struct ThreadData {
+    AVFrame *in, *out;
+    const AVPixFmtDescriptor *desc;
+    double peak;
+} ThreadData;
+
+static int tonemap_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
+{
+    TonemapContext *s = ctx->priv;
+    ThreadData *td = arg;
+    AVFrame *in = td->in;
+    AVFrame *out = td->out;
+    const AVPixFmtDescriptor *desc = td->desc;
+    const int slice_start = (in->height * jobnr) / nb_jobs;
+    const int slice_end = (in->height * (jobnr+1)) / nb_jobs;
+    double peak = td->peak;
+
+    for (int y = slice_start; y < slice_end; y++)
+        for (int x = 0; x < out->width; x++)
+            tonemap(s, out, in, desc, x, y, peak);
+
+    return 0;
+}
+
 static int filter_frame(AVFilterLink *link, AVFrame *in)
 {
-    TonemapContext *s = link->dst->priv;
-    AVFilterLink *outlink = link->dst->outputs[0];
+    AVFilterContext *ctx = link->dst;
+    TonemapContext *s = ctx->priv;
+    AVFilterLink *outlink = ctx->outputs[0];
+    ThreadData td;
     AVFrame *out;
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format);
     const AVPixFmtDescriptor *odesc = av_pix_fmt_desc_get(outlink->format);
@@ -245,9 +271,11 @@  static int filter_frame(AVFilterLink *link, AVFrame *in)
     }
 
     /* do the tone map */
-    for (y = 0; y < out->height; y++)
-        for (x = 0; x < out->width; x++)
-            tonemap(s, out, in, desc, x, y, peak);
+    td.out = out;
+    td.in = in;
+    td.desc = desc;
+    td.peak = peak;
+    ctx->internal->execute(ctx, tonemap_slice, &td, NULL, FFMIN(in->height, ff_filter_get_nb_threads(ctx)));
 
     /* copy/generate alpha if needed */
     if (desc->flags & AV_PIX_FMT_FLAG_ALPHA && odesc->flags & AV_PIX_FMT_FLAG_ALPHA) {
@@ -315,4 +343,5 @@  AVFilter ff_vf_tonemap = {
     .priv_class      = &tonemap_class,
     .inputs          = tonemap_inputs,
     .outputs         = tonemap_outputs,
+    .flags           = AVFILTER_FLAG_SLICE_THREADS,
 };