diff options
author | Stefano Sabatini <stefasab@gmail.com> | 2012-03-11 03:05:42 +0100 |
---|---|---|
committer | Stefano Sabatini <stefasab@gmail.com> | 2012-03-17 11:21:49 +0100 |
commit | 3225bc37a361c1c02effebf4c981c837d8468a70 (patch) | |
tree | 35d86d4e3a09969463bf97a72702969c2267aacf /libavfilter | |
parent | 32a5775a9192ed9d88d50ed2ff602d3ef4e98c84 (diff) | |
download | ffmpeg-3225bc37a361c1c02effebf4c981c837d8468a70.tar.gz |
lavfi: add bbox filter
Also add bbox.h and bbox.c files, based on the remove-logo filter by
Robert Edele. These files are useful for sharing code with the pending
removelogo port.
Diffstat (limited to 'libavfilter')
-rw-r--r-- | libavfilter/Makefile | 1 | ||||
-rw-r--r-- | libavfilter/allfilters.c | 1 | ||||
-rw-r--r-- | libavfilter/bbox.c | 75 | ||||
-rw-r--r-- | libavfilter/bbox.h | 44 | ||||
-rw-r--r-- | libavfilter/version.h | 4 | ||||
-rw-r--r-- | libavfilter/vf_bbox.c | 113 |
6 files changed, 236 insertions, 2 deletions
diff --git a/libavfilter/Makefile b/libavfilter/Makefile index e9c9a4b8a4..6a9a3adb7e 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -48,6 +48,7 @@ OBJS-$(CONFIG_ABUFFERSINK_FILTER) += sink_buffer.o OBJS-$(CONFIG_ANULLSINK_FILTER) += asink_anullsink.o OBJS-$(CONFIG_ASS_FILTER) += vf_ass.o +OBJS-$(CONFIG_BBOX_FILTER) += bbox.o vf_bbox.o OBJS-$(CONFIG_BLACKDETECT_FILTER) += vf_blackdetect.o OBJS-$(CONFIG_BLACKFRAME_FILTER) += vf_blackframe.o OBJS-$(CONFIG_BOXBLUR_FILTER) += vf_boxblur.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index f0a7f8b8c3..6972271666 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -56,6 +56,7 @@ void avfilter_register_all(void) REGISTER_FILTER (ANULLSINK, anullsink, asink); REGISTER_FILTER (ASS, ass, vf); + REGISTER_FILTER (BBOX, bbox, vf); REGISTER_FILTER (BLACKDETECT, blackdetect, vf); REGISTER_FILTER (BLACKFRAME, blackframe, vf); REGISTER_FILTER (BOXBLUR, boxblur, vf); diff --git a/libavfilter/bbox.c b/libavfilter/bbox.c new file mode 100644 index 0000000000..c29c75873f --- /dev/null +++ b/libavfilter/bbox.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2005 Robert Edele <yartrebo@earthlink.net> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "bbox.h" + +int ff_calculate_bounding_box(FFBoundingBox *bbox, + const uint8_t *data, int linesize, int w, int h, + int min_val) +{ + int x, y; + int start_x; + int start_y; + int end_x = w - 1; + int end_y = h - 1; + const uint8_t *line; + + /* left bound */ + for (start_x = 0; start_x < w; start_x++) + for (y = 0; y < h; y++) + if ((data[y * linesize + start_x] > min_val)) + goto outl; +outl: + if (start_x == w) /* no points found */ + return 0; + + /* right bound */ + for (end_x = w - 1; end_x >= start_x; end_x--) + for (y = 0; y < h; y++) + if ((data[y * linesize + end_x] > min_val)) + goto outr; +outr: + + /* top bound */ + line = data; + for (start_y = 0; start_y < h; start_y++) { + for (x = 0; x < w; x++) + if (line[x] > min_val) + goto outt; + line += linesize; + } +outt: + + /* bottom bound */ + line = data + (h-1)*linesize; + for (end_y = h - 1; end_y >= start_y; end_y--) { + for (x = 0; x < w; x++) + if (line[x] > min_val) + goto outb; + line -= linesize; + } +outb: + + bbox->x1 = start_x; + bbox->y1 = start_y; + bbox->x2 = end_x; + bbox->y2 = end_y; + return 1; +} diff --git a/libavfilter/bbox.h b/libavfilter/bbox.h new file mode 100644 index 0000000000..eb73154c14 --- /dev/null +++ b/libavfilter/bbox.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2005 Robert Edele <yartrebo@earthlink.net> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVFILTER_BBOX_H +#define AVFILTER_BBOX_H + +#include <stdint.h> + +typedef struct { + int x1, x2, y1, y2; +} FFBoundingBox; + +/** + * Calculate the smallest rectangle that will encompass the + * region with values > min_val. + * + * @param bbox bounding box structure which is updated with the found values. + * If no pixels could be found with value > min_val, the + * structure is not modified. + * @return 1 in case at least one pixel with value > min_val was found, + * 0 otherwise + */ +int ff_calculate_bounding_box(FFBoundingBox *bbox, + const uint8_t *data, int linesize, + int w, int h, int min_val); + +#endif /* AVFILTER_BBOX_H */ diff --git a/libavfilter/version.h b/libavfilter/version.h index fcced1d0d3..50c48d9dda 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -29,8 +29,8 @@ #include "libavutil/avutil.h" #define LIBAVFILTER_VERSION_MAJOR 2 -#define LIBAVFILTER_VERSION_MINOR 64 -#define LIBAVFILTER_VERSION_MICRO 101 +#define LIBAVFILTER_VERSION_MINOR 65 +#define LIBAVFILTER_VERSION_MICRO 100 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ LIBAVFILTER_VERSION_MINOR, \ diff --git a/libavfilter/vf_bbox.c b/libavfilter/vf_bbox.c new file mode 100644 index 0000000000..98ae92cabf --- /dev/null +++ b/libavfilter/vf_bbox.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2012 Stefano Sabatini + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * bounding box detection filter + */ + +#include "libavutil/pixdesc.h" +#include "libavutil/timestamp.h" +#include "avfilter.h" +#include "bbox.h" + +typedef struct { + unsigned int frame; + int vsub, hsub; +} BBoxContext; + +static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) +{ + BBoxContext *bbox = ctx->priv; + bbox->frame = 0; + return 0; +} + +static int query_formats(AVFilterContext *ctx) +{ + static const enum PixelFormat pix_fmts[] = { + PIX_FMT_YUV420P, + PIX_FMT_YUV444P, + PIX_FMT_YUV440P, + PIX_FMT_YUV422P, + PIX_FMT_YUV411P, + PIX_FMT_NONE, + }; + + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); + return 0; +} + +static void end_frame(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->dst; + BBoxContext *bbox = ctx->priv; + AVFilterBufferRef *picref = inlink->cur_buf; + FFBoundingBox box; + int has_bbox, w, h; + + has_bbox = + ff_calculate_bounding_box(&box, + picref->data[0], picref->linesize[0], + inlink->w, inlink->h, 16); + w = box.x2 - box.x1 + 1; + h = box.y2 - box.y1 + 1; + + av_log(ctx, AV_LOG_INFO, + "n:%d pts:%s pts_time:%s", bbox->frame, + av_ts2str(picref->pts), av_ts2timestr(picref->pts, &inlink->time_base)); + + if (has_bbox) { + av_log(ctx, AV_LOG_INFO, + "x1:%d x2:%d y1:%d y2:%d w:%d h:%d" + " crop=%d:%d:%d:%d drawbox=%d:%d:%d:%d", + box.x1, box.x2, box.y1, box.y2, w, h, + w, h, box.x1, box.y1, /* crop params */ + box.x1, box.y1, w, h); /* drawbox params */ + } + av_log(ctx, AV_LOG_INFO, "\n"); + + bbox->frame++; + avfilter_end_frame(inlink->dst->outputs[0]); +} + +AVFilter avfilter_vf_bbox = { + .name = "bbox", + .description = NULL_IF_CONFIG_SMALL("Compute bounding box for each frame."), + .priv_size = sizeof(BBoxContext), + .query_formats = query_formats, + .init = init, + + .inputs = (const AVFilterPad[]) { + { .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .get_video_buffer = avfilter_null_get_video_buffer, + .start_frame = avfilter_null_start_frame, + .end_frame = end_frame, + .min_perms = AV_PERM_READ, }, + { .name = NULL } + }, + + .outputs = (const AVFilterPad[]) { + { .name = "default", + .type = AVMEDIA_TYPE_VIDEO }, + { .name = NULL } + }, +}; |