/*
 * Audio resampling
 *
 * Copyright (c) 2004-2012 Michael Niedermayer <michaelni@gmx.at>
 *
 * 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 "config.h"

#include "libavutil/cpu.h"
#include "libavutil/avassert.h"

#include "libavutil/arm/cpu.h"
#include "libswresample/resample.h"

#define DECLARE_RESAMPLE_COMMON_TEMPLATE(TYPE, DELEM, FELEM, FELEM2, OUT)                         \
                                                                                                  \
void ff_resample_common_apply_filter_x4_##TYPE##_neon(FELEM2 *acc, const DELEM *src,              \
                                                      const FELEM *filter, int length);           \
                                                                                                  \
void ff_resample_common_apply_filter_x8_##TYPE##_neon(FELEM2 *acc, const DELEM *src,              \
                                                      const FELEM *filter, int length);           \
                                                                                                  \
static int ff_resample_common_##TYPE##_neon(ResampleContext *c, void *dest, const void *source,   \
                                            int n, int update_ctx)                                \
{                                                                                                 \
    DELEM *dst = dest;                                                                            \
    const DELEM *src = source;                                                                    \
    int dst_index;                                                                                \
    int index= c->index;                                                                          \
    int frac= c->frac;                                                                            \
    int sample_index = 0;                                                                         \
    int x4_aligned_filter_length = c->filter_length & ~3;                                         \
    int x8_aligned_filter_length = c->filter_length & ~7;                                         \
                                                                                                  \
    while (index >= c->phase_count) {                                                             \
        sample_index++;                                                                           \
        index -= c->phase_count;                                                                  \
    }                                                                                             \
                                                                                                  \
    for (dst_index = 0; dst_index < n; dst_index++) {                                             \
        FELEM *filter = ((FELEM *) c->filter_bank) + c->filter_alloc * index;                     \
                                                                                                  \
        FELEM2 val=0;                                                                             \
        int i = 0;                                                                                \
        if (x8_aligned_filter_length >= 8) {                                                      \
            ff_resample_common_apply_filter_x8_##TYPE##_neon(&val, &src[sample_index],            \
                                                             filter, x8_aligned_filter_length);   \
            i += x8_aligned_filter_length;                                                        \
                                                                                                  \
        } else if (x4_aligned_filter_length >= 4) {                                               \
            ff_resample_common_apply_filter_x4_##TYPE##_neon(&val, &src[sample_index],            \
                                                             filter, x4_aligned_filter_length);   \
            i += x4_aligned_filter_length;                                                        \
        }                                                                                         \
        for (; i < c->filter_length; i++) {                                                       \
            val += src[sample_index + i] * (FELEM2)filter[i];                                     \
        }                                                                                         \
        OUT(dst[dst_index], val);                                                                 \
                                                                                                  \
        frac  += c->dst_incr_mod;                                                                 \
        index += c->dst_incr_div;                                                                 \
        if (frac >= c->src_incr) {                                                                \
            frac -= c->src_incr;                                                                  \
            index++;                                                                              \
        }                                                                                         \
                                                                                                  \
        while (index >= c->phase_count) {                                                         \
            sample_index++;                                                                       \
            index -= c->phase_count;                                                              \
        }                                                                                         \
    }                                                                                             \
                                                                                                  \
    if(update_ctx){                                                                               \
        c->frac= frac;                                                                            \
        c->index= index;                                                                          \
    }                                                                                             \
                                                                                                  \
    return sample_index;                                                                          \
}                                                                                                 \

#define OUT(d, v) d = v
DECLARE_RESAMPLE_COMMON_TEMPLATE(float, float, float, float, OUT)
#undef OUT

#define OUT(d, v) (v) = ((v) + (1<<(14)))>>15; (d) = av_clip_int16(v)
DECLARE_RESAMPLE_COMMON_TEMPLATE(s16, int16_t, int16_t, int32_t, OUT)
#undef OUT

av_cold void swri_resample_dsp_arm_init(ResampleContext *c)
{
    int cpu_flags = av_get_cpu_flags();

    if (!have_neon(cpu_flags))
        return;

    switch(c->format) {
    case AV_SAMPLE_FMT_FLTP:
        if (!c->linear)
            c->dsp.resample = ff_resample_common_float_neon;
        break;
    case AV_SAMPLE_FMT_S16P:
        if (!c->linear)
            c->dsp.resample = ff_resample_common_s16_neon;
        break;
    }
}
