97 #define OFFSET(x) offsetof(RemovelogoContext, x)
98 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
117 #define apply_mask_fudge_factor(x) (((x) >> 2) + (x))
134 int w,
int h,
int min_val,
141 int current_pass = 0;
144 for (y = 0; y <
h; y++)
145 for (x = 0; x <
w; x++)
146 data[y*linesize + x] =
data[y*linesize + x] > min_val;
156 int has_anything_changed = 0;
157 uint8_t *current_pixel0 =
data + 1 + linesize, *current_pixel;
160 for (y = 1; y <
h-1; y++) {
161 current_pixel = current_pixel0;
162 for (x = 1; x <
w-1; x++) {
174 if ( *current_pixel >= current_pass &&
175 *(current_pixel + 1) >= current_pass &&
176 *(current_pixel - 1) >= current_pass &&
177 *(current_pixel + linesize) >= current_pass &&
178 *(current_pixel - linesize) >= current_pass) {
183 has_anything_changed = 1;
187 current_pixel0 += linesize;
189 if (!has_anything_changed)
195 for (y = 1; y <
h - 1; y++)
196 for (x = 1; x <
w - 1; x++)
216 const char *filename,
void *log_ctx)
220 uint8_t *src_data[4], *gray_data[4];
221 int src_linesize[4], gray_linesize[4];
257 uint8_t *dst_data,
int dst_linesize,
258 int src_w,
int src_h,
265 for (y = 0; y < src_h/2; y++) {
266 for (x = 0; x < src_w/2; x++) {
269 dst_data[(y * dst_linesize) + x] =
270 src_data[((y << 1) * src_linesize) + (x << 1)] ||
271 src_data[((y << 1) * src_linesize) + (x << 1) + 1] ||
272 src_data[(((y << 1) + 1) * src_linesize) + (x << 1)] ||
273 src_data[(((y << 1) + 1) * src_linesize) + (x << 1) + 1];
274 dst_data[(y * dst_linesize) + x] =
FFMIN(1, dst_data[(y * dst_linesize) + x]);
279 src_w/2, src_h/2, 0, max_mask_size);
288 int full_max_mask_size, half_max_mask_size;
302 16, &full_max_mask_size);
308 s->half_mask_data,
w/2,
309 w,
h, &half_max_mask_size);
311 s->max_mask_size =
FFMAX(full_max_mask_size, half_max_mask_size);
321 for (
a = 0;
a <=
s->max_mask_size;
a++) {
327 for (
b = -
a;
b <=
a;
b++) {
333 for (
c = -
a;
c <=
a;
c++) {
334 if ((
b *
b) + (
c *
c) <= (
a *
a))
348 #define SHOW_LOGO_INFO(mask_type) \
349 av_log(ctx, AV_LOG_VERBOSE, #mask_type " x1:%d x2:%d y1:%d y2:%d max_mask_size:%d\n", \
350 s->mask_type##_mask_bbox.x1, s->mask_type##_mask_bbox.x2, \
351 s->mask_type##_mask_bbox.y1, s->mask_type##_mask_bbox.y2, \
352 mask_type##_max_mask_size);
364 if (inlink->
w !=
s->mask_w || inlink->
h !=
s->mask_h) {
366 "Mask image size %dx%d does not match with the input video size %dx%d\n",
367 s->mask_w,
s->mask_h, inlink->
w, inlink->
h);
389 const uint8_t *mask_data,
int mask_linesize,
390 uint8_t *image_data,
int image_linesize,
391 int w,
int h,
int x,
int y)
396 int start_posx, start_posy, end_posx, end_posy;
400 const uint8_t *image_read_position;
402 const uint8_t *mask_read_position;
405 mask_size = mask_data[y * mask_linesize + x];
406 start_posx =
FFMAX(0, x - mask_size);
407 start_posy =
FFMAX(0, y - mask_size);
408 end_posx =
FFMIN(
w - 1, x + mask_size);
409 end_posy =
FFMIN(
h - 1, y + mask_size);
411 image_read_position = image_data + image_linesize * start_posy + start_posx;
412 mask_read_position = mask_data + mask_linesize * start_posy + start_posx;
414 for (j = start_posy; j <= end_posy; j++) {
415 for (
i = start_posx;
i <= end_posx;
i++) {
418 if (!(*mask_read_position) &&
mask[mask_size][
i - start_posx][j - start_posy]) {
423 image_read_position++;
424 mask_read_position++;
427 image_read_position += (image_linesize - ((end_posx + 1) - start_posx));
428 mask_read_position += (mask_linesize - ((end_posx + 1) - start_posx));
434 return divisor == 0 ? 255:
462 const uint8_t *src_data,
int src_linesize,
463 uint8_t *dst_data,
int dst_linesize,
464 const uint8_t *mask_data,
int mask_linesize,
475 for (y = bbox->
y1; y <= bbox->y2; y++) {
476 src_line = src_data + src_linesize * y;
477 dst_line = dst_data + dst_linesize * y;
479 for (x = bbox->
x1; x <= bbox->x2; x++) {
480 if (mask_data[y * mask_linesize + x]) {
483 mask_data, mask_linesize,
484 dst_data, dst_linesize,
489 dst_line[x] = src_line[x];
504 outpicref = inpicref;
517 s->full_mask_data, inlink->
w,
518 inlink->
w, inlink->
h,
direct, &
s->full_mask_bbox);
522 s->half_mask_data, inlink->
w/2,
523 inlink->
w/2, inlink->
h/2,
direct, &
s->half_mask_bbox);
527 s->half_mask_data, inlink->
w/2,
528 inlink->
w/2, inlink->
h/2,
direct, &
s->half_mask_bbox);
546 for (
a = 0;
a <=
s->max_mask_size;
a++) {
548 for (
b = -
a;
b <=
a;
b++) {
577 .
name =
"removelogo",
585 .priv_class = &removelogo_class,
static const AVFilterPad inputs[]
static const AVFilterPad outputs[]
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Main libavfilter public API header.
int ff_calculate_bounding_box(FFBoundingBox *bbox, const uint8_t *data, int linesize, int w, int h, int min_val, int depth)
Calculate the smallest rectangle that will encompass the region with values > min_val.
#define flags(name, subs,...)
static enum AVPixelFormat pix_fmt
#define AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
Some filters support a generic "enable" expression option that can be used to enable or disable a fil...
int av_frame_is_writable(AVFrame *frame)
Check if the frame data is writable.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
#define AV_LOG_INFO
Standard information.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
void av_image_copy_plane(uint8_t *dst, int dst_linesize, const uint8_t *src, int src_linesize, int bytewidth, int height)
Copy image plane from src to dst.
int ff_load_image(uint8_t *data[4], int linesize[4], int *w, int *h, enum AVPixelFormat *pix_fmt, const char *filename, void *log_ctx)
Load image from filename and put the resulting image in data.
Miscellaneous utilities which make use of the libavformat library.
static void direct(const float *in, const FFTComplex *ir, int len, float *out)
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
static enum AVPixelFormat pix_fmts[]
int ff_scale_image(uint8_t *dst_data[4], int dst_linesize[4], int dst_w, int dst_h, enum AVPixelFormat dst_pix_fmt, uint8_t *const src_data[4], int src_linesize[4], int src_w, int src_h, enum AVPixelFormat src_pix_fmt, void *log_ctx)
Scale image using libswscale.
Miscellaneous utilities which make use of the libswscale library.
static const uint16_t mask[17]
static uint8_t half(int a, int b)
AVPixelFormat
Pixel format.
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Describe the class of an AVClass context structure.
void * priv
private data for use by the filter
AVFilterLink ** outputs
array of pointers to output links
A link between two filters.
int w
agreed upon image width
int h
agreed upon image height
AVFilterContext * dst
dest filter
A filter pad used for either input or output.
const char * name
Pad name.
const char * name
Filter name.
This structure describes decoded (raw) audio or video data.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
This code implements a filter to remove annoying TV logos and other annoying images placed onto a vid...
FFBoundingBox full_mask_bbox
FFBoundingBox half_mask_bbox
#define av_malloc_array(a, b)
AVFilter ff_vf_removelogo
static void blur_image(int ***mask, const uint8_t *src_data, int src_linesize, uint8_t *dst_data, int dst_linesize, const uint8_t *mask_data, int mask_linesize, int w, int h, int direct, FFBoundingBox *bbox)
Blur image plane using a mask.
AVFILTER_DEFINE_CLASS(removelogo)
static void generate_half_size_image(const uint8_t *src_data, int src_linesize, uint8_t *dst_data, int dst_linesize, int src_w, int src_h, int *max_mask_size)
Generate a scaled down image with half width, height, and intensity.
static const AVFilterPad removelogo_outputs[]
static int query_formats(AVFilterContext *ctx)
static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
static int load_mask(uint8_t **mask, int *w, int *h, const char *filename, void *log_ctx)
static void convert_mask_to_strength_mask(uint8_t *data, int linesize, int w, int h, int min_val, int *max_mask_size)
Pre-process an image to give distance information.
static const AVOption removelogo_options[]
static av_cold int init(AVFilterContext *ctx)
#define apply_mask_fudge_factor(x)
Choose a slightly larger mask size to improve performance.
static av_cold void uninit(AVFilterContext *ctx)
static const AVFilterPad removelogo_inputs[]
static unsigned int blur_pixel(int ***mask, const uint8_t *mask_data, int mask_linesize, uint8_t *image_data, int image_linesize, int w, int h, int x, int y)
Blur image.
#define SHOW_LOGO_INFO(mask_type)
static int config_props_input(AVFilterLink *inlink)
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.