X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavfilter%2Fvf_delogo.c;h=d4135f1b9b9e602ecc9142b95a48d6378291f5c9;hb=d1bec33b46091546c5b2e6815210e73f87abf413;hp=70aa12a5d15c2e35d2709b998637dd323a35ba39;hpb=6d58358a3a3274e84a4e34a348165fbb3f484587;p=ffmpeg diff --git a/libavfilter/vf_delogo.c b/libavfilter/vf_delogo.c index 70aa12a5d15..d4135f1b9b9 100644 --- a/libavfilter/vf_delogo.c +++ b/libavfilter/vf_delogo.c @@ -25,11 +25,13 @@ * Ported from MPlayer libmpcodecs/vf_delogo.c. */ +#include "libavutil/common.h" #include "libavutil/imgutils.h" #include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "avfilter.h" #include "formats.h" +#include "internal.h" #include "video.h" /** @@ -78,12 +80,12 @@ static void apply_delogo(uint8_t *dst, int dst_linesize, topright = src+logo_y1 * src_linesize+logo_x2-1; botleft = src+(logo_y2-1) * src_linesize+logo_x1; - dst += (logo_y1+1)*dst_linesize; - src += (logo_y1+1)*src_linesize; - if (!direct) av_image_copy_plane(dst, dst_linesize, src, src_linesize, w, h); + dst += (logo_y1 + 1) * dst_linesize; + src += (logo_y1 + 1) * src_linesize; + for (y = logo_y1+1; y < logo_y2-1; y++) { for (x = logo_x1+1, xdst = dst+logo_x1+1, @@ -136,13 +138,13 @@ typedef struct { #define OFFSET(x) offsetof(DelogoContext, x) static const AVOption delogo_options[]= { - {"x", "set logo x position", OFFSET(x), FF_OPT_TYPE_INT, {-1}, -1, INT_MAX }, - {"y", "set logo y position", OFFSET(y), FF_OPT_TYPE_INT, {-1}, -1, INT_MAX }, - {"w", "set logo width", OFFSET(w), FF_OPT_TYPE_INT, {-1}, -1, INT_MAX }, - {"h", "set logo height", OFFSET(h), FF_OPT_TYPE_INT, {-1}, -1, INT_MAX }, - {"band", "set delogo area band size", OFFSET(band), FF_OPT_TYPE_INT, { 4}, -1, INT_MAX }, - {"t", "set delogo area band size", OFFSET(band), FF_OPT_TYPE_INT, { 4}, -1, INT_MAX }, - {"show", "show delogo area", OFFSET(show), FF_OPT_TYPE_INT, { 0}, 0, 1 }, + {"x", "set logo x position", OFFSET(x), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX }, + {"y", "set logo y position", OFFSET(y), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX }, + {"w", "set logo width", OFFSET(w), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX }, + {"h", "set logo height", OFFSET(h), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX }, + {"band", "set delogo area band size", OFFSET(band), AV_OPT_TYPE_INT, {.i64 = 4}, -1, INT_MAX }, + {"t", "set delogo area band size", OFFSET(band), AV_OPT_TYPE_INT, {.i64 = 4}, -1, INT_MAX }, + {"show", "show delogo area", OFFSET(show), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1 }, {NULL}, }; @@ -159,18 +161,18 @@ static const AVClass delogo_class = { static int query_formats(AVFilterContext *ctx) { - enum PixelFormat pix_fmts[] = { - PIX_FMT_YUV444P, PIX_FMT_YUV422P, PIX_FMT_YUV420P, - PIX_FMT_YUV411P, PIX_FMT_YUV410P, PIX_FMT_YUV440P, - PIX_FMT_YUVA420P, PIX_FMT_GRAY8, - PIX_FMT_NONE + enum AVPixelFormat pix_fmts[] = { + AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P, + AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV440P, + AV_PIX_FMT_YUVA420P, AV_PIX_FMT_GRAY8, + AV_PIX_FMT_NONE }; ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); return 0; } -static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) +static av_cold int init(AVFilterContext *ctx, const char *args) { DelogoContext *delogo = ctx->priv; int ret = 0; @@ -213,43 +215,38 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) return 0; } -static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) -{ - AVFilterLink *outlink = inlink->dst->outputs[0]; - AVFilterBufferRef *outpicref; - - if (inpicref->perms & AV_PERM_PRESERVE) { - outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE, - outlink->w, outlink->h); - avfilter_copy_buffer_ref_props(outpicref, inpicref); - outpicref->video->w = outlink->w; - outpicref->video->h = outlink->h; - } else - outpicref = inpicref; - - outlink->out_buf = outpicref; - ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); -} - -static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { } - -static void end_frame(AVFilterLink *inlink) +static int filter_frame(AVFilterLink *inlink, AVFrame *in) { DelogoContext *delogo = inlink->dst->priv; AVFilterLink *outlink = inlink->dst->outputs[0]; - AVFilterBufferRef *inpicref = inlink ->cur_buf; - AVFilterBufferRef *outpicref = outlink->out_buf; - int direct = inpicref == outpicref; - int hsub0 = av_pix_fmt_descriptors[inlink->format].log2_chroma_w; - int vsub0 = av_pix_fmt_descriptors[inlink->format].log2_chroma_h; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); + AVFrame *out; + int hsub0 = desc->log2_chroma_w; + int vsub0 = desc->log2_chroma_h; + int direct = 0; int plane; - for (plane = 0; plane < 4 && inpicref->data[plane]; plane++) { + if (av_frame_is_writable(in)) { + direct = 1; + out = in; + } else { + out = ff_get_video_buffer(outlink, outlink->w, outlink->h); + if (!out) { + av_frame_free(&in); + return AVERROR(ENOMEM); + } + + av_frame_copy_props(out, in); + out->width = outlink->w; + out->height = outlink->h; + } + + for (plane = 0; plane < 4 && in->data[plane]; plane++) { int hsub = plane == 1 || plane == 2 ? hsub0 : 0; int vsub = plane == 1 || plane == 2 ? vsub0 : 0; - apply_delogo(outpicref->data[plane], outpicref->linesize[plane], - inpicref ->data[plane], inpicref ->linesize[plane], + apply_delogo(out->data[plane], out->linesize[plane], + in ->data[plane], in ->linesize[plane], inlink->w>>hsub, inlink->h>>vsub, delogo->x>>hsub, delogo->y>>vsub, delogo->w>>hsub, delogo->h>>vsub, @@ -257,13 +254,30 @@ static void end_frame(AVFilterLink *inlink) delogo->show, direct); } - ff_draw_slice(outlink, 0, inlink->h, 1); - ff_end_frame(outlink); - avfilter_unref_buffer(inpicref); if (!direct) - avfilter_unref_buffer(outpicref); + av_frame_free(&in); + + return ff_filter_frame(outlink, out); } +static const AVFilterPad avfilter_vf_delogo_inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .get_video_buffer = ff_null_get_video_buffer, + .filter_frame = filter_frame, + }, + { NULL } +}; + +static const AVFilterPad avfilter_vf_delogo_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + }, + { NULL } +}; + AVFilter avfilter_vf_delogo = { .name = "delogo", .description = NULL_IF_CONFIG_SMALL("Remove logo from input video."), @@ -271,16 +285,6 @@ AVFilter avfilter_vf_delogo = { .init = init, .query_formats = query_formats, - .inputs = (AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .get_video_buffer = ff_null_get_video_buffer, - .start_frame = start_frame, - .draw_slice = null_draw_slice, - .end_frame = end_frame, - .min_perms = AV_PERM_WRITE | AV_PERM_READ, - .rej_perms = AV_PERM_PRESERVE }, - { .name = NULL}}, - .outputs = (AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO, }, - { .name = NULL}}, + .inputs = avfilter_vf_delogo_inputs, + .outputs = avfilter_vf_delogo_outputs, };