/*
 * Tee pseudo-muxer
 * Copyright (c) 2012 Nicolas George
 *
 * 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/avutil.h"
#include "libavutil/avstring.h"
#include "libavutil/opt.h"
#include "avformat.h"

#define MAX_SLAVES 16

typedef struct {
    AVFormatContext *avf;
    AVBitStreamFilterContext **bsfs; ///< bitstream filters per stream

    /** map from input to output streams indexes,
     * disabled output streams are set to -1 */
    int *stream_map;
} TeeSlave;

typedef struct TeeContext {
    const AVClass *class;
    unsigned nb_slaves;
    TeeSlave slaves[MAX_SLAVES];
} TeeContext;

static const char *const slave_delim     = "|";
static const char *const slave_opt_open  = "[";
static const char *const slave_opt_close = "]";
static const char *const slave_opt_delim = ":]"; /* must have the close too */
static const char *const slave_bsfs_spec_sep = "/";

static const AVClass tee_muxer_class = {
    .class_name = "Tee muxer",
    .item_name  = av_default_item_name,
    .version    = LIBAVUTIL_VERSION_INT,
};

static int parse_slave_options(void *log, char *slave,
                               AVDictionary **options, char **filename)
{
    const char *p;
    char *key, *val;
    int ret;

    if (!strspn(slave, slave_opt_open)) {
        *filename = slave;
        return 0;
    }
    p = slave + 1;
    if (strspn(p, slave_opt_close)) {
        *filename = (char *)p + 1;
        return 0;
    }
    while (1) {
        ret = av_opt_get_key_value(&p, "=", slave_opt_delim, 0, &key, &val);
        if (ret < 0) {
            av_log(log, AV_LOG_ERROR, "No option found near \"%s\"\n", p);
            goto fail;
        }
        ret = av_dict_set(options, key, val,
                          AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
        if (ret < 0)
            goto fail;
        if (strspn(p, slave_opt_close))
            break;
        p++;
    }
    *filename = (char *)p + 1;
    return 0;

fail:
    av_dict_free(options);
    return ret;
}

/**
 * Parse list of bitstream filters and add them to the list of filters
 * pointed to by bsfs.
 *
 * The list must be specified in the form:
 * BSFS ::= BSF[,BSFS]
 */
static int parse_bsfs(void *log_ctx, const char *bsfs_spec,
                      AVBitStreamFilterContext **bsfs)
{
    char *bsf_name, *buf, *dup, *saveptr;
    int ret = 0;

    if (!(dup = buf = av_strdup(bsfs_spec)))
        return AVERROR(ENOMEM);

    while (bsf_name = av_strtok(buf, ",", &saveptr)) {
        AVBitStreamFilterContext *bsf = av_bitstream_filter_init(bsf_name);

        if (!bsf) {
            av_log(log_ctx, AV_LOG_ERROR,
                   "Cannot initialize bitstream filter with name '%s', "
                   "unknown filter or internal error happened\n",
                   bsf_name);
            ret = AVERROR_UNKNOWN;
            goto end;
        }

        /* append bsf context to the list of bsf contexts */
        *bsfs = bsf;
        bsfs = &bsf->next;

        buf = NULL;
    }

end:
    av_free(dup);
    return ret;
}

static int open_slave(AVFormatContext *avf, char *slave, TeeSlave *tee_slave)
{
    int i, ret;
    AVDictionary *options = NULL;
    AVDictionaryEntry *entry;
    char *filename;
    char *format = NULL, *select = NULL;
    AVFormatContext *avf2 = NULL;
    AVStream *st, *st2;
    int stream_count;

    if ((ret = parse_slave_options(avf, slave, &options, &filename)) < 0)
        return ret;

#define STEAL_OPTION(option, field) do {                                \
        if ((entry = av_dict_get(options, option, NULL, 0))) {          \
            field = entry->value;                                       \
            entry->value = NULL; /* prevent it from being freed */      \
            av_dict_set(&options, option, NULL, 0);                     \
        }                                                               \
    } while (0)

    STEAL_OPTION("f", format);
    STEAL_OPTION("select", select);

    ret = avformat_alloc_output_context2(&avf2, NULL, format, filename);
    if (ret < 0)
        goto end;
    av_dict_copy(&avf2->metadata, avf->metadata, 0);

    tee_slave->stream_map = av_calloc(avf->nb_streams, sizeof(*tee_slave->stream_map));
    if (!tee_slave->stream_map) {
        ret = AVERROR(ENOMEM);
        goto end;
    }

    stream_count = 0;
    for (i = 0; i < avf->nb_streams; i++) {
        st = avf->streams[i];
        if (select) {
            ret = avformat_match_stream_specifier(avf, avf->streams[i], select);
            if (ret < 0) {
                av_log(avf, AV_LOG_ERROR,
                       "Invalid stream specifier '%s' for output '%s'\n",
                       select, slave);
                goto end;
            }

            if (ret == 0) { /* no match */
                tee_slave->stream_map[i] = -1;
                continue;
            }
        }
        tee_slave->stream_map[i] = stream_count++;

        if (!(st2 = avformat_new_stream(avf2, NULL))) {
            ret = AVERROR(ENOMEM);
            goto end;
        }
        st2->id = st->id;
        st2->r_frame_rate        = st->r_frame_rate;
        st2->time_base           = st->time_base;
        st2->start_time          = st->start_time;
        st2->duration            = st->duration;
        st2->nb_frames           = st->nb_frames;
        st2->disposition         = st->disposition;
        st2->sample_aspect_ratio = st->sample_aspect_ratio;
        st2->avg_frame_rate      = st->avg_frame_rate;
        av_dict_copy(&st2->metadata, st->metadata, 0);
        if ((ret = avcodec_copy_context(st2->codec, st->codec)) < 0)
            goto end;
    }

    if (!(avf2->oformat->flags & AVFMT_NOFILE)) {
        if ((ret = avio_open(&avf2->pb, filename, AVIO_FLAG_WRITE)) < 0) {
            av_log(avf, AV_LOG_ERROR, "Slave '%s': error opening: %s\n",
                   slave, av_err2str(ret));
            goto end;
        }
    }

    if ((ret = avformat_write_header(avf2, &options)) < 0) {
        av_log(avf, AV_LOG_ERROR, "Slave '%s': error writing header: %s\n",
               slave, av_err2str(ret));
        goto end;
    }

    tee_slave->avf = avf2;
    tee_slave->bsfs = av_calloc(avf2->nb_streams, sizeof(TeeSlave));
    if (!tee_slave->bsfs) {
        ret = AVERROR(ENOMEM);
        goto end;
    }

    entry = NULL;
    while (entry = av_dict_get(options, "bsfs", NULL, AV_DICT_IGNORE_SUFFIX)) {
        const char *spec = entry->key + strlen("bsfs");
        if (*spec) {
            if (strspn(spec, slave_bsfs_spec_sep) != 1) {
                av_log(avf, AV_LOG_ERROR,
                       "Specifier separator in '%s' is '%c', but only characters '%s' "
                       "are allowed\n", entry->key, *spec, slave_bsfs_spec_sep);
                return AVERROR(EINVAL);
            }
            spec++; /* consume separator */
        }

        for (i = 0; i < avf2->nb_streams; i++) {
            ret = avformat_match_stream_specifier(avf2, avf2->streams[i], spec);
            if (ret < 0) {
                av_log(avf, AV_LOG_ERROR,
                       "Invalid stream specifier '%s' in bsfs option '%s' for slave "
                       "output '%s'\n", spec, entry->key, filename);
                goto end;
            }

            if (ret > 0) {
                av_log(avf, AV_LOG_DEBUG, "spec:%s bsfs:%s matches stream %d of slave "
                       "output '%s'\n", spec, entry->value, i, filename);
                if (tee_slave->bsfs[i]) {
                    av_log(avf, AV_LOG_WARNING,
                           "Duplicate bsfs specification associated to stream %d of slave "
                           "output '%s', filters will be ignored\n", i, filename);
                    continue;
                }
                ret = parse_bsfs(avf, entry->value, &tee_slave->bsfs[i]);
                if (ret < 0) {
                    av_log(avf, AV_LOG_ERROR,
                           "Error parsing bitstream filter sequence '%s' associated to "
                           "stream %d of slave output '%s'\n", entry->value, i, filename);
                    goto end;
                }
            }
        }

        av_dict_set(&options, entry->key, NULL, 0);
    }

    if (options) {
        entry = NULL;
        while ((entry = av_dict_get(options, "", entry, AV_DICT_IGNORE_SUFFIX)))
            av_log(avf2, AV_LOG_ERROR, "Unknown option '%s'\n", entry->key);
        ret = AVERROR_OPTION_NOT_FOUND;
        goto end;
    }

end:
    av_free(format);
    av_free(select);
    av_dict_free(&options);
    return ret;
}

