/*
 * samplerate conversion for both audio and video
 * Copyright (c) 2000 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
 */

/**
 * @file
 * samplerate conversion for both audio and video
 */

#include <string.h>

#include "avcodec.h"
#include "audioconvert.h"
#include "libavutil/opt.h"
#include "libavutil/mem.h"
#include "libavutil/samplefmt.h"

#if FF_API_AVCODEC_RESAMPLE
FF_DISABLE_DEPRECATION_WARNINGS

#define MAX_CHANNELS 8

struct AVResampleContext;

static const char *context_to_name(void *ptr)
{
    return "audioresample";
}

static const AVOption options[] = {{NULL}};
static const AVClass audioresample_context_class = {
    "ReSampleContext", context_to_name, options, LIBAVUTIL_VERSION_INT
};

struct ReSampleContext {
    struct AVResampleContext *resample_context;
    short *temp[MAX_CHANNELS];
    int temp_len;
    float ratio;
    /* channel convert */
    int input_channels, output_channels, filter_channels;
    AVAudioConvert *convert_ctx[2];
    enum AVSampleFormat sample_fmt[2]; ///< input and output sample format
    unsigned sample_size[2];           ///< size of one sample in sample_fmt
    short *buffer[2];                  ///< buffers used for conversion to S16
    unsigned buffer_size[2];           ///< sizes of allocated buffers
};

/* n1: number of samples */
static void stereo_to_mono(short *output, short *input, int n1)
{
    short *p, *q;
    int n = n1;

    p = input;
    q = output;
    while (n >= 4) {
        q[0] = (p[0] + p[1]) >> 1;
        q[1] = (p[2] + p[3]) >> 1;
        q[2] = (p[4] + p[5]) >> 1;
        q[3] = (p[6] + p[7]) >> 1;
        q += 4;
        p += 8;
        n -= 4;
    }
    while (n > 0) {
        q[0] = (p[0] + p[1]) >> 1;
        q++;
        p += 2;
        n--;
    }
}

/* n1: number of samples */
static void mono_to_stereo(short *output, short *input, int n1)
{
    short *p, *q;
    int n = n1;
    int v;

    p = input;
    q = output;
    while (n >= 4) {
        v = p[0]; q[0] = v; q[1] = v;
        v = p[1]; q[2] = v; q[3] = v;
        v = p[2]; q[4] = v; q[5] = v;
        v = p[3]; q[6] = v; q[7] = v;
        q += 8;
        p += 4;
        n -= 4;
    }
    while (n > 0) {
        v = p[0]; q[0] = v; q[1] = v;
        q += 2;
        p += 1;
        n--;
    }
}

/*
5.1 to stereo input: [fl, fr, c, lfe, rl, rr]
- Left = front_left + rear_gain * rear_left + center_gain * center
- Right = front_right + rear_gain * rear_right + center_gain * center
Where rear_gain is usually around 0.5-1.0 and
      center_gain is almost always 0.7 (-3 dB)
*/
static void surround_to_stereo(short **output, short *input, int channels, int samples)
{
    int i;
    short l, r;

    for (i = 0; i < samples; i++) {
        int fl,fr,c,rl,rr;
        fl = input[0];
        fr = input[1];
        c = input[2];
        // lfe = input[3];
        rl = input[4];
        rr = input[5];

        l = av_clip_int16(fl + (0.5 * rl) + (0.7 * c));
        r = av_clip_int16(fr + (0.5 * rr) + (0.7 * c));

        /* output l & r. */
        *output[0]++ = l;
        *output[1]++ = r;

        /* increment input. */
        input += channels;
    }
}

static void deinterleave(short **output, short *input, int channels, int samples)
{
    int i, j;

    for (i = 0; i < samples; i++) {
        for (j = 0; j < channels; j++) {
            *output[j]++ = *input++;
        }
    }
}

