summaryrefslogtreecommitdiff
path: root/libavfilter/vf_colorchannelmixer.c
diff options
context:
space:
mode:
authorPaul B Mahol <onemda@gmail.com>2018-05-05 16:31:54 +0200
committerPaul B Mahol <onemda@gmail.com>2018-05-05 17:37:50 +0200
commit931e2c4541e0298a439383f4ffd44475babc38f0 (patch)
treef0fb864da3a6e4098163c2598402bbdfc496fe4e /libavfilter/vf_colorchannelmixer.c
parent2017b4b1c25bd72aaa9098ed4c3c669b9c11c0e0 (diff)
downloadffmpeg-931e2c4541e0298a439383f4ffd44475babc38f0.tar.gz
avfilter/vf_colorchannelmixer: refactor code
Signed-off-by: Paul B Mahol <onemda@gmail.com>
Diffstat (limited to 'libavfilter/vf_colorchannelmixer.c')
-rw-r--r--libavfilter/vf_colorchannelmixer.c200
1 files changed, 49 insertions, 151 deletions
diff --git a/libavfilter/vf_colorchannelmixer.c b/libavfilter/vf_colorchannelmixer.c
index cdd5aed8a5..bbd7eaa902 100644
--- a/libavfilter/vf_colorchannelmixer.c
+++ b/libavfilter/vf_colorchannelmixer.c
@@ -93,7 +93,8 @@ static int query_formats(AVFilterContext *ctx)
return ff_set_common_formats(ctx, fmts_list);
}
-static int filter_slice_rgba64(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
+static av_always_inline int filter_slice_rgba_packed(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs,
+ int have_alpha, int step)
{
ColorChannelMixerContext *s = ctx->priv;
ThreadData *td = arg;
@@ -110,31 +111,31 @@ static int filter_slice_rgba64(AVFilterContext *ctx, void *arg, int jobnr, int n
int i, j;
for (i = slice_start; i < slice_end; i++) {
- const uint16_t *src = (const uint16_t *)srcrow;
- uint16_t *dst = (uint16_t *)dstrow;
+ const uint8_t *src = srcrow;
+ uint8_t *dst = dstrow;
- for (j = 0; j < out->width * 4; j += 4) {
- const uint16_t rin = src[j + roffset];
- const uint16_t gin = src[j + goffset];
- const uint16_t bin = src[j + boffset];
- const uint16_t ain = src[j + aoffset];
+ for (j = 0; j < out->width * step; j += step) {
+ const uint8_t rin = src[j + roffset];
+ const uint8_t gin = src[j + goffset];
+ const uint8_t bin = src[j + boffset];
+ const uint8_t ain = src[j + aoffset];
- dst[j + roffset] = av_clip_uint16(s->lut[R][R][rin] +
- s->lut[R][G][gin] +
- s->lut[R][B][bin] +
- s->lut[R][A][ain]);
- dst[j + goffset] = av_clip_uint16(s->lut[G][R][rin] +
- s->lut[G][G][gin] +
- s->lut[G][B][bin] +
- s->lut[G][A][ain]);
- dst[j + boffset] = av_clip_uint16(s->lut[B][R][rin] +
- s->lut[B][G][gin] +
- s->lut[B][B][bin] +
- s->lut[B][A][ain]);
- dst[j + aoffset] = av_clip_uint16(s->lut[A][R][rin] +
- s->lut[A][G][gin] +
- s->lut[A][B][bin] +
- s->lut[A][A][ain]);
+ dst[j + roffset] = av_clip_uint8(s->lut[R][R][rin] +
+ s->lut[R][G][gin] +
+ s->lut[R][B][bin]);
+ dst[j + goffset] = av_clip_uint8(s->lut[G][R][rin] +
+ s->lut[G][G][gin] +
+ s->lut[G][B][bin]);
+ dst[j + boffset] = av_clip_uint8(s->lut[B][R][rin] +
+ s->lut[B][G][gin] +
+ s->lut[B][B][bin]);
+ if (have_alpha == 1) {
+ dst[j + aoffset] = av_clip_uint8(s->lut[A][R][rin] +
+ s->lut[A][G][gin] +
+ s->lut[A][B][bin] +
+ s->lut[A][A][ain]);
+ } else if (have_alpha == -1 && in != out)
+ dst[j + aoffset] = 0;
}
srcrow += in->linesize[0];
@@ -144,7 +145,8 @@ static int filter_slice_rgba64(AVFilterContext *ctx, void *arg, int jobnr, int n
return 0;
}
-static int filter_slice_rgb48(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
+static av_always_inline int filter_slice_rgba16_packed(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs,
+ int have_alpha, int step)
{
ColorChannelMixerContext *s = ctx->priv;
ThreadData *td = arg;
@@ -155,6 +157,7 @@ static int filter_slice_rgb48(AVFilterContext *ctx, void *arg, int jobnr, int nb
const uint8_t roffset = s->rgba_map[R];
const uint8_t goffset = s->rgba_map[G];
const uint8_t boffset = s->rgba_map[B];
+ const uint8_t aoffset = s->rgba_map[A];
const uint8_t *srcrow = in->data[0] + slice_start * in->linesize[0];
uint8_t *dstrow = out->data[0] + slice_start * out->linesize[0];
int i, j;
@@ -163,10 +166,11 @@ static int filter_slice_rgb48(AVFilterContext *ctx, void *arg, int jobnr, int nb
const uint16_t *src = (const uint16_t *)srcrow;
uint16_t *dst = (uint16_t *)dstrow;
- for (j = 0; j < out->width * 3; j += 3) {
+ for (j = 0; j < out->width * step; j += step) {
const uint16_t rin = src[j + roffset];
const uint16_t gin = src[j + goffset];
const uint16_t bin = src[j + boffset];
+ const uint16_t ain = src[j + aoffset];
dst[j + roffset] = av_clip_uint16(s->lut[R][R][rin] +
s->lut[R][G][gin] +
@@ -177,6 +181,13 @@ static int filter_slice_rgb48(AVFilterContext *ctx, void *arg, int jobnr, int nb
dst[j + boffset] = av_clip_uint16(s->lut[B][R][rin] +
s->lut[B][G][gin] +
s->lut[B][B][bin]);
+ if (have_alpha == 1) {
+ dst[j + aoffset] = av_clip_uint16(s->lut[A][R][rin] +
+ s->lut[A][G][gin] +
+ s->lut[A][B][bin] +
+ s->lut[A][A][ain]);
+ } else if (have_alpha == -1 && in != out)
+ dst[j + aoffset] = 0;
}
srcrow += in->linesize[0];
@@ -186,142 +197,29 @@ static int filter_slice_rgb48(AVFilterContext *ctx, void *arg, int jobnr, int nb
return 0;
}
-static int filter_slice_rgba(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
+static int filter_slice_rgba64(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
{
- ColorChannelMixerContext *s = ctx->priv;
- ThreadData *td = arg;
- AVFrame *in = td->in;
- AVFrame *out = td->out;
- const int slice_start = (out->height * jobnr) / nb_jobs;
- const int slice_end = (out->height * (jobnr+1)) / nb_jobs;
- const uint8_t roffset = s->rgba_map[R];
- const uint8_t goffset = s->rgba_map[G];
- const uint8_t boffset = s->rgba_map[B];
- const uint8_t aoffset = s->rgba_map[A];
- const uint8_t *srcrow = in->data[0] + slice_start * in->linesize[0];
- uint8_t *dstrow = out->data[0] + slice_start * out->linesize[0];
- int i, j;
-
- for (i = slice_start; i < slice_end; i++) {
- const uint8_t *src = srcrow;
- uint8_t *dst = dstrow;
-
- for (j = 0; j < out->width * 4; j += 4) {
- const uint8_t rin = src[j + roffset];
- const uint8_t gin = src[j + goffset];
- const uint8_t bin = src[j + boffset];
- const uint8_t ain = src[j + aoffset];
-
- dst[j + roffset] = av_clip_uint8(s->lut[R][R][rin] +
- s->lut[R][G][gin] +
- s->lut[R][B][bin] +
- s->lut[R][A][ain]);
- dst[j + goffset] = av_clip_uint8(s->lut[G][R][rin] +
- s->lut[G][G][gin] +
- s->lut[G][B][bin] +
- s->lut[G][A][ain]);
- dst[j + boffset] = av_clip_uint8(s->lut[B][R][rin] +
- s->lut[B][G][gin] +
- s->lut[B][B][bin] +
- s->lut[B][A][ain]);
- dst[j + aoffset] = av_clip_uint8(s->lut[A][R][rin] +
- s->lut[A][G][gin] +
- s->lut[A][B][bin] +
- s->lut[A][A][ain]);
- }
+ return filter_slice_rgba16_packed(ctx, arg, jobnr, nb_jobs, 1, 4);
+}
- srcrow += in->linesize[0];
- dstrow += out->linesize[0];
- }
+static int filter_slice_rgb48(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
+{
+ return filter_slice_rgba16_packed(ctx, arg, jobnr, nb_jobs, 0, 3);
+}
- return 0;
+static int filter_slice_rgba(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
+{
+ return filter_slice_rgba_packed(ctx, arg, jobnr, nb_jobs, 1, 4);
}
static int filter_slice_rgb24(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
{
- ColorChannelMixerContext *s = ctx->priv;
- ThreadData *td = arg;
- AVFrame *in = td->in;
- AVFrame *out = td->out;
- const int slice_start = (out->height * jobnr) / nb_jobs;
- const int slice_end = (out->height * (jobnr+1)) / nb_jobs;
- const uint8_t roffset = s->rgba_map[R];
- const uint8_t goffset = s->rgba_map[G];
- const uint8_t boffset = s->rgba_map[B];
- const uint8_t *srcrow = in->data[0] + slice_start * in->linesize[0];
- uint8_t *dstrow = out->data[0] + slice_start * out->linesize[0];
- int i, j;
-
- for (i = slice_start; i < slice_end; i++) {
- const uint8_t *src = srcrow;
- uint8_t *dst = dstrow;
-
- for (j = 0; j < out->width * 3; j += 3) {
- const uint8_t rin = src[j + roffset];
- const uint8_t gin = src[j + goffset];
- const uint8_t bin = src[j + boffset];
-
- dst[j + roffset] = av_clip_uint8(s->lut[R][R][rin] +
- s->lut[R][G][gin] +
- s->lut[R][B][bin]);
- dst[j + goffset] = av_clip_uint8(s->lut[G][R][rin] +
- s->lut[G][G][gin] +
- s->lut[G][B][bin]);
- dst[j + boffset] = av_clip_uint8(s->lut[B][R][rin] +
- s->lut[B][G][gin] +
- s->lut[B][B][bin]);
- }
-
- srcrow += in->linesize[0];
- dstrow += out->linesize[0];
- }
-
- return 0;
+ return filter_slice_rgba_packed(ctx, arg, jobnr, nb_jobs, 0, 3);
}
static int filter_slice_rgb0(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
{
- ColorChannelMixerContext *s = ctx->priv;
- ThreadData *td = arg;
- AVFrame *in = td->in;
- AVFrame *out = td->out;
- const int slice_start = (out->height * jobnr) / nb_jobs;
- const int slice_end = (out->height * (jobnr+1)) / nb_jobs;
- const uint8_t roffset = s->rgba_map[R];
- const uint8_t goffset = s->rgba_map[G];
- const uint8_t boffset = s->rgba_map[B];
- const uint8_t aoffset = s->rgba_map[A];
- const uint8_t *srcrow = in->data[0] + slice_start * in->linesize[0];
- uint8_t *dstrow = out->data[0] + slice_start * out->linesize[0];
- int i, j;
-
- for (i = slice_start; i < slice_end; i++) {
- const uint8_t *src = srcrow;
- uint8_t *dst = dstrow;
-
- for (j = 0; j < out->width * 4; j += 4) {
- const uint8_t rin = src[j + roffset];
- const uint8_t gin = src[j + goffset];
- const uint8_t bin = src[j + boffset];
-
- dst[j + roffset] = av_clip_uint8(s->lut[R][R][rin] +
- s->lut[R][G][gin] +
- s->lut[R][B][bin]);
- dst[j + goffset] = av_clip_uint8(s->lut[G][R][rin] +
- s->lut[G][G][gin] +
- s->lut[G][B][bin]);
- dst[j + boffset] = av_clip_uint8(s->lut[B][R][rin] +
- s->lut[B][G][gin] +
- s->lut[B][B][bin]);
- if (in != out)
- dst[j + aoffset] = 0;
- }
-
- srcrow += in->linesize[0];
- dstrow += out->linesize[0];
- }
-
- return 0;
+ return filter_slice_rgba_packed(ctx, arg, jobnr, nb_jobs, -1, 4);
}
static int config_output(AVFilterLink *outlink)