aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2014-11-15 03:20:02 +0100
committerMichael Niedermayer <michaelni@gmx.at>2014-11-15 03:25:43 +0100
commit18b46ecc93bf07663431ae561118990b525bc103 (patch)
tree48092edc1a27631dd2890ca039fc0cd99bfa9e60
parent9d548fce24057649f0463e1243417d8f80f1d1db (diff)
downloadffmpeg-18b46ecc93bf07663431ae561118990b525bc103.tar.gz
avfilter/tinterlace: Move lowpass_line to a separate function and call it through a function pointer
This permits replacing it by a optimized implementation Based-on / Idea-from: 2e1704059ae8625beda2ffde847ad22c5ba416dc by Kieran Kunhya Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r--libavfilter/tinterlace.h2
-rw-r--r--libavfilter/vf_tinterlace.c43
2 files changed, 30 insertions, 15 deletions
diff --git a/libavfilter/tinterlace.h b/libavfilter/tinterlace.h
index 8fc95cbc92..8d33452b0d 100644
--- a/libavfilter/tinterlace.h
+++ b/libavfilter/tinterlace.h
@@ -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 */
diff --git a/libavfilter/vf_tinterlace.c b/libavfilter/vf_tinterlace.c
index 6ef2a92c88..1d34d21436 100644
--- a/libavfilter/vf_tinterlace.c
+++ b/libavfilter/vf_tinterlace.c
@@ -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,