On Sat,  8 Aug 2015 00:13:02 +0200
Luca Barbato <[email protected]> wrote:

> Give priority to pixel formats closer to the input.
> ---
> 
> I kept it as simple as possible on purpose.
> 
>  libavfilter/avfiltergraph.c | 97 
> +++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 97 insertions(+)
> 
> diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
> index 0fc385c..91a9d71 100644
> --- a/libavfilter/avfiltergraph.c
> +++ b/libavfilter/avfiltergraph.c
> @@ -31,6 +31,7 @@
>  #include "libavutil/internal.h"
>  #include "libavutil/log.h"
>  #include "libavutil/opt.h"
> +#include "libavutil/pixdesc.h"
> 
>  #include "avfilter.h"
>  #include "formats.h"
> @@ -742,6 +743,100 @@ static int pick_formats(AVFilterGraph *graph)
>      return 0;
>  }
> 
> +#define same_flag(d1, d2, flag) \
> +    !(!!(d1->flags & flag) ^ !!(d2->flags & flag))
> +
> +static int find_best_pix_fmt_match(AVFilterLink *outlink,
> +                                   const AVPixFmtDescriptor *in_desc,
> +                                   int in_format)
> +{
> +    int j;
> +    int best_idx = -1, best_score = INT_MIN;
> +
> +    for (j = 0; j < outlink->in_formats->nb_formats; j++) {
> +        int format                     = outlink->in_formats->formats[j];
> +        const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(format);
> +
> +        int score;
> +
> +        int same_alpha = same_flag(desc, in_desc, AV_PIX_FMT_FLAG_ALPHA);
> +        int same_rgb   = same_flag(desc, in_desc, AV_PIX_FMT_FLAG_RGB);
> +        int bpc        = desc->comp[0].depth_minus1;
> +        int in_bpc     = in_desc->comp[0].depth_minus1;
> +
> +        if (bpc < in_bpc)
> +            score = bpc - in_bpc;
> +        else
> +            score = 0;
> +
> +        score += -10 * abs(desc->nb_components -
> +                           in_desc->nb_components);
> +
> +        if (same_alpha && same_rgb) {
> +            score += 2;
> +        } else if (desc->flags & AV_PIX_FMT_FLAG_ALPHA) {
> +            if (same_alpha)
> +                score += 1;
> +        } else {
> +            if (same_rgb)
> +                score += 1;
> +        }
> +
> +        if (score > best_score) {
> +            best_score = score;
> +            best_idx   = j;
> +        }
> +    }
> +
> +    return best_idx;
> +}
> +

How does this compare to avcodec_find_best_pix_fmt2()?

> +static void swap_pix_fmts_on_filter(AVFilterContext *filter)
> +{
> +    AVFilterLink *link = NULL;
> +    const AVPixFmtDescriptor *desc;
> +    int format;
> +    int i;
> +
> +    for (i = 0; i < filter->nb_inputs; i++) {
> +        link = filter->inputs[i];
> +
> +        if (link->type == AVMEDIA_TYPE_VIDEO &&
> +            link->out_formats->nb_formats == 1)
> +            break;
> +    }
> +    if (i == filter->nb_inputs)
> +        return;
> +
> +    format = link->out_formats->formats[0];
> +    desc   = av_pix_fmt_desc_get(format);
> +
> +    for (i = 0; i < filter->nb_outputs; i++) {
> +        AVFilterLink *outlink = filter->outputs[i];
> +        int best_idx;
> +
> +        if (outlink->type != AVMEDIA_TYPE_VIDEO ||
> +            outlink->in_formats->nb_formats < 2)
> +            continue;
> +
> +        best_idx = find_best_pix_fmt_match(outlink, desc, format);
> +
> +        if (best_idx > -1)
> +            FFSWAP(int, outlink->in_formats->formats[0],
> +                   outlink->in_formats->formats[best_idx]);
> +    }
> +}
> +
> +static void swap_pix_fmts(AVFilterGraph *graph)
> +{
> +    int i;
> +
> +    for (i = 0; i < graph->nb_filters; i++) {
> +        swap_pix_fmts_on_filter(graph->filters[i]);
> +    }
> +}
> +
> +
>  /**
>   * Configure the formats of all the links in the graph.
>   */
> @@ -763,6 +858,8 @@ static int graph_config_formats(AVFilterGraph *graph, 
> AVClass *log_ctx)
>      swap_sample_fmts(graph);
>      swap_samplerates(graph);
>      swap_channel_layouts(graph);
> +    /* for video filters, ensure the best format is selected */
> +    swap_pix_fmts(graph);
> 
>      if ((ret = pick_formats(graph)) < 0)
>          return ret;
> --
> 1.9.0
> 
> _______________________________________________
> libav-devel mailing list
> [email protected]
> https://lists.libav.org/mailman/listinfo/libav-devel

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to