diff options
author | Paul B Mahol <onemda@gmail.com> | 2018-05-01 13:12:50 +0200 |
---|---|---|
committer | Paul B Mahol <onemda@gmail.com> | 2018-05-01 13:12:50 +0200 |
commit | 273edb2fe45a8f3805085f879ad4717d87247aeb (patch) | |
tree | d210a4b3e25b1f3d93c9a62fd95788329936e919 | |
parent | 0807a771600956e1f3e36a202fd3877418541eb0 (diff) | |
download | ffmpeg-273edb2fe45a8f3805085f879ad4717d87247aeb.tar.gz |
avfilter/vf_neighbor: rewrite without using temp memory
Signed-off-by: Paul B Mahol <onemda@gmail.com>
-rw-r--r-- | libavfilter/vf_neighbor.c | 70 |
1 files changed, 24 insertions, 46 deletions
diff --git a/libavfilter/vf_neighbor.c b/libavfilter/vf_neighbor.c index de4a12f048..bd69c9e77f 100644 --- a/libavfilter/vf_neighbor.c +++ b/libavfilter/vf_neighbor.c @@ -34,7 +34,6 @@ typedef struct NContext { int nb_planes; int threshold[4]; int coordinates; - uint8_t *buffer; void (*filter)(uint8_t *dst, const uint8_t *p1, int width, int threshold, const uint8_t *coordinates[], int coord); @@ -52,25 +51,6 @@ static int query_formats(AVFilterContext *ctx) return ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); } -static av_cold void uninit(AVFilterContext *ctx) -{ - NContext *s = ctx->priv; - - av_freep(&s->buffer); -} - -static inline void line_copy8(uint8_t *line, const uint8_t *srcp, int width, int mergin) -{ - int i; - - memcpy(line, srcp, width); - - for (i = mergin; i > 0; i--) { - line[-i] = line[i]; - line[width - 1 + i] = line[width - 1 - i]; - } -} - static void erosion(uint8_t *dst, const uint8_t *p1, int width, int threshold, const uint8_t *coordinates[], int coord) { @@ -155,9 +135,6 @@ static int config_input(AVFilterLink *inlink) s->planeheight[0] = s->planeheight[3] = inlink->h; s->nb_planes = av_pix_fmt_count_planes(inlink->format); - s->buffer = av_malloc(3 * (s->planewidth[0] + 32)); - if (!s->buffer) - return AVERROR(ENOMEM); if (!strcmp(ctx->filter->name, "erosion")) s->filter = erosion; @@ -190,32 +167,34 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) const int threshold = s->threshold[plane]; if (threshold) { + const int stride = in->linesize[plane]; + const int dstride = out->linesize[plane]; const uint8_t *src = in->data[plane]; uint8_t *dst = out->data[plane]; - int stride = in->linesize[plane]; - int height = s->planeheight[plane]; - int width = s->planewidth[plane]; - uint8_t *p0 = s->buffer + 16; - uint8_t *p1 = p0 + s->planewidth[0]; - uint8_t *p2 = p1 + s->planewidth[0]; - uint8_t *orig = p0, *end = p2; - - line_copy8(p0, src + stride, width, 1); - line_copy8(p1, src, width, 1); + const int height = s->planeheight[plane]; + const int width = s->planewidth[plane]; for (y = 0; y < height; y++) { - const uint8_t *coordinates[] = { p0 - 1, p0, p0 + 1, - p1 - 1, p1 + 1, - p2 - 1, p2, p2 + 1}; - src += stride * (y < height - 1 ? 1 : -1); - line_copy8(p2, src, width, 1); - - s->filter(dst, p1, width, threshold, coordinates, s->coordinates); - - p0 = p1; - p1 = p2; - p2 = (p2 == end) ? orig: p2 + s->planewidth[0]; - dst += out->linesize[plane]; + const int nh = y > 0; + const int ph = y < height - 1; + const uint8_t *coordinates[] = { src - nh * stride, src + 1 - nh * stride, src + 2 - nh * stride, + src, src + 2, + src + ph * stride, src + 1 + ph * stride, src + 2 + ph * stride}; + + const uint8_t *coordinateslb[] = { src - nh * stride, src - nh * stride, src + 1 - nh * stride, + src, src + 1, + src + ph * stride, src + ph * stride, src + 1 + ph * stride}; + + const uint8_t *coordinatesrb[] = { src + width - 2 - nh * stride, src + width - 1 - nh * stride, src + width - 1 - nh * stride, + src + width - 2, src + width - 1, + src + width - 2 + ph * stride, src + width - 1 + ph * stride, src + width - 1 + ph * stride}; + + s->filter(dst, src, 1, threshold, coordinateslb, s->coordinates); + s->filter(dst + 1, src + 1, width - 2, threshold, coordinates, s->coordinates); + s->filter(dst + width - 1, src + width - 1, 1, threshold, coordinatesrb, s->coordinates); + + src += stride; + dst += dstride; } } else { av_image_copy_plane(out->data[plane], out->linesize[plane], @@ -257,7 +236,6 @@ AVFilter ff_vf_##name_ = { \ .description = NULL_IF_CONFIG_SMALL(description_), \ .priv_size = sizeof(NContext), \ .priv_class = &name_##_class, \ - .uninit = uninit, \ .query_formats = query_formats, \ .inputs = neighbor_inputs, \ .outputs = neighbor_outputs, \ |