X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavfilter%2Fvf_gradfun.c;h=2c9a9763c1fb344cfd94747d8d88e70f38d5714d;hb=adf0110d878d829f523a540d6815e2a2cc9f1344;hp=d73e83386523b858b789e9b2b8f0514c6efefd71;hpb=d4f89906e3b310609b636cf6071313ec557ec873;p=ffmpeg diff --git a/libavfilter/vf_gradfun.c b/libavfilter/vf_gradfun.c index d73e8338652..2c9a9763c1f 100644 --- a/libavfilter/vf_gradfun.c +++ b/libavfilter/vf_gradfun.c @@ -33,6 +33,7 @@ */ #include "libavutil/imgutils.h" +#include "libavutil/common.h" #include "libavutil/cpu.h" #include "libavutil/pixdesc.h" #include "avfilter.h" @@ -134,7 +135,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args) gf->blur_line = ff_gradfun_blur_line_c; gf->filter_line = ff_gradfun_filter_line_c; - if (HAVE_MMX) + if (ARCH_X86) ff_gradfun_init_x86(gf); av_log(ctx, AV_LOG_VERBOSE, "threshold:%.2f radius:%d\n", thresh, gf->radius); @@ -150,12 +151,12 @@ static av_cold void uninit(AVFilterContext *ctx) static int query_formats(AVFilterContext *ctx) { - static const enum PixelFormat pix_fmts[] = { - PIX_FMT_YUV410P, PIX_FMT_YUV420P, - PIX_FMT_GRAY8, PIX_FMT_NV12, - PIX_FMT_NV21, PIX_FMT_YUV444P, - PIX_FMT_YUV422P, PIX_FMT_YUV411P, - PIX_FMT_NONE + static const enum AVPixelFormat pix_fmts[] = { + AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV420P, + AV_PIX_FMT_GRAY8, AV_PIX_FMT_NV12, + AV_PIX_FMT_NV21, AV_PIX_FMT_YUV444P, + AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV411P, + AV_PIX_FMT_NONE }; ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); @@ -166,8 +167,9 @@ static int query_formats(AVFilterContext *ctx) static int config_input(AVFilterLink *inlink) { GradFunContext *gf = inlink->dst->priv; - int hsub = av_pix_fmt_descriptors[inlink->format].log2_chroma_w; - int vsub = av_pix_fmt_descriptors[inlink->format].log2_chroma_h; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); + int hsub = desc->log2_chroma_w; + int vsub = desc->log2_chroma_h; gf->buf = av_mallocz((FFALIGN(inlink->w, 16) * (gf->radius + 1) / 2 + 32) * sizeof(uint16_t)); if (!gf->buf) @@ -180,50 +182,29 @@ static int config_input(AVFilterLink *inlink) return 0; } -static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) +static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in) { + GradFunContext *gf = inlink->dst->priv; AVFilterLink *outlink = inlink->dst->outputs[0]; - AVFilterBufferRef *outpicref = NULL; - int ret = 0; - - if (inpicref->perms & AV_PERM_PRESERVE) { - outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); - if (!outpicref) - return AVERROR(ENOMEM); + AVFilterBufferRef *out; + int p, direct; - avfilter_copy_buffer_ref_props(outpicref, inpicref); - outpicref->video->w = outlink->w; - outpicref->video->h = outlink->h; + if ((in->perms & AV_PERM_WRITE) && !(in->perms & AV_PERM_PRESERVE)) { + direct = 1; + out = in; } else { - outpicref = avfilter_ref_buffer(inpicref, ~0); - if (!outpicref) + out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); + if (!out) { + avfilter_unref_bufferp(&in); return AVERROR(ENOMEM); - } + } - ret = ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); - if (ret < 0) { - avfilter_unref_bufferp(&outpicref); - return ret; + avfilter_copy_buffer_ref_props(out, in); + out->video->w = outlink->w; + out->video->h = outlink->h; } - outlink->out_buf = outpicref; - return 0; -} - -static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) -{ - return 0; -} - -static int end_frame(AVFilterLink *inlink) -{ - GradFunContext *gf = inlink->dst->priv; - AVFilterBufferRef *inpic = inlink->cur_buf; - AVFilterLink *outlink = inlink->dst->outputs[0]; - AVFilterBufferRef *outpic = outlink->out_buf; - int p, ret; - - for (p = 0; p < 4 && inpic->data[p]; p++) { + for (p = 0; p < 4 && in->data[p]; p++) { int w = inlink->w; int h = inlink->h; int r = gf->radius; @@ -234,17 +215,36 @@ static int end_frame(AVFilterLink *inlink) } if (FFMIN(w, h) > 2 * r) - filter(gf, outpic->data[p], inpic->data[p], w, h, outpic->linesize[p], inpic->linesize[p], r); - else if (outpic->data[p] != inpic->data[p]) - av_image_copy_plane(outpic->data[p], outpic->linesize[p], inpic->data[p], inpic->linesize[p], w, h); + filter(gf, out->data[p], in->data[p], w, h, out->linesize[p], in->linesize[p], r); + else if (out->data[p] != in->data[p]) + av_image_copy_plane(out->data[p], out->linesize[p], in->data[p], in->linesize[p], w, h); } - if ((ret = ff_draw_slice(outlink, 0, inlink->h, 1)) < 0 || - (ret = ff_end_frame(outlink)) < 0) - return ret; - return 0; + if (!direct) + avfilter_unref_bufferp(&in); + + return ff_filter_frame(outlink, out); } +static const AVFilterPad avfilter_vf_gradfun_inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .config_props = config_input, + .filter_frame = filter_frame, + .min_perms = AV_PERM_READ, + }, + { NULL } +}; + +static const AVFilterPad avfilter_vf_gradfun_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + }, + { NULL } +}; + AVFilter avfilter_vf_gradfun = { .name = "gradfun", .description = NULL_IF_CONFIG_SMALL("Debands video quickly using gradients."), @@ -253,15 +253,6 @@ AVFilter avfilter_vf_gradfun = { .uninit = uninit, .query_formats = query_formats, - .inputs = (const AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_input, - .start_frame = start_frame, - .draw_slice = null_draw_slice, - .end_frame = end_frame, - .min_perms = AV_PERM_READ, }, - { .name = NULL}}, - .outputs = (const AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO, }, - { .name = NULL}}, + .inputs = avfilter_vf_gradfun_inputs, + .outputs = avfilter_vf_gradfun_outputs, };