static void close_slaves(AVFormatContext *avf)
{
    TeeContext *tee = avf->priv_data;
    AVFormatContext *avf2;
    unsigned i, j;

    for (i = 0; i < tee->nb_slaves; i++) {
        avf2 = tee->slaves[i].avf;

        for (j = 0; j < avf2->nb_streams; j++) {
            AVBitStreamFilterContext *bsf_next, *bsf = tee->slaves[i].bsfs[j];
            while (bsf) {
                bsf_next = bsf->next;
                av_bitstream_filter_close(bsf);
                bsf = bsf_next;
            }
        }
        av_freep(&tee->slaves[i].stream_map);
        av_freep(&tee->slaves[i].bsfs);

        avio_close(avf2->pb);
        avf2->pb = NULL;
        avformat_free_context(avf2);
        tee->slaves[i].avf = NULL;
    }
}

static void log_slave(TeeSlave *slave, void *log_ctx, int log_level)
{
    int i;
    av_log(log_ctx, log_level, "filename:'%s' format:%s\n",
           slave->avf->filename, slave->avf->oformat->name);
    for (i = 0; i < slave->avf->nb_streams; i++) {
        AVStream *st = slave->avf->streams[i];
        AVBitStreamFilterContext *bsf = slave->bsfs[i];

        av_log(log_ctx, log_level, "    stream:%d codec:%s type:%s",
               i, avcodec_get_name(st->codec->codec_id),
               av_get_media_type_string(st->codec->codec_type));
        if (bsf) {
            av_log(log_ctx, log_level, " bsfs:");
            while (bsf) {
                av_log(log_ctx, log_level, "%s%s",
                       bsf->filter->name, bsf->next ? "," : "");
                bsf = bsf->next;
            }
        }
        av_log(log_ctx, log_level, "\n");
    }
}

