mirror of https://git.ffmpeg.org/ffmpeg.git
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: 2e1704059a
by Kieran Kunhya
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
9d548fce24
commit
18b46ecc93
|
@ -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 */
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue