diff mbox series

[FFmpeg-devel,3/5] avfilter: use the new AVFrame interlace flags in all filters

Message ID 20230412194936.48022-3-jamrial@gmail.com
State New
Headers show
Series [FFmpeg-devel,1/5] avutil/frame: add new interlaced and top_field_first flags | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 success Make fate finished
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

James Almer April 12, 2023, 7:49 p.m. UTC
Signed-off-by: James Almer <jamrial@gmail.com>
---
Same situation as with lavc, double checking if i missed any filter that needs
to explicitly unset the flags is welcome.

 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             |  2 ++
 libavfilter/vsrc_gradients.c       |  1 +
 libavfilter/vsrc_testsrc.c         |  1 +
 libavfilter/yadif_common.c         | 12 +++++++-----
 30 files changed, 129 insertions(+), 53 deletions(-)
diff mbox series

Patch

diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index 8d5702a0c8..0edaf17684 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..0af23d3a86 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..14800ef6bd 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..73684baf6a 100644
--- a/libavfilter/vf_weave.c
+++ b/libavfilter/vf_weave.c
@@ -150,6 +150,8 @@  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;
+    out->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST * !s->first_field;
 
     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..3086027a4a 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;