History

avfilter/vf_zscale: add slice threading support

By ffmpeg threading support implementation via frame slicing and doing zimg_filter_graph_build that used to take 30-60% of each frame processig only if necessary (some parameters changed) the performance increase vs original version in video downscale and color conversion >4x is seen on 64 cores Intel Xeon, 3x on i7-6700K (4 cores with HT)

Victoria Zhislina committed 4 years ago

Commit d0aefc31 parent d607af51 file · +282 −126Browse files

Showing the changes to libavfilter (1 of 1 file). Show all

Unified · Split

libavfilter/vf_zscale.c+282−126
@@ -1,5 +1,6 @@
1/*1/*
2 * Copyright (c) 2015 Paul B Mahol2 * Copyright (c) 2015 Paul B Mahol
3 * Copyright (c) 2022 Victoria Zhislina, Intel
3 *4 *
4 * This file is part of FFmpeg.5 * This file is part of FFmpeg.
5 *6 *
@@ -44,6 +45,8 @@ · 38 unmodified lines
44#include "libavutil/imgutils.h"45#include "libavutil/imgutils.h"
45 46
46#define ZIMG_ALIGNMENT 3247#define ZIMG_ALIGNMENT 32
48#define MIN_TILESIZE 64
49#define MAX_THREADS 64
47 50
48static const char *const var_names[] = {51static const char *const var_names[] = {
49 "in_w", "iw",52 "in_w", "iw",
@@ -113,13 +116,17 @@ typedef struct ZScaleContext { · 63 unmodified lines
113 116
114 int force_original_aspect_ratio;117 int force_original_aspect_ratio;
115 118
116 void *tmp;119 void *tmp[MAX_THREADS]; //separate for each thread;
117 size_t tmp_size;120 int nb_threads;
121 int slice_h;
118 122
119 zimg_image_format src_format, dst_format;123 zimg_image_format src_format, dst_format;
120 zimg_image_format alpha_src_format, alpha_dst_format;124 zimg_image_format alpha_src_format, alpha_dst_format;
125 zimg_image_format src_format_tmp, dst_format_tmp;
126 zimg_image_format alpha_src_format_tmp, alpha_dst_format_tmp;
121 zimg_graph_builder_params alpha_params, params;127 zimg_graph_builder_params alpha_params, params;
122 zimg_filter_graph *alpha_graph, *graph;128 zimg_graph_builder_params alpha_params_tmp, params_tmp;
129 zimg_filter_graph *alpha_graph[MAX_THREADS], *graph[MAX_THREADS];
123 130
124 enum AVColorSpace in_colorspace, out_colorspace;131 enum AVColorSpace in_colorspace, out_colorspace;
125 enum AVColorTransferCharacteristic in_trc, out_trc;132 enum AVColorTransferCharacteristic in_trc, out_trc;
@@ -128,10 +135,35 @@ typedef struct ZScaleContext { · 2 unmodified lines
128 enum AVChromaLocation in_chromal, out_chromal;135 enum AVChromaLocation in_chromal, out_chromal;
129} ZScaleContext;136} ZScaleContext;
130 137
138typedef struct ThreadData {
139 const AVPixFmtDescriptor *desc, *odesc;
140 AVFrame *in, *out;
141} ThreadData;
142
131static av_cold int init(AVFilterContext *ctx)143static av_cold int init(AVFilterContext *ctx)
132{144{
133 ZScaleContext *s = ctx->priv;145 ZScaleContext *s = ctx->priv;
134 int ret;146 int ret;
147 int i;
148 for (i = 0; i < MAX_THREADS; i++) {
149 s->tmp[i] = NULL;
150 s->graph[i] = NULL;
151 s->alpha_graph[i] = NULL;
152 }
153 zimg_image_format_default(&s->src_format, ZIMG_API_VERSION);
154 zimg_image_format_default(&s->dst_format, ZIMG_API_VERSION);
155 zimg_image_format_default(&s->src_format_tmp, ZIMG_API_VERSION);
156 zimg_image_format_default(&s->dst_format_tmp, ZIMG_API_VERSION);
157
158 zimg_image_format_default(&s->alpha_src_format, ZIMG_API_VERSION);
159 zimg_image_format_default(&s->alpha_dst_format, ZIMG_API_VERSION);
160 zimg_image_format_default(&s->alpha_src_format_tmp, ZIMG_API_VERSION);
161 zimg_image_format_default(&s->alpha_dst_format_tmp, ZIMG_API_VERSION);
162
163 zimg_graph_builder_params_default(&s->params, ZIMG_API_VERSION);
164 zimg_graph_builder_params_default(&s->params_tmp, ZIMG_API_VERSION);
165 zimg_graph_builder_params_default(&s->alpha_params, ZIMG_API_VERSION);
166 zimg_graph_builder_params_default(&s->alpha_params_tmp, ZIMG_API_VERSION);
135 167
136 if (s->size_str && (s->w_expr || s->h_expr)) {168 if (s->size_str && (s->w_expr || s->h_expr)) {
137 av_log(ctx, AV_LOG_ERROR,169 av_log(ctx, AV_LOG_ERROR,
@@ -471,6 +503,51 @@ static enum AVColorRange convert_range_from_zimg(enum zimg_pixel_range_e color_r · 333 unmodified lines
471 return AVCOL_RANGE_UNSPECIFIED;503 return AVCOL_RANGE_UNSPECIFIED;
472}504}
473 505
506/* returns 0 if image formats are the same and 1 otherwise */
507static int compare_zimg_image_formats(zimg_image_format *img_fmt0, zimg_image_format *img_fmt1)
508{
509 return ((img_fmt0->chroma_location != img_fmt1->chroma_location) ||
510#if ZIMG_API_VERSION >= 0x204
511 (img_fmt0->alpha != img_fmt1->alpha) ||
512#endif
513 (img_fmt0->color_family != img_fmt1->color_family) ||
514 (img_fmt0->color_primaries != img_fmt1->color_primaries) ||
515 (img_fmt0->depth != img_fmt1->depth) ||
516 (img_fmt0->field_parity != img_fmt1->field_parity) ||
517 (img_fmt0->height != img_fmt1->height) ||
518 (img_fmt0->matrix_coefficients != img_fmt1->matrix_coefficients) ||
519 (img_fmt0->pixel_range != img_fmt1->pixel_range) ||
520 (img_fmt0->pixel_type != img_fmt1->pixel_type) ||
521 (img_fmt0->subsample_h != img_fmt1->subsample_h) ||
522 (img_fmt0->subsample_w != img_fmt1->subsample_w) ||
523 (img_fmt0->transfer_characteristics != img_fmt1->transfer_characteristics) ||
524 (img_fmt0->width != img_fmt1->width));
525}
526
527/* returns 0 if graph builder parameters are the same and 1 otherwise */
528static int compare_zimg_graph_builder_params(zimg_graph_builder_params *parm0, zimg_graph_builder_params *parm1)
529{
530 /* the parameters that could be changed inside a single ffmpeg zscale invocation are checked only
531 and NaN values that are default for some params are treated properly*/
532 int ret = (parm0->allow_approximate_gamma != parm1->allow_approximate_gamma) ||
533 (parm0->dither_type != parm1->dither_type) ||
534 (parm0->resample_filter != parm1->resample_filter) ||
535 (parm0->resample_filter_uv != parm1->resample_filter_uv);
536
537 if ((isnan(parm0->nominal_peak_luminance) == 0) || (isnan(parm1->nominal_peak_luminance) == 0))
538 ret = ret || (parm0->nominal_peak_luminance != parm1->nominal_peak_luminance);
539 if ((isnan(parm0->filter_param_a) == 0) || (isnan(parm1->filter_param_a) == 0))
540 ret = ret || (parm0->filter_param_a != parm1->filter_param_a);
541 if ((isnan(parm0->filter_param_a_uv) == 0) || (isnan(parm1->filter_param_a_uv) == 0))
542 ret = ret || (parm0->filter_param_a_uv != parm1->filter_param_a_uv);
543 if ((isnan(parm0->filter_param_b) == 0) || (isnan(parm1->filter_param_b) == 0))
544 ret = ret || (parm0->filter_param_b != parm1->filter_param_b);
545 if ((isnan(parm0->filter_param_b_uv) == 0) || (isnan(parm1->filter_param_b_uv) == 0))
546 ret = ret || (parm0->filter_param_b_uv != parm1->filter_param_b_uv);
547
548 return ret;
549}
550
474static void format_init(zimg_image_format *format, AVFrame *frame, const AVPixFmtDescriptor *desc,551static void format_init(zimg_image_format *format, AVFrame *frame, const AVPixFmtDescriptor *desc,
475 int colorspace, int primaries, int transfer, int range, int location)552 int colorspace, int primaries, int transfer, int range, int location)
476{553{
@@ -483,46 +560,94 @@ static void format_init(zimg_image_format *format, AVFrame *frame, const AVPixFm · 6 unmodified lines
483 format->color_family = (desc->flags & AV_PIX_FMT_FLAG_RGB) ? ZIMG_COLOR_RGB : ZIMG_COLOR_YUV;560 format->color_family = (desc->flags & AV_PIX_FMT_FLAG_RGB) ? ZIMG_COLOR_RGB : ZIMG_COLOR_YUV;
484 format->matrix_coefficients = (desc->flags & AV_PIX_FMT_FLAG_RGB) ? ZIMG_MATRIX_RGB : colorspace == -1 ? convert_matrix(frame->colorspace) : colorspace;561 format->matrix_coefficients = (desc->flags & AV_PIX_FMT_FLAG_RGB) ? ZIMG_MATRIX_RGB : colorspace == -1 ? convert_matrix(frame->colorspace) : colorspace;
485 format->color_primaries = primaries == -1 ? convert_primaries(frame->color_primaries) : primaries;562 format->color_primaries = primaries == -1 ? convert_primaries(frame->color_primaries) : primaries;
486 format->transfer_characteristics = transfer == - 1 ? convert_trc(frame->color_trc) : transfer;563 format->transfer_characteristics = transfer == -1 ? convert_trc(frame->color_trc) : transfer;
487 format->pixel_range = (desc->flags & AV_PIX_FMT_FLAG_RGB) ? ZIMG_RANGE_FULL : range == -1 ? convert_range(frame->color_range) : range;564 format->pixel_range = (desc->flags & AV_PIX_FMT_FLAG_RGB) ? ZIMG_RANGE_FULL : range == -1 ? convert_range(frame->color_range) : range;
488 format->chroma_location = location == -1 ? convert_chroma_location(frame->chroma_location) : location;565 format->chroma_location = location == -1 ? convert_chroma_location(frame->chroma_location) : location;
489}566}
490 567
491static int graph_build(zimg_filter_graph **graph, zimg_graph_builder_params *params,568static int graphs_build(AVFrame *in, AVFrame *out, const AVPixFmtDescriptor *desc, const AVPixFmtDescriptor *out_desc,
492 zimg_image_format *src_format, zimg_image_format *dst_format,569 ZScaleContext *s, int job_nr)
493 void **tmp, size_t *tmp_size)
494{570{
495 int ret;571 int ret;
496 size_t size;572 size_t size;
573 zimg_image_format src_format;
574 zimg_image_format dst_format;
575 zimg_image_format alpha_src_format;
576 zimg_image_format alpha_dst_format;
577
578 src_format = s->src_format;
579 dst_format = s->dst_format;
580 /* The input slice is specified through the active_region field,
581 unlike the output slice.
582 according to zimg requirements input and output slices should have even dimentions */
583 src_format.active_region.width = in->width;
584 src_format.active_region.height = s->slice_h;
585 src_format.active_region.left = 0;
586 src_format.active_region.top = job_nr * src_format.active_region.height;
587 //dst now is the single tile only!!
588 dst_format.width = out->width;
589 dst_format.height = ((unsigned int)(out->height / s->nb_threads)) & 0xfffffffe;
590
591 //the last slice could differ from the previous ones due to the slices division "tail"
592 if (job_nr == (s->nb_threads - 1)) {
593 src_format.active_region.height = src_format.height - src_format.active_region.top;
594 dst_format.height = out->height - job_nr * dst_format.height;
595 }
497 596
498 zimg_filter_graph_free(*graph);597 if (s->graph[job_nr]) {
499 *graph = zimg_filter_graph_build(src_format, dst_format, params);598 zimg_filter_graph_free(s->graph[job_nr]);
500 if (!*graph)599 }
600 s->graph[job_nr] = zimg_filter_graph_build(&src_format, &dst_format, &s->params);
601 if (!s->graph[job_nr])
501 return print_zimg_error(NULL);602 return print_zimg_error(NULL);
502 603
503 ret = zimg_filter_graph_get_tmp_size(*graph, &size);604 ret = zimg_filter_graph_get_tmp_size(s->graph[job_nr], &size);
504 if (ret)605 if (ret)
505 return print_zimg_error(NULL);606 return print_zimg_error(NULL);
506 607
507 if (size > *tmp_size) {608 if (s->tmp[job_nr])
508 av_freep(tmp);609 av_freep(&s->tmp[job_nr]);
509 *tmp = av_malloc(size);610 s->tmp[job_nr] = av_malloc(size);
510 if (!*tmp)611 if (!s->tmp[job_nr])
511 return AVERROR(ENOMEM);612 return AVERROR(ENOMEM);
512 613
513 *tmp_size = size;614 if (desc->flags & AV_PIX_FMT_FLAG_ALPHA && out_desc->flags & AV_PIX_FMT_FLAG_ALPHA) {
514 }615 alpha_src_format = s->alpha_src_format;
616 alpha_dst_format = s->alpha_dst_format;
617 /* The input slice is specified through the active_region field, unlike the output slice.
618 according to zimg requirements input and output slices should have even dimentions */
619 alpha_src_format.active_region.width = in->width;
620 alpha_src_format.active_region.height = s->slice_h;
621 alpha_src_format.active_region.left = 0;
622 alpha_src_format.active_region.top = job_nr * alpha_src_format.active_region.height;
623 //dst now is the single tile only!!
624 alpha_dst_format.width = out->width;
625 alpha_dst_format.height = ((unsigned int)(out->height / s->nb_threads)) & 0xfffffffe;
626
627 //the last slice could differ from the previous ones due to the slices division "tail"
628 if (job_nr == (s->nb_threads - 1)) {
629 alpha_src_format.active_region.height = alpha_src_format.height - alpha_src_format.active_region.top;
630 alpha_dst_format.height = out->height - job_nr * alpha_dst_format.height;
631 }
515 632
633 if (s->alpha_graph[job_nr]) {
634 zimg_filter_graph_free(s->alpha_graph[job_nr]);
635 }
636 s->alpha_graph[job_nr] = zimg_filter_graph_build(&alpha_src_format, &alpha_dst_format, &s->alpha_params);
637 if (!s->alpha_graph[job_nr])
638 return print_zimg_error(NULL);
639 }
516 return 0;640 return 0;
517}641}
518 642
519static int realign_frame(const AVPixFmtDescriptor *desc, AVFrame **frame)643static int realign_frame(const AVPixFmtDescriptor *desc, AVFrame **frame)
520{644{
521 AVFrame *aligned = NULL;645 AVFrame *aligned = NULL;
522 int ret = 0, plane;646 int ret = 0, plane, planes;
523 647
524 /* Realign any unaligned input frame. */648 /* Realign any unaligned input frame. */
525 for (plane = 0; plane < 3; plane++) {649 planes = av_pix_fmt_count_planes(desc->nb_components);
650 for (plane = 0; plane < planes; plane++) {
526 int p = desc->comp[plane].plane;651 int p = desc->comp[plane].plane;
527 if ((uintptr_t)(*frame)->data[p] % ZIMG_ALIGNMENT || (*frame)->linesize[p] % ZIMG_ALIGNMENT) {652 if ((uintptr_t)(*frame)->data[p] % ZIMG_ALIGNMENT || (*frame)->linesize[p] % ZIMG_ALIGNMENT) {
528 if (!(aligned = av_frame_alloc())) {653 if (!(aligned = av_frame_alloc())) {
@@ -572,20 +697,77 @@ static void update_output_color_information(ZScaleContext *s, AVFrame *frame) · 43 unmodified lines
572 frame->chroma_location = (int)s->dst_format.chroma_location + 1;697 frame->chroma_location = (int)s->dst_format.chroma_location + 1;
573}698}
574 699
700static int filter_slice(AVFilterContext *ctx, void *data, int job_nr, int n_jobs)
701{
702 ThreadData *td = data;
703 int ret = 0;
704 int p;
705 int out_sampl;
706 int need_gb;
707 ZScaleContext *s = ctx->priv;
708 zimg_image_buffer_const src_buf = { ZIMG_API_VERSION };
709 zimg_image_buffer dst_buf = { ZIMG_API_VERSION };
710 int dst_tile_height = ((unsigned int)(td->out->height / n_jobs)) & 0xfffffffe;
711
712 /* create zimg filter graphs for each thread
713 only if not created earlier or there is some change in frame parameters */
714 need_gb = compare_zimg_image_formats(&s->src_format, &s->src_format_tmp) ||
715 compare_zimg_image_formats(&s->dst_format, &s->dst_format_tmp) ||
716 compare_zimg_graph_builder_params(&s->params, &s->params_tmp);
717 if(td->desc->flags & AV_PIX_FMT_FLAG_ALPHA && td->odesc->flags & AV_PIX_FMT_FLAG_ALPHA)
718 need_gb = need_gb || compare_zimg_image_formats(&s->alpha_src_format, &s->alpha_src_format_tmp) ||
719 compare_zimg_image_formats(&s->alpha_dst_format, &s->alpha_dst_format_tmp) ||
720 compare_zimg_graph_builder_params(&s->alpha_params, &s->alpha_params_tmp);
721
722 if (need_gb){
723 ret = graphs_build(td->in, td->out, td->desc, td->odesc, s, job_nr);
724 if (ret < 0)
725 return print_zimg_error(ctx);
726 }
727 out_sampl = FFMAX3(td->out->linesize[0], td->out->linesize[1], td->out->linesize[2]);
728 for (int i = 0; i < 3; i++) {
729 p = td->desc->comp[i].plane;
730
731 src_buf.plane[i].data = td->in->data[p];
732 src_buf.plane[i].stride = td->in->linesize[p];
733 src_buf.plane[i].mask = -1;
734
735 p = td->odesc->comp[i].plane;
736 dst_buf.plane[i].data = td->out->data[p] + td->out->linesize[p] * dst_tile_height * td->out->linesize[p] / out_sampl * job_nr;
737 dst_buf.plane[i].stride = td->out->linesize[p];
738 dst_buf.plane[i].mask = -1;
739 }
740 ret = zimg_filter_graph_process(s->graph[job_nr], &src_buf, &dst_buf, s->tmp[job_nr], 0, 0, 0, 0);
741 if (ret)
742 return print_zimg_error(ctx);
743
744 if (td->desc->flags & AV_PIX_FMT_FLAG_ALPHA && td->odesc->flags & AV_PIX_FMT_FLAG_ALPHA) {
745 src_buf.plane[0].data = td->in->data[3];
746 src_buf.plane[0].stride = td->in->linesize[3];
747 src_buf.plane[0].mask = -1;
748
749 dst_buf.plane[0].data = td->out->data[3] + td->out->linesize[3] * dst_tile_height * job_nr;
750 dst_buf.plane[0].stride = td->out->linesize[3];
751 dst_buf.plane[0].mask = -1;
752
753 ret = zimg_filter_graph_process(s->alpha_graph[job_nr], &src_buf, &dst_buf, s->tmp[job_nr], 0, 0, 0, 0);
754 if (ret)
755 return print_zimg_error(ctx);
756 }
757 return 0;
758}
759
575static int filter_frame(AVFilterLink *link, AVFrame *in)760static int filter_frame(AVFilterLink *link, AVFrame *in)
576{761{
577 ZScaleContext *s = link->dst->priv;762 AVFilterContext *ctx = link->dst;
578 AVFilterLink *outlink = link->dst->outputs[0];763 ZScaleContext *s = ctx->priv;
764 AVFilterLink *outlink = ctx->outputs[0];
579 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format);765 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format);
580 const AVPixFmtDescriptor *odesc = av_pix_fmt_desc_get(outlink->format);766 const AVPixFmtDescriptor *odesc = av_pix_fmt_desc_get(outlink->format);
581 zimg_image_buffer_const src_buf = { ZIMG_API_VERSION };
582 zimg_image_buffer dst_buf = { ZIMG_API_VERSION };
583 char buf[32];767 char buf[32];
584 int ret = 0, plane;768 int ret = 0;
585 AVFrame *out = NULL;769 AVFrame *out = NULL;
586 770 ThreadData td;
587 if ((ret = realign_frame(desc, &in)) < 0)
588 goto fail;
589 771
590 if (!(out = ff_get_video_buffer(outlink, outlink->w, outlink->h))) {772 if (!(out = ff_get_video_buffer(outlink, outlink->w, outlink->h))) {
591 ret = AVERROR(ENOMEM);773 ret = AVERROR(ENOMEM);
@@ -596,19 +778,23 @@ static int filter_frame(AVFilterLink *link, AVFrame *in) · 4 unmodified lines
596 out->width = outlink->w;778 out->width = outlink->w;
597 out->height = outlink->h;779 out->height = outlink->h;
598 780
599 if( in->width != link->w781 //we need to use this filter if something is different for an input and output only
600 || in->height != link->h782 //otherwise - just copy the input frame to the output
601 || in->format != link->format783 if ((link->w != outlink->w) ||
602 || s->in_colorspace != in->colorspace784 (link->h != outlink->h) ||
603 || s->in_trc != in->color_trc785 (s->src_format.chroma_location != s->dst_format.chroma_location) ||
604 || s->in_primaries != in->color_primaries786 (s->src_format.color_family !=s->dst_format.color_family) ||
605 || s->in_range != in->color_range787 (s->src_format.color_primaries !=s->dst_format.color_primaries) ||
606 || s->out_colorspace != out->colorspace788 (s->src_format.depth !=s->dst_format.depth) ||
607 || s->out_trc != out->color_trc789 (s->src_format.matrix_coefficients !=s->dst_format.matrix_coefficients) ||
608 || s->out_primaries != out->color_primaries790 (s->src_format.field_parity !=s->dst_format.field_parity) ||
609 || s->out_range != out->color_range791 (s->src_format.pixel_range !=s->dst_format.pixel_range) ||
610 || s->in_chromal != in->chroma_location792 (s->src_format.pixel_type !=s->dst_format.pixel_type) ||
611 || s->out_chromal != out->chroma_location) {793 (s->src_format.transfer_characteristics !=s->dst_format.transfer_characteristics)
794 ){
795 if ((ret = realign_frame(desc, &in)) < 0)
796 goto fail;
797
612 snprintf(buf, sizeof(buf)-1, "%d", outlink->w);798 snprintf(buf, sizeof(buf)-1, "%d", outlink->w);
613 av_opt_set(s, "w", buf, 0);799 av_opt_set(s, "w", buf, 0);
614 snprintf(buf, sizeof(buf)-1, "%d", outlink->h);800 snprintf(buf, sizeof(buf)-1, "%d", outlink->h);
@@ -618,13 +804,26 @@ static int filter_frame(AVFilterLink *link, AVFrame *in) · 3 unmodified lines
618 link->dst->inputs[0]->w = in->width;804 link->dst->inputs[0]->w = in->width;
619 link->dst->inputs[0]->h = in->height;805 link->dst->inputs[0]->h = in->height;
620 806
621 if ((ret = config_props(outlink)) < 0)807 s->nb_threads = FFMIN(ff_filter_get_nb_threads(ctx), link->h / MIN_TILESIZE);
622 goto fail;808 s->slice_h = ((unsigned int)(link->h / s->nb_threads)) & 0xfffffffe; // slice_h should be even for zimg
809 s->in_colorspace = in->colorspace;
810 s->in_trc = in->color_trc;
811 s->in_primaries = in->color_primaries;
812 s->in_range = in->color_range;
813 s->out_colorspace = out->colorspace;
814 s->out_trc = out->color_trc;
815 s->out_primaries = out->color_primaries;
816 s->out_range = out->color_range;
623 817
624 zimg_image_format_default(&s->src_format, ZIMG_API_VERSION);818 zimg_image_format_default(&s->src_format, ZIMG_API_VERSION);
625 zimg_image_format_default(&s->dst_format, ZIMG_API_VERSION);819 zimg_image_format_default(&s->dst_format, ZIMG_API_VERSION);
626 zimg_graph_builder_params_default(&s->params, ZIMG_API_VERSION);820 zimg_graph_builder_params_default(&s->params, ZIMG_API_VERSION);
627 821
822 format_init(&s->src_format, in, desc, s->colorspace_in,
823 s->primaries_in, s->trc_in, s->range_in, s->chromal_in);
824 format_init(&s->dst_format, out, odesc, s->colorspace,
825 s->primaries, s->trc, s->range, s->chromal);
826
628 s->params.dither_type = s->dither;827 s->params.dither_type = s->dither;
629 s->params.cpu_type = ZIMG_CPU_AUTO;828 s->params.cpu_type = ZIMG_CPU_AUTO;
630 s->params.resample_filter = s->filter;829 s->params.resample_filter = s->filter;
@@ -634,27 +833,6 @@ static int filter_frame(AVFilterLink *link, AVFrame *in) · 3 unmodified lines
634 s->params.filter_param_a = s->params.filter_param_a_uv = s->param_a;833 s->params.filter_param_a = s->params.filter_param_a_uv = s->param_a;
635 s->params.filter_param_b = s->params.filter_param_b_uv = s->param_b;834 s->params.filter_param_b = s->params.filter_param_b_uv = s->param_b;
636 835
637 format_init(&s->src_format, in, desc, s->colorspace_in,
638 s->primaries_in, s->trc_in, s->range_in, s->chromal_in);
639 format_init(&s->dst_format, out, odesc, s->colorspace,
640 s->primaries, s->trc, s->range, s->chromal);
641
642 update_output_color_information(s, out);
643
644 ret = graph_build(&s->graph, &s->params, &s->src_format, &s->dst_format,
645 &s->tmp, &s->tmp_size);
646 if (ret < 0)
647 goto fail;
648
649 s->in_colorspace = in->colorspace;
650 s->in_trc = in->color_trc;
651 s->in_primaries = in->color_primaries;
652 s->in_range = in->color_range;
653 s->out_colorspace = out->colorspace;
654 s->out_trc = out->color_trc;
655 s->out_primaries = out->color_primaries;
656 s->out_range = out->color_range;
657
658 if (desc->flags & AV_PIX_FMT_FLAG_ALPHA && odesc->flags & AV_PIX_FMT_FLAG_ALPHA) {836 if (desc->flags & AV_PIX_FMT_FLAG_ALPHA && odesc->flags & AV_PIX_FMT_FLAG_ALPHA) {
659 zimg_image_format_default(&s->alpha_src_format, ZIMG_API_VERSION);837 zimg_image_format_default(&s->alpha_src_format, ZIMG_API_VERSION);
660 zimg_image_format_default(&s->alpha_dst_format, ZIMG_API_VERSION);838 zimg_image_format_default(&s->alpha_dst_format, ZIMG_API_VERSION);
@@ -670,76 +848,52 @@ static int filter_frame(AVFilterLink *link, AVFrame *in) · 9 unmodified lines
670 s->alpha_src_format.pixel_type = (desc->flags & AV_PIX_FMT_FLAG_FLOAT) ? ZIMG_PIXEL_FLOAT : desc->comp[0].depth > 8 ? ZIMG_PIXEL_WORD : ZIMG_PIXEL_BYTE;848 s->alpha_src_format.pixel_type = (desc->flags & AV_PIX_FMT_FLAG_FLOAT) ? ZIMG_PIXEL_FLOAT : desc->comp[0].depth > 8 ? ZIMG_PIXEL_WORD : ZIMG_PIXEL_BYTE;
671 s->alpha_src_format.color_family = ZIMG_COLOR_GREY;849 s->alpha_src_format.color_family = ZIMG_COLOR_GREY;
672 850
673 s->alpha_dst_format.width = out->width;
674 s->alpha_dst_format.height = out->height;
675 s->alpha_dst_format.depth = odesc->comp[0].depth;851 s->alpha_dst_format.depth = odesc->comp[0].depth;
676 s->alpha_dst_format.pixel_type = (odesc->flags & AV_PIX_FMT_FLAG_FLOAT) ? ZIMG_PIXEL_FLOAT : odesc->comp[0].depth > 8 ? ZIMG_PIXEL_WORD : ZIMG_PIXEL_BYTE;852 s->alpha_dst_format.pixel_type = (odesc->flags & AV_PIX_FMT_FLAG_FLOAT) ? ZIMG_PIXEL_FLOAT : odesc->comp[0].depth > 8 ? ZIMG_PIXEL_WORD : ZIMG_PIXEL_BYTE;
677 s->alpha_dst_format.color_family = ZIMG_COLOR_GREY;853 s->alpha_dst_format.color_family = ZIMG_COLOR_GREY;
678
679 zimg_filter_graph_free(s->alpha_graph);
680 s->alpha_graph = zimg_filter_graph_build(&s->alpha_src_format, &s->alpha_dst_format, &s->alpha_params);
681 if (!s->alpha_graph) {
682 ret = print_zimg_error(link->dst);
683 goto fail;
684 }
685 }854 }
686 }
687
688 update_output_color_information(s, out);
689
690 av_reduce(&out->sample_aspect_ratio.num, &out->sample_aspect_ratio.den,
691 (int64_t)in->sample_aspect_ratio.num * outlink->h * link->w,
692 (int64_t)in->sample_aspect_ratio.den * outlink->w * link->h,
693 INT_MAX);
694
695 for (plane = 0; plane < 3; plane++) {
696 int p = desc->comp[plane].plane;
697 src_buf.plane[plane].data = in->data[p];
698 src_buf.plane[plane].stride = in->linesize[p];
699 src_buf.plane[plane].mask = -1;
700
701 p = odesc->comp[plane].plane;
702 dst_buf.plane[plane].data = out->data[p];
703 dst_buf.plane[plane].stride = out->linesize[p];
704 dst_buf.plane[plane].mask = -1;
705 }
706 855
707 ret = zimg_filter_graph_process(s->graph, &src_buf, &dst_buf, s->tmp, 0, 0, 0, 0);856 update_output_color_information(s, out);
708 if (ret) {857 av_reduce(&out->sample_aspect_ratio.num, &out->sample_aspect_ratio.den,
709 ret = print_zimg_error(link->dst);858 (int64_t)in->sample_aspect_ratio.num * outlink->h * link->w,
710 goto fail;859 (int64_t)in->sample_aspect_ratio.den * outlink->w * link->h,
711 }860 INT_MAX);
712 861
713 if (desc->flags & AV_PIX_FMT_FLAG_ALPHA && odesc->flags & AV_PIX_FMT_FLAG_ALPHA) {862 td.in = in;
714 src_buf.plane[0].data = in->data[3];863 td.out = out;
715 src_buf.plane[0].stride = in->linesize[3];864 td.desc = desc;
716 src_buf.plane[0].mask = -1;865 td.odesc = odesc;
717 866
718 dst_buf.plane[0].data = out->data[3];867 ff_filter_execute(ctx, filter_slice, &td, NULL, s->nb_threads);
719 dst_buf.plane[0].stride = out->linesize[3];
720 dst_buf.plane[0].mask = -1;
721 868
722 ret = zimg_filter_graph_process(s->alpha_graph, &src_buf, &dst_buf, s->tmp, 0, 0, 0, 0);869 s->src_format_tmp = s->src_format;
723 if (ret) {870 s->dst_format_tmp = s->dst_format;
724 ret = print_zimg_error(link->dst);871 s->params_tmp = s->params;
725 goto fail;872 if (desc->flags & AV_PIX_FMT_FLAG_ALPHA && odesc->flags & AV_PIX_FMT_FLAG_ALPHA) {
873 s->alpha_src_format_tmp = s->alpha_src_format;
874 s->alpha_dst_format_tmp = s->alpha_dst_format;
875 s->alpha_params_tmp = s->alpha_params;
726 }876 }
727 } else if (odesc->flags & AV_PIX_FMT_FLAG_ALPHA) {877
728 int x, y;878 if ((!(desc->flags & AV_PIX_FMT_FLAG_ALPHA)) && (odesc->flags & AV_PIX_FMT_FLAG_ALPHA) ){
729 879 int x, y;
730 if (odesc->flags & AV_PIX_FMT_FLAG_FLOAT) {880 if (odesc->flags & AV_PIX_FMT_FLAG_FLOAT) {
731 for (y = 0; y < out->height; y++) {881 for (y = 0; y < out->height; y++) {
732 for (x = 0; x < out->width; x++) {882 for (x = 0; x < out->width; x++) {
733 AV_WN32(out->data[3] + x * odesc->comp[3].step + y * out->linesize[3],883 AV_WN32(out->data[3] + x * odesc->comp[3].step + y * out->linesize[3],
734 av_float2int(1.0f));884 av_float2int(1.0f));
885 }
735 }886 }
887 } else {
888 for (y = 0; y < outlink->h; y++)
889 memset(out->data[3] + y * out->linesize[3], 0xff, outlink->w);
736 }890 }
737 } else {
738 for (y = 0; y < outlink->h; y++)
739 memset(out->data[3] + y * out->linesize[3], 0xff, outlink->w);
740 }891 }
741 }892 }
742 893 else {
894 /*no need for any filtering */
895 return ff_filter_frame(outlink, in);
896 }
743fail:897fail:
744 av_frame_free(&in);898 av_frame_free(&in);
745 if (ret) {899 if (ret) {
@@ -754,10 +908,11 @@ static av_cold void uninit(AVFilterContext *ctx) · 8 unmodified lines
754{908{
755 ZScaleContext *s = ctx->priv;909 ZScaleContext *s = ctx->priv;
756 910
757 zimg_filter_graph_free(s->graph);911 for (int i = 0; i < s->nb_threads; i++) {
758 zimg_filter_graph_free(s->alpha_graph);912 av_freep(&s->tmp[i]);
759 av_freep(&s->tmp);913 zimg_filter_graph_free(s->graph[i]);
760 s->tmp_size = 0;914 zimg_filter_graph_free(s->alpha_graph[i]);
915 }
761}916}
762 917
763static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,918static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
@@ -941,4 +1096,5 @@ const AVFilter ff_vf_zscale = { · 177 unmodified lines
941 FILTER_OUTPUTS(avfilter_vf_zscale_outputs),1096 FILTER_OUTPUTS(avfilter_vf_zscale_outputs),
942 FILTER_QUERY_FUNC(query_formats),1097 FILTER_QUERY_FUNC(query_formats),
943 .process_command = process_command,1098 .process_command = process_command,
1099 .flags = AVFILTER_FLAG_SLICE_THREADS,
944};1100};

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t