/*
 * Copyright (c) 2015 Paul B Mahol
 *
 * 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/avstring.h"
#include "libavutil/common.h"
#include "libavutil/internal.h"
#include "libavutil/opt.h"

#include "avfilter.h"
#include "internal.h"
#include "video.h"

typedef struct ShuffleFramesContext {
    const AVClass *class;
    char *mapping;
    AVFrame **frames;
    int *map;
    int64_t *pts;
    int in_frames;
    int nb_frames;
} ShuffleFramesContext;

static av_cold int init(AVFilterContext *ctx)
{
    ShuffleFramesContext *s = ctx->priv;
    char *mapping, *saveptr = NULL, *p;
    int n, nb_items;

    nb_items = 1;
    for (p = s->mapping; *p; p++) {
        if (*p == '|' || *p == ' ')
            nb_items++;
    }

    s->frames = av_calloc(nb_items, sizeof(*s->frames));
    s->map    = av_calloc(nb_items, sizeof(*s->map));
    s->pts    = av_calloc(nb_items, sizeof(*s->pts));
    if (!s->map || !s->frames || !s->pts) {
        return AVERROR(ENOMEM);
    }

    mapping = av_strdup(s->mapping);
    if (!mapping)
        return AVERROR(ENOMEM);

    for (n = 0; n < nb_items; n++) {
        char *map = av_strtok(n == 0 ? mapping : NULL, " |", &saveptr);
        if (!map || sscanf(map, "%d", &s->map[n]) != 1) {
            av_free(mapping);
            return AVERROR(EINVAL);
        }

        if (s->map[n] < 0 || s->map[n] >= nb_items) {
            av_log(ctx, AV_LOG_ERROR, "Index out of range.\n");
            av_free(mapping);
            return AVERROR(EINVAL);
        }
    }

    s->nb_frames = nb_items;
    av_free(mapping);
    return 0;
}

static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
{
    AVFilterContext    *ctx = inlink->dst;
    ShuffleFramesContext *s = ctx->priv;
    int ret;

    if (s->in_frames < s->nb_frames) {
        s->frames[s->in_frames] = frame;
        s->pts[s->in_frames] = frame->pts;
        s->in_frames++;
        ret = 0;
    } else if (s->in_frames == s->nb_frames) {
        int n, x;

        for (n = 0; n < s->nb_frames; n++) {
            AVFrame *out;

            x = s->map[n];
            out = av_frame_clone(s->frames[x]);
            if (!out)
                return AVERROR(ENOMEM);
            out->pts = s->pts[n];
            ret = ff_filter_frame(ctx->outputs[0], out);
            s->in_frames--;
        }

        for (n = 0; n < s->nb_frames; n++)
            av_frame_free(&s->frames[n]);
    } else
        av_assert0(0);

    return ret;
}

static av_cold void uninit(AVFilterContext *ctx)
{
    ShuffleFramesContext *s = ctx->priv;

    av_freep(&s->frames);
    av_freep(&s->map);
    av_freep(&s->pts);
}

#define OFFSET(x) offsetof(ShuffleFramesContext, x)
#define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
static const AVOption shuffleframes_options[] = {
    { "mapping", "set destination indexes of input frames",  OFFSET(mapping), AV_OPT_TYPE_STRING, {.str="0"}, 0, 0, FLAGS },
    { NULL },
};

AVFILTER_DEFINE_CLASS(shuffleframes);

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

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

AVFilter ff_vf_shuffleframes = {
    .name          = "shuffleframes",
    .description   = NULL_IF_CONFIG_SMALL("Shuffle video frames."),
    .priv_size     = sizeof(ShuffleFramesContext),
    .priv_class    = &shuffleframes_class,
    .init          = init,
    .uninit        = uninit,
    .inputs        = shuffleframes_inputs,
    .outputs       = shuffleframes_outputs,
    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
};
