/*
 * FFM (ffserver live feed) muxer
 * Copyright (c) 2001 Fabrice Bellard
 *
 * 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/intreadwrite.h"
#include "libavutil/intfloat.h"
#include "libavutil/avassert.h"
#include "libavutil/parseutils.h"
#include "libavutil/opt.h"
#include "avformat.h"
#include "avio_internal.h"
#include "internal.h"
#include "ffm.h"

static void flush_packet(AVFormatContext *s)
{
    FFMContext *ffm = s->priv_data;
    int fill_size, h;
    AVIOContext *pb = s->pb;

    fill_size = ffm->packet_end - ffm->packet_ptr;
    memset(ffm->packet_ptr, 0, fill_size);

    av_assert1(avio_tell(pb) % ffm->packet_size == 0);

    /* put header */
    avio_wb16(pb, PACKET_ID);
    avio_wb16(pb, fill_size);
    avio_wb64(pb, ffm->dts);
    h = ffm->frame_offset;
    if (ffm->first_packet)
        h |= 0x8000;
    avio_wb16(pb, h);
    avio_write(pb, ffm->packet, ffm->packet_end - ffm->packet);
    avio_flush(pb);

    /* prepare next packet */
    ffm->frame_offset = 0; /* no key frame */
    ffm->packet_ptr = ffm->packet;
    ffm->first_packet = 0;
}

/* 'first' is true if first data of a frame */
static void ffm_write_data(AVFormatContext *s,
                           const uint8_t *buf, int size,
                           int64_t dts, int header)
{
    FFMContext *ffm = s->priv_data;
    int len;

    if (header && ffm->frame_offset == 0) {
        ffm->frame_offset = ffm->packet_ptr - ffm->packet + FFM_HEADER_SIZE;
        ffm->dts = dts;
    }

    /* write as many packets as needed */
    while (size > 0) {
        len = ffm->packet_end - ffm->packet_ptr;
        if (len > size)
            len = size;
        memcpy(ffm->packet_ptr, buf, len);

        ffm->packet_ptr += len;
        buf += len;
        size -= len;
        if (ffm->packet_ptr >= ffm->packet_end)
            flush_packet(s);
    }
}

static void write_header_chunk(AVIOContext *pb, AVIOContext *dpb, unsigned id)
{
    uint8_t *dyn_buf;
    int dyn_size= avio_close_dyn_buf(dpb, &dyn_buf);
    avio_wb32(pb, id);
    avio_wb32(pb, dyn_size);
    avio_write(pb, dyn_buf, dyn_size);
    av_free(dyn_buf);
}

static int ffm_write_header_codec_ctx(AVIOContext *pb, AVCodecParameters *ctxpar, unsigned tag, int type)
{
    AVIOContext *tmp;
    char *buf = NULL;
    int ret, need_coma = 0;
    AVCodecContext *ctx = NULL;

#define SKIP_DEFAULTS   AV_OPT_SERIALIZE_SKIP_DEFAULTS
#define OPT_FLAGS_EXACT AV_OPT_SERIALIZE_OPT_FLAGS_EXACT
#define ENC             AV_OPT_FLAG_ENCODING_PARAM

    if (avio_open_dyn_buf(&tmp) < 0)
        return AVERROR(ENOMEM);

    // AVCodecParameters does not suport AVOptions, we thus must copy it over to a context that does
    // otherwise it could be used directly and this would be much simpler
    ctx = avcodec_alloc_context3(NULL);
    if (!ctx) {
        ret = AVERROR(ENOMEM);
        goto fail;
    }
    avcodec_parameters_to_context(ctx, ctxpar);

    if ((ret = av_opt_serialize(ctx, ENC | type, SKIP_DEFAULTS, &buf, '=', ',')) < 0)
        goto fail;
    if (buf && strlen(buf)) {
        avio_write(tmp, buf, strlen(buf));
        av_freep(&buf);
        need_coma = 1;
    }
    if ((ret = av_opt_serialize(ctx, 0, SKIP_DEFAULTS | OPT_FLAGS_EXACT, &buf, '=', ',')) < 0)
        goto fail;
    if (buf && strlen(buf)) {
        if (need_coma)
            avio_w8(tmp, ',');
        avio_write(tmp, buf, strlen(buf));
    }
    av_freep(&buf);
    avio_w8(tmp, 0);
    write_header_chunk(pb, tmp, tag);
    avcodec_free_context(&ctx);
    return 0;
  fail:
    av_free(buf);
    ffio_free_dyn_buf(&tmp);
    avcodec_free_context(&ctx);
    return ret;

#undef SKIP_DEFAULTS
#undef OPT_FLAGS_EXACT
#undef ENC
}

