/*
 * Copyright (c) 2013 Vittorio Giovara
 *
 * 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
 * Generate a frame packed video, by combining two views in a single surface.
 */

#include <string.h>

#include "libavutil/imgutils.h"
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
#include "libavutil/rational.h"
#include "libavutil/stereo3d.h"

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

#define LEFT  0
#define RIGHT 1

typedef struct FramepackContext {
    const AVClass *class;

    const AVPixFmtDescriptor *pix_desc; ///< agreed pixel format

    enum AVStereo3DType format;         ///< frame pack type output

    AVFrame *input_views[2];            ///< input frames

    int64_t double_pts;                 ///< new pts for frameseq mode
} FramepackContext;

static const enum AVPixelFormat formats_supported[] = {
    AV_PIX_FMT_YUV420P,  AV_PIX_FMT_YUV422P,  AV_PIX_FMT_YUV444P,
    AV_PIX_FMT_YUV410P,  AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVJ420P,
    AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P,
    AV_PIX_FMT_NONE
};

static int query_formats(AVFilterContext *ctx)
{
    // this will ensure that formats are the same on all pads
    ff_set_common_formats(ctx, ff_make_format_list(formats_supported));
    return 0;
}

static av_cold void framepack_uninit(AVFilterContext *ctx)
{
    FramepackContext *s = ctx->priv;

    // clean any leftover frame
    av_frame_free(&s->input_views[LEFT]);
    av_frame_free(&s->input_views[RIGHT]);
}

static int config_output(AVFilterLink *outlink)
{
    AVFilterContext *ctx = outlink->src;
    FramepackContext *s  = outlink->src->priv;

    int width            = ctx->inputs[LEFT]->w;
    int height           = ctx->inputs[LEFT]->h;
    AVRational time_base = ctx->inputs[LEFT]->time_base;
    AVRational frame_rate = ctx->inputs[LEFT]->frame_rate;

    // check size and fps match on the other input
    if (width  != ctx->inputs[RIGHT]->w ||
        height != ctx->inputs[RIGHT]->h) {
        av_log(ctx, AV_LOG_ERROR,
               "Left and right sizes differ (%dx%d vs %dx%d).\n",
               width, height,
               ctx->inputs[RIGHT]->w, ctx->inputs[RIGHT]->h);
        return AVERROR_INVALIDDATA;
    } else if (av_cmp_q(time_base, ctx->inputs[RIGHT]->time_base) != 0) {
        av_log(ctx, AV_LOG_ERROR,
               "Left and right time bases differ (%d/%d vs %d/%d).\n",
               time_base.num, time_base.den,
               ctx->inputs[RIGHT]->time_base.num,
               ctx->inputs[RIGHT]->time_base.den);
        return AVERROR_INVALIDDATA;
    } else if (av_cmp_q(frame_rate, ctx->inputs[RIGHT]->frame_rate) != 0) {
        av_log(ctx, AV_LOG_ERROR,
               "Left and right framerates differ (%d/%d vs %d/%d).\n",
               frame_rate.num, frame_rate.den,
               ctx->inputs[RIGHT]->frame_rate.num,
               ctx->inputs[RIGHT]->frame_rate.den);
        return AVERROR_INVALIDDATA;
    }

    s->pix_desc = av_pix_fmt_desc_get(outlink->format);
    if (!s->pix_desc)
        return AVERROR_BUG;

    // modify output properties as needed
    switch (s->format) {
    case AV_STEREO3D_FRAMESEQUENCE:
        time_base.den *= 2;
        frame_rate.num *= 2;

        s->double_pts = AV_NOPTS_VALUE;
        break;
    case AV_STEREO3D_COLUMNS:
    case AV_STEREO3D_SIDEBYSIDE:
        width *= 2;
        break;
    case AV_STEREO3D_LINES:
    case AV_STEREO3D_TOPBOTTOM:
        height *= 2;
        break;
    default:
        av_log(ctx, AV_LOG_ERROR, "Unknown packing mode.");
        return AVERROR_INVALIDDATA;
    }

    outlink->w         = width;
    outlink->h         = height;
    outlink->time_base = time_base;
    outlink->frame_rate= frame_rate;

    return 0;
}

