X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavfilter%2Fvf_gradfun.c;h=2c9a9763c1fb344cfd94747d8d88e70f38d5714d;hb=5af53731d9788897240b3ed9c9176902f2788682;hp=1cbf8d8c2a41b9b196c2934a0ce9ef8803036e5c;hpb=d5f187fd3355ec6d4922d8479930c10d1b6f9ebf;p=ffmpeg diff --git a/libavfilter/vf_gradfun.c b/libavfilter/vf_gradfun.c index 1cbf8d8c2a4..2c9a9763c1f 100644 --- a/libavfilter/vf_gradfun.c +++ b/libavfilter/vf_gradfun.c @@ -2,20 +2,20 @@ * Copyright (c) 2010 Nolan Lum * Copyright (c) 2009 Loren Merritt * - * This file is part of FFmpeg. + * This file is part of Libav. * - * FFmpeg is free software; you can redistribute it and/or + * Libav 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, + * Libav 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 + * License along with Libav; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -32,11 +32,15 @@ * Dither it back to 8bit. */ -#include "libavcore/imgutils.h" +#include "libavutil/imgutils.h" +#include "libavutil/common.h" #include "libavutil/cpu.h" #include "libavutil/pixdesc.h" #include "avfilter.h" +#include "formats.h" #include "gradfun.h" +#include "internal.h" +#include "video.h" DECLARE_ALIGNED(16, static const uint16_t, dither)[8][8] = { {0x00,0x60,0x18,0x78,0x06,0x66,0x1E,0x7E}, @@ -115,12 +119,11 @@ static void filter(GradFunContext *ctx, uint8_t *dst, uint8_t *src, int width, i } } -static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) +static av_cold int init(AVFilterContext *ctx, const char *args) { GradFunContext *gf = ctx->priv; float thresh = 1.2; int radius = 16; - av_unused int cpu_flags = av_get_cpu_flags(); if (args) sscanf(args, "%f:%d", &thresh, &radius); @@ -132,14 +135,10 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) gf->blur_line = ff_gradfun_blur_line_c; gf->filter_line = ff_gradfun_filter_line_c; - if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX2) - gf->filter_line = ff_gradfun_filter_line_mmx2; - if (HAVE_SSSE3 && cpu_flags & AV_CPU_FLAG_SSSE3) - gf->filter_line = ff_gradfun_filter_line_ssse3; - if (HAVE_SSE && cpu_flags & AV_CPU_FLAG_SSE2) - gf->blur_line = ff_gradfun_blur_line_sse2; + if (ARCH_X86) + ff_gradfun_init_x86(gf); - av_log(ctx, AV_LOG_INFO, "threshold:%.2f radius:%d\n", thresh, gf->radius); + av_log(ctx, AV_LOG_VERBOSE, "threshold:%.2f radius:%d\n", thresh, gf->radius); return 0; } @@ -152,15 +151,15 @@ 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 }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); return 0; } @@ -168,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) @@ -182,34 +182,29 @@ static int config_input(AVFilterLink *inlink) 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 = avfilter_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; - avfilter_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, AVFilterBufferRef *in) { GradFunContext *gf = inlink->dst->priv; - AVFilterBufferRef *inpic = inlink->cur_buf; AVFilterLink *outlink = inlink->dst->outputs[0]; - AVFilterBufferRef *outpic = outlink->out_buf; - int p; + AVFilterBufferRef *out; + int p, direct; + + if ((in->perms & AV_PERM_WRITE) && !(in->perms & AV_PERM_PRESERVE)) { + direct = 1; + out = in; + } else { + out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); + if (!out) { + avfilter_unref_bufferp(&in); + return AVERROR(ENOMEM); + } - for (p = 0; p < 4 && inpic->data[p]; p++) { + avfilter_copy_buffer_ref_props(out, in); + out->video->w = outlink->w; + out->video->h = outlink->h; + } + + for (p = 0; p < 4 && in->data[p]; p++) { int w = inlink->w; int h = inlink->h; int r = gf->radius; @@ -220,17 +215,36 @@ static void 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); } - avfilter_draw_slice(outlink, 0, inlink->h, 1); - avfilter_end_frame(outlink); - avfilter_unref_buffer(inpic); - avfilter_unref_buffer(outpic); + 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."), @@ -239,15 +253,6 @@ AVFilter avfilter_vf_gradfun = { .uninit = uninit, .query_formats = query_formats, - .inputs = (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 = (AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO, }, - { .name = NULL}}, + .inputs = avfilter_vf_gradfun_inputs, + .outputs = avfilter_vf_gradfun_outputs, };