cf. the other deinterlacing-aware filters.
Unified · Split
| @@ -16632,6 +16632,11 @@ Yet another deinterlacing filter. See the @ref{yadif} filter for more details. · 16631 unmodified lines | |||
| 16632 | 16632 | ||
| 16633 | @item skip_spatial_check | 16633 | @item skip_spatial_check |
| 16634 | Skip the spatial deinterlacing check when using @code{yadif} deinterlacing. | 16634 | Skip the spatial deinterlacing check when using @code{yadif} deinterlacing. |
| 16635 | |||
| 16636 | @item send_fields | ||
| 16637 | Output a frame for each field, rather than for each frame. Note that this will | ||
| 16638 | always double the tagged output frame rate, even if the input does not contain | ||
| 16639 | any interlaced frames. Disabled by default. | ||
| 16635 | @end table | 16640 | @end table |
| 16636 | 16641 | ||
| 16637 | @subsubsection Debanding | 16642 | @subsubsection Debanding |
| @@ -215,6 +215,7 @@ typedef struct LibplaceboContext { · 214 unmodified lines | |||
| 215 | /* pl_deinterlace_params */ | 215 | /* pl_deinterlace_params */ |
| 216 | int deinterlace; | 216 | int deinterlace; |
| 217 | int skip_spatial_check; | 217 | int skip_spatial_check; |
| 218 | int send_fields; | ||
| 218 | 219 | ||
| 219 | /* pl_deband_params */ | 220 | /* pl_deband_params */ |
| 220 | int deband; | 221 | int deband; |
| @@ -967,8 +968,7 @@ static int handle_input(AVFilterContext *ctx, LibplaceboInput *input) · 746 unmodified lines | |||
| 967 | int64_t pts; | 968 | int64_t pts; |
| 968 | 969 | ||
| 969 | while ((ret = ff_inlink_consume_frame(inlink, &in)) > 0) { | 970 | while ((ret = ff_inlink_consume_frame(inlink, &in)) > 0) { |
| 970 | in->opaque = s; | 971 | struct pl_source_frame src = { |
| 971 | pl_queue_push(input->queue, &(struct pl_source_frame) { | ||
| 972 | .pts = in->pts * av_q2d(inlink->time_base), | 972 | .pts = in->pts * av_q2d(inlink->time_base), |
| 973 | .duration = in->duration * av_q2d(inlink->time_base), | 973 | .duration = in->duration * av_q2d(inlink->time_base), |
| 974 | .first_field = s->deinterlace ? pl_field_from_avframe(in) : PL_FIELD_NONE, | 974 | .first_field = s->deinterlace ? pl_field_from_avframe(in) : PL_FIELD_NONE, |
| @@ -976,12 +976,21 @@ static int handle_input(AVFilterContext *ctx, LibplaceboInput *input) · 1 unmodified line | |||
| 976 | .map = map_frame, | 976 | .map = map_frame, |
| 977 | .unmap = unmap_frame, | 977 | .unmap = unmap_frame, |
| 978 | .discard = discard_frame, | 978 | .discard = discard_frame, |
| 979 | }); | 979 | }; |
| 980 | |||
| 981 | in->opaque = s; | ||
| 982 | pl_queue_push(input->queue, &src); | ||
| 980 | 983 | ||
| 981 | if (!s->fps.num) { | 984 | if (!s->fps.num) { |
| 982 | /* Internally queue an output frame for the same PTS */ | 985 | /* Internally queue an output frame for the same PTS */ |
| 983 | pts = av_rescale_q(in->pts, inlink->time_base, outlink->time_base); | 986 | pts = av_rescale_q(in->pts, inlink->time_base, outlink->time_base); |
| 984 | av_fifo_write(input->out_pts, &pts, 1); | 987 | av_fifo_write(input->out_pts, &pts, 1); |
| 988 | |||
| 989 | if (s->send_fields && src.first_field != PL_FIELD_NONE) { | ||
| 990 | /* Queue the second field for interlaced content */ | ||
| 991 | pts += av_rescale_q(in->duration, inlink->time_base, outlink->time_base) / 2; | ||
| 992 | av_fifo_write(input->out_pts, &pts, 1); | ||
| 993 | } | ||
| 985 | } | 994 | } |
| 986 | } | 995 | } |
| 987 | 996 | ||
| @@ -1239,6 +1248,13 @@ static int libplacebo_config_output(AVFilterLink *outlink) · 251 unmodified lines | |||
| 1239 | avctx->inputs[i]->time_base, | 1248 | avctx->inputs[i]->time_base, |
| 1240 | AV_TIME_BASE / 2, AV_TIME_BASE_Q); | 1249 | AV_TIME_BASE / 2, AV_TIME_BASE_Q); |
| 1241 | } | 1250 | } |
| 1251 | |||
| 1252 | if (s->deinterlace && s->send_fields) { | ||
| 1253 | const AVRational q2 = { 2, 1 }; | ||
| 1254 | ol->frame_rate = av_mul_q(ol->frame_rate, q2); | ||
| 1255 | /* Ensure output frame timestamps are divisible by two */ | ||
| 1256 | outlink->time_base = av_div_q(outlink->time_base, q2); | ||
| 1257 | } | ||
| 1242 | } | 1258 | } |
| 1243 | 1259 | ||
| 1244 | /* Static variables */ | 1260 | /* Static variables */ |
| @@ -1373,6 +1389,7 @@ static const AVOption libplacebo_options[] = { · 128 unmodified lines | |||
| 1373 | { "bob", "Naive bob deinterlacing", 0, AV_OPT_TYPE_CONST, {.i64 = PL_DEINTERLACE_BOB}, 0, 0, STATIC, .unit = "deinterlace" }, | 1389 | { "bob", "Naive bob deinterlacing", 0, AV_OPT_TYPE_CONST, {.i64 = PL_DEINTERLACE_BOB}, 0, 0, STATIC, .unit = "deinterlace" }, |
| 1374 | { "yadif", "Yet another deinterlacing filter", 0, AV_OPT_TYPE_CONST, {.i64 = PL_DEINTERLACE_YADIF}, 0, 0, STATIC, .unit = "deinterlace" }, | 1390 | { "yadif", "Yet another deinterlacing filter", 0, AV_OPT_TYPE_CONST, {.i64 = PL_DEINTERLACE_YADIF}, 0, 0, STATIC, .unit = "deinterlace" }, |
| 1375 | { "skip_spatial_check", "Skip yadif spatial check", OFFSET(skip_spatial_check), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC }, | 1391 | { "skip_spatial_check", "Skip yadif spatial check", OFFSET(skip_spatial_check), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC }, |
| 1392 | { "send_fields", "Output a frame for each field", OFFSET(send_fields), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC }, | ||
| 1376 | 1393 | ||
| 1377 | { "deband", "Enable debanding", OFFSET(deband), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC }, | 1394 | { "deband", "Enable debanding", OFFSET(deband), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC }, |
| 1378 | { "deband_iterations", "Deband iterations", OFFSET(deband_iterations), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 16, DYNAMIC }, | 1395 | { "deband_iterations", "Deband iterations", OFFSET(deband_iterations), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 16, DYNAMIC }, |