You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	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.
This commit is contained in:
		| @@ -14,6 +14,7 @@ version next: | ||||
| - blackdetect filter | ||||
| - libutvideo encoder wrapper (--enable-libutvideo) | ||||
| - swapuv filter | ||||
| - bbox filter | ||||
|  | ||||
|  | ||||
| version 0.10: | ||||
|   | ||||
| @@ -761,6 +761,16 @@ video, use the command: | ||||
| ass=sub.ass | ||||
| @end example | ||||
|  | ||||
| @section bbox | ||||
|  | ||||
| Compute the bounding box for the non-black pixels in the input frame | ||||
| luminance plane. | ||||
|  | ||||
| This filter computes the bounding box containing all the pixels with a | ||||
| luminance value greater than the minimum allowed value. | ||||
| The parameters describing the bounding box are printed on the filter | ||||
| log. | ||||
|  | ||||
| @section blackdetect | ||||
|  | ||||
| Detect video intervals that are (almost) completely black. Can be | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
							
								
								
									
										75
									
								
								libavfilter/bbox.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								libavfilter/bbox.c
									
									
									
									
									
										Normal file
									
								
							| @@ -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; | ||||
| } | ||||
							
								
								
									
										44
									
								
								libavfilter/bbox.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								libavfilter/bbox.h
									
									
									
									
									
										Normal file
									
								
							| @@ -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 */ | ||||
| @@ -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, \ | ||||
|   | ||||
							
								
								
									
										113
									
								
								libavfilter/vf_bbox.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								libavfilter/vf_bbox.c
									
									
									
									
									
										Normal file
									
								
							| @@ -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 } | ||||
|     }, | ||||
| }; | ||||
		Reference in New Issue
	
	Block a user