summaryrefslogtreecommitdiff
path: root/libavfilter
diff options
context:
space:
mode:
authorPaul B Mahol <onemda@gmail.com>2021-09-26 13:02:03 +0200
committerPaul B Mahol <onemda@gmail.com>2021-09-26 20:27:23 +0200
commit4727e30ec3372ea3d758c28338d65f0c67539b02 (patch)
tree1bd8298b2d09317d39b1cceb359deef086760425 /libavfilter
parent8983c3d7e4acf9b216599cce218acbea498154c7 (diff)
avfilter/vf_colorlevels: refactor code so all components are processed in same loop
This is also faster.
Diffstat (limited to 'libavfilter')
-rw-r--r--libavfilter/vf_colorlevels.c100
1 files changed, 59 insertions, 41 deletions
diff --git a/libavfilter/vf_colorlevels.c b/libavfilter/vf_colorlevels.c
index 418a3037d0..9fd49d4536 100644
--- a/libavfilter/vf_colorlevels.c
+++ b/libavfilter/vf_colorlevels.c
@@ -104,56 +104,74 @@ typedef struct ThreadData {
int omin[4];
} ThreadData;
-#define LOAD_COMMON \
- ColorLevelsContext *s = ctx->priv; \
- const ThreadData *td = arg; \
- const int process_h = td->h; \
- const int slice_start = (process_h * jobnr ) / nb_jobs; \
- const int slice_end = (process_h * (jobnr+1)) / nb_jobs; \
- const uint8_t *srcrow = td->srcrow; \
- uint8_t *dstrow = td->dstrow; \
- const int step = s->step;
+#define DO_COMMON(type, clip) \
+ ColorLevelsContext *s = ctx->priv; \
+ const ThreadData *td = arg; \
+ const int linesize = s->linesize; \
+ const int step = s->step; \
+ const int process_h = td->h; \
+ const int slice_start = (process_h * jobnr ) / nb_jobs; \
+ const int slice_end = (process_h * (jobnr+1)) / nb_jobs; \
+ const int src_linesize = td->src_linesize / sizeof(type); \
+ const int dst_linesize = td->dst_linesize / sizeof(type); \
+ const type *srcrow = (const type *)td->srcrow + src_linesize * slice_start; \
+ type *dstrow = (type *)td->dstrow + dst_linesize * slice_start; \
+ const uint8_t offset_r = s->rgba_map[R]; \
+ const uint8_t offset_g = s->rgba_map[G]; \
+ const uint8_t offset_b = s->rgba_map[B]; \
+ const uint8_t offset_a = s->rgba_map[A]; \
+ const int imin_r = td->imin[R]; \
+ const int imin_g = td->imin[G]; \
+ const int imin_b = td->imin[B]; \
+ const int imin_a = td->imin[A]; \
+ const int omin_r = td->omin[R]; \
+ const int omin_g = td->omin[G]; \
+ const int omin_b = td->omin[B]; \
+ const int omin_a = td->omin[A]; \
+ const float coeff_r = td->coeff[R]; \
+ const float coeff_g = td->coeff[G]; \
+ const float coeff_b = td->coeff[B]; \
+ const float coeff_a = td->coeff[A]; \
+ const type *src_r = srcrow + offset_r; \
+ const type *src_g = srcrow + offset_g; \
+ const type *src_b = srcrow + offset_b; \
+ const type *src_a = srcrow + offset_a; \
+ type *dst_r = dstrow + offset_r; \
+ type *dst_g = dstrow + offset_g; \
+ type *dst_b = dstrow + offset_b; \
+ type *dst_a = dstrow + offset_a; \
+ \
+ for (int y = slice_start; y < slice_end; y++) { \
+ for (int x = 0; x < linesize; x += step) { \
+ dst_r[x] = clip((src_r[x] - imin_r) * coeff_r + omin_r); \
+ dst_g[x] = clip((src_g[x] - imin_g) * coeff_g + omin_g); \
+ dst_b[x] = clip((src_b[x] - imin_b) * coeff_b + omin_b); \
+ } \
+ \
+ for (int x = 0; x < linesize && s->nb_comp == 4; x += step) \
+ dst_a[x] = clip((src_a[x] - imin_a) * coeff_a + omin_a); \
+ \
+ src_r += src_linesize; \
+ src_g += src_linesize; \
+ src_b += src_linesize; \
+ src_a += src_linesize; \
+ \
+ dst_r += dst_linesize; \
+ dst_g += dst_linesize; \
+ dst_b += dst_linesize; \
+ dst_a += dst_linesize; \
+ }
static int colorlevels_slice_8(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
{
- LOAD_COMMON
-
- for (int comp = 0; comp < s->nb_comp; comp++) {
- const uint8_t offset = s->rgba_map[comp];
- const int imin = td->imin[comp];
- const int omin = td->omin[comp];
- const float coeff = td->coeff[comp];
-
- for (int y = slice_start; y < slice_end; y++) {
- const uint8_t *src = srcrow + y * td->src_linesize;
- uint8_t *dst = dstrow + y * td->dst_linesize;
-
- for (int x = 0; x < s->linesize; x += step)
- dst[x + offset] = av_clip_uint8((src[x + offset] - imin) * coeff + omin);
- }
- }
+ DO_COMMON(uint8_t, av_clip_uint8)
return 0;
}
static int colorlevels_slice_16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
{
- LOAD_COMMON
-
- for (int comp = 0; comp < s->nb_comp; comp++) {
- const uint8_t offset = s->rgba_map[comp];
- const int imin = td->imin[comp];
- const int omin = td->omin[comp];
- const float coeff = td->coeff[comp];
-
- for (int y = slice_start; y < slice_end; y++) {
- const uint16_t *src = (const uint16_t *)(srcrow + y * td->src_linesize);
- uint16_t *dst = (uint16_t *)(dstrow + y * td->dst_linesize);
-
- for (int x = 0; x < s->linesize; x += step)
- dst[x + offset] = av_clip_uint16((src[x + offset] - imin) * coeff + omin);
- }
- }
+ DO_COMMON(uint16_t, av_clip_uint16)
return 0;
}