/*
 * 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
 */

#include "libavutil/avassert.h"
#include "libavutil/eval.h"
#include "libavutil/opt.h"
#include "avfilter.h"
#include "internal.h"

enum {
    X, Y, W, H,
    NB_PARAMS,
};
static const char *addroi_param_names[] = {
    "x", "y", "w", "h",
};

enum {
    VAR_IW,
    VAR_IH,
    NB_VARS,
};
static const char *const addroi_var_names[] = {
    "iw",
    "ih",
};

typedef struct AddROIContext {
    const AVClass *class;

    char   *region_str[NB_PARAMS];
    AVExpr *region_expr[NB_PARAMS];

    int region[NB_PARAMS];
    AVRational qoffset;

    int clear;
} AddROIContext;

static int addroi_config_input(AVFilterLink *inlink)
{
    AVFilterContext *avctx = inlink->dst;
    AddROIContext     *ctx = avctx->priv;
    int i;
    double vars[NB_VARS];
    double val;

    vars[VAR_IW] = inlink->w;
    vars[VAR_IH] = inlink->h;

    for (i = 0; i < NB_PARAMS; i++) {
        int max_value;
        switch (i) {
        case X: max_value = inlink->w;                  break;
        case Y: max_value = inlink->h;                  break;
        case W: max_value = inlink->w - ctx->region[X]; break;
        case H: max_value = inlink->h - ctx->region[Y]; break;
        }

        val = av_expr_eval(ctx->region_expr[i], vars, NULL);
        if (val < 0.0) {
            av_log(avctx, AV_LOG_WARNING, "Calculated value %g for %s is "
                   "less than zero - using zero instead.\n", val,
                   addroi_param_names[i]);
            val = 0.0;
        } else if (val > max_value) {
            av_log(avctx, AV_LOG_WARNING, "Calculated value %g for %s is "
                   "greater than maximum allowed value %d - "
                   "using %d instead.\n", val, addroi_param_names[i],
                   max_value, max_value);
            val = max_value;
        }
        ctx->region[i] = val;
    }

    return 0;
}

static int addroi_filter_frame(AVFilterLink *inlink, AVFrame *frame)
{
    AVFilterContext *avctx = inlink->dst;
    AVFilterLink  *outlink = avctx->outputs[0];
    AddROIContext     *ctx = avctx->priv;
    AVRegionOfInterest *roi;
    AVFrameSideData *sd;
    int err;

    if (ctx->clear) {
        av_frame_remove_side_data(frame, AV_FRAME_DATA_REGIONS_OF_INTEREST);
        sd = NULL;
    } else {
        sd = av_frame_get_side_data(frame, AV_FRAME_DATA_REGIONS_OF_INTEREST);
    }
    if (sd) {
        const AVRegionOfInterest *old_roi;
        uint32_t old_roi_size;
        AVBufferRef *roi_ref;
        int nb_roi, i;

        old_roi = (const AVRegionOfInterest*)sd->data;
        old_roi_size = old_roi->self_size;
        av_assert0(old_roi_size && sd->size % old_roi_size == 0);
        nb_roi = sd->size / old_roi_size + 1;

        roi_ref = av_buffer_alloc(sizeof(*roi) * nb_roi);
        if (!roi_ref) {
            err = AVERROR(ENOMEM);
            goto fail;
        }
        roi = (AVRegionOfInterest*)roi_ref->data;

        for (i = 0; i < nb_roi - 1; i++) {
            old_roi = (const AVRegionOfInterest*)
                (sd->data + old_roi_size * i);

            roi[i] = (AVRegionOfInterest) {
                .self_size = sizeof(*roi),
                .top       = old_roi->top,
                .bottom    = old_roi->bottom,
                .left      = old_roi->left,
                .right     = old_roi->right,
                .qoffset   = old_roi->qoffset,
            };
        }

        roi[nb_roi - 1] = (AVRegionOfInterest) {
            .self_size = sizeof(*roi),
            .top       = ctx->region[Y],
            .bottom    = ctx->region[Y] + ctx->region[H],
            .left      = ctx->region[X],
            .right     = ctx->region[X] + ctx->region[W],
            .qoffset   = ctx->qoffset,
        };

        av_frame_remove_side_data(frame, AV_FRAME_DATA_REGIONS_OF_INTEREST);

        sd = av_frame_new_side_data_from_buf(frame,
                                             AV_FRAME_DATA_REGIONS_OF_INTEREST,
                                             roi_ref);
        if (!sd) {
            av_buffer_unref(&roi_ref);
            err = AVERROR(ENOMEM);
            goto fail;
        }

    } else {
        sd = av_frame_new_side_data(frame, AV_FRAME_DATA_REGIONS_OF_INTEREST,
                                    sizeof(AVRegionOfInterest));
        if (!sd) {
            err = AVERROR(ENOMEM);
            goto fail;
        }
        roi = (AVRegionOfInterest*)sd->data;
        *roi = (AVRegionOfInterest) {
            .self_size = sizeof(*roi),
            .top       = ctx->region[Y],
            .bottom    = ctx->region[Y] + ctx->region[H],
            .left      = ctx->region[X],
            .right     = ctx->region[X] + ctx->region[W],
            .qoffset   = ctx->qoffset,
        };
    }

    return ff_filter_frame(outlink, frame);

fail:
    av_frame_free(&frame);
    return err;
}

