aboutsummaryrefslogtreecommitdiffstats
path: root/libavfilter/vf_signalstats.c
diff options
context:
space:
mode:
authorClément Bœsch <u@pkh.me>2014-11-22 23:50:10 +0100
committerClément Bœsch <clement@stupeflix.com>2014-11-26 21:29:09 +0100
commit7acbd56a8a996c984d4799039b72ecf2cfbec615 (patch)
tree9621fb3e103eb23667276ffe3f98195db6211ac6 /libavfilter/vf_signalstats.c
parent9db78a296c37ab854dab87d991ce666e9a2e30ea (diff)
downloadffmpeg-7acbd56a8a996c984d4799039b72ecf2cfbec615.tar.gz
avfilter/signalstats: isolate sat hue computation metrics in a function
This will be useful for the following commit
Diffstat (limited to 'libavfilter/vf_signalstats.c')
-rw-r--r--libavfilter/vf_signalstats.c77
1 files changed, 70 insertions, 7 deletions
diff --git a/libavfilter/vf_signalstats.c b/libavfilter/vf_signalstats.c
index 960e98adb4..0403a6d87a 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 ++) {