[FFmpeg-devel] [PATCH 07/10] avfilter/signalstats: isolate sat hue computation metrics in a function

Clément Bœsch u at pkh.me
Sun Nov 23 00:39:03 CET 2014


This will be useful for the following commit
---
 libavfilter/vf_signalstats.c | 77 ++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 70 insertions(+), 7 deletions(-)

diff --git a/libavfilter/vf_signalstats.c b/libavfilter/vf_signalstats.c
index 960e98a..0403a6d 100644
--- a/libavfilter/vf_signalstats.c
+++ b/libavfilter/vf_signalstats.c
@@ -47,6 +47,9 @@ typedef struct {
     int yuv_color[3];
     int nb_jobs;
     int *jobs_rets;
+
+    AVFrame *frame_sat;
+    AVFrame *frame_hue;
 } SignalstatsContext;
 
 typedef struct ThreadData {
@@ -94,6 +97,8 @@ static av_cold void uninit(AVFilterContext *ctx)
 {
     SignalstatsContext *s = ctx->priv;
     av_frame_free(&s->frame_prev);
+    av_frame_free(&s->frame_sat);
+    av_frame_free(&s->frame_hue);
     av_freep(&s->jobs_rets);
 }
 
@@ -112,6 +117,22 @@ static int query_formats(AVFilterContext *ctx)
     return 0;
 }
 
+static AVFrame *alloc_frame(enum AVPixelFormat pixfmt, int w, int h)
+{
+    AVFrame *frame = av_frame_alloc();
+    if (!frame)
+        return NULL;
+
+    frame->format = pixfmt;
+    frame->width  = w;
+    frame->height = h;
+
+    if (av_frame_get_buffer(frame, 32) < 0)
+        return NULL;
+
+    return frame;
+}
+
 static int config_props(AVFilterLink *outlink)
 {
     AVFilterContext *ctx = outlink->src;
@@ -134,6 +155,12 @@ static int config_props(AVFilterLink *outlink)
     s->jobs_rets = av_malloc_array(s->nb_jobs, sizeof(*s->jobs_rets));
     if (!s->jobs_rets)
         return AVERROR(ENOMEM);
+
+    s->frame_sat = alloc_frame(AV_PIX_FMT_GRAY8,  inlink->w, inlink->h);
+    s->frame_hue = alloc_frame(AV_PIX_FMT_GRAY16, inlink->w, inlink->h);
+    if (!s->frame_sat || !s->frame_hue)
+        return AVERROR(ENOMEM);
+
     return 0;
 }
 
@@ -281,6 +308,36 @@ static const struct {
 
 #define DEPTH 256
 
+static void compute_sat_hue_metrics(const SignalstatsContext *s,
+                                    const AVFrame *src,
+                                    AVFrame *dst_sat, AVFrame *dst_hue)
+{
+    int i, j;
+
+    const uint8_t *p_u = src->data[1];
+    const uint8_t *p_v = src->data[2];
+    const int lsz_u = src->linesize[1];
+    const int lsz_v = src->linesize[2];
+
+    uint8_t *p_sat = dst_sat->data[0];
+    uint8_t *p_hue = dst_hue->data[0];
+    const int lsz_sat = dst_sat->linesize[0];
+    const int lsz_hue = dst_hue->linesize[0];
+
+    for (j = 0; j < s->chromah; j++) {
+        for (i = 0; i < s->chromaw; i++) {
+            const int yuvu = p_u[i];
+            const int yuvv = p_v[i];
+            p_sat[i] = hypot(yuvu - 128, yuvv - 128); // int or round?
+            ((int16_t*)p_hue)[i] = floor((180 / M_PI) * atan2f(yuvu-128, yuvv-128) + 180);
+        }
+        p_u   += lsz_u;
+        p_v   += lsz_v;
+        p_sat += lsz_sat;
+        p_hue += lsz_hue;
+    }
+}
+
 static int filter_frame(AVFilterLink *link, AVFrame *in)
 {
     AVFilterContext *ctx = link->dst;
@@ -314,6 +371,13 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
     int filtot[FILT_NUMB] = {0};
     AVFrame *prev;
 
+    AVFrame *sat = s->frame_sat;
+    AVFrame *hue = s->frame_hue;
+    const uint8_t *p_sat = sat->data[0];
+    const uint8_t *p_hue = hue->data[0];
+    const int lsz_sat = sat->linesize[0];
+    const int lsz_hue = hue->linesize[0];
+
     if (!s->frame_prev)
         s->frame_prev = av_frame_clone(in);
 
@@ -324,6 +388,8 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
         av_frame_make_writable(out);
     }
 
+    compute_sat_hue_metrics(s, in, sat, hue);
+
     // Calculate luma histogram and difference with previous frame or field.
     for (j = 0; j < link->h; j++) {
         for (i = 0; i < link->w; i++) {
@@ -338,8 +404,6 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
     // Calculate chroma histogram and difference with previous frame or field.
     for (j = 0; j < s->chromah; j++) {
         for (i = 0; i < s->chromaw; i++) {
-            int sat, hue;
-
             yuvu = in->data[1][cw+i];
             yuvv = in->data[2][cw+i];
             histu[yuvu]++;
@@ -347,14 +411,13 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
             histv[yuvv]++;
             difv += abs(in->data[2][cw+i] - prev->data[2][cpw+i]);
 
-            // int or round?
-            sat = hypot(yuvu - 128, yuvv - 128);
-            histsat[sat]++;
-            hue = floor((180 / M_PI) * atan2f(yuvu-128, yuvv-128) + 180);
-            histhue[hue]++;
+            histsat[p_sat[i]]++;
+            histhue[((int16_t*)p_hue)[i]]++;
         }
         cw  += in->linesize[1];
         cpw += prev->linesize[1];
+        p_sat += lsz_sat;
+        p_hue += lsz_hue;
     }
 
     for (fil = 0; fil < FILT_NUMB; fil ++) {
-- 
2.1.3



More information about the ffmpeg-devel mailing list