static void interleave(short *output, short **input, int channels, int samples)
{
    int i, j;

    for (i = 0; i < samples; i++) {
        for (j = 0; j < channels; j++) {
            *output++ = *input[j]++;
        }
    }
}

static void ac3_5p1_mux(short *output, short *input1, short *input2, int n)
{
    int i;
    short l, r;

    for (i = 0; i < n; i++) {
        l = *input1++;
        r = *input2++;
        *output++ = l;                  /* left */
        *output++ = (l / 2) + (r / 2);  /* center */
        *output++ = r;                  /* right */
        *output++ = 0;                  /* left surround */
        *output++ = 0;                  /* right surroud */
        *output++ = 0;                  /* low freq */
    }
}

#define SUPPORT_RESAMPLE(ch1, ch2, ch3, ch4, ch5, ch6, ch7, ch8) \
    ch8<<7 | ch7<<6 | ch6<<5 | ch5<<4 | ch4<<3 | ch3<<2 | ch2<<1 | ch1<<0

static const uint8_t supported_resampling[MAX_CHANNELS] = {
    // output ch:    1  2  3  4  5  6  7  8
    SUPPORT_RESAMPLE(1, 1, 0, 0, 0, 0, 0, 0), // 1 input channel
    SUPPORT_RESAMPLE(1, 1, 0, 0, 0, 1, 0, 0), // 2 input channels
    SUPPORT_RESAMPLE(0, 0, 1, 0, 0, 0, 0, 0), // 3 input channels
    SUPPORT_RESAMPLE(0, 0, 0, 1, 0, 0, 0, 0), // 4 input channels
    SUPPORT_RESAMPLE(0, 0, 0, 0, 1, 0, 0, 0), // 5 input channels
    SUPPORT_RESAMPLE(0, 1, 0, 0, 0, 1, 0, 0), // 6 input channels
    SUPPORT_RESAMPLE(0, 0, 0, 0, 0, 0, 1, 0), // 7 input channels
    SUPPORT_RESAMPLE(0, 0, 0, 0, 0, 0, 0, 1), // 8 input channels
};

ReSampleContext *av_audio_resample_init(int output_channels, int input_channels,
                                        int output_rate, int input_rate,
                                        enum AVSampleFormat sample_fmt_out,
                                        enum AVSampleFormat sample_fmt_in,
                                        int filter_length, int log2_phase_count,
                                        int linear, double cutoff)
{
    ReSampleContext *s;

    if (input_channels > MAX_CHANNELS) {
        av_log(NULL, AV_LOG_ERROR,
               "Resampling with input channels greater than %d is unsupported.\n",
               MAX_CHANNELS);
        return NULL;
    }
    if (!(supported_resampling[input_channels-1] & (1<<(output_channels-1)))) {
        int i;
        av_log(NULL, AV_LOG_ERROR, "Unsupported audio resampling. Allowed "
               "output channels for %d input channel%s", input_channels,
               input_channels > 1 ? "s:" : ":");
        for (i = 0; i < MAX_CHANNELS; i++)
            if (supported_resampling[input_channels-1] & (1<<i))
                av_log(NULL, AV_LOG_ERROR, " %d", i + 1);
        av_log(NULL, AV_LOG_ERROR, "\n");
        return NULL;
    }

    s = av_mallocz(sizeof(ReSampleContext));
    if (!s) {
        av_log(NULL, AV_LOG_ERROR, "Can't allocate memory for resample context.\n");
        return NULL;
    }

    s->ratio = (float)output_rate / (float)input_rate;

    s->input_channels = input_channels;
    s->output_channels = output_channels;

    s->filter_channels = s->input_channels;
    if (s->output_channels < s->filter_channels)
        s->filter_channels = s->output_channels;

    s->sample_fmt[0]  = sample_fmt_in;
    s->sample_fmt[1]  = sample_fmt_out;
    s->sample_size[0] = av_get_bytes_per_sample(s->sample_fmt[0]);
    s->sample_size[1] = av_get_bytes_per_sample(s->sample_fmt[1]);

    if (s->sample_fmt[0] != AV_SAMPLE_FMT_S16) {
        if (!(s->convert_ctx[0] = av_audio_convert_alloc(AV_SAMPLE_FMT_S16, 1,
                                                         s->sample_fmt[0], 1, NULL, 0))) {
            av_log(s, AV_LOG_ERROR,
                   "Cannot convert %s sample format to s16 sample format\n",
                   av_get_sample_fmt_name(s->sample_fmt[0]));
            av_free(s);
            return NULL;
        }
    }

    if (s->sample_fmt[1] != AV_SAMPLE_FMT_S16) {
        if (!(s->convert_ctx[1] = av_audio_convert_alloc(s->sample_fmt[1], 1,
                                                         AV_SAMPLE_FMT_S16, 1, NULL, 0))) {
            av_log(s, AV_LOG_ERROR,
                   "Cannot convert s16 sample format to %s sample format\n",
                   av_get_sample_fmt_name(s->sample_fmt[1]));
            av_audio_convert_free(s->convert_ctx[0]);
            av_free(s);
            return NULL;
        }
    }

    s->resample_context = av_resample_init(output_rate, input_rate,
                                           filter_length, log2_phase_count,
                                           linear, cutoff);

    *(const AVClass**)s->resample_context = &audioresample_context_class;

    return s;
}

