X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavfilter%2Fvf_signalstats.c;h=6f0ff53029c6c231a37ce4f812ae4bcbf13366c9;hb=3a3e8c35b63a40c4d59161097dc8652c15d13779;hp=298881bc72b902f641351ac3fef1273d092a3619;hpb=41cd5af3250ef976f0a48adeb6dbccc9b2683e58;p=ffmpeg diff --git a/libavfilter/vf_signalstats.c b/libavfilter/vf_signalstats.c index 298881bc72b..6f0ff53029c 100644 --- a/libavfilter/vf_signalstats.c +++ b/libavfilter/vf_signalstats.c @@ -50,6 +50,7 @@ typedef struct SignalstatsContext { int nb_jobs; int *jobs_rets; + int maxsize; // history stats array size int *histy, *histu, *histv, *histsat; AVFrame *frame_sat; @@ -149,7 +150,7 @@ static AVFrame *alloc_frame(enum AVPixelFormat pixfmt, int w, int h) frame->width = w; frame->height = h; - if (av_frame_get_buffer(frame, 32) < 0) { + if (av_frame_get_buffer(frame, 0) < 0) { av_frame_free(&frame); return NULL; } @@ -157,7 +158,7 @@ static AVFrame *alloc_frame(enum AVPixelFormat pixfmt, int w, int h) return frame; } -static int config_props(AVFilterLink *outlink) +static int config_output(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; SignalstatsContext *s = ctx->priv; @@ -166,15 +167,14 @@ static int config_props(AVFilterLink *outlink) s->hsub = desc->log2_chroma_w; s->vsub = desc->log2_chroma_h; s->depth = desc->comp[0].depth; - if (s->depth > 8) { - s->histy = av_malloc_array(1 << s->depth, sizeof(*s->histy)); - s->histu = av_malloc_array(1 << s->depth, sizeof(*s->histu)); - s->histv = av_malloc_array(1 << s->depth, sizeof(*s->histv)); - s->histsat = av_malloc_array(1 << s->depth, sizeof(*s->histsat)); - - if (!s->histy || !s->histu || !s->histv || !s->histsat) - return AVERROR(ENOMEM); - } + s->maxsize = 1 << s->depth; + s->histy = av_malloc_array(s->maxsize, sizeof(*s->histy)); + s->histu = av_malloc_array(s->maxsize, sizeof(*s->histu)); + s->histv = av_malloc_array(s->maxsize, sizeof(*s->histv)); + s->histsat = av_malloc_array(s->maxsize, sizeof(*s->histsat)); + + if (!s->histy || !s->histu || !s->histv || !s->histsat) + return AVERROR(ENOMEM); outlink->w = inlink->w; outlink->h = inlink->h; @@ -462,8 +462,6 @@ static const struct { {NULL} }; -#define DEPTH 256 - static int compute_sat_hue_metrics8(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { int i, j; @@ -491,7 +489,7 @@ static int compute_sat_hue_metrics8(AVFilterContext *ctx, void *arg, int jobnr, 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); + ((int16_t*)p_hue)[i] = fmod(floor((180 / M_PI) * atan2f(yuvu-128, yuvv-128) + 180), 360.); } p_u += lsz_u; p_v += lsz_v; @@ -530,7 +528,7 @@ static int compute_sat_hue_metrics16(AVFilterContext *ctx, void *arg, int jobnr, const int yuvu = p_u[i]; const int yuvv = p_v[i]; p_sat[i] = hypot(yuvu - mid, yuvv - mid); // int or round? - ((int16_t*)p_hue)[i] = floor((180 / M_PI) * atan2f(yuvu-mid, yuvv-mid) + 180); + ((int16_t*)p_hue)[i] = fmod(floor((180 / M_PI) * atan2f(yuvu-mid, yuvv-mid) + 180), 360.); } p_u += lsz_u; p_v += lsz_v; @@ -557,11 +555,11 @@ static int filter_frame8(AVFilterLink *link, AVFrame *in) pw = 0, cpw = 0; // prev int fil; char metabuf[128]; - unsigned int histy[DEPTH] = {0}, - histu[DEPTH] = {0}, - histv[DEPTH] = {0}, + unsigned int *histy = s->histy, + *histu = s->histu, + *histv = s->histv, histhue[360] = {0}, - histsat[DEPTH] = {0}; // limited to 8 bit data. + *histsat = s->histsat; int miny = -1, minu = -1, minv = -1; int maxy = -1, maxu = -1, maxv = -1; int lowy = -1, lowu = -1, lowv = -1; @@ -605,6 +603,7 @@ static int filter_frame8(AVFilterLink *link, AVFrame *in) NULL, FFMIN(s->chromah, ff_filter_get_nb_threads(ctx))); // Calculate luma histogram and difference with previous frame or field. + memset(s->histy, 0, s->maxsize * sizeof(*s->histy)); for (j = 0; j < link->h; j++) { for (i = 0; i < link->w; i++) { const int yuv = in->data[0][w + i]; @@ -618,6 +617,9 @@ static int filter_frame8(AVFilterLink *link, AVFrame *in) } // Calculate chroma histogram and difference with previous frame or field. + memset(s->histu, 0, s->maxsize * sizeof(*s->histu)); + memset(s->histv, 0, s->maxsize * sizeof(*s->histv)); + memset(s->histsat, 0, s->maxsize * sizeof(*s->histsat)); for (j = 0; j < s->chromah; j++) { for (i = 0; i < s->chromaw; i++) { const int yuvu = in->data[1][cw+i]; @@ -662,7 +664,7 @@ static int filter_frame8(AVFilterLink *link, AVFrame *in) chighp = lrint(s->cfs * 90 / 100.); accy = accu = accv = accsat = 0; - for (fil = 0; fil < DEPTH; fil++) { + for (fil = 0; fil < s->maxsize; fil++) { if (miny < 0 && histy[fil]) miny = fil; if (minu < 0 && histu[fil]) minu = fil; if (minv < 0 && histv[fil]) minv = fil; @@ -823,23 +825,23 @@ static int filter_frame16(AVFilterLink *link, AVFrame *in) NULL, FFMIN(s->chromah, ff_filter_get_nb_threads(ctx))); // Calculate luma histogram and difference with previous frame or field. - memset(s->histy, 0, (1 << s->depth) * sizeof(*s->histy)); + memset(s->histy, 0, s->maxsize * sizeof(*s->histy)); for (j = 0; j < link->h; j++) { for (i = 0; i < link->w; i++) { const int yuv = AV_RN16(in->data[0] + w + i * 2); masky |= yuv; histy[yuv]++; - dify += abs(yuv - AV_RN16(prev->data[0] + pw + i * 2)); + dify += abs(yuv - (int)AV_RN16(prev->data[0] + pw + i * 2)); } w += in->linesize[0]; pw += prev->linesize[0]; } // Calculate chroma histogram and difference with previous frame or field. - memset(s->histu, 0, (1 << s->depth) * sizeof(*s->histu)); - memset(s->histv, 0, (1 << s->depth) * sizeof(*s->histv)); - memset(s->histsat, 0, (1 << s->depth) * sizeof(*s->histsat)); + memset(s->histu, 0, s->maxsize * sizeof(*s->histu)); + memset(s->histv, 0, s->maxsize * sizeof(*s->histv)); + memset(s->histsat, 0, s->maxsize * sizeof(*s->histsat)); for (j = 0; j < s->chromah; j++) { for (i = 0; i < s->chromaw; i++) { const int yuvu = AV_RN16(in->data[1] + cw + i * 2); @@ -848,9 +850,9 @@ static int filter_frame16(AVFilterLink *link, AVFrame *in) masku |= yuvu; maskv |= yuvv; histu[yuvu]++; - difu += abs(yuvu - AV_RN16(prev->data[1] + cpw + i * 2)); + difu += abs(yuvu - (int)AV_RN16(prev->data[1] + cpw + i * 2)); histv[yuvv]++; - difv += abs(yuvv - AV_RN16(prev->data[2] + cpw + i * 2)); + difv += abs(yuvv - (int)AV_RN16(prev->data[2] + cpw + i * 2)); histsat[p_sat[i]]++; histhue[((int16_t*)p_hue)[i]]++; @@ -884,7 +886,7 @@ static int filter_frame16(AVFilterLink *link, AVFrame *in) chighp = lrint(s->cfs * 90 / 100.); accy = accu = accv = accsat = 0; - for (fil = 0; fil < 1 << s->depth; fil++) { + for (fil = 0; fil < s->maxsize; fil++) { if (miny < 0 && histy[fil]) miny = fil; if (minu < 0 && histu[fil]) minu = fil; if (minv < 0 && histv[fil]) minv = fil; @@ -1004,13 +1006,13 @@ static const AVFilterPad signalstats_inputs[] = { static const AVFilterPad signalstats_outputs[] = { { .name = "default", - .config_props = config_props, + .config_props = config_output, .type = AVMEDIA_TYPE_VIDEO, }, { NULL } }; -AVFilter ff_vf_signalstats = { +const AVFilter ff_vf_signalstats = { .name = "signalstats", .description = "Generate statistics from video analysis.", .init = init,