static int tee_write_header(AVFormatContext *avf)
{
    TeeContext *tee = avf->priv_data;
    unsigned nb_slaves = 0, i;
    const char *filename = avf->filename;
    char *slaves[MAX_SLAVES];
    int ret;

    while (*filename) {
        if (nb_slaves == MAX_SLAVES) {
            av_log(avf, AV_LOG_ERROR, "Maximum %d slave muxers reached.\n",
                   MAX_SLAVES);
            ret = AVERROR_PATCHWELCOME;
            goto fail;
        }
        if (!(slaves[nb_slaves++] = av_get_token(&filename, slave_delim))) {
            ret = AVERROR(ENOMEM);
            goto fail;
        }
        if (strspn(filename, slave_delim))
            filename++;
    }

    for (i = 0; i < nb_slaves; i++) {
        if ((ret = open_slave(avf, slaves[i], &tee->slaves[i])) < 0)
            goto fail;
        log_slave(&tee->slaves[i], avf, AV_LOG_VERBOSE);
        av_freep(&slaves[i]);
    }

    tee->nb_slaves = nb_slaves;

    for (i = 0; i < avf->nb_streams; i++) {
        int j, mapped = 0;
        for (j = 0; j < tee->nb_slaves; j++)
            mapped += tee->slaves[j].stream_map[i] >= 0;
        if (!mapped)
            av_log(avf, AV_LOG_WARNING, "Input stream #%d is not mapped "
                   "to any slave.\n", i);
    }
    return 0;

fail:
    for (i = 0; i < nb_slaves; i++)
        av_freep(&slaves[i]);
    close_slaves(avf);
    return ret;
}