/* resample audio. 'nb_samples' is the number of input samples */
/* XXX: optimize it ! */
int audio_resample(ReSampleContext *s, short *output, short *input, int nb_samples)
{
    int i, nb_samples1;
    short *bufin[MAX_CHANNELS];
    short *bufout[MAX_CHANNELS];
    short *buftmp2[MAX_CHANNELS], *buftmp3[MAX_CHANNELS];
    short *output_bak = NULL;
    int lenout;

    if (s->sample_fmt[0] != AV_SAMPLE_FMT_S16) {
        int istride[1] = { s->sample_size[0] };
        int ostride[1] = { 2 };
        const void *ibuf[1] = { input };
        void       *obuf[1];
        unsigned input_size = nb_samples * s->input_channels * 2;

        if (!s->buffer_size[0] || s->buffer_size[0] < input_size) {
            av_free(s->buffer[0]);
            s->buffer_size[0] = input_size;
            s->buffer[0] = av_malloc(s->buffer_size[0]);
            if (!s->buffer[0]) {
                av_log(s->resample_context, AV_LOG_ERROR, "Could not allocate buffer\n");
                return 0;
            }
        }

        obuf[0] = s->buffer[0];

        if (av_audio_convert(s->convert_ctx[0], obuf, ostride,
                             ibuf, istride, nb_samples * s->input_channels) < 0) {
            av_log(s->resample_context, AV_LOG_ERROR,
                   "Audio sample format conversion failed\n");
            return 0;
        }

        input = s->buffer[0];
    }

    lenout= 2*s->output_channels*nb_samples * s->ratio + 16;

    if (s->sample_fmt[1] != AV_SAMPLE_FMT_S16) {
        int out_size = lenout * av_get_bytes_per_sample(s->sample_fmt[1]) *
                       s->output_channels;
        output_bak = output;

        if (!s->buffer_size[1] || s->buffer_size[1] < out_size) {
            av_free(s->buffer[1]);
            s->buffer_size[1] = out_size;
            s->buffer[1] = av_malloc(s->buffer_size[1]);
            if (!s->buffer[1]) {
                av_log(s->resample_context, AV_LOG_ERROR, "Could not allocate buffer\n");
                return 0;
            }
        }

        output = s->buffer[1];
    }

    /* XXX: move those malloc to resample init code */
    for (i = 0; i < s->filter_channels; i++) {
        bufin[i] = av_malloc_array((nb_samples + s->temp_len), sizeof(short));
        bufout[i] = av_malloc_array(lenout, sizeof(short));

        if (!bufin[i] || !bufout[i]) {
            av_log(s->resample_context, AV_LOG_ERROR, "Could not allocate buffer\n");
            nb_samples1 = 0;
            goto fail;
        }

        memcpy(bufin[i], s->temp[i], s->temp_len * sizeof(short));
        buftmp2[i] = bufin[i] + s->temp_len;
    }

    if (s->input_channels == 2 && s->output_channels == 1) {
        buftmp3[0] = output;
        stereo_to_mono(buftmp2[0], input, nb_samples);
    } else if (s->output_channels >= 2 && s->input_channels == 1) {
        buftmp3[0] = bufout[0];
        memcpy(buftmp2[0], input, nb_samples * sizeof(short));
    } else if (s->input_channels == 6 && s->output_channels ==2) {
        buftmp3[0] = bufout[0];
        buftmp3[1] = bufout[1];
        surround_to_stereo(buftmp2, input, s->input_channels, nb_samples);
    } else if (s->output_channels >= s->input_channels && s->input_channels >= 2) {
        for (i = 0; i < s->input_channels; i++) {
            buftmp3[i] = bufout[i];
        }
        deinterleave(buftmp2, input, s->input_channels, nb_samples);
    } else {
        buftmp3[0] = output;
        memcpy(buftmp2[0], input, nb_samples * sizeof(short));
    }

    nb_samples += s->temp_len;

    /* resample each channel */
    nb_samples1 = 0; /* avoid warning */
    for (i = 0; i < s->filter_channels; i++) {
        int consumed;
        int is_last = i + 1 == s->filter_channels;

        nb_samples1 = av_resample(s->resample_context, buftmp3[i], bufin[i],
                                  &consumed, nb_samples, lenout, is_last);
        s->temp_len = nb_samples - consumed;
        s->temp[i] = av_realloc_array(s->temp[i], s->temp_len, sizeof(short));
        memcpy(s->temp[i], bufin[i] + consumed, s->temp_len * sizeof(short));
    }

    if (s->output_channels == 2 && s->input_channels == 1) {
        mono_to_stereo(output, buftmp3[0], nb_samples1);
    } else if (s->output_channels == 6 && s->input_channels == 2) {
        ac3_5p1_mux(output, buftmp3[0], buftmp3[1], nb_samples1);
    } else if ((s->output_channels == s->input_channels && s->input_channels >= 2) ||
               (s->output_channels == 2 && s->input_channels == 6)) {
        interleave(output, buftmp3, s->output_channels, nb_samples1);
    }

    if (s->sample_fmt[1] != AV_SAMPLE_FMT_S16) {
        int istride[1] = { 2 };
        int ostride[1] = { s->sample_size[1] };
        const void *ibuf[1] = { output };
        void       *obuf[1] = { output_bak };

        if (av_audio_convert(s->convert_ctx[1], obuf, ostride,
                             ibuf, istride, nb_samples1 * s->output_channels) < 0) {
            av_log(s->resample_context, AV_LOG_ERROR,
                   "Audio sample format conversion failed\n");
            return 0;
        }
    }

fail:
    for (i = 0; i < s->filter_channels; i++) {
        av_free(bufin[i]);
        av_free(bufout[i]);
    }

    return nb_samples1;
}

void audio_resample_close(ReSampleContext *s)
{
    int i;
    av_resample_close(s->resample_context);
    for (i = 0; i < s->filter_channels; i++)
        av_freep(&s->temp[i]);
    av_freep(&s->buffer[0]);
    av_freep(&s->buffer[1]);
    av_audio_convert_free(s->convert_ctx[0]);
    av_audio_convert_free(s->convert_ctx[1]);
    av_free(s);
}

FF_ENABLE_DEPRECATION_WARNINGS
#endif
