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 | 16633 | @item skip_spatial_check |
| 16634 | 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 | 16640 | @end table |
| 16636 | 16641 | |
| 16637 | 16642 | @subsubsection Debanding |
| @@ -215,6 +215,7 @@ typedef struct LibplaceboContext { · 214 unmodified lines | ||
| 215 | 215 | /* pl_deinterlace_params */ |
| 216 | 216 | int deinterlace; |
| 217 | 217 | int skip_spatial_check; |
| 218 | + int send_fields; | |
| 218 | 219 | |
| 219 | 220 | /* pl_deband_params */ |
| 220 | 221 | int deband; |
| @@ -967,8 +968,7 @@ static int handle_input(AVFilterContext *ctx, LibplaceboInput *input) · 746 unmodified lines | ||
| 967 | 968 | int64_t pts; |
| 968 | 969 | |
| 969 | 970 | while ((ret = ff_inlink_consume_frame(inlink, &in)) > 0) { |
| 970 | − in->opaque = s; | |
| 971 | − pl_queue_push(input->queue, &(struct pl_source_frame) { | |
| 971 | + struct pl_source_frame src = { | |
| 972 | 972 | .pts = in->pts * av_q2d(inlink->time_base), |
| 973 | 973 | .duration = in->duration * av_q2d(inlink->time_base), |
| 974 | 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 | 976 | .map = map_frame, |
| 977 | 977 | .unmap = unmap_frame, |
| 978 | 978 | .discard = discard_frame, |
| 979 | − }); | |
| 979 | + }; | |
| 980 | + | |
| 981 | + in->opaque = s; | |
| 982 | + pl_queue_push(input->queue, &src); | |
| 980 | 983 | |
| 981 | 984 | if (!s->fps.num) { |
| 982 | 985 | /* Internally queue an output frame for the same PTS */ |
| 983 | 986 | pts = av_rescale_q(in->pts, inlink->time_base, outlink->time_base); |
| 984 | 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 | 1248 | avctx->inputs[i]->time_base, |
| 1240 | 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 | 1260 | /* Static variables */ |
| @@ -1373,6 +1389,7 @@ static const AVOption libplacebo_options[] = { · 128 unmodified lines | ||
| 1373 | 1389 | { "bob", "Naive bob deinterlacing", 0, AV_OPT_TYPE_CONST, {.i64 = PL_DEINTERLACE_BOB}, 0, 0, STATIC, .unit = "deinterlace" }, |
| 1374 | 1390 | { "yadif", "Yet another deinterlacing filter", 0, AV_OPT_TYPE_CONST, {.i64 = PL_DEINTERLACE_YADIF}, 0, 0, STATIC, .unit = "deinterlace" }, |
| 1375 | 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 | 1394 | { "deband", "Enable debanding", OFFSET(deband), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC }, |
| 1378 | 1395 | { "deband_iterations", "Deband iterations", OFFSET(deband_iterations), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 16, DYNAMIC }, |