static int filter_packet(void *log_ctx, AVPacket *pkt,
                         AVFormatContext *fmt_ctx, AVBitStreamFilterContext *bsf_ctx)
{
    AVCodecContext *enc_ctx = fmt_ctx->streams[pkt->stream_index]->codec;
    int ret = 0;

    while (bsf_ctx) {
        AVPacket new_pkt = *pkt;
        ret = av_bitstream_filter_filter(bsf_ctx, enc_ctx, NULL,
                                             &new_pkt.data, &new_pkt.size,
                                             pkt->data, pkt->size,
                                             pkt->flags & AV_PKT_FLAG_KEY);
        if (ret == 0 && new_pkt.data != pkt->data && new_pkt.destruct) {
            if ((ret = av_copy_packet(&new_pkt, pkt)) < 0)
                break;
            ret = 1;
        }

        if (ret > 0) {
            av_free_packet(pkt);
            new_pkt.buf = av_buffer_create(new_pkt.data, new_pkt.size,
                                           av_buffer_default_free, NULL, 0);
            if (!new_pkt.buf)
                break;
        }
        if (ret < 0) {
            av_log(log_ctx, AV_LOG_ERROR,
                "Failed to filter bitstream with filter %s for stream %d in file '%s' with codec %s\n",
                bsf_ctx->filter->name, pkt->stream_index, fmt_ctx->filename,
                avcodec_get_name(enc_ctx->codec_id));
        }
        *pkt = new_pkt;

        bsf_ctx = bsf_ctx->next;
    }

    return ret;
}

static int tee_write_trailer(AVFormatContext *avf)
{
    TeeContext *tee = avf->priv_data;
    AVFormatContext *avf2;
    int ret_all = 0, ret;
    unsigned i;

    for (i = 0; i < tee->nb_slaves; i++) {
        avf2 = tee->slaves[i].avf;
        if ((ret = av_write_trailer(avf2)) < 0)
            if (!ret_all)
                ret_all = ret;
        if (!(avf2->oformat->flags & AVFMT_NOFILE)) {
            if ((ret = avio_close(avf2->pb)) < 0)
                if (!ret_all)
                    ret_all = ret;
            avf2->pb = NULL;
        }
    }
    close_slaves(avf);
    return ret_all;
}

static int tee_write_packet(AVFormatContext *avf, AVPacket *pkt)
{
    TeeContext *tee = avf->priv_data;
    AVFormatContext *avf2;
    AVPacket pkt2;
    int ret_all = 0, ret;
    unsigned i, s;
    int s2;
    AVRational tb, tb2;

    for (i = 0; i < tee->nb_slaves; i++) {
        avf2 = tee->slaves[i].avf;
        s = pkt->stream_index;
        s2 = tee->slaves[i].stream_map[s];
        if (s2 < 0)
            continue;

        if ((ret = av_copy_packet(&pkt2, pkt)) < 0 ||
            (ret = av_dup_packet(&pkt2))< 0)
            if (!ret_all) {
                ret_all = ret;
                continue;
            }
        tb  = avf ->streams[s ]->time_base;
        tb2 = avf2->streams[s2]->time_base;
        pkt2.pts      = av_rescale_q(pkt->pts,      tb, tb2);
        pkt2.dts      = av_rescale_q(pkt->dts,      tb, tb2);
        pkt2.duration = av_rescale_q(pkt->duration, tb, tb2);
        pkt2.stream_index = s2;

        filter_packet(avf2, &pkt2, avf2, tee->slaves[i].bsfs[s2]);
        if ((ret = av_interleaved_write_frame(avf2, &pkt2)) < 0)
            if (!ret_all)
                ret_all = ret;
    }
    return ret_all;
}

AVOutputFormat ff_tee_muxer = {
    .name              = "tee",
    .long_name         = NULL_IF_CONFIG_SMALL("Multiple muxer tee"),
    .priv_data_size    = sizeof(TeeContext),
    .write_header      = tee_write_header,
    .write_trailer     = tee_write_trailer,
    .write_packet      = tee_write_packet,
    .priv_class        = &tee_muxer_class,
    .flags             = AVFMT_NOFILE,
};
