avfilter/tinterlace: Move lowpass_line to a separate function and call it through...
authorMichael Niedermayer <michaelni@gmx.at>
Sat, 15 Nov 2014 02:20:02 +0000 (03:20 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Sat, 15 Nov 2014 02:25:43 +0000 (03:25 +0100)
This permits replacing it by a optimized implementation
Based-on / Idea-from: 2e1704059ae8625beda2ffde847ad22c5ba416dc by Kieran Kunhya

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
libavfilter/tinterlace.h
libavfilter/vf_tinterlace.c

index 8fc95cb..8d33452 100644 (file)
@@ -51,6 +51,8 @@ typedef struct {
     AVFrame *next;
     uint8_t *black_data[4];     ///< buffer used to fill padded lines
     int black_linesize[4];
+    void (*lowpass_line)(uint8_t *dstp, ptrdiff_t width, const uint8_t *srcp,
+                         const uint8_t *srcp_above, const uint8_t *srcp_below);
 } TInterlaceContext;
 
 #endif /* AVFILTER_TINTERLACE_H */
index 6ef2a92..1d34d21 100644 (file)
@@ -77,6 +77,18 @@ static int query_formats(AVFilterContext *ctx)
     return 0;
 }
 
+static void lowpass_line_c(uint8_t *dstp, ptrdiff_t width, const uint8_t *srcp,
+                           const uint8_t *srcp_above, const uint8_t *srcp_below)
+{
+    int i;
+    for (i = 0; i < width; i++) {
+        // this calculation is an integer representation of
+        // '0.5 * current + 0.25 * above + 0.25 * below'
+        // '1 +' is for rounding.
+        dstp[i] = (1 + srcp[i] + srcp[i] + srcp_above[i] + srcp_below[i]) >> 2;
+    }
+}
+
 static av_cold void uninit(AVFilterContext *ctx)
 {
     TInterlaceContext *tinterlace = ctx->priv;
@@ -131,6 +143,10 @@ static int config_out_props(AVFilterLink *outlink)
         outlink->frame_rate = av_mul_q(inlink->frame_rate, (AVRational){1,2});
     }
 
+    if (tinterlace->flags & TINTERLACE_FLAG_VLPF) {
+        tinterlace->lowpass_line = lowpass_line_c;
+    }
+
     av_log(ctx, AV_LOG_VERBOSE, "mode:%d filter:%s h:%d -> h:%d\n",
            tinterlace->mode, (tinterlace->flags & TINTERLACE_FLAG_VLPF) ? "on" : "off",
            inlink->h, outlink->h);
@@ -152,7 +168,8 @@ static int config_out_props(AVFilterLink *outlink)
  * @param flags context flags
  */
 static inline
-void copy_picture_field(uint8_t *dst[4], int dst_linesize[4],
+void copy_picture_field(TInterlaceContext *tinterlace,
+                        uint8_t *dst[4], int dst_linesize[4],
                         const uint8_t *src[4], int src_linesize[4],
                         enum AVPixelFormat format, int w, int src_h,
                         int src_field, int interleave, int dst_field,
@@ -189,12 +206,8 @@ void copy_picture_field(uint8_t *dst[4], int dst_linesize[4],
                 const uint8_t *srcp_below = srcp + src_linesize[plane];
                 if (h == lines) srcp_above = srcp; // there is no line above
                 if (h == 1) srcp_below = srcp;     // there is no line below
-                for (i = 0; i < cols; i++) {
-                    // this calculation is an integer representation of
-                    // '0.5 * current + 0.25 * above + 0.25 * below'
-                    // '1 +' is for rounding. */
-                    dstp[i] = (1 + srcp[i] + srcp[i] + srcp_above[i] + srcp_below[i]) >> 2;
-                }
+
+                tinterlace->lowpass_line(dstp, cols, srcp, srcp_above, srcp_below);
                 dstp += dstp_linesize;
                 srcp += srcp_linesize;
             }
@@ -235,12 +248,12 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref)
         out->top_field_first = 1;
 
         /* write odd frame lines into the upper field of the new frame */
-        copy_picture_field(out->data, out->linesize,
+        copy_picture_field(tinterlace, out->data, out->linesize,
                            (const uint8_t **)cur->data, cur->linesize,
                            inlink->format, inlink->w, inlink->h,
                            FIELD_UPPER_AND_LOWER, 1, FIELD_UPPER, tinterlace->flags);
         /* write even frame lines into the lower field of the new frame */
-        copy_picture_field(out->data, out->linesize,
+        copy_picture_field(tinterlace, out->data, out->linesize,
                            (const uint8_t **)next->data, next->linesize,
                            inlink->format, inlink->w, inlink->h,
                            FIELD_UPPER_AND_LOWER, 1, FIELD_LOWER, tinterlace->flags);
@@ -265,12 +278,12 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref)
 
         field = (1 + tinterlace->frame) & 1 ? FIELD_UPPER : FIELD_LOWER;
         /* copy upper and lower fields */
-        copy_picture_field(out->data, out->linesize,
+        copy_picture_field(tinterlace, out->data, out->linesize,
                            (const uint8_t **)cur->data, cur->linesize,
                            inlink->format, inlink->w, inlink->h,
                            FIELD_UPPER_AND_LOWER, 1, field, tinterlace->flags);
         /* pad with black the other field */
-        copy_picture_field(out->data, out->linesize,
+        copy_picture_field(tinterlace, out->data, out->linesize,
                            (const uint8_t **)tinterlace->black_data, tinterlace->black_linesize,
                            inlink->format, inlink->w, inlink->h,
                            FIELD_UPPER_AND_LOWER, 1, !field, tinterlace->flags);
@@ -289,13 +302,13 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref)
         out->top_field_first = tff;
 
         /* copy upper/lower field from cur */
-        copy_picture_field(out->data, out->linesize,
+        copy_picture_field(tinterlace, out->data, out->linesize,
                            (const uint8_t **)cur->data, cur->linesize,
                            inlink->format, inlink->w, inlink->h,
                            tff ? FIELD_UPPER : FIELD_LOWER, 1, tff ? FIELD_UPPER : FIELD_LOWER,
                            tinterlace->flags);
         /* copy lower/upper field from next */
-        copy_picture_field(out->data, out->linesize,
+        copy_picture_field(tinterlace, out->data, out->linesize,
                            (const uint8_t **)next->data, next->linesize,
                            inlink->format, inlink->w, inlink->h,
                            tff ? FIELD_LOWER : FIELD_UPPER, 1, tff ? FIELD_LOWER : FIELD_UPPER,
@@ -328,13 +341,13 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref)
         else
             out->pts = AV_NOPTS_VALUE;
         /* write current frame second field lines into the second field of the new frame */
-        copy_picture_field(out->data, out->linesize,
+        copy_picture_field(tinterlace, out->data, out->linesize,
                            (const uint8_t **)cur->data, cur->linesize,
                            inlink->format, inlink->w, inlink->h,
                            tff ? FIELD_LOWER : FIELD_UPPER, 1, tff ? FIELD_LOWER : FIELD_UPPER,
                            tinterlace->flags);
         /* write next frame first field lines into the first field of the new frame */
-        copy_picture_field(out->data, out->linesize,
+        copy_picture_field(tinterlace, out->data, out->linesize,
                            (const uint8_t **)next->data, next->linesize,
                            inlink->format, inlink->w, inlink->h,
                            tff ? FIELD_UPPER : FIELD_LOWER, 1, tff ? FIELD_UPPER : FIELD_LOWER,