/*
 * Copyright (c) 2011 Smartjog S.A.S, Clément Bœsch <clement.boesch@smartjog.com>
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
 * @file
 * Potential thumbnail lookup filter to reduce the risk of an inappropriate
 * selection (such as a black frame) we could get with an absolute seek.
 *
 * Simplified version of algorithm by Vadim Zaliva <lord@crocodile.org>.
 * @url http://notbrainsurgery.livejournal.com/29773.html
 */

#include "avfilter.h"

#define HIST_SIZE (3*256)

struct thumb_frame {
    AVFilterBufferRef *buf;     ///< cached frame
    int histogram[HIST_SIZE];   ///< RGB color distribution histogram of the frame
};

typedef struct {
    int n;                      ///< current frame
    int n_frames;               ///< number of frames for analysis
    struct thumb_frame *frames; ///< the n_frames frames
} ThumbContext;

static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
{
    ThumbContext *thumb = ctx->priv;

    if (!args) {
        thumb->n_frames = 100;
    } else {
        int n = sscanf(args, "%d", &thumb->n_frames);
        if (n != 1 || thumb->n_frames < 2) {
            thumb->n_frames = 0;
            av_log(ctx, AV_LOG_ERROR,
                   "Invalid number of frames specified (minimum is 2).\n");
            return AVERROR(EINVAL);
        }
    }
    thumb->frames = av_calloc(thumb->n_frames, sizeof(*thumb->frames));
    if (!thumb->frames) {
        av_log(ctx, AV_LOG_ERROR,
               "Allocation failure, try to lower the number of frames\n");
        return AVERROR(ENOMEM);
    }
    av_log(ctx, AV_LOG_INFO, "batch size: %d frames\n", thumb->n_frames);
    return 0;
}

static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
{
    int i, j;
    AVFilterContext *ctx = inlink->dst;
    ThumbContext *thumb = ctx->priv;
    int *hist = thumb->frames[thumb->n].histogram;
    AVFilterBufferRef *picref = inlink->cur_buf;
    const uint8_t *p = picref->data[0] + y * picref->linesize[0];

    // update current frame RGB histogram
    for (j = 0; j < h; j++) {
        for (i = 0; i < inlink->w; i++) {
            hist[0*256 + p[i*3    ]]++;
            hist[1*256 + p[i*3 + 1]]++;
            hist[2*256 + p[i*3 + 2]]++;
        }
        p += picref->linesize[0];
    }
}

/**
 * @brief        Compute Sum-square deviation to estimate "closeness".
 * @param hist   color distribution histogram
 * @param median average color distribution histogram
 * @return       sum of squared errors
 */
static double frame_sum_square_err(const int *hist, const double *median)
{
    int i;
    double err, sum_sq_err = 0;

    for (i = 0; i < HIST_SIZE; i++) {
        err = median[i] - (double)hist[i];
        sum_sq_err += err*err;
    }
    return sum_sq_err;
}

