Commit 7acbd56a authored by Clément Bœsch's avatar Clément Bœsch Committed by Clément Bœsch

avfilter/signalstats: isolate sat hue computation metrics in a function

This will be useful for the following commit
parent 9db78a29
...@@ -47,6 +47,9 @@ typedef struct { ...@@ -47,6 +47,9 @@ typedef struct {
int yuv_color[3]; int yuv_color[3];
int nb_jobs; int nb_jobs;
int *jobs_rets; int *jobs_rets;
AVFrame *frame_sat;
AVFrame *frame_hue;
} SignalstatsContext; } SignalstatsContext;
typedef struct ThreadData { typedef struct ThreadData {
...@@ -94,6 +97,8 @@ static av_cold void uninit(AVFilterContext *ctx) ...@@ -94,6 +97,8 @@ static av_cold void uninit(AVFilterContext *ctx)
{ {
SignalstatsContext *s = ctx->priv; SignalstatsContext *s = ctx->priv;
av_frame_free(&s->frame_prev); av_frame_free(&s->frame_prev);
av_frame_free(&s->frame_sat);
av_frame_free(&s->frame_hue);
av_freep(&s->jobs_rets); av_freep(&s->jobs_rets);
} }
...@@ -112,6 +117,22 @@ static int query_formats(AVFilterContext *ctx) ...@@ -112,6 +117,22 @@ static int query_formats(AVFilterContext *ctx)
return 0; 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) static int config_props(AVFilterLink *outlink)
{ {
AVFilterContext *ctx = outlink->src; AVFilterContext *ctx = outlink->src;
...@@ -134,6 +155,12 @@ static int config_props(AVFilterLink *outlink) ...@@ -134,6 +155,12 @@ static int config_props(AVFilterLink *outlink)
s->jobs_rets = av_malloc_array(s->nb_jobs, sizeof(*s->jobs_rets)); s->jobs_rets = av_malloc_array(s->nb_jobs, sizeof(*s->jobs_rets));
if (!s->jobs_rets) if (!s->jobs_rets)
return AVERROR(ENOMEM); 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; return 0;
} }
...@@ -281,6 +308,36 @@ static const struct { ...@@ -281,6 +308,36 @@ static const struct {
#define DEPTH 256 #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) static int filter_frame(AVFilterLink *link, AVFrame *in)
{ {
AVFilterContext *ctx = link->dst; AVFilterContext *ctx = link->dst;
...@@ -314,6 +371,13 @@ static int filter_frame(AVFilterLink *link, AVFrame *in) ...@@ -314,6 +371,13 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
int filtot[FILT_NUMB] = {0}; int filtot[FILT_NUMB] = {0};
AVFrame *prev; 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) if (!s->frame_prev)
s->frame_prev = av_frame_clone(in); s->frame_prev = av_frame_clone(in);
...@@ -324,6 +388,8 @@ static int filter_frame(AVFilterLink *link, AVFrame *in) ...@@ -324,6 +388,8 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
av_frame_make_writable(out); av_frame_make_writable(out);
} }
compute_sat_hue_metrics(s, in, sat, hue);
// Calculate luma histogram and difference with previous frame or field. // Calculate luma histogram and difference with previous frame or field.
for (j = 0; j < link->h; j++) { for (j = 0; j < link->h; j++) {
for (i = 0; i < link->w; i++) { for (i = 0; i < link->w; i++) {
...@@ -338,8 +404,6 @@ static int filter_frame(AVFilterLink *link, AVFrame *in) ...@@ -338,8 +404,6 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
// Calculate chroma histogram and difference with previous frame or field. // Calculate chroma histogram and difference with previous frame or field.
for (j = 0; j < s->chromah; j++) { for (j = 0; j < s->chromah; j++) {
for (i = 0; i < s->chromaw; i++) { for (i = 0; i < s->chromaw; i++) {
int sat, hue;
yuvu = in->data[1][cw+i]; yuvu = in->data[1][cw+i];
yuvv = in->data[2][cw+i]; yuvv = in->data[2][cw+i];
histu[yuvu]++; histu[yuvu]++;
...@@ -347,14 +411,13 @@ static int filter_frame(AVFilterLink *link, AVFrame *in) ...@@ -347,14 +411,13 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
histv[yuvv]++; histv[yuvv]++;
difv += abs(in->data[2][cw+i] - prev->data[2][cpw+i]); difv += abs(in->data[2][cw+i] - prev->data[2][cpw+i]);
// int or round? histsat[p_sat[i]]++;
sat = hypot(yuvu - 128, yuvv - 128); histhue[((int16_t*)p_hue)[i]]++;
histsat[sat]++;
hue = floor((180 / M_PI) * atan2f(yuvu-128, yuvv-128) + 180);
histhue[hue]++;
} }
cw += in->linesize[1]; cw += in->linesize[1];
cpw += prev->linesize[1]; cpw += prev->linesize[1];
p_sat += lsz_sat;
p_hue += lsz_hue;
} }
for (fil = 0; fil < FILT_NUMB; fil ++) { for (fil = 0; fil < FILT_NUMB; fil ++) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment