[FFmpeg-devel] Patch: Add-multithreading-for-swscale-filter

Paul B Mahol onemda at gmail.com
Fri Jul 19 16:43:25 EEST 2019


On 7/19/19, Nicolas George <george at nsup.org> wrote:
> Pawlowski, Slawomir (12019-07-19):
>> From 3ce39207e95eb4697abb0fbaccd37cc451559e49 Mon Sep 17 00:00:00 2001
>> From: Slawomir Pawlowski <slawomir.pawlowski at intel.com>
>> Date: Fri, 19 Jul 2019 13:16:16 +0200
>> Subject: [PATCH] Add multithreading for swscale filter.
>>
>> Use with option "-filter_scale_threads <num_threads>"
>> Split slice in scaler in to parts.
>>
>> Signed-off-by: Slawomir Pawlowski <slawomir.pawlowski at intel.com>
>> Signed-off-by: Tomasz Szumski <tomasz.szumski at intel.com>
>
> Thanks for the patch. Just a quick review for the most visible issues.
>
>> ---
>>  fftools/ffmpeg.h              |   1 +
>>  fftools/ffmpeg_filter.c       |   3 +
>>  fftools/ffmpeg_opt.c          |   7 +
>>  libavfilter/avfilter.h        |  18 ++
>>  libavfilter/avfiltergraph.c   |   4 +
>>  libavfilter/vf_scale.c        |   4 +
>>  libswscale/options.c          |   3 +
>>  libswscale/slice.c            |  32 +++-
>>  libswscale/swscale.c          | 414
>> +++++++++++++++++++++++++++++-------------
>>  libswscale/swscale_internal.h |  46 +++++
>>  libswscale/utils.c            | 152 +++++++++++++++-
>>  11 files changed, 547 insertions(+), 137 deletions(-)
>
> This patch probably needs to be split: swscale, lavfi infrastructure,
> scale filter, command-line tool.
>
>>
>> diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
>> index eb1eaf6..ea1cef5 100644
>> --- a/fftools/ffmpeg.h
>> +++ b/fftools/ffmpeg.h
>> @@ -609,6 +609,7 @@ extern char *videotoolbox_pixfmt;
>>
>>  extern int filter_nbthreads;
>>  extern int filter_complex_nbthreads;
>> +extern int filter_scale_nbthreads;
>>  extern int vstats_version;
>>
>>  extern const AVIOInterruptCB int_cb;
>> diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
>> index 6518d50..793d3e9 100644
>> --- a/fftools/ffmpeg_filter.c
>> +++ b/fftools/ffmpeg_filter.c
>> @@ -1011,6 +1011,9 @@ int configure_filtergraph(FilterGraph *fg)
>>          AVDictionaryEntry *e = NULL;
>>
>>          fg->graph->nb_threads = filter_nbthreads;
>
>> +#if HAVE_THREADS
>> +        fg->graph->sws_nbthreads = filter_scale_nbthreads;
>> +#endif
>
> Here and elsewhere: there is no need for HAVE_THREADS to just define a
> field and set it. Do not litter the code with unnecessary conditional
> compilation.
>
>>
>>          args[0] = 0;
>>          while ((e = av_dict_get(ost->sws_dict, "", e,
>> diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
>> index d4851a2..37791ff 100644
>> --- a/fftools/ffmpeg_opt.c
>> +++ b/fftools/ffmpeg_opt.c
>> @@ -109,6 +109,9 @@ int frame_bits_per_raw_sample = 0;
>>  float max_error_rate  = 2.0/3;
>>  int filter_nbthreads = 0;
>>  int filter_complex_nbthreads = 0;
>> +#if HAVE_THREADS
>> +int filter_scale_nbthreads      = 0;
>> +#endif
>>  int vstats_version = 2;
>>
>>
>> @@ -3497,6 +3500,10 @@ const OptionDef options[] = {
>>      { "disposition",    OPT_STRING | HAS_ARG | OPT_SPEC |
>>                          OPT_OUTPUT,                                  {
>> .off = OFFSET(disposition) },
>>          "disposition", "" },
>> +#if HAVE_THREADS
>> +    { "filter_scale_threads",  HAS_ARG | OPT_INT,
>>  { &filter_scale_nbthreads },
>> +        "number of threads for scale filter" },
>> +#endif
>>      { "thread_queue_size", HAS_ARG | OPT_INT | OPT_OFFSET | OPT_EXPERT |
>> OPT_INPUT,
>>                                                                       {
>> .off = OFFSET(thread_queue_size) },
>>          "set the maximum number of queued packets from the demuxer" },
>> diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
>> index 9d70e71..a2835d7 100644
>> --- a/libavfilter/avfilter.h
>> +++ b/libavfilter/avfilter.h
>> @@ -422,6 +422,16 @@ struct AVFilterContext {
>>       * configured.
>>       */
>>      int extra_hw_frames;
>> +
>> +
>> +#if HAVE_THREADS
>
>> +    /**
>> +     * Number of threads to processing scale
>> +     */
>> +    int sws_slice_nbthreads;
>
> Adding a field to AVFilterContext that is relevant only for vf_scale is
> not acceptable. Use the option system.

Also there is already option to override number of threads per filter.

>
>> +
>> +#endif
>> +
>>  };
>>
>>  /**
>> @@ -907,6 +917,14 @@ typedef struct AVFilterGraph {
>>      int sink_links_count;
>>
>>      unsigned disable_auto_convert;
>> +
>> +#if HAVE_THREADS
>> +    /**
>> +     * Number of threads to processing scale
>> +     */
>> +    int sws_nbthreads;
>> +#endif
>> +
>>  } AVFilterGraph;
>>
>>  /**
>> diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
>> index a149f8f..cbd6ad1 100644
>> --- a/libavfilter/avfiltergraph.c
>> +++ b/libavfilter/avfiltergraph.c
>> @@ -257,6 +257,10 @@ static int graph_config_links(AVFilterGraph *graph,
>> AVClass *log_ctx)
>>      for (i = 0; i < graph->nb_filters; i++) {
>>          filt = graph->filters[i];
>>
>> +#if HAVE_THREADS
>> +        filt->sws_slice_nbthreads = graph->sws_nbthreads;
>> +#endif
>> +
>>          if (!filt->nb_outputs) {
>>              if ((ret = avfilter_config_links(filt)))
>>                  return ret;
>> diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c
>> index f741419..5098aee 100644
>> --- a/libavfilter/vf_scale.c
>> +++ b/libavfilter/vf_scale.c
>> @@ -299,6 +299,10 @@ static int config_props(AVFilterLink *outlink)
>>              av_opt_set_int(*s, "sws_flags", scale->flags, 0);
>>              av_opt_set_int(*s, "param0", scale->param[0], 0);
>>              av_opt_set_int(*s, "param1", scale->param[1], 0);
>> +#if HAVE_THREADS
>> +            av_opt_set_int(*s, "sw_nbthreads", ctx->sws_slice_nbthreads,
>> 0);
>> +#endif
>> +
>>              if (scale->in_range != AVCOL_RANGE_UNSPECIFIED)
>>                  av_opt_set_int(*s, "src_range",
>>                                 scale->in_range == AVCOL_RANGE_JPEG, 0);
>> diff --git a/libswscale/options.c b/libswscale/options.c
>> index 7eb2752..942c12d 100644
>> --- a/libswscale/options.c
>> +++ b/libswscale/options.c
>> @@ -80,6 +80,9 @@ static const AVOption swscale_options[] = {
>>      { "none",            "ignore alpha",                  0,
>>    AV_OPT_TYPE_CONST,  { .i64  = SWS_ALPHA_BLEND_NONE}, INT_MIN, INT_MAX,
>>      VE, "alphablend" },
>>      { "uniform_color",   "blend onto a uniform color",    0,
>>    AV_OPT_TYPE_CONST,  { .i64  = SWS_ALPHA_BLEND_UNIFORM},INT_MIN,
>> INT_MAX,     VE, "alphablend" },
>>      { "checkerboard",    "blend onto a checkerboard",     0,
>>    AV_OPT_TYPE_CONST,  { .i64  = SWS_ALPHA_BLEND_CHECKERBOARD},INT_MIN,
>> INT_MAX,     VE, "alphablend" },
>> +#if HAVE_THREADS
>
>> +    { "sw_nbthreads",    "Threads number for scaling",
>> OFFSET(sw_nbthreads),      AV_OPT_TYPE_INT,    { .i64 = 0
>> }, 0,       128,        VE },
>
> Since this filter only does scaling, namespacing this option is not
> necessary.
>
>> +#endif
>>
>>      { NULL }
>>  };
>> diff --git a/libswscale/slice.c b/libswscale/slice.c
>
> Regards,
>
> --
>   Nicolas George
>


More information about the ffmpeg-devel mailing list