This aligns the behavior of vf_libplacebo with other filters in the vf_scale family, that forward any change in the SAR as a result of changing the output resolution to the output frame / link, and updates the ff_scale_adjust_dimensions() call to continue working as intended. The new behavior reflects the documentation of vf_libplacebo, which described this behavior despite that not being the way the filter worked up to this point. As an aside, also fixes a bug where the AVFrame SAR was inconsistent with the AVFilterLink SAR when the s->nb_inputs > 1 condition was met.
Unified · Split
| @@ -186,6 +186,7 @@ typedef struct LibplaceboContext { · 185 unmodified lines | |||
| 186 | float corner_rounding; | 186 | float corner_rounding; |
| 187 | int force_original_aspect_ratio; | 187 | int force_original_aspect_ratio; |
| 188 | int force_divisible_by; | 188 | int force_divisible_by; |
| 189 | int reset_sar; | ||
| 189 | int normalize_sar; | 190 | int normalize_sar; |
| 190 | int apply_filmgrain; | 191 | int apply_filmgrain; |
| 191 | int apply_dovi; | 192 | int apply_dovi; |
| @@ -929,6 +930,15 @@ static int output_frame(AVFilterContext *ctx, int64_t pts) · 737 unmodified lines | |||
| 929 | if (s->apply_filmgrain) | 930 | if (s->apply_filmgrain) |
| 930 | av_frame_remove_side_data(out, AV_FRAME_DATA_FILM_GRAIN_PARAMS); | 931 | av_frame_remove_side_data(out, AV_FRAME_DATA_FILM_GRAIN_PARAMS); |
| 931 | 932 | ||
| 933 | if (s->reset_sar) { | ||
| 934 | out->sample_aspect_ratio = ref->sample_aspect_ratio; | ||
| 935 | } else { | ||
| 936 | const AVRational ar_ref = { ref->width, ref->height }; | ||
| 937 | const AVRational ar_out = { out->width, out->height }; | ||
| 938 | const AVRational stretch = av_div_q(ar_ref, ar_out); | ||
| 939 | out->sample_aspect_ratio = av_mul_q(ref->sample_aspect_ratio, stretch); | ||
| 940 | } | ||
| 941 | |||
| 932 | /* Map, render and unmap output frame */ | 942 | /* Map, render and unmap output frame */ |
| 933 | if (outdesc->flags & AV_PIX_FMT_FLAG_HWACCEL) { | 943 | if (outdesc->flags & AV_PIX_FMT_FLAG_HWACCEL) { |
| 934 | ok = pl_map_avframe_ex(s->gpu, &target, pl_avframe_params( | 944 | ok = pl_map_avframe_ex(s->gpu, &target, pl_avframe_params( |
| @@ -1288,19 +1298,28 @@ static int libplacebo_config_output(AVFilterLink *outlink) · 353 unmodified lines | |||
| 1288 | RET(ff_scale_eval_dimensions(s, s->w_expr, s->h_expr, inlink, outlink, | 1298 | RET(ff_scale_eval_dimensions(s, s->w_expr, s->h_expr, inlink, outlink, |
| 1289 | &outlink->w, &outlink->h)); | 1299 | &outlink->w, &outlink->h)); |
| 1290 | 1300 | ||
| 1301 | s->reset_sar = s->normalize_sar || s->nb_inputs > 1; | ||
| 1302 | double sar_in = inlink->sample_aspect_ratio.num ? | ||
| 1303 | av_q2d(inlink->sample_aspect_ratio) : 1.0; | ||
| 1304 | |||
| 1291 | ff_scale_adjust_dimensions(inlink, &outlink->w, &outlink->h, | 1305 | ff_scale_adjust_dimensions(inlink, &outlink->w, &outlink->h, |
| 1292 | s->force_original_aspect_ratio, | 1306 | s->force_original_aspect_ratio, |
| 1293 | s->force_divisible_by, 1.f); | 1307 | s->force_divisible_by, |
| 1308 | s->reset_sar ? sar_in : 1.0); | ||
| 1294 | 1309 | ||
| 1295 | if (s->normalize_sar || s->nb_inputs > 1) { | 1310 | if (s->reset_sar) { |
| 1296 | /* SAR is normalized, or we have multiple inputs, set out to 1:1 */ | 1311 | /* SAR is normalized, or we have multiple inputs, set out to 1:1 */ |
| 1297 | outlink->sample_aspect_ratio = (AVRational){ 1, 1 }; | 1312 | outlink->sample_aspect_ratio = (AVRational){ 1, 1 }; |
| 1298 | } else { | 1313 | } else if (inlink->sample_aspect_ratio.num) { |
| 1299 | /* This is consistent with other scale_* filters, which only | 1314 | /* This is consistent with other scale_* filters, which only |
| 1300 | * set the outlink SAR to be equal to the scale SAR iff the input SAR | 1315 | * set the outlink SAR to be equal to the scale SAR iff the input SAR |
| 1301 | * was set to something nonzero */ | 1316 | * was set to something nonzero */ |
| 1302 | if (inlink->sample_aspect_ratio.num) | 1317 | const AVRational ar_in = { inlink->w, inlink->h }; |
| 1303 | outlink->sample_aspect_ratio = inlink->sample_aspect_ratio; | 1318 | const AVRational ar_out = { outlink->w, outlink->h }; |
| 1319 | const AVRational stretch = av_div_q(ar_in, ar_out); | ||
| 1320 | outlink->sample_aspect_ratio = av_mul_q(inlink->sample_aspect_ratio, stretch); | ||
| 1321 | } else { | ||
| 1322 | outlink->sample_aspect_ratio = inlink->sample_aspect_ratio; | ||
| 1304 | } | 1323 | } |
| 1305 | 1324 | ||
| 1306 | /* Frame rate */ | 1325 | /* Frame rate */ |