static int ffm_write_recommended_config(AVIOContext *pb, AVCodecParameters *codecpar, unsigned tag,
                                        const char *configuration)
{
    int ret;
    const AVCodec *enc = avcodec_find_encoder(codecpar->codec_id);
    AVIOContext *tmp;
    AVDictionaryEntry *t = NULL;
    AVDictionary *all = NULL, *comm = NULL, *prv = NULL;
    char *buf = NULL;

    if (!enc || !enc->priv_class || !enc->priv_data_size) {
        /* codec is not known/has no private options, so save everything as common options */
        if (avio_open_dyn_buf(&tmp) < 0)
            return AVERROR(ENOMEM);
        avio_put_str(tmp, configuration);
        write_header_chunk(pb, tmp, tag);
        return 0;
    }

    if ((ret = av_dict_parse_string(&all, configuration, "=", ",", 0)) < 0)
        return ret;

    while ((t = av_dict_get(all, "", t, AV_DICT_IGNORE_SUFFIX))) {
        if (av_opt_find((void *)&enc->priv_class, t->key, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ)) {
            if ((ret = av_dict_set(&prv, t->key, t->value, 0)) < 0)
                goto fail;
        } else if ((ret = av_dict_set(&comm, t->key, t->value, 0)) < 0)
            goto fail;
    }

    if (comm) {
        if ((ret = av_dict_get_string(comm, &buf, '=', ',')) < 0 ||
            (ret = avio_open_dyn_buf(&tmp)) < 0)
            goto fail;
        avio_put_str(tmp, buf);
        av_freep(&buf);
        write_header_chunk(pb, tmp, tag);
    }
    if (prv) {
        if ((ret = av_dict_get_string(prv, &buf, '=', ',')) < 0 ||
            (ret = avio_open_dyn_buf(&tmp)) < 0)
            goto fail;
        avio_put_str(tmp, buf);
        write_header_chunk(pb, tmp, MKBETAG('C', 'P', 'R', 'V'));
    }

  fail:
    av_free(buf);
    av_dict_free(&all);
    av_dict_free(&comm);
    av_dict_free(&prv);
    return ret;
}

