76
80
topright = src+logo_y1 * src_linesize+logo_x2-1;
77
81
botleft = src+(logo_y2-1) * src_linesize+logo_x1;
79
dst += (logo_y1+1)*dst_linesize;
80
src += (logo_y1+1)*src_linesize;
83
84
av_image_copy_plane(dst, dst_linesize, src, src_linesize, w, h);
86
dst += (logo_y1 + 1) * dst_linesize;
87
src += (logo_y1 + 1) * src_linesize;
85
89
for (y = logo_y1+1; y < logo_y2-1; y++) {
86
90
for (x = logo_x1+1,
87
91
xdst = dst+logo_x1+1,
134
138
#define OFFSET(x) offsetof(DelogoContext, x)
136
140
static const AVOption delogo_options[]= {
137
{"x", "set logo x position", OFFSET(x), FF_OPT_TYPE_INT, {-1}, -1, INT_MAX },
138
{"y", "set logo y position", OFFSET(y), FF_OPT_TYPE_INT, {-1}, -1, INT_MAX },
139
{"w", "set logo width", OFFSET(w), FF_OPT_TYPE_INT, {-1}, -1, INT_MAX },
140
{"h", "set logo height", OFFSET(h), FF_OPT_TYPE_INT, {-1}, -1, INT_MAX },
141
{"band", "set delogo area band size", OFFSET(band), FF_OPT_TYPE_INT, { 4}, -1, INT_MAX },
142
{"t", "set delogo area band size", OFFSET(band), FF_OPT_TYPE_INT, { 4}, -1, INT_MAX },
143
{"show", "show delogo area", OFFSET(show), FF_OPT_TYPE_INT, { 0}, 0, 1 },
141
{"x", "set logo x position", OFFSET(x), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX },
142
{"y", "set logo y position", OFFSET(y), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX },
143
{"w", "set logo width", OFFSET(w), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX },
144
{"h", "set logo height", OFFSET(h), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX },
145
{"band", "set delogo area band size", OFFSET(band), AV_OPT_TYPE_INT, {.i64 = 4}, -1, INT_MAX },
146
{"t", "set delogo area band size", OFFSET(band), AV_OPT_TYPE_INT, {.i64 = 4}, -1, INT_MAX },
147
{"show", "show delogo area", OFFSET(show), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1 },
158
162
static int query_formats(AVFilterContext *ctx)
160
enum PixelFormat pix_fmts[] = {
161
PIX_FMT_YUV444P, PIX_FMT_YUV422P, PIX_FMT_YUV420P,
162
PIX_FMT_YUV411P, PIX_FMT_YUV410P, PIX_FMT_YUV440P,
163
PIX_FMT_YUVA420P, PIX_FMT_GRAY8,
164
enum AVPixelFormat pix_fmts[] = {
165
AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P,
166
AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV440P,
167
AV_PIX_FMT_YUVA420P, AV_PIX_FMT_GRAY8,
167
avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
171
ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
171
static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
175
static av_cold int init(AVFilterContext *ctx, const char *args)
173
177
DelogoContext *delogo = ctx->priv;
214
static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
216
AVFilterLink *outlink = inlink->dst->outputs[0];
217
AVFilterBufferRef *outpicref;
219
if (inpicref->perms & AV_PERM_PRESERVE) {
220
outpicref = avfilter_get_video_buffer(outlink, AV_PERM_WRITE,
221
outlink->w, outlink->h);
222
avfilter_copy_buffer_ref_props(outpicref, inpicref);
223
outpicref->video->w = outlink->w;
224
outpicref->video->h = outlink->h;
226
outpicref = inpicref;
228
outlink->out_buf = outpicref;
229
avfilter_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0));
232
static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { }
234
static void end_frame(AVFilterLink *inlink)
218
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
236
220
DelogoContext *delogo = inlink->dst->priv;
237
221
AVFilterLink *outlink = inlink->dst->outputs[0];
238
AVFilterBufferRef *inpicref = inlink ->cur_buf;
239
AVFilterBufferRef *outpicref = outlink->out_buf;
240
int direct = inpicref == outpicref;
241
int hsub0 = av_pix_fmt_descriptors[inlink->format].log2_chroma_w;
242
int vsub0 = av_pix_fmt_descriptors[inlink->format].log2_chroma_h;
222
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
223
AVFilterBufferRef *out;
224
int hsub0 = desc->log2_chroma_w;
225
int vsub0 = desc->log2_chroma_h;
245
for (plane = 0; plane < 4 && inpicref->data[plane]; plane++) {
229
if ((in->perms & AV_PERM_WRITE) && !(in->perms & AV_PERM_PRESERVE)) {
233
out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
235
avfilter_unref_bufferp(&in);
236
return AVERROR(ENOMEM);
239
avfilter_copy_buffer_ref_props(out, in);
240
out->video->w = outlink->w;
241
out->video->h = outlink->h;
244
for (plane = 0; plane < 4 && in->data[plane]; plane++) {
246
245
int hsub = plane == 1 || plane == 2 ? hsub0 : 0;
247
246
int vsub = plane == 1 || plane == 2 ? vsub0 : 0;
249
apply_delogo(outpicref->data[plane], outpicref->linesize[plane],
250
inpicref ->data[plane], inpicref ->linesize[plane],
248
apply_delogo(out->data[plane], out->linesize[plane],
249
in ->data[plane], in ->linesize[plane],
251
250
inlink->w>>hsub, inlink->h>>vsub,
252
251
delogo->x>>hsub, delogo->y>>vsub,
253
252
delogo->w>>hsub, delogo->h>>vsub,
255
254
delogo->show, direct);
258
avfilter_draw_slice(outlink, 0, inlink->h, 1);
259
avfilter_end_frame(outlink);
260
avfilter_unref_buffer(inpicref);
262
avfilter_unref_buffer(outpicref);
258
avfilter_unref_bufferp(&in);
260
return ff_filter_frame(outlink, out);
263
static const AVFilterPad avfilter_vf_delogo_inputs[] = {
266
.type = AVMEDIA_TYPE_VIDEO,
267
.get_video_buffer = ff_null_get_video_buffer,
268
.filter_frame = filter_frame,
269
.min_perms = AV_PERM_WRITE | AV_PERM_READ,
270
.rej_perms = AV_PERM_PRESERVE
275
static const AVFilterPad avfilter_vf_delogo_outputs[] = {
278
.type = AVMEDIA_TYPE_VIDEO,
265
283
AVFilter avfilter_vf_delogo = {
266
284
.name = "delogo",
267
285
.description = NULL_IF_CONFIG_SMALL("Remove logo from input video."),
270
288
.query_formats = query_formats,
272
.inputs = (AVFilterPad[]) {{ .name = "default",
273
.type = AVMEDIA_TYPE_VIDEO,
274
.get_video_buffer = avfilter_null_get_video_buffer,
275
.start_frame = start_frame,
276
.draw_slice = null_draw_slice,
277
.end_frame = end_frame,
278
.min_perms = AV_PERM_WRITE | AV_PERM_READ,
279
.rej_perms = AV_PERM_PRESERVE },
281
.outputs = (AVFilterPad[]) {{ .name = "default",
282
.type = AVMEDIA_TYPE_VIDEO, },
290
.inputs = avfilter_vf_delogo_inputs,
291
.outputs = avfilter_vf_delogo_outputs,