/*
 * AST muxer
 * Copyright (c) 2012 James Almer
 *
 * 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 "avformat.h"
#include "avio_internal.h"
#include "internal.h"
#include "ast.h"
#include "libavutil/mathematics.h"
#include "libavutil/opt.h"

typedef struct ASTMuxContext {
    AVClass *class;
    int64_t  size;
    int64_t  samples;
    int64_t  loopstart;
    int64_t  loopend;
    int      fbs;
} ASTMuxContext;

#define CHECK_LOOP(type) \
    if (ast->loop ## type > 0) { \
        ast->loop ## type = av_rescale_rnd(ast->loop ## type, enc->sample_rate, 1000, AV_ROUND_DOWN); \
        if (ast->loop ## type < 0 || ast->loop ## type > UINT_MAX) { \
            av_log(s, AV_LOG_ERROR, "Invalid loop" #type " value\n"); \
            return AVERROR(EINVAL);  \
        } \
    }

static int ast_write_header(AVFormatContext *s)
{
    ASTMuxContext *ast = s->priv_data;
    AVIOContext *pb = s->pb;
    AVCodecContext *enc;
    unsigned int codec_tag;

    if (s->nb_streams == 1) {
        enc = s->streams[0]->codec;
    } else {
        av_log(s, AV_LOG_ERROR, "only one stream is supported\n");
        return AVERROR(EINVAL);
    }

    if (enc->codec_id == AV_CODEC_ID_ADPCM_AFC) {
        av_log(s, AV_LOG_ERROR, "muxing ADPCM AFC is not implemented\n");
        return AVERROR_PATCHWELCOME;
    }

    codec_tag = ff_codec_get_tag(ff_codec_ast_tags, enc->codec_id);
    if (!codec_tag) {
        av_log(s, AV_LOG_ERROR, "unsupported codec\n");
        return AVERROR(EINVAL);
    }

    if (ast->loopend > 0 && ast->loopstart >= ast->loopend) {
        av_log(s, AV_LOG_ERROR, "loopend can't be less or equal to loopstart\n");
        return AVERROR(EINVAL);
    }

    /* Convert milliseconds to samples */
    CHECK_LOOP(start)
    CHECK_LOOP(end)

    ffio_wfourcc(pb, "STRM");

    ast->size = avio_tell(pb);
    avio_wb32(pb, 0); /* File size minus header */
    avio_wb16(pb, codec_tag);
    avio_wb16(pb, 16); /* Bit depth */
    avio_wb16(pb, enc->channels);
    avio_wb16(pb, 0); /* Loop flag */
    avio_wb32(pb, enc->sample_rate);

    ast->samples = avio_tell(pb);
    avio_wb32(pb, 0); /* Number of samples */
    avio_wb32(pb, 0); /* Loopstart */
    avio_wb32(pb, 0); /* Loopend */
    avio_wb32(pb, 0); /* Size of first block */

    /* Unknown */
    avio_wb32(pb, 0);
    avio_wl32(pb, 0x7F);
    avio_wb64(pb, 0);
    avio_wb64(pb, 0);
    avio_wb32(pb, 0);

    avio_flush(pb);

    return 0;
}

static int ast_write_packet(AVFormatContext *s, AVPacket *pkt)
{
    AVIOContext *pb = s->pb;
    ASTMuxContext *ast = s->priv_data;
    AVCodecContext *enc = s->streams[0]->codec;
    int size = pkt->size / enc->channels;

    if (s->streams[0]->nb_frames == 0)
        ast->fbs = size;

    ffio_wfourcc(pb, "BLCK");
    avio_wb32(pb, size); /* Block size */

    /* padding */
    avio_wb64(pb, 0);
    avio_wb64(pb, 0);
    avio_wb64(pb, 0);

    avio_write(pb, pkt->data, pkt->size);

    return 0;
}

static int ast_write_trailer(AVFormatContext *s)
{
    AVIOContext *pb = s->pb;
    ASTMuxContext *ast = s->priv_data;
    AVCodecContext *enc = s->streams[0]->codec;
    int64_t file_size = avio_tell(pb);
    int64_t samples = (file_size - 64 - (32 * s->streams[0]->nb_frames)) / enc->block_align; /* PCM_S16BE_PLANAR */

    av_log(s, AV_LOG_DEBUG, "total samples: %"PRId64"\n", samples);

    if (s->pb->seekable) {
        /* Number of samples */
        avio_seek(pb, ast->samples, SEEK_SET);
        avio_wb32(pb, samples);

        /* Loopstart if provided */
        if (ast->loopstart > 0) {
        if (ast->loopstart >= samples) {
            av_log(s, AV_LOG_WARNING, "Loopstart value is out of range and will be ignored\n");
            ast->loopstart = -1;
            avio_skip(pb, 4);
        } else
        avio_wb32(pb, ast->loopstart);
        } else
            avio_skip(pb, 4);

        /* Loopend if provided. Otherwise number of samples again */
        if (ast->loopend && ast->loopstart >= 0) {
            if (ast->loopend > samples) {
                av_log(s, AV_LOG_WARNING, "Loopend value is out of range and will be ignored\n");
                ast->loopend = samples;
            }
            avio_wb32(pb, ast->loopend);
        } else {
            avio_wb32(pb, samples);
        }

        /* Size of first block */
        avio_wb32(pb, ast->fbs);

        /* File size minus header */
        avio_seek(pb, ast->size, SEEK_SET);
        avio_wb32(pb, file_size - 64);

        /* Loop flag */
        if (ast->loopstart >= 0) {
            avio_skip(pb, 6);
            avio_wb16(pb, 0xFFFF);
        }

        avio_seek(pb, file_size, SEEK_SET);
        avio_flush(pb);
    }
    return 0;
}

#define OFFSET(obj) offsetof(ASTMuxContext, obj)
static const AVOption options[] = {
  { "loopstart", "Loopstart position in milliseconds.", OFFSET(loopstart), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
  { "loopend",   "Loopend position in milliseconds.",   OFFSET(loopend),   AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
  { NULL },
};

static const AVClass ast_muxer_class = {
    .class_name = "AST muxer",
    .item_name  = av_default_item_name,
    .option     = options,
    .version    = LIBAVUTIL_VERSION_INT,
};

AVOutputFormat ff_ast_muxer = {
    .name              = "ast",
    .long_name         = NULL_IF_CONFIG_SMALL("AST (Audio Stream)"),
    .extensions        = "ast",
    .priv_data_size    = sizeof(ASTMuxContext),
    .audio_codec       = AV_CODEC_ID_PCM_S16BE_PLANAR,
    .video_codec       = AV_CODEC_ID_NONE,
    .write_header      = ast_write_header,
    .write_packet      = ast_write_packet,
    .write_trailer     = ast_write_trailer,
    .priv_class        = &ast_muxer_class,
    .codec_tag         = (const AVCodecTag* const []){ff_codec_ast_tags, 0},
};
