Android ndk Android NDK Libspeex导致神秘的本机崩溃

Android ndk Android NDK Libspeex导致神秘的本机崩溃,android-ndk,Android Ndk,我想在我的android应用程序中使用libspeex,所以我基本上是从将库复制到项目中。然后我写了一个简单的jni: #include <jni.h> #include <android/log.h> #include <include/speex/speex_bits.h> #include <include/speex/speex.h> #include <stdlib.h> #include <string.h>

我想在我的android应用程序中使用libspeex,所以我基本上是从将库复制到项目中。然后我写了一个简单的jni:

#include <jni.h>
#include <android/log.h>
#include <include/speex/speex_bits.h>
#include <include/speex/speex.h>
#include <stdlib.h>
#include <string.h>

SpeexBits enc_bits, dec_bits;
void* enc_state = NULL;
void* dec_state = NULL;
int frame_size = 0;

JNIEXPORT jint JNICALL
Java_dt_test_Codec_encode(JNIEnv *env, jclass type, jshortArray input_, jbyteArray output_)
{
    if(enc_state == NULL)
    {
        return 0;
    }

    //check the input size is correct
    int input_size = (int)(*env)->GetArrayLength(env, input_);
    if(input_size != frame_size)
    {
        return 0;
    }

    //encode
    jshort* input = (*env)->GetShortArrayElements(env, input_, NULL);
    speex_bits_reset(&enc_bits);
    speex_encode_int(enc_state, input, &enc_bits);

    //write output
    int nbBytes = 0;
    char* output = (char*)malloc((size_t)frame_size); //output can't be bigger than the input
    memset(output, 0, (size_t)frame_size);
    nbBytes = speex_bits_write(&enc_bits, output, frame_size);
    (*env)->SetByteArrayRegion(env, output_, 0, nbBytes, (jbyte*)output);

    //cleanup
    free(output);
    (*env)->ReleaseShortArrayElements(env, input_, input, 0);
    return  nbBytes;
}

JNIEXPORT void JNICALL
Java_dt_test_Codec_closeEncoder(JNIEnv *env, jclass type)
{
    speex_bits_destroy(&enc_bits);
    speex_encoder_destroy(enc_state);
    enc_state = NULL;
    memset(&enc_bits, 0, sizeof(enc_bits));
    frame_size = 0;
}

JNIEXPORT jint JNICALL
Java_dt_test_Codec_getFramesize(JNIEnv *env, jclass type)
{
    return frame_size;
}

JNIEXPORT void JNICALL
Java_dt_test_Codec_decode(JNIEnv *env, jclass type, jbyteArray input_, jshortArray output_)
{
    if(dec_state == NULL)
    {
        return;
    }

    jbyte* input = (*env)->GetByteArrayElements(env, input_, NULL);
    int input_size = (int)(*env)->GetArrayLength(env, input_);
    speex_bits_read_from(&dec_bits, (char*)input, input_size);
    short* output = (short*)malloc((size_t)frame_size);
    speex_decode_int(dec_state, &dec_bits, output);
    (*env)->SetShortArrayRegion(env, output_, 0, frame_size, output);

    (*env)->ReleaseByteArrayElements(env, input_, input, 0);
    free(output);
}

JNIEXPORT void JNICALL
Java_dt_test_Codec_closeDecoder(JNIEnv *env, jclass type)
{
    speex_bits_destroy(&dec_bits);
    speex_decoder_destroy(dec_state);
    dec_state = NULL;
    memset(&dec_bits, 0, sizeof(dec_bits));
}

JNIEXPORT void JNICALL
Java_dt_test_Codec_initEncoder(JNIEnv *env, jclass type)
{
    //cleanup old stuff if necessary
    if(enc_state != NULL)
    {
        Java_dt_test_Codec_closeEncoder(env, NULL);
    }

    //setup encoder
    speex_bits_init(&enc_bits);
    enc_state = speex_encoder_init(&speex_uwb_mode);
    speex_encoder_ctl(enc_state, SPEEX_GET_FRAME_SIZE, &frame_size);
    int quality = 7;
    speex_encoder_ctl(enc_state, SPEEX_SET_QUALITY, &quality);
}

JNIEXPORT void JNICALL
Java_dt_test_Codec_initDecoder(JNIEnv *env, jclass type)
{
    //cleanup old stuff if necessary
    if(dec_state != NULL)
    {
        Java_dt_test_Codec_closeDecoder(env, NULL);
    }

    //setup decoder
    speex_bits_init(&dec_bits);
    dec_state = speex_decoder_init(&speex_uwb_mode);
}

在调试模式下运行您的代码。您将能够看到有关seg FAULT的更多信息。我已经这样做了。这就是我如何知道错误地址、它发生在渲染线程上的事实以及堆栈跟踪由调试器报告为未知帧的内容组成。
                    Codec.initEncoder();
                    Codec.initDecoder();
                    WAVBUFFERSHORTS = Codec.getFramesize();

                    while (true)
                    {
                        short[] wavshorts = new short[WAVBUFFERSHORTS];


                        Codec.encode(wavshorts, encbuffer);
                        short[] reconstruct = new short[WAVBUFFERSHORTS];
                        Codec.decode(encbuffer, reconstruct);