summaryrefslogtreecommitdiff
path: root/libavfilter/vf_deshake.c
diff options
context:
space:
mode:
authorhighgod0401 <highgod0401@gmail.com>2013-04-02 20:54:22 +0800
committerMichael Niedermayer <michaelni@gmx.at>2013-04-02 15:57:44 +0200
commit90793591417f29302e97dbd9823481423eabdacc (patch)
tree84034e32997cf8b2eca401321358c5a6a0ab783d /libavfilter/vf_deshake.c
parentc09da45ffbeb84b56ab4837e62919c3bf3684d4f (diff)
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.c117
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;