[FFmpeg-devel] [PATCH 2/2] avfilter/vf_colorkey: Transform calculations to integer math

Timo Rothenpieler timo at rothenpieler.org
Tue Apr 28 19:31:33 CEST 2015


---
 libavfilter/vf_colorkey.c | 36 +++++++++++++++++++++++++++---------
 1 file changed, 27 insertions(+), 9 deletions(-)

diff --git a/libavfilter/vf_colorkey.c b/libavfilter/vf_colorkey.c
index 6c76991..6964809 100644
--- a/libavfilter/vf_colorkey.c
+++ b/libavfilter/vf_colorkey.c
@@ -29,6 +29,8 @@ typedef struct ColorkeyContext {
 
     /* color offsets rgba */
     int co[4];
+    int i_similarity;
+    int i_blend;
 
     uint8_t colorkey_rgba[4];
     float similarity;
@@ -107,18 +109,20 @@ static int offset_a(int fmt)
     }
 }
 
+#define SHIFT 8
+
 static uint8_t do_colorkey_pixel(ColorkeyContext *ctx, uint8_t r, uint8_t g, uint8_t b)
 {
-    int dr = (int)r - ctx->colorkey_rgba[0];
-    int dg = (int)g - ctx->colorkey_rgba[1];
-    int db = (int)b - ctx->colorkey_rgba[2];
+    int dr = ((int)r - ctx->colorkey_rgba[0]) << SHIFT;
+    int dg = ((int)g - ctx->colorkey_rgba[1]) << SHIFT;
+    int db = ((int)b - ctx->colorkey_rgba[2]) << SHIFT;
 
-    double diff = sqrt((dr * dr + dg * dg + db * db) / (255.0 * 255.0));
+    int diff = (int)sqrt(dr * dr + dg * dg + db * db) - ctx->i_similarity;
 
-    if (ctx->blend > 0.0001) {
-        return av_clipd(FFMAX(diff - ctx->similarity, 0.0) / ctx->blend, 0.0, 1.0) * 255.0;
+    if (ctx->i_blend) {
+        return av_clip(FFMAX(diff, 0) * ctx->i_blend, 0, 255 << (SHIFT + SHIFT)) >> (SHIFT + SHIFT);
     } else {
-        return ((diff - ctx->similarity) > 0.0) ? 255 : 0;
+        return (diff > 0) ? 255 : 0;
     }
 }
 
@@ -164,7 +168,7 @@ static int filter_frame(AVFilterLink *link, AVFrame *frame)
     return ff_filter_frame(avctx->outputs[0], frame);
 }
 
-static int config_output(AVFilterLink *outlink)
+static av_cold int config_output(AVFilterLink *outlink)
 {
     AVFilterContext *avctx = outlink->src;
     ColorkeyContext *ctx = avctx->priv;
@@ -183,7 +187,7 @@ static int config_output(AVFilterLink *outlink)
     return 0;
 }
 
-static int query_formats(AVFilterContext *avctx)
+static av_cold int query_formats(AVFilterContext *avctx)
 {
     static const enum AVPixelFormat pixel_fmts_in[] = {
         AV_PIX_FMT_0RGB,
@@ -222,6 +226,19 @@ static int query_formats(AVFilterContext *avctx)
     return 0;
 }
 
+static av_cold int init(AVFilterContext *avctx)
+{
+    ColorkeyContext *ctx = avctx->priv;
+
+    ctx->i_similarity = ctx->similarity * 255.0 * 1000.0;
+    ctx->i_blend = (1.0 / ctx->blend) * 1000.0;
+
+    ctx->i_similarity = (ctx->i_similarity << SHIFT) / 1000;
+    ctx->i_blend = (ctx->i_blend << SHIFT) / 1000;
+
+    return 0;
+}
+
 static const AVFilterPad colorkey_inputs[] = {
     {
         .name = "default",
@@ -255,6 +272,7 @@ AVFILTER_DEFINE_CLASS(colorkey);
 AVFilter ff_vf_colorkey = {
     .name          = "colorkey",
     .description   = NULL_IF_CONFIG_SMALL("colorkey filter"),
+    .init          = init,
     .priv_size     = sizeof(ColorkeyContext),
     .priv_class    = &colorkey_class,
     .query_formats = query_formats,
-- 
2.3.6



More information about the ffmpeg-devel mailing list