Setting it was broken in 8160178dfc0e6bdaacf80dec58e595a9d595eedc, since links are not yet set up during init. It is also redundant, as the struct also stores the input index.
Unified · Split
| @@ -143,7 +143,6 @@ typedef struct LibplaceboInput { · 142 unmodified lines | |||
| 143 | pl_queue queue; | 143 | pl_queue queue; |
| 144 | enum pl_queue_status qstatus; | 144 | enum pl_queue_status qstatus; |
| 145 | struct pl_frame_mix mix; ///< temporary storage | 145 | struct pl_frame_mix mix; ///< temporary storage |
| 146 | AVFilterLink *link; | ||
| 147 | AVFifo *out_pts; ///< timestamps of wanted output frames | 146 | AVFifo *out_pts; ///< timestamps of wanted output frames |
| 148 | int64_t status_pts; | 147 | int64_t status_pts; |
| 149 | int status; | 148 | int status; |
| @@ -593,8 +592,7 @@ static void unlock_queue(void *priv, uint32_t qf, uint32_t qidx) · 443 unmodified lines | |||
| 593 | } | 592 | } |
| 594 | #endif | 593 | #endif |
| 595 | 594 | ||
| 596 | static int input_init(AVFilterContext *avctx, AVFilterLink *link, | 595 | static int input_init(AVFilterContext *avctx, LibplaceboInput *input, int idx) |
| 597 | LibplaceboInput *input, int idx) | ||
| 598 | { | 596 | { |
| 599 | LibplaceboContext *s = avctx->priv; | 597 | LibplaceboContext *s = avctx->priv; |
| 600 | 598 | ||
| @@ -603,7 +601,6 @@ static int input_init(AVFilterContext *avctx, AVFilterLink *link, · 2 unmodified lines | |||
| 603 | return AVERROR(ENOMEM); | 601 | return AVERROR(ENOMEM); |
| 604 | input->queue = pl_queue_create(s->gpu); | 602 | input->queue = pl_queue_create(s->gpu); |
| 605 | input->renderer = pl_renderer_create(s->log, s->gpu); | 603 | input->renderer = pl_renderer_create(s->log, s->gpu); |
| 606 | input->link = link; | ||
| 607 | input->idx = idx; | 604 | input->idx = idx; |
| 608 | 605 | ||
| 609 | return 0; | 606 | return 0; |
| @@ -690,7 +687,7 @@ static int init_vulkan(AVFilterContext *avctx, const AVVulkanDeviceContext *hwct · 80 unmodified lines | |||
| 690 | if (!s->inputs) | 687 | if (!s->inputs) |
| 691 | return AVERROR(ENOMEM); | 688 | return AVERROR(ENOMEM); |
| 692 | for (int i = 0; i < s->nb_inputs; i++) | 689 | for (int i = 0; i < s->nb_inputs; i++) |
| 693 | RET(input_init(avctx, avctx->inputs[i], &s->inputs[i], i)); | 690 | RET(input_init(avctx, &s->inputs[i], i)); |
| 694 | 691 | ||
| 695 | /* fall through */ | 692 | /* fall through */ |
| 696 | fail: | 693 | fail: |
| @@ -756,6 +753,7 @@ static void update_crops(AVFilterContext *ctx, LibplaceboInput *in, · 59 unmodified lines | |||
| 756 | { | 753 | { |
| 757 | FilterLink *outl = ff_filter_link(ctx->outputs[0]); | 754 | FilterLink *outl = ff_filter_link(ctx->outputs[0]); |
| 758 | LibplaceboContext *s = ctx->priv; | 755 | LibplaceboContext *s = ctx->priv; |
| 756 | const AVFilterLink *inlink = ctx->inputs[in->idx]; | ||
| 759 | const AVFrame *ref = ref_frame(&in->mix); | 757 | const AVFrame *ref = ref_frame(&in->mix); |
| 760 | 758 | ||
| 761 | for (int i = 0; i < in->mix.num_frames; i++) { | 759 | for (int i = 0; i < in->mix.num_frames; i++) { |
| @@ -763,15 +761,15 @@ static void update_crops(AVFilterContext *ctx, LibplaceboInput *in, · 1 unmodified line | |||
| 763 | // own the entire pl_queue, and hence, the pointed-at frames. | 761 | // own the entire pl_queue, and hence, the pointed-at frames. |
| 764 | struct pl_frame *image = (struct pl_frame *) in->mix.frames[i]; | 762 | struct pl_frame *image = (struct pl_frame *) in->mix.frames[i]; |
| 765 | const AVFrame *src = pl_get_mapped_avframe(image); | 763 | const AVFrame *src = pl_get_mapped_avframe(image); |
| 766 | double image_pts = src->pts * av_q2d(in->link->time_base); | 764 | double image_pts = src->pts * av_q2d(inlink->time_base); |
| 767 | 765 | ||
| 768 | /* Update dynamic variables */ | 766 | /* Update dynamic variables */ |
| 769 | s->var_values[VAR_IN_IDX] = s->var_values[VAR_IDX] = in->idx; | 767 | s->var_values[VAR_IN_IDX] = s->var_values[VAR_IDX] = in->idx; |
| 770 | s->var_values[VAR_IN_W] = s->var_values[VAR_IW] = in->link->w; | 768 | s->var_values[VAR_IN_W] = s->var_values[VAR_IW] = inlink->w; |
| 771 | s->var_values[VAR_IN_H] = s->var_values[VAR_IH] = in->link->h; | 769 | s->var_values[VAR_IN_H] = s->var_values[VAR_IH] = inlink->h; |
| 772 | s->var_values[VAR_A] = (double) in->link->w / in->link->h; | 770 | s->var_values[VAR_A] = (double) inlink->w / inlink->h; |
| 773 | s->var_values[VAR_SAR] = in->link->sample_aspect_ratio.num ? | 771 | s->var_values[VAR_SAR] = inlink->sample_aspect_ratio.num ? |
| 774 | av_q2d(in->link->sample_aspect_ratio) : 1.0; | 772 | av_q2d(inlink->sample_aspect_ratio) : 1.0; |
| 775 | s->var_values[VAR_IN_T] = s->var_values[VAR_T] = image_pts; | 773 | s->var_values[VAR_IN_T] = s->var_values[VAR_T] = image_pts; |
| 776 | s->var_values[VAR_OUT_T] = s->var_values[VAR_OT] = target_pts; | 774 | s->var_values[VAR_OUT_T] = s->var_values[VAR_OT] = target_pts; |
| 777 | s->var_values[VAR_N] = outl->frame_count_out; | 775 | s->var_values[VAR_N] = outl->frame_count_out; |
| @@ -809,7 +807,7 @@ static void update_crops(AVFilterContext *ctx, LibplaceboInput *in, · 31 unmodified lines | |||
| 809 | target->crop.y1 = target->crop.y0 + s->var_values[VAR_POS_H]; | 807 | target->crop.y1 = target->crop.y0 + s->var_values[VAR_POS_H]; |
| 810 | if (s->normalize_sar) { | 808 | if (s->normalize_sar) { |
| 811 | float aspect = pl_rect2df_aspect(&image->crop); | 809 | float aspect = pl_rect2df_aspect(&image->crop); |
| 812 | aspect *= av_q2d(in->link->sample_aspect_ratio); | 810 | aspect *= av_q2d(inlink->sample_aspect_ratio); |
| 813 | pl_rect2df_aspect_set(&target->crop, aspect, s->pad_crop_ratio); | 811 | pl_rect2df_aspect_set(&target->crop, aspect, s->pad_crop_ratio); |
| 814 | } | 812 | } |
| 815 | } | 813 | } |
| @@ -899,7 +897,7 @@ static int output_frame(AVFilterContext *ctx, int64_t pts) · 83 unmodified lines | |||
| 899 | opts->params.blend_params = NULL; | 897 | opts->params.blend_params = NULL; |
| 900 | for (int i = 0; i < s->nb_inputs; i++) { | 898 | for (int i = 0; i < s->nb_inputs; i++) { |
| 901 | LibplaceboInput *in = &s->inputs[i]; | 899 | LibplaceboInput *in = &s->inputs[i]; |
| 902 | FilterLink *il = ff_filter_link(in->link); | 900 | FilterLink *il = ff_filter_link(ctx->inputs[in->idx]); |
| 903 | FilterLink *ol = ff_filter_link(outlink); | 901 | FilterLink *ol = ff_filter_link(outlink); |
| 904 | int high_fps = av_cmp_q(il->frame_rate, ol->frame_rate) >= 0; | 902 | int high_fps = av_cmp_q(il->frame_rate, ol->frame_rate) >= 0; |
| 905 | if (in->qstatus != PL_QUEUE_OK) | 903 | if (in->qstatus != PL_QUEUE_OK) |
| @@ -960,14 +958,15 @@ static int handle_input(AVFilterContext *ctx, LibplaceboInput *input) · 54 unmodified lines | |||
| 960 | int ret, status; | 958 | int ret, status; |
| 961 | LibplaceboContext *s = ctx->priv; | 959 | LibplaceboContext *s = ctx->priv; |
| 962 | AVFilterLink *outlink = ctx->outputs[0]; | 960 | AVFilterLink *outlink = ctx->outputs[0]; |
| 961 | AVFilterLink *inlink = ctx->inputs[input->idx]; | ||
| 963 | AVFrame *in; | 962 | AVFrame *in; |
| 964 | int64_t pts; | 963 | int64_t pts; |
| 965 | 964 | ||
| 966 | while ((ret = ff_inlink_consume_frame(input->link, &in)) > 0) { | 965 | while ((ret = ff_inlink_consume_frame(inlink, &in)) > 0) { |
| 967 | in->opaque = s; | 966 | in->opaque = s; |
| 968 | pl_queue_push(input->queue, &(struct pl_source_frame) { | 967 | pl_queue_push(input->queue, &(struct pl_source_frame) { |
| 969 | .pts = in->pts * av_q2d(input->link->time_base), | 968 | .pts = in->pts * av_q2d(inlink->time_base), |
| 970 | .duration = in->duration * av_q2d(input->link->time_base), | 969 | .duration = in->duration * av_q2d(inlink->time_base), |
| 971 | .first_field = pl_field_from_avframe(in), | 970 | .first_field = pl_field_from_avframe(in), |
| 972 | .frame_data = in, | 971 | .frame_data = in, |
| 973 | .map = map_frame, | 972 | .map = map_frame, |
| @@ -977,7 +976,7 @@ static int handle_input(AVFilterContext *ctx, LibplaceboInput *input) · 3 unmodified lines | |||
| 977 | 976 | ||
| 978 | if (!s->fps.num) { | 977 | if (!s->fps.num) { |
| 979 | /* Internally queue an output frame for the same PTS */ | 978 | /* Internally queue an output frame for the same PTS */ |
| 980 | pts = av_rescale_q(in->pts, input->link->time_base, outlink->time_base); | 979 | pts = av_rescale_q(in->pts, inlink->time_base, outlink->time_base); |
| 981 | av_fifo_write(input->out_pts, &pts, 1); | 980 | av_fifo_write(input->out_pts, &pts, 1); |
| 982 | } | 981 | } |
| 983 | } | 982 | } |
| @@ -985,8 +984,8 @@ static int handle_input(AVFilterContext *ctx, LibplaceboInput *input) · 1 unmodified line | |||
| 985 | if (ret < 0) | 984 | if (ret < 0) |
| 986 | return ret; | 985 | return ret; |
| 987 | 986 | ||
| 988 | if (!input->status && ff_inlink_acknowledge_status(input->link, &status, &pts)) { | 987 | if (!input->status && ff_inlink_acknowledge_status(inlink, &status, &pts)) { |
| 989 | pts = av_rescale_q_rnd(pts, input->link->time_base, outlink->time_base, | 988 | pts = av_rescale_q_rnd(pts, inlink->time_base, outlink->time_base, |
| 990 | AV_ROUND_UP); | 989 | AV_ROUND_UP); |
| 991 | pl_queue_push(input->queue, NULL); /* Signal EOF to pl_queue */ | 990 | pl_queue_push(input->queue, NULL); /* Signal EOF to pl_queue */ |
| 992 | input->status = status; | 991 | input->status = status; |
| @@ -1035,7 +1034,7 @@ static int libplacebo_activate(AVFilterContext *ctx) · 42 unmodified lines | |||
| 1035 | if (av_fifo_peek(in->out_pts, &pts, 1, 0) >= 0) { | 1034 | if (av_fifo_peek(in->out_pts, &pts, 1, 0) >= 0) { |
| 1036 | out_pts = FFMIN(out_pts, pts); | 1035 | out_pts = FFMIN(out_pts, pts); |
| 1037 | } else if (!in->status) { | 1036 | } else if (!in->status) { |
| 1038 | ff_inlink_request_frame(in->link); | 1037 | ff_inlink_request_frame(ctx->inputs[in->idx]); |
| 1039 | retry = true; | 1038 | retry = true; |
| 1040 | } | 1039 | } |
| 1041 | } | 1040 | } |
| @@ -1061,7 +1060,7 @@ static int libplacebo_activate(AVFilterContext *ctx) · 19 unmodified lines | |||
| 1061 | 1060 | ||
| 1062 | switch (in->qstatus) { | 1061 | switch (in->qstatus) { |
| 1063 | case PL_QUEUE_MORE: | 1062 | case PL_QUEUE_MORE: |
| 1064 | ff_inlink_request_frame(in->link); | 1063 | ff_inlink_request_frame(ctx->inputs[in->idx]); |
| 1065 | retry = true; | 1064 | retry = true; |
| 1066 | break; | 1065 | break; |
| 1067 | case PL_QUEUE_OK: | 1066 | case PL_QUEUE_OK: |