static void horizontal_frame_pack(FramepackContext *s,
                                  AVFrame *dst,
                                  int interleaved)
{
    int plane, i;
    int length = dst->width / 2;
    int lines  = dst->height;

    for (plane = 0; plane < s->pix_desc->nb_components; plane++) {
        const uint8_t *leftp  = s->input_views[LEFT]->data[plane];
        const uint8_t *rightp = s->input_views[RIGHT]->data[plane];
        uint8_t *dstp         = dst->data[plane];

        if (plane == 1 || plane == 2) {
            length = -(-(dst->width / 2) >> s->pix_desc->log2_chroma_w);
            lines  = -(-(dst->height)    >> s->pix_desc->log2_chroma_h);
        }

        if (interleaved) {
            for (i = 0; i < lines; i++) {
                int j;
                int k = 0;

                for (j = 0; j < length; j++) {
                    dstp[k++] = leftp[j];
                    dstp[k++] = rightp[j];
                }

                dstp   += dst->linesize[plane];
                leftp  += s->input_views[LEFT]->linesize[plane];
                rightp += s->input_views[RIGHT]->linesize[plane];
            }
        } else {
            av_image_copy_plane(dst->data[plane], dst->linesize[plane],
                                leftp, s->input_views[LEFT]->linesize[plane],
                                length, lines);
            av_image_copy_plane(dst->data[plane] + length, dst->linesize[plane],
                                rightp, s->input_views[RIGHT]->linesize[plane],
                                length, lines);
        }
    }
}

static void vertical_frame_pack(FramepackContext *s,
                                AVFrame *dst,
                                int interleaved)
{
    int plane, offset;
    int length = dst->width;
    int lines  = dst->height / 2;

    for (plane = 0; plane < s->pix_desc->nb_components; plane++) {
        if (plane == 1 || plane == 2) {
            length = -(-(dst->width)      >> s->pix_desc->log2_chroma_w);
            lines  = -(-(dst->height / 2) >> s->pix_desc->log2_chroma_h);
        }

        offset = interleaved ? dst->linesize[plane] : dst->linesize[plane] * lines;

        av_image_copy_plane(dst->data[plane],
                            dst->linesize[plane] << interleaved,
                            s->input_views[LEFT]->data[plane],
                            s->input_views[LEFT]->linesize[plane],
                            length, lines);
        av_image_copy_plane(dst->data[plane] + offset,
                            dst->linesize[plane] << interleaved,
                            s->input_views[RIGHT]->data[plane],
                            s->input_views[RIGHT]->linesize[plane],
                            length, lines);
    }
}

static av_always_inline void spatial_frame_pack(FramepackContext *s, AVFrame *dst)
{
    switch (s->format) {
    case AV_STEREO3D_SIDEBYSIDE:
        horizontal_frame_pack(s, dst, 0);
        break;
    case AV_STEREO3D_COLUMNS:
        horizontal_frame_pack(s, dst, 1);
        break;
    case AV_STEREO3D_TOPBOTTOM:
        vertical_frame_pack(s, dst, 0);
        break;
    case AV_STEREO3D_LINES:
        vertical_frame_pack(s, dst, 1);
        break;
    }
}

static int filter_frame_left(AVFilterLink *inlink, AVFrame *frame)
{
    FramepackContext *s = inlink->dst->priv;
    s->input_views[LEFT] = frame;
    return 0;
}

static int filter_frame_right(AVFilterLink *inlink, AVFrame *frame)
{
    FramepackContext *s = inlink->dst->priv;
    s->input_views[RIGHT] = frame;
    return 0;
}

