From 36827ea783afbb39e5b75e8a982e316739009773 Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 12 Apr 2023 11:38:46 -0300 Subject: [PATCH] avfilter: use the new AVFrame interlace flags in all filters Signed-off-by: James Almer --- libavfilter/avfilter.c | 4 ++-- libavfilter/buffersrc.c | 5 +++++ libavfilter/f_select.c | 8 ++++---- libavfilter/phase_template.c | 4 ++-- libavfilter/qsvvpp.c | 4 ++-- libavfilter/setpts.c | 2 +- libavfilter/vf_coreimage.m | 1 + libavfilter/vf_deinterlace_vaapi.c | 5 +++-- libavfilter/vf_estdif.c | 7 ++++--- libavfilter/vf_field.c | 1 + libavfilter/vf_fieldhint.c | 2 ++ libavfilter/vf_fieldmatch.c | 15 +++++++++++---- libavfilter/vf_fieldorder.c | 10 +++++++--- libavfilter/vf_framerate.c | 2 +- libavfilter/vf_idet.c | 17 +++++++++++++---- libavfilter/vf_kerndeint.c | 1 + libavfilter/vf_nnedi.c | 7 ++++--- libavfilter/vf_pullup.c | 3 ++- libavfilter/vf_repeatfields.c | 7 ++++--- libavfilter/vf_scale.c | 3 ++- libavfilter/vf_separatefields.c | 7 ++++--- libavfilter/vf_setparams.c | 6 ++++++ libavfilter/vf_showinfo.c | 4 ++-- libavfilter/vf_telecine.c | 18 ++++++++++++++++-- libavfilter/vf_tinterlace.c | 16 ++++++++++++++-- libavfilter/vf_w3fdif.c | 7 ++++--- libavfilter/vf_weave.c | 5 +++++ libavfilter/vsrc_gradients.c | 1 + libavfilter/vsrc_testsrc.c | 1 + libavfilter/yadif_common.c | 12 +++++++----- 30 files changed, 132 insertions(+), 53 deletions(-) diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index d2e9ba47ef..889808c580 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -57,8 +57,8 @@ static void tlog_ref(void *ctx, AVFrame *ref, int end) ff_tlog(ctx, " a:%d/%d s:%dx%d i:%c iskey:%d type:%c", ref->sample_aspect_ratio.num, ref->sample_aspect_ratio.den, ref->width, ref->height, - !ref->interlaced_frame ? 'P' : /* Progressive */ - ref->top_field_first ? 'T' : 'B', /* Top / Bottom */ + !(ref->flags & AV_FRAME_FLAG_INTERLACED) ? 'P' : /* Progressive */ + (ref->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? 'T' : 'B', /* Top / Bottom */ ref->key_frame, av_get_picture_type_char(ref->pict_type)); } diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c index a1740da054..927b16ea06 100644 --- a/libavfilter/buffersrc.c +++ b/libavfilter/buffersrc.c @@ -247,6 +247,11 @@ FF_DISABLE_DEPRECATION_WARNINGS FF_ENABLE_DEPRECATION_WARNINGS #endif + if (copy->interlaced_frame) + copy->flags |= AV_FRAME_FLAG_INTERLACED; + if (copy->top_field_first) + copy->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST; + ret = ff_filter_frame(ctx->outputs[0], copy); if (ret < 0) return ret; diff --git a/libavfilter/f_select.c b/libavfilter/f_select.c index d76c248fc5..6eab92b32f 100644 --- a/libavfilter/f_select.c +++ b/libavfilter/f_select.c @@ -356,8 +356,8 @@ FF_ENABLE_DEPRECATION_WARNINGS case AVMEDIA_TYPE_VIDEO: select->var_values[VAR_INTERLACE_TYPE] = - !frame->interlaced_frame ? INTERLACE_TYPE_P : - frame->top_field_first ? INTERLACE_TYPE_T : INTERLACE_TYPE_B; + !(frame->flags & AV_FRAME_FLAG_INTERLACED) ? INTERLACE_TYPE_P : + (frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? INTERLACE_TYPE_T : INTERLACE_TYPE_B; select->var_values[VAR_PICT_TYPE] = frame->pict_type; if (select->do_scene_detect) { char buf[32]; @@ -380,8 +380,8 @@ FF_ENABLE_DEPRECATION_WARNINGS switch (inlink->type) { case AVMEDIA_TYPE_VIDEO: av_log(inlink->dst, AV_LOG_DEBUG, " interlace_type:%c pict_type:%c scene:%f", - (!frame->interlaced_frame) ? 'P' : - frame->top_field_first ? 'T' : 'B', + !(frame->flags & AV_FRAME_FLAG_INTERLACED) ? 'P' : + (frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? 'T' : 'B', av_get_picture_type_char(frame->pict_type), select->var_values[VAR_SCENE]); break; diff --git a/libavfilter/phase_template.c b/libavfilter/phase_template.c index 8450670234..2621a543a1 100644 --- a/libavfilter/phase_template.c +++ b/libavfilter/phase_template.c @@ -57,10 +57,10 @@ static enum PhaseMode fn(analyze_plane)(void *ctx, enum PhaseMode mode, AVFrame double bdiff, tdiff, pdiff; if (mode == AUTO) { - mode = new->interlaced_frame ? new->top_field_first ? + mode = (new->flags & AV_FRAME_FLAG_INTERLACED) ? (new->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? TOP_FIRST : BOTTOM_FIRST : PROGRESSIVE; } else if (mode == AUTO_ANALYZE) { - mode = new->interlaced_frame ? new->top_field_first ? + mode = (new->flags & AV_FRAME_FLAG_INTERLACED) ? (new->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? TOP_FIRST_ANALYZE : BOTTOM_FIRST_ANALYZE : FULL_ANALYZE; } diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c index 54e7284234..b233b81243 100644 --- a/libavfilter/qsvvpp.c +++ b/libavfilter/qsvvpp.c @@ -460,8 +460,8 @@ static QSVFrame *submit_frame(QSVVPPContext *s, AVFilterLink *inlink, AVFrame *p inlink->time_base, default_tb); qsv_frame->surface.Info.PicStruct = - !qsv_frame->frame->interlaced_frame ? MFX_PICSTRUCT_PROGRESSIVE : - (qsv_frame->frame->top_field_first ? MFX_PICSTRUCT_FIELD_TFF : + !(qsv_frame->frame->flags & AV_FRAME_FLAG_INTERLACED) ? MFX_PICSTRUCT_PROGRESSIVE : + ((qsv_frame->frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? MFX_PICSTRUCT_FIELD_TFF : MFX_PICSTRUCT_FIELD_BFF); if (qsv_frame->frame->repeat_pict == 1) qsv_frame->surface.Info.PicStruct |= MFX_PICSTRUCT_FIELD_REPEATED; diff --git a/libavfilter/setpts.c b/libavfilter/setpts.c index 5bcc0c2dcf..7a5cd3ef78 100644 --- a/libavfilter/setpts.c +++ b/libavfilter/setpts.c @@ -174,7 +174,7 @@ FF_ENABLE_DEPRECATION_WARNINGS if (frame) { if (inlink->type == AVMEDIA_TYPE_VIDEO) { - setpts->var_values[VAR_INTERLACED] = frame->interlaced_frame; + setpts->var_values[VAR_INTERLACED] = !!(frame->flags & AV_FRAME_FLAG_INTERLACED); } else if (inlink->type == AVMEDIA_TYPE_AUDIO) { setpts->var_values[VAR_S] = frame->nb_samples; setpts->var_values[VAR_NB_SAMPLES] = frame->nb_samples; diff --git a/libavfilter/vf_coreimage.m b/libavfilter/vf_coreimage.m index b1959861de..a5bfdaef6d 100644 --- a/libavfilter/vf_coreimage.m +++ b/libavfilter/vf_coreimage.m @@ -303,6 +303,7 @@ static int request_frame(AVFilterLink *link) frame->duration = 1; frame->key_frame = 1; frame->interlaced_frame = 0; + frame->flags &= ~AV_FRAME_FLAG_INTERLACED; frame->pict_type = AV_PICTURE_TYPE_I; frame->sample_aspect_ratio = ctx->sar; diff --git a/libavfilter/vf_deinterlace_vaapi.c b/libavfilter/vf_deinterlace_vaapi.c index 1304561034..d4246eb4fc 100644 --- a/libavfilter/vf_deinterlace_vaapi.c +++ b/libavfilter/vf_deinterlace_vaapi.c @@ -252,7 +252,7 @@ static int deint_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame) if (err < 0) goto fail; - if (!ctx->auto_enable || input_frame->interlaced_frame) { + if (!ctx->auto_enable || (input_frame->flags & AV_FRAME_FLAG_INTERLACED)) { vas = vaMapBuffer(vpp_ctx->hwctx->display, vpp_ctx->filter_buffers[0], &filter_params_addr); if (vas != VA_STATUS_SUCCESS) { @@ -263,7 +263,7 @@ static int deint_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame) } filter_params = filter_params_addr; filter_params->flags = 0; - if (input_frame->top_field_first) { + if (input_frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) { filter_params->flags |= field ? VA_DEINTERLACING_BOTTOM_FIELD : 0; } else { filter_params->flags |= VA_DEINTERLACING_BOTTOM_FIELD_FIRST; @@ -304,6 +304,7 @@ static int deint_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame) ctx->frame_queue[current_frame_index + 1]->pts; } output_frame->interlaced_frame = 0; + output_frame->flags &= ~AV_FRAME_FLAG_INTERLACED; av_log(avctx, AV_LOG_DEBUG, "Filter output: %s, %ux%u (%"PRId64").\n", av_get_pix_fmt_name(output_frame->format), diff --git a/libavfilter/vf_estdif.c b/libavfilter/vf_estdif.c index 0164f4638a..d71d39e268 100644 --- a/libavfilter/vf_estdif.c +++ b/libavfilter/vf_estdif.c @@ -345,8 +345,8 @@ static int deinterlace_slice(AVFilterContext *ctx, void *arg, const int rslope = s->rslope; const int redge = s->redge; const int depth = s->depth; - const int interlaced = in->interlaced_frame; - const int tff = (s->field == (s->parity == -1 ? interlaced ? in->top_field_first : 1 : + const int interlaced = !!(in->flags & AV_FRAME_FLAG_INTERLACED); + const int tff = (s->field == (s->parity == -1 ? interlaced ? (in->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) : 1 : s->parity ^ 1)); for (int plane = 0; plane < s->nb_planes; plane++) { @@ -444,6 +444,7 @@ static int filter(AVFilterContext *ctx, AVFrame *in, int64_t pts, int64_t durati return AVERROR(ENOMEM); av_frame_copy_props(out, in); out->interlaced_frame = 0; + out->flags &= ~AV_FRAME_FLAG_INTERLACED; out->pts = pts; out->duration = duration; @@ -502,7 +503,7 @@ static int config_input(AVFilterLink *inlink) return 0; } - if ((s->deint && !s->prev->interlaced_frame) || ctx->is_disabled) { + if ((s->deint && !(s->prev->flags & AV_FRAME_FLAG_INTERLACED)) || ctx->is_disabled) { s->prev->pts *= 2; s->prev->duration *= 2; ret = ff_filter_frame(ctx->outputs[0], s->prev); diff --git a/libavfilter/vf_field.c b/libavfilter/vf_field.c index 8d06ffe663..66b646c72d 100644 --- a/libavfilter/vf_field.c +++ b/libavfilter/vf_field.c @@ -74,6 +74,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref) inpicref->height = outlink->h; inpicref->interlaced_frame = 0; + inpicref->flags &= ~AV_FRAME_FLAG_INTERLACED; for (i = 0; i < field->nb_planes; i++) { if (field->type == FIELD_TYPE_BOTTOM) diff --git a/libavfilter/vf_fieldhint.c b/libavfilter/vf_fieldhint.c index 4af9e26925..df6fb0b8df 100644 --- a/libavfilter/vf_fieldhint.c +++ b/libavfilter/vf_fieldhint.c @@ -218,9 +218,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) switch (hint) { case '+': out->interlaced_frame = 1; + out->flags |= AV_FRAME_FLAG_INTERLACED; break; case '-': out->interlaced_frame = 0; + out->flags &= ~AV_FRAME_FLAG_INTERLACED; break; case '=': break; diff --git a/libavfilter/vf_fieldmatch.c b/libavfilter/vf_fieldmatch.c index bf946beec9..a177cb3fd8 100644 --- a/libavfilter/vf_fieldmatch.c +++ b/libavfilter/vf_fieldmatch.c @@ -714,7 +714,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) in = fm->src; /* parity */ - order = fm->order != FM_PARITY_AUTO ? fm->order : (in->interlaced_frame ? in->top_field_first : 1); + order = fm->order != FM_PARITY_AUTO ? fm->order : ((in->flags & AV_FRAME_FLAG_INTERLACED) ? + !!(in->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) : 1); field = fm->field != FM_PARITY_AUTO ? fm->field : order; av_assert0(order == 0 || order == 1 || field == 0 || field == 1); fxo = field ^ order ? fxo1m : fxo0m; @@ -820,15 +821,21 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) /* mark the frame we are unable to match properly as interlaced so a proper * de-interlacer can take the relay */ dst->interlaced_frame = interlaced_frame; - if (dst->interlaced_frame) { + if (interlaced_frame) { + dst->flags |= AV_FRAME_FLAG_INTERLACED; av_log(ctx, AV_LOG_WARNING, "Frame #%"PRId64" at %s is still interlaced\n", outlink->frame_count_in, av_ts2timestr(in->pts, &inlink->time_base)); dst->top_field_first = field; - } + if (field) + dst->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST; + else + dst->flags &= ~AV_FRAME_FLAG_TOP_FIELD_FIRST; + } else + dst->flags &= ~AV_FRAME_FLAG_INTERLACED; av_log(ctx, AV_LOG_DEBUG, "SC:%d | COMBS: %3d %3d %3d %3d %3d (combpel=%d)" " match=%d combed=%s\n", sc, combs[0], combs[1], combs[2], combs[3], combs[4], - fm->combpel, match, dst->interlaced_frame ? "YES" : "NO"); + fm->combpel, match, (dst->flags & AV_FRAME_FLAG_INTERLACED) ? "YES" : "NO"); fail: for (i = 0; i < FF_ARRAY_ELEMS(gen_frames); i++) diff --git a/libavfilter/vf_fieldorder.c b/libavfilter/vf_fieldorder.c index 52b4b3d8aa..e4d0eda1a4 100644 --- a/libavfilter/vf_fieldorder.c +++ b/libavfilter/vf_fieldorder.c @@ -76,11 +76,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) uint8_t *dst, *src; AVFrame *out; - if (!frame->interlaced_frame || - frame->top_field_first == s->dst_tff) { + if (!(frame->flags & AV_FRAME_FLAG_INTERLACED) || + !!(frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) == s->dst_tff) { av_log(ctx, AV_LOG_VERBOSE, "Skipping %s.\n", - frame->interlaced_frame ? + (frame->flags & AV_FRAME_FLAG_INTERLACED) ? "frame with same field order" : "progressive frame"); return ff_filter_frame(outlink, frame); } @@ -141,6 +141,10 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) } } out->top_field_first = s->dst_tff; + if (s->dst_tff) + out->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST; + else + out->flags &= ~AV_FRAME_FLAG_TOP_FIELD_FIRST; if (frame != out) av_frame_free(&frame); diff --git a/libavfilter/vf_framerate.c b/libavfilter/vf_framerate.c index 49bf6cdfff..6ef5dca27a 100644 --- a/libavfilter/vf_framerate.c +++ b/libavfilter/vf_framerate.c @@ -318,7 +318,7 @@ retry: return ret; if (inpicref) { - if (inpicref->interlaced_frame) + if (inpicref->flags & AV_FRAME_FLAG_INTERLACED) av_log(ctx, AV_LOG_WARNING, "Interlaced frame found - the output will not be correct.\n"); if (inpicref->pts == AV_NOPTS_VALUE) { diff --git a/libavfilter/vf_idet.c b/libavfilter/vf_idet.c index 83d992add1..0f150a273d 100644 --- a/libavfilter/vf_idet.c +++ b/libavfilter/vf_idet.c @@ -185,11 +185,15 @@ static void filter(AVFilterContext *ctx) if (idet->last_type == TFF){ idet->cur->top_field_first = 1; idet->cur->interlaced_frame = 1; + idet->cur->flags |= (AV_FRAME_FLAG_INTERLACED | AV_FRAME_FLAG_TOP_FIELD_FIRST); }else if(idet->last_type == BFF){ idet->cur->top_field_first = 0; idet->cur->interlaced_frame = 1; + idet->cur->flags &= ~AV_FRAME_FLAG_TOP_FIELD_FIRST; + idet->cur->flags |= AV_FRAME_FLAG_INTERLACED; }else if(idet->last_type == PROGRESSIVE){ idet->cur->interlaced_frame = 0; + idet->cur->flags &= ~AV_FRAME_FLAG_INTERLACED; } for(i=0; i<3; i++) @@ -238,13 +242,15 @@ static int filter_frame(AVFilterLink *link, AVFrame *picref) // initial frame(s) and not interlaced, just pass through for // the analyze_interlaced_flag mode if (idet->analyze_interlaced_flag && - !picref->interlaced_frame && + !(picref->flags & AV_FRAME_FLAG_INTERLACED) && !idet->next) { return ff_filter_frame(ctx->outputs[0], picref); } if (idet->analyze_interlaced_flag_done) { - if (picref->interlaced_frame && idet->interlaced_flag_accuracy < 0) + if ((picref->flags & AV_FRAME_FLAG_INTERLACED) && idet->interlaced_flag_accuracy < 0) { picref->interlaced_frame = 0; + picref->flags &= ~AV_FRAME_FLAG_INTERLACED; + } return ff_filter_frame(ctx->outputs[0], picref); } @@ -282,8 +288,9 @@ static int filter_frame(AVFilterLink *link, AVFrame *picref) } if (idet->analyze_interlaced_flag) { - if (idet->cur->interlaced_frame) { + if (idet->cur->flags & AV_FRAME_FLAG_INTERLACED) { idet->cur->interlaced_frame = 0; + idet->cur->flags &= ~AV_FRAME_FLAG_INTERLACED; filter(ctx); if (idet->last_type == PROGRESSIVE) { idet->interlaced_flag_accuracy --; @@ -295,8 +302,10 @@ static int filter_frame(AVFilterLink *link, AVFrame *picref) if (idet->analyze_interlaced_flag == 1) { ff_filter_frame(ctx->outputs[0], av_frame_clone(idet->cur)); - if (idet->next->interlaced_frame && idet->interlaced_flag_accuracy < 0) + if ((idet->next->flags & AV_FRAME_FLAG_INTERLACED) && idet->interlaced_flag_accuracy < 0) { idet->next->interlaced_frame = 0; + idet->next->flags &= ~AV_FRAME_FLAG_INTERLACED; + } idet->analyze_interlaced_flag_done = 1; av_log(ctx, AV_LOG_INFO, "Final flag accuracy %d\n", idet->interlaced_flag_accuracy); return ff_filter_frame(ctx->outputs[0], av_frame_clone(idet->next)); diff --git a/libavfilter/vf_kerndeint.c b/libavfilter/vf_kerndeint.c index dd320fbebf..e8ec1f474a 100644 --- a/libavfilter/vf_kerndeint.c +++ b/libavfilter/vf_kerndeint.c @@ -142,6 +142,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpic) } av_frame_copy_props(outpic, inpic); outpic->interlaced_frame = 0; + outpic->flags &= ~AV_FRAME_FLAG_INTERLACED; for (plane = 0; plane < 4 && inpic->data[plane] && inpic->linesize[plane]; plane++) { h = plane == 0 ? inlink->h : AV_CEIL_RSHIFT(inlink->h, kerndeint->vsub); diff --git a/libavfilter/vf_nnedi.c b/libavfilter/vf_nnedi.c index 63b83e5efd..39cb4f5a85 100644 --- a/libavfilter/vf_nnedi.c +++ b/libavfilter/vf_nnedi.c @@ -540,8 +540,8 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) const float in_scale = s->in_scale; const float out_scale = s->out_scale; const int depth = s->depth; - const int interlaced = in->interlaced_frame; - const int tff = s->field_n == (s->field < 0 ? interlaced ? in->top_field_first : 1 : + const int interlaced = !!(in->flags & AV_FRAME_FLAG_INTERLACED); + const int tff = s->field_n == (s->field < 0 ? interlaced ? (in->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) : 1 : (s->field & 1) ^ 1); @@ -666,6 +666,7 @@ static int get_frame(AVFilterContext *ctx, int is_second) return AVERROR(ENOMEM); av_frame_copy_props(dst, s->prev); dst->interlaced_frame = 0; + dst->flags &= ~AV_FRAME_FLAG_INTERLACED; dst->pts = s->pts; ff_filter_execute(ctx, filter_slice, dst, NULL, @@ -688,7 +689,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) return 0; } - if ((s->deint && !s->prev->interlaced_frame) || ctx->is_disabled) { + if ((s->deint && !(s->prev->flags & AV_FRAME_FLAG_INTERLACED)) || ctx->is_disabled) { s->prev->pts *= 2; ret = ff_filter_frame(ctx->outputs[0], s->prev); s->prev = in; diff --git a/libavfilter/vf_pullup.c b/libavfilter/vf_pullup.c index 054e3f90a9..fcdcfc44af 100644 --- a/libavfilter/vf_pullup.c +++ b/libavfilter/vf_pullup.c @@ -670,7 +670,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) (const uint8_t**)in->data, in->linesize, inlink->format, inlink->w, inlink->h); - p = in->interlaced_frame ? !in->top_field_first : 0; + p = (in->flags & AV_FRAME_FLAG_INTERLACED) ? + !(in->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) : 0; pullup_submit_field(s, b, p ); pullup_submit_field(s, b, p^1); diff --git a/libavfilter/vf_repeatfields.c b/libavfilter/vf_repeatfields.c index 4d31f3b4f5..782b1e543f 100644 --- a/libavfilter/vf_repeatfields.c +++ b/libavfilter/vf_repeatfields.c @@ -93,11 +93,12 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) s->frame->pts = AV_NOPTS_VALUE; } - if ((state == 0 && !in->top_field_first) || - (state == 1 && in->top_field_first)) { + if ((state == 0 && !(in->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST)) || + (state == 1 && (in->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST))) { av_log(ctx, AV_LOG_WARNING, "Unexpected field flags: " "state=%d top_field_first=%d repeat_first_field=%d\n", - state, in->top_field_first, in->repeat_pict); + state, !!(in->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST), + in->repeat_pict); state ^= 1; } diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c index 6b82763596..b0221e8538 100644 --- a/libavfilter/vf_scale.c +++ b/libavfilter/vf_scale.c @@ -884,7 +884,8 @@ scale: (int64_t)in->sample_aspect_ratio.den * outlink->w * link->h, INT_MAX); - if (scale->interlaced>0 || (scale->interlaced<0 && in->interlaced_frame)) { + if (scale->interlaced>0 || (scale->interlaced<0 && + (in->flags & AV_FRAME_FLAG_INTERLACED))) { ret = scale_field(scale, out, in, 0); if (ret >= 0) ret = scale_field(scale, out, in, 1); diff --git a/libavfilter/vf_separatefields.c b/libavfilter/vf_separatefields.c index 7db64c5479..814ea52e21 100644 --- a/libavfilter/vf_separatefields.c +++ b/libavfilter/vf_separatefields.c @@ -71,13 +71,14 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref) inpicref->height = outlink->h; inpicref->interlaced_frame = 0; + inpicref->flags &= ~AV_FRAME_FLAG_INTERLACED; if (!s->second) { goto clone; } else { AVFrame *second = s->second; - extract_field(second, s->nb_planes, second->top_field_first); + extract_field(second, s->nb_planes, !!(second->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST)); if (second->pts != AV_NOPTS_VALUE && inpicref->pts != AV_NOPTS_VALUE) @@ -94,7 +95,7 @@ clone: return AVERROR(ENOMEM); } - extract_field(inpicref, s->nb_planes, !inpicref->top_field_first); + extract_field(inpicref, s->nb_planes, !(inpicref->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST)); if (inpicref->pts != AV_NOPTS_VALUE) inpicref->pts *= 2; @@ -110,7 +111,7 @@ static int flush_frame(AVFilterLink *outlink, int64_t pts, int64_t *out_pts) if (s->second) { *out_pts = s->second->pts += pts; - extract_field(s->second, s->nb_planes, s->second->top_field_first); + extract_field(s->second, s->nb_planes, !!(s->second->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST)); ret = ff_filter_frame(outlink, s->second); s->second = NULL; } diff --git a/libavfilter/vf_setparams.c b/libavfilter/vf_setparams.c index 95a2d15c02..0165a5aaa6 100644 --- a/libavfilter/vf_setparams.c +++ b/libavfilter/vf_setparams.c @@ -128,9 +128,15 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) /* set field */ if (s->field_mode == MODE_PROG) { frame->interlaced_frame = 0; + frame->flags &= ~AV_FRAME_FLAG_INTERLACED; } else if (s->field_mode != MODE_AUTO) { frame->interlaced_frame = 1; frame->top_field_first = s->field_mode; + frame->flags |= AV_FRAME_FLAG_INTERLACED; + if (s->field_mode) + frame->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST; + else + frame->flags &= ~AV_FRAME_FLAG_TOP_FIELD_FIRST; } /* set range */ diff --git a/libavfilter/vf_showinfo.c b/libavfilter/vf_showinfo.c index 9caa618b01..6ecab2bf71 100644 --- a/libavfilter/vf_showinfo.c +++ b/libavfilter/vf_showinfo.c @@ -722,8 +722,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) desc->name, frame->sample_aspect_ratio.num, frame->sample_aspect_ratio.den, frame->width, frame->height, - !frame->interlaced_frame ? 'P' : /* Progressive */ - frame->top_field_first ? 'T' : 'B', /* Top / Bottom */ + !(frame->flags & AV_FRAME_FLAG_INTERLACED) ? 'P' : /* Progressive */ + (frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? 'T' : 'B', /* Top / Bottom */ frame->key_frame, av_get_picture_type_char(frame->pict_type)); diff --git a/libavfilter/vf_telecine.c b/libavfilter/vf_telecine.c index 227de6f733..d8daa25939 100644 --- a/libavfilter/vf_telecine.c +++ b/libavfilter/vf_telecine.c @@ -206,6 +206,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref) } s->frame[nout]->interlaced_frame = 1; s->frame[nout]->top_field_first = !s->first_field; + s->frame[nout]->flags |= AV_FRAME_FLAG_INTERLACED; + if (s->first_field) + s->frame[nout]->flags &= ~AV_FRAME_FLAG_TOP_FIELD_FIRST; + else + s->frame[nout]->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST; nout++; len--; s->occupied = 0; @@ -225,6 +230,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref) s->planeheight[i]); s->frame[nout]->interlaced_frame = inpicref->interlaced_frame; s->frame[nout]->top_field_first = inpicref->top_field_first; + s->frame[nout]->flags |= (inpicref->flags & (AV_FRAME_FLAG_INTERLACED | AV_FRAME_FLAG_TOP_FIELD_FIRST)); nout++; len -= 2; } @@ -241,8 +247,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref) for (i = 0; i < nout; i++) { AVFrame *frame = av_frame_clone(s->frame[i]); - int interlaced = frame ? frame->interlaced_frame : 0; - int tff = frame ? frame->top_field_first : 0; + int interlaced = frame ? !!(frame->flags & AV_FRAME_FLAG_INTERLACED) : 0; + int tff = frame ? !!(frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) : 0; if (!frame) { av_frame_free(&inpicref); @@ -252,6 +258,14 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref) av_frame_copy_props(frame, inpicref); frame->interlaced_frame = interlaced; frame->top_field_first = tff; + if (interlaced) + frame->flags |= AV_FRAME_FLAG_INTERLACED; + else + frame->flags &= ~AV_FRAME_FLAG_INTERLACED; + if (tff) + frame->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST; + else + frame->flags &= ~AV_FRAME_FLAG_TOP_FIELD_FIRST; frame->pts = ((s->start_time == AV_NOPTS_VALUE) ? 0 : s->start_time) + av_rescale(outlink->frame_count_in, s->ts_unit.num, s->ts_unit.den); diff --git a/libavfilter/vf_tinterlace.c b/libavfilter/vf_tinterlace.c index 032629279a..742d4e195a 100644 --- a/libavfilter/vf_tinterlace.c +++ b/libavfilter/vf_tinterlace.c @@ -393,6 +393,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref) out->height = outlink->h; out->interlaced_frame = 1; out->top_field_first = 1; + out->flags |= AV_FRAME_FLAG_INTERLACED | AV_FRAME_FLAG_TOP_FIELD_FIRST; out->sample_aspect_ratio = av_mul_q(cur->sample_aspect_ratio, av_make_q(2, 1)); /* write odd frame lines into the upper field of the new frame */ @@ -444,7 +445,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref) * halving the frame rate and preserving image height */ case MODE_INTERLEAVE_TOP: /* top field first */ case MODE_INTERLEAVE_BOTTOM: /* bottom field first */ - if ((tinterlace->flags & TINTERLACE_FLAG_BYPASS_IL) && cur->interlaced_frame) { + if ((tinterlace->flags & TINTERLACE_FLAG_BYPASS_IL) && (cur->flags & AV_FRAME_FLAG_INTERLACED)) { av_log(ctx, AV_LOG_WARNING, "video is already interlaced, adjusting framerate only\n"); out = av_frame_clone(cur); @@ -461,6 +462,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref) av_frame_copy_props(out, cur); out->interlaced_frame = 1; out->top_field_first = tff; + out->flags |= AV_FRAME_FLAG_INTERLACED; + if (tff) + out->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST; + else + out->flags &= ~AV_FRAME_FLAG_TOP_FIELD_FIRST; /* copy upper/lower field from cur */ copy_picture_field(tinterlace, out->data, out->linesize, @@ -482,6 +488,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref) if (!out) return AVERROR(ENOMEM); out->interlaced_frame = 1; + out->flags |= AV_FRAME_FLAG_INTERLACED; if (cur->pts != AV_NOPTS_VALUE) out->pts = cur->pts*2; @@ -490,13 +497,18 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref) return ret; /* output mix of current and next frame */ - tff = next->top_field_first; + tff = !!(next->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST); out = ff_get_video_buffer(outlink, outlink->w, outlink->h); if (!out) return AVERROR(ENOMEM); av_frame_copy_props(out, next); out->interlaced_frame = 1; out->top_field_first = !tff; + out->flags |= AV_FRAME_FLAG_INTERLACED; + if (tff) + out->flags &= ~AV_FRAME_FLAG_TOP_FIELD_FIRST; + else + out->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST; if (next->pts != AV_NOPTS_VALUE && cur->pts != AV_NOPTS_VALUE) out->pts = cur->pts + next->pts; diff --git a/libavfilter/vf_w3fdif.c b/libavfilter/vf_w3fdif.c index 512c8070c7..7c3ffbc5f0 100644 --- a/libavfilter/vf_w3fdif.c +++ b/libavfilter/vf_w3fdif.c @@ -379,8 +379,8 @@ static int deinterlace_plane_slice(AVFilterContext *ctx, void *arg, const int start = (height * jobnr) / nb_jobs; const int end = (height * (jobnr+1)) / nb_jobs; const int max = s->max; - const int interlaced = cur->interlaced_frame; - const int tff = s->field == (s->parity == -1 ? interlaced ? cur->top_field_first : 1 : + const int interlaced = !!(cur->flags & AV_FRAME_FLAG_INTERLACED); + const int tff = s->field == (s->parity == -1 ? interlaced ? !!(cur->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) : 1 : s->parity ^ 1); int j, y_in, y_out; @@ -487,6 +487,7 @@ static int filter(AVFilterContext *ctx, int is_second) return AVERROR(ENOMEM); av_frame_copy_props(out, s->cur); out->interlaced_frame = 0; + out->flags &= ~AV_FRAME_FLAG_INTERLACED; if (!is_second) { if (out->pts != AV_NOPTS_VALUE) @@ -533,7 +534,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) if (!s->prev) return 0; - if ((s->deint && !s->cur->interlaced_frame) || ctx->is_disabled) { + if ((s->deint && !(s->cur->flags & AV_FRAME_FLAG_INTERLACED)) || ctx->is_disabled) { AVFrame *out = av_frame_clone(s->cur); if (!out) return AVERROR(ENOMEM); diff --git a/libavfilter/vf_weave.c b/libavfilter/vf_weave.c index 2bd3994e5e..e738c9ba17 100644 --- a/libavfilter/vf_weave.c +++ b/libavfilter/vf_weave.c @@ -150,6 +150,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) out->pts = s->double_weave ? s->prev->pts : in->pts / 2; out->interlaced_frame = 1; out->top_field_first = !s->first_field; + out->flags |= AV_FRAME_FLAG_INTERLACED; + if (s->first_field) + out->flags &= ~AV_FRAME_FLAG_TOP_FIELD_FIRST; + else + out->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST; if (!s->double_weave) av_frame_free(&in); diff --git a/libavfilter/vsrc_gradients.c b/libavfilter/vsrc_gradients.c index 3c524b9242..2811dd8bb6 100644 --- a/libavfilter/vsrc_gradients.c +++ b/libavfilter/vsrc_gradients.c @@ -399,6 +399,7 @@ static int activate(AVFilterContext *ctx) frame->key_frame = 1; frame->interlaced_frame = 0; + frame->flags &= ~AV_FRAME_FLAG_INTERLACED; frame->pict_type = AV_PICTURE_TYPE_I; frame->sample_aspect_ratio = (AVRational) {1, 1}; frame->pts = s->pts++; diff --git a/libavfilter/vsrc_testsrc.c b/libavfilter/vsrc_testsrc.c index 9760e5fc80..cef3a9be36 100644 --- a/libavfilter/vsrc_testsrc.c +++ b/libavfilter/vsrc_testsrc.c @@ -186,6 +186,7 @@ static int activate(AVFilterContext *ctx) frame->duration = 1; frame->key_frame = 1; frame->interlaced_frame = 0; + frame->flags &= ~AV_FRAME_FLAG_INTERLACED; frame->pict_type = AV_PICTURE_TYPE_I; frame->sample_aspect_ratio = test->sar; if (!test->draw_once) diff --git a/libavfilter/yadif_common.c b/libavfilter/yadif_common.c index a10cf7a17f..5b29d2e6d8 100644 --- a/libavfilter/yadif_common.c +++ b/libavfilter/yadif_common.c @@ -31,8 +31,8 @@ static int return_frame(AVFilterContext *ctx, int is_second) int tff, ret; if (yadif->parity == -1) { - tff = yadif->cur->interlaced_frame ? - yadif->cur->top_field_first : 1; + tff = (yadif->cur->flags & AV_FRAME_FLAG_INTERLACED) ? + !!(yadif->cur->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) : 1; } else { tff = yadif->parity ^ 1; } @@ -44,6 +44,7 @@ static int return_frame(AVFilterContext *ctx, int is_second) av_frame_copy_props(yadif->out, yadif->cur); yadif->out->interlaced_frame = 0; + yadif->out->flags &= ~AV_FRAME_FLAG_INTERLACED; if (yadif->current_field == YADIF_FIELD_BACK_END) yadif->current_field = YADIF_FIELD_END; } @@ -128,10 +129,10 @@ int ff_yadif_filter_frame(AVFilterLink *link, AVFrame *frame) if (!yadif->prev) return 0; - if ((yadif->deint && !yadif->cur->interlaced_frame) || + if ((yadif->deint && !(yadif->cur->flags & AV_FRAME_FLAG_INTERLACED)) || ctx->is_disabled || - (yadif->deint && !yadif->prev->interlaced_frame && yadif->prev->repeat_pict) || - (yadif->deint && !yadif->next->interlaced_frame && yadif->next->repeat_pict) + (yadif->deint && !(yadif->prev->flags & AV_FRAME_FLAG_INTERLACED) && yadif->prev->repeat_pict) || + (yadif->deint && !(yadif->next->flags & AV_FRAME_FLAG_INTERLACED) && yadif->next->repeat_pict) ) { yadif->out = av_frame_clone(yadif->cur); if (!yadif->out) @@ -149,6 +150,7 @@ int ff_yadif_filter_frame(AVFilterLink *link, AVFrame *frame) av_frame_copy_props(yadif->out, yadif->cur); yadif->out->interlaced_frame = 0; + yadif->out->flags &= ~AV_FRAME_FLAG_INTERLACED; if (yadif->out->pts != AV_NOPTS_VALUE) yadif->out->pts *= 2;