diff options
author | highgod0401 <highgod0401@gmail.com> | 2013-04-02 20:54:22 +0800 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2013-04-02 15:57:44 +0200 |
commit | 90793591417f29302e97dbd9823481423eabdacc (patch) | |
tree | 84034e32997cf8b2eca401321358c5a6a0ab783d /libavfilter/vf_deshake.c | |
parent | c09da45ffbeb84b56ab4837e62919c3bf3684d4f (diff) | |
download | ffmpeg-90793591417f29302e97dbd9823481423eabdacc.tar.gz |
deshake opencl based on comments on 20130402 3rd
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavfilter/vf_deshake.c')
-rw-r--r-- | libavfilter/vf_deshake.c | 117 |
1 files changed, 60 insertions, 57 deletions
diff --git a/libavfilter/vf_deshake.c b/libavfilter/vf_deshake.c index 2740bba0e9..ee6e474caf 100644 --- a/libavfilter/vf_deshake.c +++ b/libavfilter/vf_deshake.c @@ -59,55 +59,12 @@ #include "libavutil/pixdesc.h" #include "libavcodec/dsputil.h" -#include "transform.h" +#include "deshake.h" +#include "deshake_opencl.h" #define CHROMA_WIDTH(link) -((-link->w) >> av_pix_fmt_desc_get(link->format)->log2_chroma_w) #define CHROMA_HEIGHT(link) -((-link->h) >> av_pix_fmt_desc_get(link->format)->log2_chroma_h) -enum SearchMethod { - EXHAUSTIVE, ///< Search all possible positions - SMART_EXHAUSTIVE, ///< Search most possible positions (faster) - SEARCH_COUNT -}; - -typedef struct { - int x; ///< Horizontal shift - int y; ///< Vertical shift -} IntMotionVector; - -typedef struct { - double x; ///< Horizontal shift - double y; ///< Vertical shift -} MotionVector; - -typedef struct { - MotionVector vector; ///< Motion vector - double angle; ///< Angle of rotation - double zoom; ///< Zoom percentage -} Transform; - -typedef struct { - const AVClass *class; - AVFrame *ref; ///< Previous frame - int rx; ///< Maximum horizontal shift - int ry; ///< Maximum vertical shift - int edge; ///< Edge fill method - int blocksize; ///< Size of blocks to compare - int contrast; ///< Contrast threshold - int search; ///< Motion search method - AVCodecContext *avctx; - DSPContext c; ///< Context providing optimized SAD methods - Transform last; ///< Transform from last frame - int refcount; ///< Number of reference frames (defines averaging window) - FILE *fp; - Transform avg; - int cw; ///< Crop motion search to this box - int ch; - int cx; - int cy; - char *filename; ///< Motion search detailed log filename -} DeshakeContext; - #define OFFSET(x) offsetof(DeshakeContext, x) #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM @@ -129,6 +86,7 @@ static const AVOption deshake_options[] = { { "exhaustive", "exhaustive search", 0, AV_OPT_TYPE_CONST, {.i64=EXHAUSTIVE}, INT_MIN, INT_MAX, FLAGS, "smode" }, { "less", "less exhaustive search", 0, AV_OPT_TYPE_CONST, {.i64=SMART_EXHAUSTIVE}, INT_MIN, INT_MAX, FLAGS, "smode" }, { "filename", "set motion search detailed log file name", OFFSET(filename), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, + { "opencl", "use OpenCL filtering capabilities", OFFSET(opencl), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, .flags = FLAGS }, { NULL } }; @@ -360,8 +318,35 @@ static void find_motion(DeshakeContext *deshake, uint8_t *src1, uint8_t *src2, av_free(angles); } +static int deshake_transform_c(AVFilterContext *ctx, + int width, int height, int cw, int ch, + const float *matrix_y, const float *matrix_uv, + enum InterpolateMethod interpolate, + enum FillMethod fill, AVFrame *in, AVFrame *out) +{ + int i = 0, ret = 0; + const float *matrixs[3]; + int plane_w[3], plane_h[3]; + matrixs[0] = matrix_y; + matrixs[1] = matrixs[2] = matrix_uv; + plane_w[0] = width; + plane_w[1] = plane_w[2] = cw; + plane_h[0] = height; + plane_h[1] = plane_h[2] = ch; + + for (i = 0; i < 3; i++) { + // Transform the luma and chroma planes + ret = avfilter_transform(in->data[i], out->data[i], in->linesize[i], out->linesize[i], + plane_w[i], plane_h[i], matrixs[i], interpolate, fill); + if (ret < 0) + return ret; + } + return ret; +} + static av_cold int init(AVFilterContext *ctx, const char *args) { + int ret; DeshakeContext *deshake = ctx->priv; deshake->refcount = 20; // XXX: add to options? @@ -379,7 +364,18 @@ static av_cold int init(AVFilterContext *ctx, const char *args) deshake->cw += deshake->cx - (deshake->cx & ~15); deshake->cx &= ~15; } + deshake->transform = deshake_transform_c; + if (!CONFIG_OPENCL && deshake->opencl) { + av_log(ctx, AV_LOG_ERROR, "OpenCL support was not enabled in this build, cannot be selected\n"); + return AVERROR(EINVAL); + } + if (deshake->opencl && CONFIG_OPENCL) { + deshake->transform = ff_opencl_transform; + ret = ff_opencl_deshake_init(ctx); + if (ret < 0) + return ret; + } av_log(ctx, AV_LOG_VERBOSE, "cx: %d, cy: %d, cw: %d, ch: %d, rx: %d, ry: %d, edge: %d blocksize: %d contrast: %d search: %d\n", deshake->cx, deshake->cy, deshake->cw, deshake->ch, deshake->rx, deshake->ry, deshake->edge, deshake->blocksize * 2, deshake->contrast, deshake->search); @@ -419,7 +415,9 @@ static int config_props(AVFilterLink *link) static av_cold void uninit(AVFilterContext *ctx) { DeshakeContext *deshake = ctx->priv; - + if (deshake->opencl && CONFIG_OPENCL) { + ff_opencl_deshake_uninit(ctx); + } av_frame_free(&deshake->ref); if (deshake->fp) fclose(deshake->fp); @@ -434,9 +432,10 @@ static int filter_frame(AVFilterLink *link, AVFrame *in) AVFilterLink *outlink = link->dst->outputs[0]; AVFrame *out; Transform t = {{0},0}, orig = {{0},0}; - float matrix[9]; + float matrix_y[9], matrix_uv[9]; float alpha = 2.0 / deshake->refcount; char tmp[256]; + int ret = 0; out = ff_get_video_buffer(outlink, outlink->w, outlink->h); if (!out) { @@ -445,6 +444,12 @@ static int filter_frame(AVFilterLink *link, AVFrame *in) } av_frame_copy_props(out, in); + if (deshake->opencl && CONFIG_OPENCL) { + ret = ff_opencl_deshake_process_inout_buf(link->dst,in, out); + if (ret < 0) + return ret; + } + if (deshake->cx < 0 || deshake->cy < 0 || deshake->cw < 0 || deshake->ch < 0) { // Find the most likely global motion for the current frame find_motion(deshake, (deshake->ref == NULL) ? in->data[0] : deshake->ref->data[0], in->data[0], link->w, link->h, in->linesize[0], &t); @@ -517,21 +522,19 @@ static int filter_frame(AVFilterLink *link, AVFrame *in) deshake->last.zoom = t.zoom; // Generate a luma transformation matrix - avfilter_get_matrix(t.vector.x, t.vector.y, t.angle, 1.0 + t.zoom / 100.0, matrix); - - // Transform the luma plane - avfilter_transform(in->data[0], out->data[0], in->linesize[0], out->linesize[0], link->w, link->h, matrix, INTERPOLATE_BILINEAR, deshake->edge); - + avfilter_get_matrix(t.vector.x, t.vector.y, t.angle, 1.0 + t.zoom / 100.0, matrix_y); // Generate a chroma transformation matrix - avfilter_get_matrix(t.vector.x / (link->w / CHROMA_WIDTH(link)), t.vector.y / (link->h / CHROMA_HEIGHT(link)), t.angle, 1.0 + t.zoom / 100.0, matrix); - - // Transform the chroma planes - avfilter_transform(in->data[1], out->data[1], in->linesize[1], out->linesize[1], CHROMA_WIDTH(link), CHROMA_HEIGHT(link), matrix, INTERPOLATE_BILINEAR, deshake->edge); - avfilter_transform(in->data[2], out->data[2], in->linesize[2], out->linesize[2], CHROMA_WIDTH(link), CHROMA_HEIGHT(link), matrix, INTERPOLATE_BILINEAR, deshake->edge); + avfilter_get_matrix(t.vector.x / (link->w / CHROMA_WIDTH(link)), t.vector.y / (link->h / CHROMA_HEIGHT(link)), t.angle, 1.0 + t.zoom / 100.0, matrix_uv); + // Transform the luma and chroma planes + ret = deshake->transform(link->dst, link->w, link->h, CHROMA_WIDTH(link), CHROMA_HEIGHT(link), + matrix_y, matrix_uv, INTERPOLATE_BILINEAR, deshake->edge, in, out); // Cleanup the old reference frame av_frame_free(&deshake->ref); + if (ret < 0) + return ret; + // Store the current frame as the reference frame for calculating the // motion of the next frame deshake->ref = in; |