static int request_frame(AVFilterLink *outlink)
{
    AVFilterContext *ctx = outlink->src;
    FramepackContext *s = ctx->priv;
    AVStereo3D *stereo;
    int ret, i;

    /* get a frame on the either input, stop as soon as a video ends */
    for (i = 0; i < 2; i++) {
        if (!s->input_views[i]) {
            ret = ff_request_frame(ctx->inputs[i]);
            if (ret < 0)
                return ret;
        }
    }

    if (s->format == AV_STEREO3D_FRAMESEQUENCE) {
        if (s->double_pts == AV_NOPTS_VALUE)
            s->double_pts = s->input_views[LEFT]->pts;

        for (i = 0; i < 2; i++) {
            // set correct timestamps
            s->input_views[i]->pts = s->double_pts++;

            // set stereo3d side data
            stereo = av_stereo3d_create_side_data(s->input_views[i]);
            if (!stereo)
                return AVERROR(ENOMEM);
            stereo->type = s->format;

            // filter the frame and immediately relinquish its pointer
            ret = ff_filter_frame(outlink, s->input_views[i]);
            s->input_views[i] = NULL;
            if (ret < 0)
                return ret;
        }
        return ret;
    } else {
        AVFrame *dst = ff_get_video_buffer(outlink, outlink->w, outlink->h);
        if (!dst)
            return AVERROR(ENOMEM);

        spatial_frame_pack(s, dst);

        // get any property from the original frame
        ret = av_frame_copy_props(dst, s->input_views[LEFT]);
        if (ret < 0) {
            av_frame_free(&dst);
            return ret;
        }

        for (i = 0; i < 2; i++)
            av_frame_free(&s->input_views[i]);

        // set stereo3d side data
        stereo = av_stereo3d_create_side_data(dst);
        if (!stereo) {
            av_frame_free(&dst);
            return AVERROR(ENOMEM);
        }
        stereo->type = s->format;

        return ff_filter_frame(outlink, dst);
    }
}

#define OFFSET(x) offsetof(FramepackContext, x)
#define V AV_OPT_FLAG_VIDEO_PARAM
static const AVOption options[] = {
    { "format", "Frame pack output format", OFFSET(format), AV_OPT_TYPE_INT,
        { .i64 = AV_STEREO3D_SIDEBYSIDE }, 0, INT_MAX, .flags = V, .unit = "format" },
    { "sbs", "Views are packed next to each other", 0, AV_OPT_TYPE_CONST,
        { .i64 = AV_STEREO3D_SIDEBYSIDE }, INT_MIN, INT_MAX, .flags = V, .unit = "format" },
    { "tab", "Views are packed on top of each other", 0, AV_OPT_TYPE_CONST,
        { .i64 = AV_STEREO3D_TOPBOTTOM }, INT_MIN, INT_MAX, .flags = V, .unit = "format" },
    { "frameseq", "Views are one after the other", 0, AV_OPT_TYPE_CONST,
        { .i64 = AV_STEREO3D_FRAMESEQUENCE }, INT_MIN, INT_MAX, .flags = V, .unit = "format" },
    { "lines", "Views are interleaved by lines", 0, AV_OPT_TYPE_CONST,
        { .i64 = AV_STEREO3D_LINES }, INT_MIN, INT_MAX, .flags = V, .unit = "format" },
    { "columns", "Views are interleaved by columns", 0, AV_OPT_TYPE_CONST,
        { .i64 = AV_STEREO3D_COLUMNS }, INT_MIN, INT_MAX, .flags = V, .unit = "format" },
    { NULL },
};

static const AVClass framepack_class = {
    .class_name = "framepack",
    .item_name  = av_default_item_name,
    .option     = options,
    .version    = LIBAVUTIL_VERSION_INT,
};

static const AVFilterPad framepack_inputs[] = {
    {
        .name         = "left",
        .type         = AVMEDIA_TYPE_VIDEO,
        .filter_frame = filter_frame_left,
        .needs_fifo   = 1,
    },
    {
        .name         = "right",
        .type         = AVMEDIA_TYPE_VIDEO,
        .filter_frame = filter_frame_right,
        .needs_fifo   = 1,
    },
    { NULL }
};

static const AVFilterPad framepack_outputs[] = {
    {
        .name          = "packed",
        .type          = AVMEDIA_TYPE_VIDEO,
        .config_props  = config_output,
        .request_frame = request_frame,
    },
    { NULL }
};

AVFilter ff_vf_framepack = {
    .name          = "framepack",
    .description   = NULL_IF_CONFIG_SMALL("Generate a frame packed stereoscopic video."),
    .priv_size     = sizeof(FramepackContext),
    .priv_class    = &framepack_class,
    .query_formats = query_formats,
    .inputs        = framepack_inputs,
    .outputs       = framepack_outputs,
    .uninit        = framepack_uninit,
};
