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