static void end_frame(AVFilterLink *inlink)
{
    int i, j, best_frame_idx = 0;
    double avg_hist[HIST_SIZE] = {0}, sq_err, min_sq_err = -1;
    AVFilterLink *outlink = inlink->dst->outputs[0];
    ThumbContext *thumb   = inlink->dst->priv;
    AVFilterContext *ctx  = inlink->dst;
    AVFilterBufferRef *picref;

    // keep a reference of each frame
    thumb->frames[thumb->n].buf = inlink->cur_buf;

    // no selection until the buffer of N frames is filled up
    if (thumb->n < thumb->n_frames - 1) {
        thumb->n++;
        return;
    }

    // average histogram of the N frames
    for (j = 0; j < FF_ARRAY_ELEMS(avg_hist); j++) {
        for (i = 0; i < thumb->n_frames; i++)
            avg_hist[j] += (double)thumb->frames[i].histogram[j];
        avg_hist[j] /= thumb->n_frames;
    }

    // find the frame closer to the average using the sum of squared errors
    for (i = 0; i < thumb->n_frames; i++) {
        sq_err = frame_sum_square_err(thumb->frames[i].histogram, avg_hist);
        if (i == 0 || sq_err < min_sq_err)
            best_frame_idx = i, min_sq_err = sq_err;
    }

    // free and reset everything (except the best frame buffer)
    for (i = 0; i < thumb->n_frames; i++) {
        memset(thumb->frames[i].histogram, 0, sizeof(thumb->frames[i].histogram));
        if (i == best_frame_idx)
            continue;
        avfilter_unref_buffer(thumb->frames[i].buf);
        thumb->frames[i].buf = NULL;
    }
    thumb->n = 0;

    // raise the chosen one
    picref = thumb->frames[best_frame_idx].buf;
    av_log(ctx, AV_LOG_INFO, "frame id #%d (pts_time=%f) selected\n",
           best_frame_idx, picref->pts * av_q2d(inlink->time_base));
    avfilter_start_frame(outlink, picref);
    thumb->frames[best_frame_idx].buf = NULL;
    avfilter_draw_slice(outlink, 0, inlink->h, 1);
    avfilter_end_frame(outlink);
}

static av_cold void uninit(AVFilterContext *ctx)
{
    int i;
    ThumbContext *thumb = ctx->priv;
    for (i = 0; i < thumb->n_frames && thumb->frames[i].buf; i++) {
        avfilter_unref_buffer(thumb->frames[i].buf);
        thumb->frames[i].buf = NULL;
    }
    av_freep(&thumb->frames);
}

static void null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) { }

static int request_frame(AVFilterLink *link)
{
    ThumbContext *thumb = link->src->priv;

    /* loop until a frame thumbnail is available (when a frame is queued,
     * thumb->n is reset to zero) */
    while (thumb->n) {
        int ret = avfilter_request_frame(link->src->inputs[0]);
        if (ret < 0)
            return ret;
    }
    return 0;
}

static int poll_frame(AVFilterLink *link)
{
    ThumbContext *thumb  = link->src->priv;
    AVFilterLink *inlink = link->src->inputs[0];
    int ret, available_frames = avfilter_poll_frame(inlink);

    /* If the input link is not able to provide any frame, we can't do anything
     * at the moment and thus have zero thumbnail available. */
    if (!available_frames)
        return 0;

    /* Since at least one frame is available and the next frame will allow us
     * to compute a thumbnail, we can return 1 frame. */
    if (thumb->n == thumb->n_frames - 1)
        return 1;

    /* we have some frame(s) available in the input link, but not yet enough to
     * output a thumbnail, so we request more */
    ret = avfilter_request_frame(inlink);
    return ret < 0 ? ret : 0;
}

static int query_formats(AVFilterContext *ctx)
{
    static const enum PixelFormat pix_fmts[] = {
        PIX_FMT_RGB24, PIX_FMT_BGR24,
        PIX_FMT_NONE
    };
    avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts));
    return 0;
}

AVFilter avfilter_vf_thumbnail = {
    .name          = "thumbnail",
    .description   = NULL_IF_CONFIG_SMALL("Select the most representative frame in a given sequence of consecutive frames."),
    .priv_size     = sizeof(ThumbContext),
    .init          = init,
    .uninit        = uninit,
    .query_formats = query_formats,
    .inputs        = (const AVFilterPad[]) {
        {   .name             = "default",
            .type             = AVMEDIA_TYPE_VIDEO,
            .get_video_buffer = avfilter_null_get_video_buffer,
            .start_frame      = null_start_frame,
            .draw_slice       = draw_slice,
            .end_frame        = end_frame,
        },{ .name = NULL }
    },
    .outputs       = (const AVFilterPad[]) {
        {   .name             = "default",
            .type             = AVMEDIA_TYPE_VIDEO,
            .request_frame    = request_frame,
            .poll_frame       = poll_frame,
            .rej_perms        = AV_PERM_REUSE2,
        },{ .name = NULL }
    },
};
