示例#1
0
static int vibrance_slice16(AVFilterContext *avctx, void *arg, int jobnr, int nb_jobs)
{
    VibranceContext *s = avctx->priv;
    AVFrame *frame = arg;
    const int depth = s->depth;
    const float max = (1 << depth) - 1;
    const float scale = 1.f / max;
    const float gc = s->lcoeffs[0];
    const float bc = s->lcoeffs[1];
    const float rc = s->lcoeffs[2];
    const int width = frame->width;
    const int height = frame->height;
    const float intensity = s->intensity;
    const float alternate = s->alternate ? 1.f : -1.f;
    const float gintensity = intensity * s->balance[0];
    const float bintensity = intensity * s->balance[1];
    const float rintensity = intensity * s->balance[2];
    const float sgintensity = alternate * FFSIGN(gintensity);
    const float sbintensity = alternate * FFSIGN(bintensity);
    const float srintensity = alternate * FFSIGN(rintensity);
    const int slice_start = (height * jobnr) / nb_jobs;
    const int slice_end = (height * (jobnr + 1)) / nb_jobs;
    const int glinesize = frame->linesize[0] / 2;
    const int blinesize = frame->linesize[1] / 2;
    const int rlinesize = frame->linesize[2] / 2;
    uint16_t *gptr = (uint16_t *)frame->data[0] + slice_start * glinesize;
    uint16_t *bptr = (uint16_t *)frame->data[1] + slice_start * blinesize;
    uint16_t *rptr = (uint16_t *)frame->data[2] + slice_start * rlinesize;

    for (int y = slice_start; y < slice_end; y++) {
        for (int x = 0; x < width; x++) {
            float g = gptr[x] * scale;
            float b = bptr[x] * scale;
            float r = rptr[x] * scale;
            float max_color = FFMAX3(r, g, b);
            float min_color = FFMIN3(r, g, b);
            float color_saturation = max_color - min_color;
            float luma = g * gc + r * rc + b * bc;
            const float cg = 1.f + gintensity * (1.f - sgintensity * color_saturation);
            const float cb = 1.f + bintensity * (1.f - sbintensity * color_saturation);
            const float cr = 1.f + rintensity * (1.f - srintensity * color_saturation);

            g = lerpf(luma, g, cg);
            b = lerpf(luma, b, cb);
            r = lerpf(luma, r, cr);

            gptr[x] = av_clip_uintp2_c(g * max, depth);
            bptr[x] = av_clip_uintp2_c(b * max, depth);
            rptr[x] = av_clip_uintp2_c(r * max, depth);
        }

        gptr += glinesize;
        bptr += blinesize;
        rptr += rlinesize;
    }

    return 0;
}
示例#2
0
文件: cfhd.c 项目: bavison/FFmpeg
static inline void filter(int16_t *output, ptrdiff_t out_stride, int16_t *low, ptrdiff_t low_stride,
                          int16_t *high, ptrdiff_t high_stride, int len, uint8_t clip)
{
    int16_t tmp;

    int i;
    for (i = 0; i < len; i++) {
        if (i == 0) {
            tmp = (11*low[0*low_stride] - 4*low[1*low_stride] + low[2*low_stride] + 4) >> 3;
            output[(2*i+0)*out_stride] = (tmp + high[0*high_stride]) >> 1;
            if (clip)
                output[(2*i+0)*out_stride] = av_clip_uintp2_c(output[(2*i+0)*out_stride], clip);

            tmp = ( 5*low[0*low_stride] + 4*low[1*low_stride] - low[2*low_stride] + 4) >> 3;
            output[(2*i+1)*out_stride] = (tmp - high[0*high_stride]) >> 1;
            if (clip)
                output[(2*i+1)*out_stride] = av_clip_uintp2_c(output[(2*i+1)*out_stride], clip);
        } else if (i == len-1) {
示例#3
0
static int amplify_frame(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
{
    AmplifyContext *s = ctx->priv;
    ThreadData *td = arg;
    AVFrame **in = td->in;
    AVFrame *out = td->out;
    const int radius = s->radius;
    const int nb_inputs = s->nb_inputs;
    const float threshold = s->threshold;
    const float factor = s->factor;
    const int llimit = s->llimit;
    const int hlimit = s->hlimit;
    const int depth = s->depth;
    int i, p, x, y;

    if (s->depth <= 8) {
        for (p = 0; p < s->nb_planes; p++) {
            const int slice_start = (s->height[p] * jobnr) / nb_jobs;
            const int slice_end = (s->height[p] * (jobnr+1)) / nb_jobs;
            uint8_t *dst = out->data[p] + slice_start * out->linesize[p];

            if (!((1 << p) & s->planes)) {
                av_image_copy_plane(dst, out->linesize[p],
                                    in[radius]->data[p] + slice_start * in[radius]->linesize[p],
                                    in[radius]->linesize[p],
                                    s->linesize[p], slice_end - slice_start);
                continue;
            }

            for (y = slice_start; y < slice_end; y++) {
                for (x = 0; x < s->linesize[p]; x++) {
                    int src = in[radius]->data[p][y * in[radius]->linesize[p] + x];
                    float diff, avg;
                    int sum = 0;

                    for (i = 0; i < nb_inputs; i++) {
                        sum += in[i]->data[p][y * in[i]->linesize[p] + x];
                    }

                    avg = sum / (float)nb_inputs;
                    diff = src - avg;
                    if (fabsf(diff) < threshold) {
                        int amp;
                        if (diff < 0) {
                            amp = -FFMIN(FFABS(diff * factor), llimit);
                        } else {
                            amp = FFMIN(FFABS(diff * factor), hlimit);
                        }
                        dst[x] = av_clip_uint8(src + amp);
                    } else {
                        dst[x] = src;
                    }
                }

                dst += out->linesize[p];
            }
        }
    } else {
        for (p = 0; p < s->nb_planes; p++) {
            const int slice_start = (s->height[p] * jobnr) / nb_jobs;
            const int slice_end = (s->height[p] * (jobnr+1)) / nb_jobs;
            uint16_t *dst = (uint16_t *)(out->data[p] + slice_start * out->linesize[p]);

            if (!((1 << p) & s->planes)) {
                av_image_copy_plane((uint8_t *)dst, out->linesize[p],
                                    in[radius]->data[p] + slice_start * in[radius]->linesize[p],
                                    in[radius]->linesize[p],
                                    s->linesize[p], slice_end - slice_start);
                continue;
            }

            for (y = slice_start; y < slice_end; y++) {
                for (x = 0; x < s->linesize[p] / 2; x++) {
                    int src = AV_RN16(in[radius]->data[p] + y * in[radius]->linesize[p] + x * 2);
                    float diff, avg;
                    int sum = 0;

                    for (i = 0; i < nb_inputs; i++) {
                        sum += AV_RN16(in[i]->data[p] + y * in[i]->linesize[p] + x * 2);
                    }

                    avg = sum / (float)nb_inputs;
                    diff = src - avg;

                    if (fabsf(diff) < threshold) {
                        int amp;
                        if (diff < 0) {
                            amp = -FFMIN(FFABS(diff * factor), llimit);
                        } else {
                            amp = FFMIN(FFABS(diff * factor), hlimit);
                        }
                        dst[x] = av_clip_uintp2_c(src + amp, depth);
                    } else {
                        dst[x] = src;
                    }
                }

                dst += out->linesize[p] / 2;
            }
        }
    }

    return 0;
}