Showing the changes to libavfilter (1 of 1 file). Show all
Unified · Split
| @@ -44,8 +44,7 @@ · 43 unmodified lines | ||
| 44 | 44 | #include "libavutil/pixdesc.h" |
| 45 | 45 | #include "libavutil/imgutils.h" |
| 46 | 46 | |
| 47 | −#define ZIMG_ALIGNMENT 32 | |
| 48 | −#define MIN_TILESIZE 64 | |
| 47 | +#define ZIMG_ALIGNMENT 64 | |
| 49 | 48 | #define MAX_THREADS 64 |
| 50 | 49 | |
| 51 | 50 | static const char *const var_names[] = { |
| @@ -118,7 +117,6 @@ typedef struct ZScaleContext { · 66 unmodified lines | ||
| 118 | 117 | |
| 119 | 118 | void *tmp[MAX_THREADS]; //separate for each thread; |
| 120 | 119 | int nb_threads; |
| 121 | − int slice_h; | |
| 122 | 120 | |
| 123 | 121 | zimg_image_format src_format, dst_format; |
| 124 | 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 | 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 | 570 | int ret; |
| 572 | 571 | size_t size; |
| 573 | 572 | zimg_image_format src_format; |
| 574 | 573 | zimg_image_format dst_format; |
| 575 | 574 | zimg_image_format alpha_src_format; |
| 576 | 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 | 581 | src_format = s->src_format; |
| 579 | 582 | dst_format = s->dst_format; |
| 580 | 583 | /* The input slice is specified through the active_region field, |
| 581 | 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 | 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 | 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 | 590 | //dst now is the single tile only!! |
| 588 | 591 | 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 | − } | |
| 592 | + dst_format.height = out_slice_end - out_slice_start; | |
| 596 | 593 | |
| 597 | 594 | if (s->graph[job_nr]) { |
| 598 | 595 | zimg_filter_graph_free(s->graph[job_nr]); |
| 599 | 596 | } |
| 600 | 597 | s->graph[job_nr] = zimg_filter_graph_build(&src_format, &dst_format, &s->params); |
| 601 | 598 | if (!s->graph[job_nr]) |
| 602 | − return print_zimg_error(NULL); | |
| 599 | + return print_zimg_error(ctx); | |
| 603 | 600 | |
| 604 | 601 | ret = zimg_filter_graph_get_tmp_size(s->graph[job_nr], &size); |
| 605 | 602 | if (ret) |
| 606 | − return print_zimg_error(NULL); | |
| 603 | + return print_zimg_error(ctx); | |
| 607 | 604 | |
| 608 | 605 | if (s->tmp[job_nr]) |
| 609 | 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 | 608 | if (!s->tmp[job_nr]) |
| 612 | 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 | 614 | /* The input slice is specified through the active_region field, unlike the output slice. |
| 618 | 615 | according to zimg requirements input and output slices should have even dimentions */ |
| 619 | 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 | 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 | 620 | //dst now is the single tile only!! |
| 624 | 621 | 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 | − } | |
| 622 | + alpha_dst_format.height = out_slice_end - out_slice_start; | |
| 632 | 623 | |
| 633 | 624 | if (s->alpha_graph[job_nr]) { |
| 634 | 625 | zimg_filter_graph_free(s->alpha_graph[job_nr]); |
| 635 | 626 | } |
| 636 | 627 | s->alpha_graph[job_nr] = zimg_filter_graph_build(&alpha_src_format, &alpha_dst_format, &s->alpha_params); |
| 637 | 628 | if (!s->alpha_graph[job_nr]) |
| 638 | − return print_zimg_error(NULL); | |
| 629 | + return print_zimg_error(ctx); | |
| 639 | 630 | } |
| 640 | 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 | 693 | ThreadData *td = data; |
| 703 | 694 | int ret = 0; |
| 704 | 695 | int p; |
| 705 | − int out_sampl; | |
| 706 | 696 | int need_gb; |
| 707 | 697 | ZScaleContext *s = ctx->priv; |
| 708 | 698 | zimg_image_buffer_const src_buf = { ZIMG_API_VERSION }; |
| 709 | 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 | 702 | /* create zimg filter graphs for each thread |
| 713 | 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 | 710 | compare_zimg_graph_builder_params(&s->alpha_params, &s->alpha_params_tmp); |
| 721 | 711 | |
| 722 | 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 | 714 | if (ret < 0) |
| 725 | 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 | 717 | for (int i = 0; i < 3; i++) { |
| 718 | + const int vsamp = i >= 1 ? td->odesc->log2_chroma_h : 0; | |
| 719 | + | |
| 729 | 720 | p = td->desc->comp[i].plane; |
| 730 | 721 | |
| 731 | 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 | 724 | src_buf.plane[i].mask = -1; |
| 734 | 725 | |
| 735 | 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 | 728 | dst_buf.plane[i].stride = td->out->linesize[p]; |
| 738 | 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 | 737 | src_buf.plane[0].stride = td->in->linesize[3]; |
| 747 | 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 | 741 | dst_buf.plane[0].stride = td->out->linesize[3]; |
| 751 | 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 | 795 | link->dst->inputs[0]->w = in->width; |
| 805 | 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); | |
| 808 | − s->slice_h = ((unsigned int)(link->h / s->nb_threads)) & 0xfffffffe; // slice_h should be even for zimg | |
| 798 | + s->nb_threads = FFMIN(ff_filter_get_nb_threads(ctx), link->h / 8); | |
| 809 | 799 | s->in_colorspace = in->colorspace; |
| 810 | 800 | s->in_trc = in->color_trc; |
| 811 | 801 | s->in_primaries = in->color_primaries; |