static int ffm_write_header(AVFormatContext *s)
{
    FFMContext *ffm = s->priv_data;
    AVStream *st;
    AVIOContext *pb = s->pb;
    AVCodecParameters *codecpar;
    int bit_rate, i, ret;

    if ((ret = ff_parse_creation_time_metadata(s, &ffm->start_time, 0)) < 0)
        return ret;

    ffm->packet_size = FFM_PACKET_SIZE;

    /* header */
    avio_wl32(pb, MKTAG('F', 'F', 'M', '2'));
    avio_wb32(pb, ffm->packet_size);
    avio_wb64(pb, 0); /* current write position */

    if(avio_open_dyn_buf(&pb) < 0)
        return AVERROR(ENOMEM);

    avio_wb32(pb, s->nb_streams);
    bit_rate = 0;
    for(i=0;i<s->nb_streams;i++) {
        st = s->streams[i];
        bit_rate += st->codecpar->bit_rate;
    }
    avio_wb32(pb, bit_rate);

    write_header_chunk(s->pb, pb, MKBETAG('M', 'A', 'I', 'N'));

    /* list of streams */
    for(i=0;i<s->nb_streams;i++) {
        int flags = 0;
        st = s->streams[i];
        avpriv_set_pts_info(st, 64, 1, 1000000);
        if(avio_open_dyn_buf(&pb) < 0)
            return AVERROR(ENOMEM);

        codecpar = st->codecpar;
        /* generic info */
        avio_wb32(pb, codecpar->codec_id);
        avio_w8(pb, codecpar->codec_type);
        avio_wb32(pb, codecpar->bit_rate);
        if (codecpar->extradata_size)
            flags |= AV_CODEC_FLAG_GLOBAL_HEADER;

        // If the user is not providing us with a configuration we have to fill it in as we cannot access the encoder
        if (!st->recommended_encoder_configuration) {
            if (s->flags & AVFMT_FLAG_BITEXACT)
                flags |= AV_CODEC_FLAG_BITEXACT;
        }

        avio_wb32(pb, flags);
        avio_wb32(pb, 0); // flags2
        avio_wb32(pb, 0); // debug
        if (codecpar->extradata_size) {
            avio_wb32(pb, codecpar->extradata_size);
            avio_write(pb, codecpar->extradata, codecpar->extradata_size);
        }
        write_header_chunk(s->pb, pb, MKBETAG('C', 'O', 'M', 'M'));
        /* specific info */
        switch(codecpar->codec_type) {
        case AVMEDIA_TYPE_VIDEO:
            if (st->recommended_encoder_configuration) {
                av_log(NULL, AV_LOG_DEBUG, "writing recommended configuration: %s\n",
                       st->recommended_encoder_configuration);
                if ((ret = ffm_write_recommended_config(s->pb, codecpar, MKBETAG('S', '2', 'V', 'I'),
                                                        st->recommended_encoder_configuration)) < 0)
                return ret;
            } else if ((ret = ffm_write_header_codec_ctx(s->pb, codecpar, MKBETAG('S', '2', 'V', 'I'), AV_OPT_FLAG_VIDEO_PARAM)) < 0)
                return ret;
            break;
        case AVMEDIA_TYPE_AUDIO:
            if (st->recommended_encoder_configuration) {
                av_log(NULL, AV_LOG_DEBUG, "writing recommended configuration: %s\n",
                       st->recommended_encoder_configuration);
                if ((ret = ffm_write_recommended_config(s->pb, codecpar, MKBETAG('S', '2', 'A', 'U'),
                                                        st->recommended_encoder_configuration)) < 0)
                return ret;
            } else if ((ret = ffm_write_header_codec_ctx(s->pb, codecpar, MKBETAG('S', '2', 'A', 'U'), AV_OPT_FLAG_AUDIO_PARAM)) < 0)
                return ret;
            break;
        default:
            return -1;
        }
    }
    pb = s->pb;

    avio_wb64(pb, 0); // end of header

    /* flush until end of block reached */
    while ((avio_tell(pb) % ffm->packet_size) != 0)
        avio_w8(pb, 0);

    avio_flush(pb);

    /* init packet mux */
    ffm->packet_ptr = ffm->packet;
    ffm->packet_end = ffm->packet + ffm->packet_size - FFM_HEADER_SIZE;
    av_assert0(ffm->packet_end >= ffm->packet);
    ffm->frame_offset = 0;
    ffm->dts = 0;
    ffm->first_packet = 1;

    return 0;
}

static int ffm_write_packet(AVFormatContext *s, AVPacket *pkt)
{
    FFMContext *ffm = s->priv_data;
    int64_t dts;
    uint8_t header[FRAME_HEADER_SIZE+4];
    int header_size = FRAME_HEADER_SIZE;

    dts = ffm->start_time + pkt->dts;
    /* packet size & key_frame */
    header[0] = pkt->stream_index;
    header[1] = 0;
    if (pkt->flags & AV_PKT_FLAG_KEY)
        header[1] |= FLAG_KEY_FRAME;
    AV_WB24(header+2, pkt->size);
    AV_WB24(header+5, pkt->duration);
    AV_WB64(header+8, ffm->start_time + pkt->pts);
    if (pkt->pts != pkt->dts) {
        header[1] |= FLAG_DTS;
        AV_WB32(header+16, pkt->pts - pkt->dts);
        header_size += 4;
    }
    ffm_write_data(s, header, header_size, dts, 1);
    ffm_write_data(s, pkt->data, pkt->size, dts, 0);

    return 0;
}

static int ffm_write_trailer(AVFormatContext *s)
{
    FFMContext *ffm = s->priv_data;

    /* flush packets */
    if (ffm->packet_ptr > ffm->packet)
        flush_packet(s);

    return 0;
}

AVOutputFormat ff_ffm_muxer = {
    .name              = "ffm",
    .long_name         = NULL_IF_CONFIG_SMALL("FFM (FFserver live feed)"),
    .extensions        = "ffm",
    .priv_data_size    = sizeof(FFMContext),
    .audio_codec       = AV_CODEC_ID_MP2,
    .video_codec       = AV_CODEC_ID_MPEG1VIDEO,
    .write_header      = ffm_write_header,
    .write_packet      = ffm_write_packet,
    .write_trailer     = ffm_write_trailer,
    .flags             = AVFMT_TS_NEGATIVE,
};
