Ejemplo n.º 1
0
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{
    HistogramContext *h   = inlink->dst->priv;
    AVFilterContext *ctx  = inlink->dst;
    AVFilterLink *outlink = ctx->outputs[0];
    AVFrame *out;
    int i, j, k, l, m;

    out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
    if (!out) {
        av_frame_free(&in);
        return AVERROR(ENOMEM);
    }

    out->pts = in->pts;

    for (k = 0; k < 4 && out->data[k]; k++) {
        const int is_chroma = (k == 1 || k == 2);
        const int dst_h = AV_CEIL_RSHIFT(outlink->h, (is_chroma ? h->odesc->log2_chroma_h : 0));
        const int dst_w = AV_CEIL_RSHIFT(outlink->w, (is_chroma ? h->odesc->log2_chroma_w : 0));

        if (h->histogram_size <= 256) {
            for (i = 0; i < dst_h ; i++)
                memset(out->data[h->odesc->comp[k].plane] +
                       i * out->linesize[h->odesc->comp[k].plane],
                       h->bg_color[k], dst_w);
        } else {
            const int mult = h->mult;

            for (i = 0; i < dst_h ; i++)
                for (j = 0; j < dst_w; j++)
                    AV_WN16(out->data[h->odesc->comp[k].plane] +
                        i * out->linesize[h->odesc->comp[k].plane] + j * 2,
                        h->bg_color[k] * mult);
        }
    }

    for (m = 0, k = 0; k < h->ncomp; k++) {
        const int p = h->desc->comp[k].plane;
        const int height = h->planeheight[p];
        const int width = h->planewidth[p];
        double max_hval_log;
        unsigned max_hval = 0;
        int start;

        if (!((1 << k) & h->components))
            continue;
        start = m++ * (h->level_height + h->scale_height) * h->display_mode;

        if (h->histogram_size <= 256) {
            for (i = 0; i < height; i++) {
                const uint8_t *src = in->data[p] + i * in->linesize[p];
                for (j = 0; j < width; j++)
                    h->histogram[src[j]]++;
            }
        } else {
            for (i = 0; i < height; i++) {
                const uint16_t *src = (const uint16_t *)(in->data[p] + i * in->linesize[p]);
                for (j = 0; j < width; j++)
                    h->histogram[src[j]]++;
            }
        }

        for (i = 0; i < h->histogram_size; i++)
            max_hval = FFMAX(max_hval, h->histogram[i]);
        max_hval_log = log2(max_hval + 1);

        for (i = 0; i < outlink->w; i++) {
            int col_height;

            if (h->levels_mode)
                col_height = lrint(h->level_height * (1. - (log2(h->histogram[i] + 1) / max_hval_log)));
            else
                col_height = h->level_height - (h->histogram[i] * (int64_t)h->level_height + max_hval - 1) / max_hval;

            if (h->histogram_size <= 256) {
                for (j = h->level_height - 1; j >= col_height; j--) {
                    if (h->display_mode) {
                        for (l = 0; l < h->dncomp; l++)
                            out->data[l][(j + start) * out->linesize[l] + i] = h->fg_color[l];
                    } else {
                        out->data[p][(j + start) * out->linesize[p] + i] = 255;
                    }
                }
                for (j = h->level_height + h->scale_height - 1; j >= h->level_height; j--)
                    out->data[p][(j + start) * out->linesize[p] + i] = i;
            } else {
                const int mult = h->mult;

                for (j = h->level_height - 1; j >= col_height; j--) {
                    if (h->display_mode) {
                        for (l = 0; l < h->dncomp; l++)
                            AV_WN16(out->data[l] + (j + start) * out->linesize[l] + i * 2, h->fg_color[l] * mult);
                    } else {
                        AV_WN16(out->data[p] + (j + start) * out->linesize[p] + i * 2, 255 * mult);
                    }
                }
                for (j = h->level_height + h->scale_height - 1; j >= h->level_height; j--)
                    AV_WN16(out->data[p] + (j + start) * out->linesize[p] + i * 2, i);
            }
        }

        memset(h->histogram, 0, h->histogram_size * sizeof(unsigned));
    }

    av_frame_free(&in);
    return ff_filter_frame(outlink, out);
}
Ejemplo n.º 2
0
static void vectorscope16(VectorscopeContext *s, AVFrame *in, AVFrame *out, int pd)
{
    const uint16_t * const *src = (const uint16_t * const *)in->data;
    const int slinesizex = in->linesize[s->x] / 2;
    const int slinesizey = in->linesize[s->y] / 2;
    const int slinesized = in->linesize[pd] / 2;
    const int dlinesize = out->linesize[0] / 2;
    const int intensity = s->intensity;
    const int px = s->x, py = s->y;
    const int h = s->planeheight[py];
    const int w = s->planewidth[px];
    const uint16_t *spx = src[px];
    const uint16_t *spy = src[py];
    const uint16_t *spd = src[pd];
    const int hsub = s->hsub;
    const int vsub = s->vsub;
    uint16_t **dst = (uint16_t **)out->data;
    uint16_t *dpx = dst[px];
    uint16_t *dpy = dst[py];
    uint16_t *dpd = dst[pd];
    const int max = s->size - 1;
    const int mid = s->size / 2;
    const int tmin = s->tmin;
    const int tmax = s->tmax;
    int i, j, k;

    for (k = 0; k < 4 && dst[k]; k++) {
        for (i = 0; i < out->height ; i++)
            for (j = 0; j < out->width; j++)
                AV_WN16(out->data[k] + i * out->linesize[k] + j * 2,
                        (s->mode == COLOR || s->mode == COLOR5) && k == s->pd ? 0 : s->bg_color[k]);
    }

    switch (s->mode) {
    case COLOR:
    case COLOR5:
    case GRAY:
        if (s->is_yuv) {
            for (i = 0; i < h; i++) {
                const int iwx = i * slinesizex;
                const int iwy = i * slinesizey;
                const int iwd = i * slinesized;
                for (j = 0; j < w; j++) {
                    const int x = FFMIN(spx[iwx + j], max);
                    const int y = FFMIN(spy[iwy + j], max);
                    const int z = spd[iwd + j];
                    const int pos = y * dlinesize + x;

                    if (z < tmin || z > tmax)
                        continue;

                    dpd[pos] = FFMIN(dpd[pos] + intensity, max);
                    if (dst[3])
                        dst[3][pos] = max;
                }
            }
        } else {
            for (i = 0; i < h; i++) {
                const int iwx = i * slinesizex;
                const int iwy = i * slinesizey;
                const int iwd = i * slinesized;
                for (j = 0; j < w; j++) {
                    const int x = FFMIN(spx[iwx + j], max);
                    const int y = FFMIN(spy[iwy + j], max);
                    const int z = spd[iwd + j];
                    const int pos = y * dlinesize + x;

                    if (z < tmin || z > tmax)
                        continue;

                    dst[0][pos] = FFMIN(dst[0][pos] + intensity, max);
                    dst[1][pos] = FFMIN(dst[1][pos] + intensity, max);
                    dst[2][pos] = FFMIN(dst[2][pos] + intensity, max);
                    if (dst[3])
                        dst[3][pos] = max;
                }
            }
        }
        break;
    case COLOR2:
        if (s->is_yuv) {
            for (i = 0; i < h; i++) {
                const int iw1 = i * slinesizex;
                const int iw2 = i * slinesizey;
                const int iwd = i * slinesized;
                for (j = 0; j < w; j++) {
                    const int x = FFMIN(spx[iw1 + j], max);
                    const int y = FFMIN(spy[iw2 + j], max);
                    const int z = spd[iwd + j];
                    const int pos = y * dlinesize + x;

                    if (z < tmin || z > tmax)
                        continue;

                    if (!dpd[pos])
                        dpd[pos] = FFABS(mid - x) + FFABS(mid - y);
                    dpx[pos] = x;
                    dpy[pos] = y;
                    if (dst[3])
                        dst[3][pos] = max;
                }
            }
        } else {
            for (i = 0; i < h; i++) {
                const int iw1 = i * slinesizex;
                const int iw2 = i * slinesizey;
                const int iwd = i * slinesized;
                for (j = 0; j < w; j++) {
                    const int x = FFMIN(spx[iw1 + j], max);
                    const int y = FFMIN(spy[iw2 + j], max);
                    const int z = spd[iwd + j];
                    const int pos = y * dlinesize + x;

                    if (z < tmin || z > tmax)
                        continue;

                    if (!dpd[pos])
                        dpd[pos] = FFMIN(x + y, max);
                    dpx[pos] = x;
                    dpy[pos] = y;
                    if (dst[3])
                        dst[3][pos] = max;
                }
            }
        }
        break;
    case COLOR3:
        for (i = 0; i < h; i++) {
            const int iw1 = i * slinesizex;
            const int iw2 = i * slinesizey;
            const int iwd = i * slinesized;
            for (j = 0; j < w; j++) {
                const int x = FFMIN(spx[iw1 + j], max);
                const int y = FFMIN(spy[iw2 + j], max);
                const int z = spd[iwd + j];
                const int pos = y * dlinesize + x;

                if (z < tmin || z > tmax)
                    continue;

                dpd[pos] = FFMIN(max, dpd[pos] + intensity);
                dpx[pos] = x;
                dpy[pos] = y;
                if (dst[3])
                    dst[3][pos] = max;
            }
        }
        break;
    case COLOR4:
        for (i = 0; i < in->height; i++) {
            const int iwx = (i >> vsub) * slinesizex;
            const int iwy = (i >> vsub) * slinesizey;
            const int iwd = i * slinesized;
            for (j = 0; j < in->width; j++) {
                const int x = FFMIN(spx[iwx + (j >> hsub)], max);
                const int y = FFMIN(spy[iwy + (j >> hsub)], max);
                const int z = spd[iwd + j];
                const int pos = y * dlinesize + x;

                if (z < tmin || z > tmax)
                    continue;

                dpd[pos] = FFMAX(z, dpd[pos]);
                dpx[pos] = x;
                dpy[pos] = y;
                if (dst[3])
                    dst[3][pos] = max;
            }
        }
        break;
    default:
        av_assert0(0);
    }

    envelope16(s, out);

    if (s->mode == COLOR) {
        for (i = 0; i < out->height; i++) {
            for (j = 0; j < out->width; j++) {
                if (!dpd[i * dlinesize + j]) {
                    dpx[i * dlinesize + j] = j;
                    dpy[i * dlinesize + j] = i;
                    dpd[i * dlinesize + j] = mid;
                }
            }
        }
    } else if (s->mode == COLOR5) {
        for (i = 0; i < out->height; i++) {
            for (j = 0; j < out->width; j++) {
                if (!dpd[i * dlinesize + j]) {
                    dpx[i * dlinesize + j] = j;
                    dpy[i * dlinesize + j] = i;
                    dpd[i * dlinesize + j] = mid * M_SQRT2 - hypot(i - mid, j - mid);
                }
            }
        }
    }
}