static av_cold int addroi_init(AVFilterContext *avctx)
{
    AddROIContext *ctx = avctx->priv;
    int i, err;

    for (i = 0; i < NB_PARAMS; i++) {
        err = av_expr_parse(&ctx->region_expr[i], ctx->region_str[i],
                            addroi_var_names, NULL, NULL, NULL, NULL,
                            0, avctx);
        if (err < 0) {
            av_log(ctx, AV_LOG_ERROR,
                   "Error parsing %s expression '%s'.\n",
                   addroi_param_names[i], ctx->region_str[i]);
            return err;
        }
    }

    return 0;
}

static av_cold void addroi_uninit(AVFilterContext *avctx)
{
    AddROIContext *ctx = avctx->priv;
    int i;

    for (i = 0; i < NB_PARAMS; i++) {
        av_expr_free(ctx->region_expr[i]);
        ctx->region_expr[i] = NULL;
    }
}

#define OFFSET(x) offsetof(AddROIContext, x)
#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
static const AVOption addroi_options[] = {
    { "x", "Region distance from left edge of frame.",
      OFFSET(region_str[X]), AV_OPT_TYPE_STRING, { .str = "0" }, .flags = FLAGS },
    { "y", "Region distance from top edge of frame.",
      OFFSET(region_str[Y]), AV_OPT_TYPE_STRING, { .str = "0" }, .flags = FLAGS },
    { "w", "Region width.",
      OFFSET(region_str[W]), AV_OPT_TYPE_STRING, { .str = "0" }, .flags = FLAGS },
    { "h", "Region height.",
      OFFSET(region_str[H]), AV_OPT_TYPE_STRING, { .str = "0" }, .flags = FLAGS },

    { "qoffset", "Quantisation offset to apply in the region.",
      OFFSET(qoffset), AV_OPT_TYPE_RATIONAL, { .dbl = -0.1 }, -1, +1, FLAGS },

    { "clear", "Remove any existing regions of interest before adding the new one.",
      OFFSET(clear), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },

    { NULL }
};

AVFILTER_DEFINE_CLASS(addroi);

static const AVFilterPad addroi_inputs[] = {
    {
        .name         = "default",
        .type         = AVMEDIA_TYPE_VIDEO,
        .config_props = addroi_config_input,
        .filter_frame = addroi_filter_frame,
    },
    { NULL }
};

static const AVFilterPad addroi_outputs[] = {
    {
        .name = "default",
        .type = AVMEDIA_TYPE_VIDEO,
    },
    { NULL }
};

AVFilter ff_vf_addroi = {
    .name        = "addroi",
    .description = NULL_IF_CONFIG_SMALL("Add region of interest to frame."),
    .init        = addroi_init,
    .uninit      = addroi_uninit,

    .priv_size   = sizeof(AddROIContext),
    .priv_class  = &addroi_class,

    .inputs      = addroi_inputs,
    .outputs     = addroi_outputs,
};
