cmdutils: print missing caps in print_codec().
[ffmpeg.git] / libavfilter / vf_phase.c
index 04e59cb..fadeb62 100644 (file)
@@ -41,8 +41,8 @@ enum PhaseMode {
 
 typedef struct PhaseContext {
     const AVClass *class;
 
 typedef struct PhaseContext {
     const AVClass *class;
-    enum PhaseMode mode;
-    AVFrame *frame;
+    int mode;                   ///<PhaseMode
+    AVFrame *frame; /* previous frame */
     int nb_planes;
     int planeheight[4];
     int linesize[4];
     int nb_planes;
     int planeheight[4];
     int linesize[4];
@@ -77,8 +77,10 @@ static int query_formats(AVFilterContext *ctx)
         AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE
     };
 
         AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE
     };
 
-    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
-    return 0;
+    AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts);
+    if (!fmts_list)
+        return AVERROR(ENOMEM);
+    return ff_set_common_formats(ctx, fmts_list);
 }
 
 static int config_input(AVFilterLink *inlink)
 }
 
 static int config_input(AVFilterLink *inlink)
@@ -90,7 +92,7 @@ static int config_input(AVFilterLink *inlink)
     if ((ret = av_image_fill_linesizes(s->linesize, inlink->format, inlink->w)) < 0)
         return ret;
 
     if ((ret = av_image_fill_linesizes(s->linesize, inlink->format, inlink->w)) < 0)
         return ret;
 
-    s->planeheight[1] = s->planeheight[2] = FF_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
+    s->planeheight[1] = s->planeheight[2] = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
     s->planeheight[0] = s->planeheight[3] = inlink->h;
 
     s->nb_planes = av_pix_fmt_count_planes(inlink->format);
     s->planeheight[0] = s->planeheight[3] = inlink->h;
 
     s->nb_planes = av_pix_fmt_count_planes(inlink->format);
@@ -106,26 +108,15 @@ static int config_input(AVFilterLink *inlink)
  *
  * (The result is actually multiplied by 25)
  */
  *
  * (The result is actually multiplied by 25)
  */
-#define DIFF(a, as, b, bs) (t = ((*a - b[bs]) << 2) + a[as << 1] - b[-bs], t * t)
+#define DIFF(a, as, b, bs) ((t) = ((*(a) - (b)[bs]) << 2) + (a)[(as) << 1] - (b)[-(bs)], (t) * (t))
 
 /*
  * Find which field combination has the smallest average squared difference
  * between the fields.
  */
 
 /*
  * Find which field combination has the smallest average squared difference
  * between the fields.
  */
