diff options
author | Paul B Mahol <onemda@gmail.com> | 2022-04-19 19:50:49 +0200 |
---|---|---|
committer | Paul B Mahol <onemda@gmail.com> | 2022-04-19 20:32:23 +0200 |
commit | da4b7c2be4af70f39da0e356517069aaecf9402d (patch) | |
tree | c06f6e04e1d83c040a410de5e794c3c981cede6e /libavfilter | |
parent | 8b717a40441659d852517a2326646ad4dbd96f7d (diff) | |
download | ffmpeg-da4b7c2be4af70f39da0e356517069aaecf9402d.tar.gz |
avfilter/vf_ciescope: little optimizations
Diffstat (limited to 'libavfilter')
-rw-r--r-- | libavfilter/vf_ciescope.c | 304 |
1 files changed, 167 insertions, 137 deletions
diff --git a/libavfilter/vf_ciescope.c b/libavfilter/vf_ciescope.c index fcb28d2b5e..31e7953edc 100644 --- a/libavfilter/vf_ciescope.c +++ b/libavfilter/vf_ciescope.c @@ -62,12 +62,14 @@ typedef struct CiescopeContext { float contrast; int background; - double log2lin[65536]; - double igamma; - double i[3][3]; - double m[3][3]; + float log2lin[65536]; + float igamma; + float i[3][3]; + float m[3][3]; AVFrame *f; - void (*filter)(AVFilterContext *ctx, AVFrame *in, double *cx, double *cy, int x, int y); + void (*filter)(AVFilterContext *ctx, const uint8_t *ptr, + ptrdiff_t linesize, + float *cx, float *cy, int x, int y); } CiescopeContext; #define OFFSET(x) offsetof(CiescopeContext, x) @@ -163,11 +165,11 @@ static int config_output(AVFilterLink *outlink) point. */ struct ColorSystem { - double xRed, yRed, /* Red primary illuminant */ - xGreen, yGreen, /* Green primary illuminant */ - xBlue, yBlue, /* Blue primary illuminant */ - xWhite, yWhite, /* White point */ - gamma; /* gamma of nonlinear correction */ + float xRed, yRed, /* Red primary illuminant */ + xGreen, yGreen, /* Green primary illuminant */ + xBlue, yBlue, /* Blue primary illuminant */ + xWhite, yWhite, /* White point */ + gamma; /* gamma of nonlinear correction */ }; static float const spectral_chromaticity[][3] = { @@ -712,23 +714,23 @@ static struct ColorSystem CustomSystem = { */ static void -uv_to_xy(double const u, - double const v, - double * const xc, - double * const yc) +uv_to_xy(float const u, + float const v, + float *const xc, + float *const yc) { /* Given 1970 coordinates u, v, determine 1931 chromaticities x, y */ - *xc = 3*u / (2*u - 8*v + 4); - *yc = 2*v / (2*u - 8*v + 4); + *xc = 3.f*u / (2.f*u - 8.f*v + 4.f); + *yc = 2.f*v / (2.f*u - 8.f*v + 4.f); } static void -upvp_to_xy(double const up, - double const vp, - double * const xc, - double * const yc) +upvp_to_xy(float const up, + float const vp, + float * const xc, + float * const yc) { /* Given 1976 coordinates u', v', determine 1931 chromaticities x, y @@ -738,48 +740,50 @@ upvp_to_xy(double const up, } static void -xy_to_upvp(double xc, - double yc, - double * const up, - double * const vp) +xy_to_upvp(float xc, + float yc, + float * const up, + float * const vp) { /* Given 1931 chromaticities x, y, determine 1976 coordinates u', v' */ - *up = 4*xc / (- 2*xc + 12*yc + 3); - *vp = 9*yc / (- 2*xc + 12*yc + 3); + const float scale = 1.f / (-2.f*xc + 12.f*yc + 3.f); + *up = 4.f*xc * scale; + *vp = 9.f*yc * scale; } static void -xy_to_uv(double xc, - double yc, - double * const u, - double * const v) +xy_to_uv(float xc, + float yc, + float * const u, + float * const v) { /* Given 1931 chromaticities x, y, determine 1960 coordinates u, v */ - *u = 4*xc / (- 2*xc + 12*yc + 3); - *v = 6*yc / (- 2*xc + 12*yc + 3); + const float scale = 1.f / (-2.f*xc + 12.f*yc + 3.f); + *u = 4.f*xc * scale; + *v = 6.f*yc * scale; } static void -xyz_to_rgb(const double m[3][3], - double xc, double yc, double zc, - double * const r, double * const g, double * const b) +xyz_to_rgb(const float m[3][3], + float xc, float yc, float zc, + float * const r, float * const g, float * const b) { *r = m[0][0]*xc + m[0][1]*yc + m[0][2]*zc; *g = m[1][0]*xc + m[1][1]*yc + m[1][2]*zc; *b = m[2][0]*xc + m[2][1]*yc + m[2][2]*zc; } -static void invert_matrix3x3(double in[3][3], double out[3][3]) +static void invert_matrix3x3(float in[3][3], float out[3][3]) { - double m00 = in[0][0], m01 = in[0][1], m02 = in[0][2], + float m00 = in[0][0], m01 = in[0][1], m02 = in[0][2], m10 = in[1][0], m11 = in[1][1], m12 = in[1][2], m20 = in[2][0], m21 = in[2][1], m22 = in[2][2]; int i, j; - double det; + float det; out[0][0] = (m11 * m22 - m21 * m12); out[0][1] = -(m01 * m22 - m21 * m02); @@ -800,9 +804,9 @@ static void invert_matrix3x3(double in[3][3], double out[3][3]) } } -static void get_rgb2xyz_matrix(struct ColorSystem system, double m[3][3]) +static void get_rgb2xyz_matrix(struct ColorSystem system, float m[3][3]) { - double S[3], X[4], Z[4]; + float S[3], X[4], Z[4]; int i; X[0] = system.xRed / system.yRed; @@ -834,31 +838,32 @@ static void get_rgb2xyz_matrix(struct ColorSystem system, double m[3][3]) } static void -rgb_to_xy(double rc, - double gc, - double bc, - double * const x, - double * const y, - double * const z, - const double m[3][3]) +rgb_to_xy(float rc, + float gc, + float bc, + float * const x, + float * const y, + float * const z, + const float m[3][3]) { - double sum; + float scale; *x = m[0][0] * rc + m[0][1] * gc + m[0][2] * bc; *y = m[1][0] * rc + m[1][1] * gc + m[1][2] * bc; *z = m[2][0] * rc + m[2][1] * gc + m[2][2] * bc; - sum = *x + *y + *z; - if (sum == 0) - sum = 1; - *x = *x / sum; - *y = *y / sum; + scale = *x + *y + *z; + if (scale == 0.f) + scale = 1.f; + scale = 1.f / scale; + *x = *x * scale; + *y = *y * scale; } static int -constrain_rgb(double * const r, - double * const g, - double * const b) +constrain_rgb(float * const r, + float * const g, + float * const b) { /*---------------------------------------------------------------------------- If the requested RGB shade contains a negative weight for one of @@ -866,7 +871,7 @@ constrain_rgb(double * const r, the given triple of primaries. Desaturate it by adding white, equal quantities of R, G, and B, enough to make RGB all positive. -----------------------------------------------------------------------------*/ - double w; + float w; /* Amount of white needed is w = - min(0, *r, *g, *b) */ w = (0 < *r) ? 0 : *r; @@ -886,7 +891,7 @@ constrain_rgb(double * const r, static void gamma_correct(const struct ColorSystem * const cs, - double * const c) + float * const c) { /*---------------------------------------------------------------------------- Transform linear RGB values to nonlinear RGB values. @@ -899,8 +904,8 @@ gamma_correct(const struct ColorSystem * const cs, http://www.inforamp.net/~poynton/ColorFAQ.html http://www.inforamp.net/~poynton/GammaFAQ.html -----------------------------------------------------------------------------*/ - double gamma; - double cc; + float gamma; + float cc; gamma = cs->gamma; @@ -922,9 +927,9 @@ gamma_correct(const struct ColorSystem * const cs, static void gamma_correct_rgb(const struct ColorSystem * const cs, - double * const r, - double * const g, - double * const b) + float * const r, + float * const g, + float * const b) { gamma_correct(cs, r); gamma_correct(cs, g); @@ -938,24 +943,24 @@ gamma_correct_rgb(const struct ColorSystem * const cs, #define Sz(x) (((x) * (int)FFMIN(w, h)) / 512) static void -monochrome_color_location(double waveLength, int w, int h, +monochrome_color_location(float waveLength, int w, int h, int cie, int *xP, int *yP) { const int ix = waveLength - 360; - const double pX = spectral_chromaticity[ix][0]; - const double pY = spectral_chromaticity[ix][1]; - const double pZ = spectral_chromaticity[ix][2]; - const double px = pX / (pX + pY + pZ); - const double py = pY / (pX + pY + pZ); + const float pX = spectral_chromaticity[ix][0]; + const float pY = spectral_chromaticity[ix][1]; + const float pZ = spectral_chromaticity[ix][2]; + const float px = pX / (pX + pY + pZ); + const float py = pY / (pX + pY + pZ); if (cie == LUV) { - double up, vp; + float up, vp; xy_to_upvp(px, py, &up, &vp); *xP = up * (w - 1); *yP = (h - 1) - vp * (h - 1); } else if (cie == UCS) { - double u, v; + float u, v; xy_to_uv(px, py, &u, &v); *xP = u * (w - 1); @@ -1099,7 +1104,7 @@ fill_in_tongue(uint16_t* const pixels, int const h, uint16_t const maxval, const struct ColorSystem * const cs, - double const m[3][3], + float const m[3][3], int const cie, int const correct_gamma, float const contrast) @@ -1122,24 +1127,24 @@ fill_in_tongue(uint16_t* const pixels, int x; for (x = leftEdge; x <= rightEdge; ++x) { - double cx, cy, cz, jr, jg, jb, jmax; + float cx, cy, cz, jr, jg, jb, jmax; int r, g, b, mx = maxval; if (cie == LUV) { - double up, vp; - up = ((double) x) / (w - 1); - vp = 1.0 - ((double) y) / (h - 1); + float up, vp; + up = ((float) x) / (w - 1); + vp = 1.0 - ((float) y) / (h - 1); upvp_to_xy(up, vp, &cx, &cy); cz = 1.0 - (cx + cy); } else if (cie == UCS) { - double u, v; - u = ((double) x) / (w - 1); - v = 1.0 - ((double) y) / (h - 1); + float u, v; + u = ((float) x) / (w - 1); + v = 1.0 - ((float) y) / (h - 1); uv_to_xy(u, v, &cx, &cy); cz = 1.0 - (cx + cy); } else if (cie == XYY) { - cx = ((double) x) / (w - 1); - cy = 1.0 - ((double) y) / (h - 1); + cx = ((float) x) / (w - 1); + cy = 1.0 - ((float) y) / (h - 1); cz = 1.0 - (cx + cy); } else { av_assert0(0); @@ -1189,12 +1194,12 @@ plot_white_point(uint16_t* pixels, int wx, wy; if (cie == LUV) { - double wup, wvp; + float wup, wvp; xy_to_upvp(cs->xWhite, cs->yWhite, &wup, &wvp); wx = (w - 1) * wup; wy = (h - 1) - ((int) ((h - 1) * wvp)); } else if (cie == UCS) { - double wu, wv; + float wu, wv; xy_to_uv(cs->xWhite, cs->yWhite, &wu, &wv); wx = (w - 1) * wu; wy = (h - 1) - ((int) ((h - 1) * wv)); @@ -1234,68 +1239,82 @@ static int draw_background(AVFilterContext *ctx) tongue_outline(pixels, s->f->linesize[0] / 2, w, h, 65535, s->cie); - fill_in_tongue(pixels, s->f->linesize[0] / 2, w, h, 65535, cs, (const double (*)[3])s->i, s->cie, + fill_in_tongue(pixels, s->f->linesize[0] / 2, w, h, 65535, cs, (const float (*)[3])s->i, s->cie, s->correct_gamma, s->contrast); return 0; } -static void filter_rgb48(AVFilterContext *ctx, AVFrame *in, double *cx, double *cy, int x, int y) +static void filter_rgb48(AVFilterContext *ctx, const uint8_t *ptr, + ptrdiff_t linesize, + float *cx, float *cy, int x, int y) { CiescopeContext *s = ctx->priv; - const uint16_t* src = (const uint16_t*)(in->data[0] + in->linesize[0] * y + x * 6); - double r = src[0] / 65535.; - double g = src[1] / 65535.; - double b = src[2] / 65535.; - double cz; - - rgb_to_xy(r, g, b, cx, cy, &cz, (const double (*)[3])s->m); + const float scale = 1. / 65535.; + const uint16_t *src = (const uint16_t*)(ptr + linesize * y + x * 6); + float r = src[0] * scale; + float g = src[1] * scale; + float b = src[2] * scale; + float cz; + + rgb_to_xy(r, g, b, cx, cy, &cz, (const float (*)[3])s->m); } -static void filter_rgba64(AVFilterContext *ctx, AVFrame *in, double *cx, double *cy, int x, int y) +static void filter_rgba64(AVFilterContext *ctx, const uint8_t *ptr, + ptrdiff_t linesize, + float *cx, float *cy, int x, int y) { CiescopeContext *s = ctx->priv; - const uint16_t* src = (const uint16_t*)(in->data[0] + in->linesize[0] * y + x * 8); - double r = src[0] / 65535.; - double g = src[1] / 65535.; - double b = src[2] / 65535.; - double cz; - - rgb_to_xy(r, g, b, cx, cy, &cz, (const double (*)[3])s->m); + const float scale = 1. / 65535.; + const uint16_t *src = (const uint16_t*)(ptr + linesize * y + x * 8); + float r = src[0] * scale; + float g = src[1] * scale; + float b = src[2] * scale; + float cz; + + rgb_to_xy(r, g, b, cx, cy, &cz, (const float (*)[3])s->m); } -static void filter_rgb24(AVFilterContext *ctx, AVFrame *in, double *cx, double *cy, int x, int y) +static void filter_rgb24(AVFilterContext *ctx, const uint8_t *ptr, + ptrdiff_t linesize, + float *cx, float *cy, int x, int y) { CiescopeContext *s = ctx->priv; - const uint8_t* src = in->data[0] + in->linesize[0] * y + x * 3; - double r = src[0] / 255.; - double g = src[1] / 255.; - double b = src[2] / 255.; - double cz; - - rgb_to_xy(r, g, b, cx, cy, &cz, (const double (*)[3])s->m); + const float scale = 1. / 255.; + const uint8_t *src = ptr + linesize * y + x * 3; + float r = src[0] * scale; + float g = src[1] * scale; + float b = src[2] * scale; + float cz; + + rgb_to_xy(r, g, b, cx, cy, &cz, (const float (*)[3])s->m); } -static void filter_rgba(AVFilterContext *ctx, AVFrame *in, double *cx, double *cy, int x, int y) +static void filter_rgba(AVFilterContext *ctx, const uint8_t *ptr, + ptrdiff_t linesize, + float *cx, float *cy, int x, int y) { CiescopeContext *s = ctx->priv; - const uint8_t* src = in->data[0] + in->linesize[0] * y + x * 4; - double r = src[0] / 255.; - double g = src[1] / 255.; - double b = src[2] / 255.; - double cz; - - rgb_to_xy(r, g, b, cx, cy, &cz, (const double (*)[3])s->m); + const float scale = 1. / 255.; + const uint8_t *src = ptr + linesize * y + x * 4; + float r = src[0] * scale; + float g = src[1] * scale; + float b = src[2] * scale; + float cz; + + rgb_to_xy(r, g, b, cx, cy, &cz, (const float (*)[3])s->m); } -static void filter_xyz(AVFilterContext *ctx, AVFrame *in, double *cx, double *cy, int x, int y) +static void filter_xyz(AVFilterContext *ctx, const uint8_t *ptr, + ptrdiff_t linesize, + float *cx, float *cy, int x, int y) { CiescopeContext *s = ctx->priv; - const uint16_t* src = (uint16_t *)(in->data[0] + in->linesize[0] * y + x * 6); - double lx = s->log2lin[src[0]]; - double ly = s->log2lin[src[1]]; - double lz = s->log2lin[src[2]]; - double sum = lx + ly + lz; + const uint16_t* src = (uint16_t *)(ptr + linesize * y + x * 6); + float lx = s->log2lin[src[0]]; + float ly = s->log2lin[src[1]]; + float lz = s->log2lin[src[2]]; + float sum = lx + ly + lz; if (sum == 0) sum = 1; @@ -1315,7 +1334,7 @@ static void plot_gamuts(uint16_t *pixels, int linesize, int w, int h, if (!((1 << i) & gamuts)) continue; if (cie == LUV) { - double wup, wvp; + float wup, wvp; xy_to_upvp(cs->xRed, cs->yRed, &wup, &wvp); rx = (w - 1) * wup; ry = (h - 1) - ((int) ((h - 1) * wvp)); @@ -1326,7 +1345,7 @@ static void plot_gamuts(uint16_t *pixels, int linesize, int w, int h, bx = (w - 1) * wup; by = (h - 1) - ((int) ((h - 1) * wvp)); } else if (cie == UCS) { - double wu, wv; + float wu, wv; xy_to_uv(cs->xRed, cs->yRed, &wu, &wv); rx = (w - 1) * wu; ry = (h - 1) - ((int) ((h - 1) * wv)); @@ -1384,37 +1403,48 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) } for (y = 0; y < in->height; y++) { + const uint8_t *src = in->data[0]; + const ptrdiff_t src_linesize = in->linesize[0]; + uint16_t *dst = (uint16_t *)out->data[0]; + const ptrdiff_t linesize = out->linesize[0] / 2; + const int w_1 = w - 1; + const int h_1 = h - 1; + for (x = 0; x < in->width; x++) { - double cx, cy; - uint16_t *dst; - int wx, wy; + float cx, cy; + int wx, wy, pos; + int r, g, b; - s->filter(ctx, in, &cx, &cy, x, y); + s->filter(ctx, src, src_linesize, &cx, &cy, x, y); if (s->cie == LUV) { - double up, vp; + float up, vp; xy_to_upvp(cx, cy, &up, &vp); cx = up; cy = vp; } else if (s->cie == UCS) { - double u, v; + float u, v; xy_to_uv(cx, cy, &u, &v); cx = u; cy = v; } - wx = (w - 1) * cx; - wy = (h - 1) - ((h - 1) * cy); + wx = w_1 * cx; + wy = h_1 - h_1 * cy; if (wx < 0 || wx >= w || wy < 0 || wy >= h) continue; - dst = (uint16_t *)(out->data[0] + wy * out->linesize[0] + wx * 8 + 0); - dst[0] = FFMIN(dst[0] + i, 65535); - dst[1] = FFMIN(dst[1] + i, 65535); - dst[2] = FFMIN(dst[2] + i, 65535); - dst[3] = 65535; + pos = wy * linesize + wx * 4; + r = dst[pos + 0] + i; + g = dst[pos + 1] + i; + b = dst[pos + 2] + i; + + dst[pos + 0] = FFMIN(r, 65535); + dst[pos + 1] = FFMIN(g, 65535); + dst[pos + 2] = FFMIN(b, 65535); + dst[pos + 3] = 65535; } } |