Showing the changes to libavfilter (1 of 1 file). Show all
Unified · Split
| @@ -44,8 +44,7 @@ · 43 unmodified lines | |||
| 44 | #include "libavutil/pixdesc.h" | 44 | #include "libavutil/pixdesc.h" |
| 45 | #include "libavutil/imgutils.h" | 45 | #include "libavutil/imgutils.h" |
| 46 | 46 | ||
| 47 | #define ZIMG_ALIGNMENT 32 | 47 | #define ZIMG_ALIGNMENT 64 |
| 48 | #define MIN_TILESIZE 64 | ||
| 49 | #define MAX_THREADS 64 | 48 | #define MAX_THREADS 64 |
| 50 | 49 | ||
| 51 | static const char *const var_names[] = { | 50 | static const char *const var_names[] = { |
| @@ -118,7 +117,6 @@ typedef struct ZScaleContext { · 66 unmodified lines | |||
| 118 | 117 | ||
| 119 | void *tmp[MAX_THREADS]; //separate for each thread; | 118 | void *tmp[MAX_THREADS]; //separate for each thread; |
| 120 | int nb_threads; | 119 | int nb_threads; |
| 121 | int slice_h; | ||
| 122 | 120 | ||
| 123 | zimg_image_format src_format, dst_format; | 121 | zimg_image_format src_format, dst_format; |
| 124 | zimg_image_format alpha_src_format, alpha_dst_format; | 122 | zimg_image_format alpha_src_format, alpha_dst_format; |
| @@ -566,48 +564,47 @@ static void format_init(zimg_image_format *format, AVFrame *frame, const AVPixFm · 441 unmodified lines | |||
| 566 | } | 564 | } |
| 567 | 565 | ||
| 568 | static int graphs_build(AVFrame *in, AVFrame *out, const AVPixFmtDescriptor *desc, const AVPixFmtDescriptor *out_desc, | 566 | static int graphs_build(AVFrame *in, AVFrame *out, const AVPixFmtDescriptor *desc, const AVPixFmtDescriptor *out_desc, |
| 569 | ZScaleContext *s, int job_nr) | 567 | AVFilterContext *ctx, int job_nr, int n_jobs) |
| 570 | { | 568 | { |
| 569 | ZScaleContext *s = ctx->priv; | ||
| 571 | int ret; | 570 | int ret; |
| 572 | size_t size; | 571 | size_t size; |
| 573 | zimg_image_format src_format; | 572 | zimg_image_format src_format; |
| 574 | zimg_image_format dst_format; | 573 | zimg_image_format dst_format; |
| 575 | zimg_image_format alpha_src_format; | 574 | zimg_image_format alpha_src_format; |
| 576 | zimg_image_format alpha_dst_format; | 575 | zimg_image_format alpha_dst_format; |
| 576 | const int in_slice_start = 4 * ((((in->height + 2) / 4) * job_nr) / n_jobs); | ||
| 577 | const int in_slice_end = (job_nr == n_jobs-1) ? in->height : 4 * (((in->height + 2) / 4) * (job_nr+1) / n_jobs); | ||
| 578 | const int out_slice_start = 4 * ((((out->height + 2) / 4) * job_nr) / n_jobs); | ||
| 579 | const int out_slice_end = (job_nr == n_jobs-1) ? out->height : 4 * (((out->height + 2) / 4) * (job_nr+1) / n_jobs); | ||
| 577 | 580 | ||
| 578 | src_format = s->src_format; | 581 | src_format = s->src_format; |
| 579 | dst_format = s->dst_format; | 582 | dst_format = s->dst_format; |
| 580 | /* The input slice is specified through the active_region field, | 583 | /* The input slice is specified through the active_region field, |
| 581 | unlike the output slice. | 584 | unlike the output slice. |
| 582 | according to zimg requirements input and output slices should have even dimentions */ | 585 | according to zimg requirements input and output slices should have even dimensions */ |
| 583 | src_format.active_region.width = in->width; | 586 | src_format.active_region.width = in->width; |
| 584 | src_format.active_region.height = s->slice_h; | 587 | src_format.active_region.height = in_slice_end - in_slice_start; |
| 585 | src_format.active_region.left = 0; | 588 | src_format.active_region.left = 0; |
| 586 | src_format.active_region.top = job_nr * src_format.active_region.height; | 589 | src_format.active_region.top = in_slice_start; |
| 587 | //dst now is the single tile only!! | 590 | //dst now is the single tile only!! |
| 588 | dst_format.width = out->width; | 591 | dst_format.width = out->width; |
| 589 | dst_format.height = ((unsigned int)(out->height / s->nb_threads)) & 0xfffffffe; | 592 | dst_format.height = out_slice_end - out_slice_start; |
| 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 | } | ||
| 596 | 593 | ||
| 597 | if (s->graph[job_nr]) { | 594 | if (s->graph[job_nr]) { |
| 598 | zimg_filter_graph_free(s->graph[job_nr]); | 595 | zimg_filter_graph_free(s->graph[job_nr]); |
| 599 | } | 596 | } |
| 600 | s->graph[job_nr] = zimg_filter_graph_build(&src_format, &dst_format, &s->params); | 597 | s->graph[job_nr] = zimg_filter_graph_build(&src_format, &dst_format, &s->params); |
| 601 | if (!s->graph[job_nr]) | 598 | if (!s->graph[job_nr]) |
| 602 | return print_zimg_error(NULL); | 599 | return print_zimg_error(ctx); |
| 603 | 600 | ||
| 604 | ret = zimg_filter_graph_get_tmp_size(s->graph[job_nr], &size); | 601 | ret = zimg_filter_graph_get_tmp_size(s->graph[job_nr], &size); |
| 605 | if (ret) | 602 | if (ret) |
| 606 | return print_zimg_error(NULL); | 603 | return print_zimg_error(ctx); |
| 607 | 604 | ||
| 608 | if (s->tmp[job_nr]) | 605 | if (s->tmp[job_nr]) |
| 609 | av_freep(&s->tmp[job_nr]); | 606 | av_freep(&s->tmp[job_nr]); |
| 610 | s->tmp[job_nr] = av_malloc(size); | 607 | s->tmp[job_nr] = av_calloc(size, 1); |
| 611 | if (!s->tmp[job_nr]) | 608 | if (!s->tmp[job_nr]) |
| 612 | return AVERROR(ENOMEM); | 609 | return AVERROR(ENOMEM); |
| 613 | 610 | ||
| @@ -617,25 +614,19 @@ static int graphs_build(AVFrame *in, AVFrame *out, const AVPixFmtDescriptor *des · 3 unmodified lines | |||
| 617 | /* The input slice is specified through the active_region field, unlike the output slice. | 614 | /* 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 */ | 615 | according to zimg requirements input and output slices should have even dimentions */ |
| 619 | alpha_src_format.active_region.width = in->width; | 616 | alpha_src_format.active_region.width = in->width; |
| 620 | alpha_src_format.active_region.height = s->slice_h; | 617 | alpha_src_format.active_region.height = in_slice_end - in_slice_start; |
| 621 | alpha_src_format.active_region.left = 0; | 618 | alpha_src_format.active_region.left = 0; |
| 622 | alpha_src_format.active_region.top = job_nr * alpha_src_format.active_region.height; | 619 | alpha_src_format.active_region.top = in_slice_start; |
| 623 | //dst now is the single tile only!! | 620 | //dst now is the single tile only!! |
| 624 | alpha_dst_format.width = out->width; | 621 | alpha_dst_format.width = out->width; |
| 625 | alpha_dst_format.height = ((unsigned int)(out->height / s->nb_threads)) & 0xfffffffe; | 622 | alpha_dst_format.height = out_slice_end - out_slice_start; |
| 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 | } | ||
| 632 | 623 | ||
| 633 | if (s->alpha_graph[job_nr]) { | 624 | if (s->alpha_graph[job_nr]) { |
| 634 | zimg_filter_graph_free(s->alpha_graph[job_nr]); | 625 | zimg_filter_graph_free(s->alpha_graph[job_nr]); |
| 635 | } | 626 | } |
| 636 | s->alpha_graph[job_nr] = zimg_filter_graph_build(&alpha_src_format, &alpha_dst_format, &s->alpha_params); | 627 | 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]) | 628 | if (!s->alpha_graph[job_nr]) |
| 638 | return print_zimg_error(NULL); | 629 | return print_zimg_error(ctx); |
| 639 | } | 630 | } |
| 640 | return 0; | 631 | return 0; |
| 641 | } | 632 | } |
| @@ -702,12 +693,11 @@ static int filter_slice(AVFilterContext *ctx, void *data, int job_nr, int n_jobs · 60 unmodified lines | |||
| 702 | ThreadData *td = data; | 693 | ThreadData *td = data; |
| 703 | int ret = 0; | 694 | int ret = 0; |
| 704 | int p; | 695 | int p; |
| 705 | int out_sampl; | ||
| 706 | int need_gb; | 696 | int need_gb; |
| 707 | ZScaleContext *s = ctx->priv; | 697 | ZScaleContext *s = ctx->priv; |
| 708 | zimg_image_buffer_const src_buf = { ZIMG_API_VERSION }; | 698 | zimg_image_buffer_const src_buf = { ZIMG_API_VERSION }; |
| 709 | zimg_image_buffer dst_buf = { ZIMG_API_VERSION }; | 699 | zimg_image_buffer dst_buf = { ZIMG_API_VERSION }; |
| 710 | int dst_tile_height = ((unsigned int)(td->out->height / n_jobs)) & 0xfffffffe; | 700 | const int out_slice_start = 4 * ((((td->out->height + 2) / 4) * job_nr) / n_jobs); |
| 711 | 701 | ||
| 712 | /* create zimg filter graphs for each thread | 702 | /* create zimg filter graphs for each thread |
| 713 | only if not created earlier or there is some change in frame parameters */ | 703 | only if not created earlier or there is some change in frame parameters */ |
| @@ -720,12 +710,13 @@ static int filter_slice(AVFilterContext *ctx, void *data, int job_nr, int n_jobs · 6 unmodified lines | |||
| 720 | compare_zimg_graph_builder_params(&s->alpha_params, &s->alpha_params_tmp); | 710 | compare_zimg_graph_builder_params(&s->alpha_params, &s->alpha_params_tmp); |
| 721 | 711 | ||
| 722 | if (need_gb){ | 712 | if (need_gb){ |
| 723 | ret = graphs_build(td->in, td->out, td->desc, td->odesc, s, job_nr); | 713 | ret = graphs_build(td->in, td->out, td->desc, td->odesc, ctx, job_nr, n_jobs); |
| 724 | if (ret < 0) | 714 | if (ret < 0) |
| 725 | return print_zimg_error(ctx); | 715 | return print_zimg_error(ctx); |
| 726 | } | 716 | } |
| 727 | out_sampl = FFMAX3(td->out->linesize[0], td->out->linesize[1], td->out->linesize[2]); | ||
| 728 | for (int i = 0; i < 3; i++) { | 717 | for (int i = 0; i < 3; i++) { |
| 718 | const int vsamp = i >= 1 ? td->odesc->log2_chroma_h : 0; | ||
| 719 | |||
| 729 | p = td->desc->comp[i].plane; | 720 | p = td->desc->comp[i].plane; |
| 730 | 721 | ||
| 731 | src_buf.plane[i].data = td->in->data[p]; | 722 | src_buf.plane[i].data = td->in->data[p]; |
| @@ -733,7 +724,7 @@ static int filter_slice(AVFilterContext *ctx, void *data, int job_nr, int n_jobs · 1 unmodified line | |||
| 733 | src_buf.plane[i].mask = -1; | 724 | src_buf.plane[i].mask = -1; |
| 734 | 725 | ||
| 735 | p = td->odesc->comp[i].plane; | 726 | 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; | 727 | dst_buf.plane[i].data = td->out->data[p] + td->out->linesize[p] * (out_slice_start >> vsamp); |
| 737 | dst_buf.plane[i].stride = td->out->linesize[p]; | 728 | dst_buf.plane[i].stride = td->out->linesize[p]; |
| 738 | dst_buf.plane[i].mask = -1; | 729 | dst_buf.plane[i].mask = -1; |
| 739 | } | 730 | } |
| @@ -746,7 +737,7 @@ static int filter_slice(AVFilterContext *ctx, void *data, int job_nr, int n_jobs · 6 unmodified lines | |||
| 746 | src_buf.plane[0].stride = td->in->linesize[3]; | 737 | src_buf.plane[0].stride = td->in->linesize[3]; |
| 747 | src_buf.plane[0].mask = -1; | 738 | src_buf.plane[0].mask = -1; |
| 748 | 739 | ||
| 749 | dst_buf.plane[0].data = td->out->data[3] + td->out->linesize[3] * dst_tile_height * job_nr; | 740 | dst_buf.plane[0].data = td->out->data[3] + td->out->linesize[3] * out_slice_start; |
| 750 | dst_buf.plane[0].stride = td->out->linesize[3]; | 741 | dst_buf.plane[0].stride = td->out->linesize[3]; |
| 751 | dst_buf.plane[0].mask = -1; | 742 | dst_buf.plane[0].mask = -1; |
| 752 | 743 | ||
| @@ -804,8 +795,7 @@ static int filter_frame(AVFilterLink *link, AVFrame *in) · 51 unmodified lines | |||
| 804 | link->dst->inputs[0]->w = in->width; | 795 | link->dst->inputs[0]->w = in->width; |
| 805 | link->dst->inputs[0]->h = in->height; | 796 | link->dst->inputs[0]->h = in->height; |
| 806 | 797 | ||
| 807 | s->nb_threads = FFMIN(ff_filter_get_nb_threads(ctx), link->h / MIN_TILESIZE); | 798 | s->nb_threads = FFMIN(ff_filter_get_nb_threads(ctx), link->h / 8); |
| 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; | 799 | s->in_colorspace = in->colorspace; |
| 810 | s->in_trc = in->color_trc; | 800 | s->in_trc = in->color_trc; |
| 811 | s->in_primaries = in->color_primaries; | 801 | s->in_primaries = in->color_primaries; |