-static enum PhaseMode analyze_plane(AVFilterContext *ctx, PhaseContext *s,
-                                    AVFrame *old, AVFrame *new)
+static enum PhaseMode analyze_plane(void *ctx, enum PhaseMode mode, AVFrame *old, AVFrame *new)
 {
 {
-    double bdiff, tdiff, pdiff, scale;
-    const int ns = new->linesize[0];
-    const int os = old->linesize[0];
-    uint8_t *nptr = new->data[0];
-    uint8_t *optr = old->data[0];
-    const int h = new->height;
-    const int w = new->width;
-    int bdif, tdif, pdif;
-    enum PhaseMode mode = s->mode;
-    uint8_t *end, *rend;
-    int top, t;
+    double bdiff, tdiff, pdiff;
 
     if (mode == AUTO) {
         mode = new->interlaced_frame ? new->top_field_first ?
 
     if (mode == AUTO) {
         mode = new->interlaced_frame ? new->top_field_first ?
@@ -138,10 +129,23 @@ static enum PhaseMode analyze_plane(AVFilterContext *ctx, PhaseContext *s,
     if (mode <= BOTTOM_FIRST) {
         bdiff = pdiff = tdiff = 65536.0;
     } else {
     if (mode <= BOTTOM_FIRST) {
         bdiff = pdiff = tdiff = 65536.0;
     } else {
+        const int ns = new->linesize[0];
+        const int os = old->linesize[0];
+        const uint8_t *nptr = new->data[0];
+        const uint8_t *optr = old->data[0];
+        const int h = new->height;
+        const int w = new->width;
+        int bdif, tdif, pdif;
+        double scale;
+
+        int top = 0, t;
+        const uint8_t *rend, *end = nptr + (h - 2) * ns;
+
         bdiff = pdiff = tdiff = 0.0;
 
         bdiff = pdiff = tdiff = 0.0;
 
-        for (end = nptr + (h - 2) * ns, nptr += ns, optr += os, top = 0;
-             nptr < end; nptr += ns - w, optr += os - w, top ^= 1) {
+        nptr += ns;
+        optr += os;
+        while (nptr < end) {
             pdif = tdif = bdif = 0;
 
             switch (mode) {
             pdif = tdif = bdif = 0;
 
             switch (mode) {
@@ -206,6 +210,9 @@ static enum PhaseMode analyze_plane(AVFilterContext *ctx, PhaseContext *s,
             pdiff += (double)pdif;
             tdiff += (double)tdif;
             bdiff += (double)bdif;
             pdiff += (double)pdif;
             tdiff += (double)tdif;
             bdiff += (double)bdif;
+            nptr += ns - w;
+            optr += os - w;
+            top ^= 1;
         }
 
         scale = 1.0 / (w * (h - 3)) / 25.0;
         }
 
         scale = 1.0 / (w * (h - 3)) / 25.0;
@@ -241,10 +248,19 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
     AVFilterContext *ctx = inlink->dst;
     AVFilterLink *outlink = ctx->outputs[0];
     PhaseContext *s = ctx->priv;
     AVFilterContext *ctx = inlink->dst;
     AVFilterLink *outlink = ctx->outputs[0];
     PhaseContext *s = ctx->priv;
-    enum PhaseMode mode = s->mode;
+    enum PhaseMode mode;
     int plane, top, y;
     AVFrame *out;
 
     int plane, top, y;
     AVFrame *out;
 
+    if (ctx->is_disabled) {
+        av_frame_free(&s->frame);
+        /* we keep a reference to the previous frame so the filter can start
+         * being useful as soon as it's not disabled, avoiding the 1-frame
+         * delay. */
+        s->frame = av_frame_clone(in);
+        return ff_filter_frame(outlink, in);
+    }
+
     out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
     if (!out) {
         av_frame_free(&in);
     out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
     if (!out) {
         av_frame_free(&in);
@@ -253,25 +269,19 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
     av_frame_copy_props(out, in);
 
     if (!s->frame) {
     av_frame_copy_props(out, in);
 
     if (!s->frame) {
+        s->frame = in;
         mode = PROGRESSIVE;
         mode = PROGRESSIVE;
-        s->frame = ff_get_video_buffer(outlink, outlink->w, outlink->h);
-        if (!s->frame) {
-            av_frame_free(&in);
-            av_frame_free(&out);
-            return AVERROR(ENOMEM);
-        }
     } else {
     } else {
-        mode = analyze_plane(ctx, s, s->frame, in);
+        mode = analyze_plane(ctx, s->mode, s->frame, in);
     }
 
     for (plane = 0; plane < s->nb_planes; plane++) {
     }
 
     for (plane = 0; plane < s->nb_planes; plane++) {
-        uint8_t *buf = s->frame->data[plane];
-        uint8_t *from = in->data[plane];
+        const uint8_t *buf = s->frame->data[plane];
+        const uint8_t *from = in->data[plane];
         uint8_t *to = out->data[plane];
 
         for (y = 0, top = 1; y < s->planeheight[plane]; y++, top ^= 1) {
             memcpy(to, mode == (top ? BOTTOM_FIRST : TOP_FIRST) ? buf : from, s->linesize[plane]);
         uint8_t *to = out->data[plane];
 
         for (y = 0, top = 1; y < s->planeheight[plane]; y++, top ^= 1) {
             memcpy(to, mode == (top ? BOTTOM_FIRST : TOP_FIRST) ? buf : from, s->linesize[plane]);
-            memcpy(buf, from, s->linesize[plane]);
 
             buf += s->frame->linesize[plane];
             from += in->linesize[plane];
 
             buf += s->frame->linesize[plane];
             from += in->linesize[plane];
@@ -279,7 +289,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
         }
     }
 
         }
     }
 
-    av_frame_free(&in);
+    if (in != s->frame)
+        av_frame_free(&s->frame);
+    s->frame = in;
     return ff_filter_frame(outlink, out);
 }
 
     return ff_filter_frame(outlink, out);
 }
 
@@ -292,10 +304,10 @@ static av_cold void uninit(AVFilterContext *ctx)
 
 static const AVFilterPad phase_inputs[] = {
     {
 
 static const AVFilterPad phase_inputs[] = {
     {
-        .name          = "default",
-        .type          = AVMEDIA_TYPE_VIDEO,
-        .filter_frame  = filter_frame,
-        .config_props  = config_input,
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_VIDEO,
+        .filter_frame = filter_frame,
+        .config_props = config_input,
     },
     { NULL }
 };
     },
     { NULL }
 };
@@ -308,7 +320,7 @@ static const AVFilterPad phase_outputs[] = {
     { NULL }
 };
 
     { NULL }
 };
 
-AVFilter avfilter_vf_phase = {
+AVFilter ff_vf_phase = {
     .name          = "phase",
     .description   = NULL_IF_CONFIG_SMALL("Phase shift fields."),
     .priv_size     = sizeof(PhaseContext),
     .name          = "phase",
     .description   = NULL_IF_CONFIG_SMALL("Phase shift fields."),
     .priv_size     = sizeof(PhaseContext),
@@ -317,4 +329,5 @@ AVFilter avfilter_vf_phase = {
     .query_formats = query_formats,
     .inputs        = phase_inputs,
     .outputs       = phase_outputs,
     .query_formats = query_formats,
     .inputs        = phase_inputs,
     .outputs       = phase_outputs,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
 };