blob: b74220a92fc1c6600ff284b62b4c162a3626c947 [file] [log] [blame]
/*
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*
*/
#include <cpu-features.h>
#include "android/log.h"
#include "dl/sp/api/omxSP.h"
int HasArmNeon() {
return (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0;
}
static void SetFFTRoutines() {
/*
* Choose the correct (NEON or non-NEON) routines for both the
* forward and inverse FFTs
*/
if (HasArmNeon()) {
__android_log_print(ANDROID_LOG_INFO, "OpenMAX DL FFT",
"Using NEON FFT");
omxSP_FFTFwd_RToCCS_F32 = omxSP_FFTFwd_RToCCS_F32_Sfs;
omxSP_FFTInv_CCSToR_F32 = omxSP_FFTInv_CCSToR_F32_Sfs;
} else {
__android_log_print(ANDROID_LOG_INFO, "OpenMAX DL FFT",
"Using non-NEON FFT");
omxSP_FFTFwd_RToCCS_F32 = omxSP_FFTFwd_RToCCS_F32_Sfs_vfp;
omxSP_FFTInv_CCSToR_F32 = omxSP_FFTInv_CCSToR_F32_Sfs_vfp;
}
}
/*
* FIXME: It would be beneficial to use the GCC ifunc attribute to
* select the appropriate function at load time. This is apparently
* not supported on Android at this time. (Compiler warning that the
* ifunc attribute is ignored.)
*/
/*
* Forward FFT. Detect if NEON is supported and update function
* pointers to the correct routines for both the forward and inverse
* FFTs. Then run the forward FFT routine.
*/
static OMXResult DetectForwardRealFFT(
const OMX_F32* pSrc,
OMX_F32* pDst,
const OMXFFTSpec_R_F32* pFFTSpec) {
SetFFTRoutines();
return omxSP_FFTFwd_RToCCS_F32(pSrc, pDst, pFFTSpec);
}
/*
* Inverse FFT. Detect if NEON is supported and update function
* pointers to the correct routines for both the forward and inverse
* FFTs. Then run the inverse FFT routine.
*/
static OMXResult DetectInverseRealFFT(
const OMX_F32* pSrc,
OMX_F32* pDst,
const OMXFFTSpec_R_F32* pFFTSpec) {
SetFFTRoutines();
return omxSP_FFTInv_CCSToR_F32(pSrc, pDst, pFFTSpec);
}
/*
* Implementation of the forward and inverse real float FFT.
* Initialize to detection routine which will update the pointer to
* the correct routine and then call the correct one.
*/
OMXResult (*omxSP_FFTFwd_RToCCS_F32)(
const OMX_F32* pSrc,
OMX_F32* pDst,
const OMXFFTSpec_R_F32* pFFTSpec) = DetectForwardRealFFT;
OMXResult (*omxSP_FFTInv_CCSToR_F32)(
const OMX_F32* pSrc,
OMX_F32* pDst,
const OMXFFTSpec_R_F32* pFFTSpec) = DetectInverseRealFFT;