这可能是我自己的一个错误,但我似乎无法找到错误。在尝试提高应用程序的性能之后,我将音频缓冲从Java层移动到本机层。音频处理(录制/播放)已经使用OpenSL ES API本地完成。
然而,每当我启动应用程序时,本机缓冲都会导致我的应用程序崩溃。我使用一个简单的Queue实现作为我的缓冲区,其中第一个节点是最早的数据(FIFO)。
struct bufferNode{
struct bufferNode* next;
jbyte* data;
};
struct bufferQueue{
struct bufferNode* first;
struct bufferNode* last;
int size;
};
音频数据由bufferNode中的jbyte *引用。通过这两种方法访问队列,并与互斥锁同步。
void enqueueInBuffer(struct bufferQueue* queue, jbyte* data){
SLresult result;
if(queue != NULL){
if(data != NULL){
result = pthread_mutex_lock(&recMutex);
if(result != 0){
decodeMutexResult(result);
logErr("EnqueueInBuffer", "Unable to acquire recording mutex");
} else {
struct bufferNode* node = (struct bufferNode*)malloc(sizeof(struct bufferNode));
if(node == NULL){
logErr("EnqueueInBuffer", "Insufficient memory available to buffer new audio");
} else {
node->data = data;
if(queue->first == NULL){
queue->first = queue->last = node;
} else {
queue->last->next = node;
queue->last = node;
}
queue->size = queue->size + 1;
node->next = NULL;
}
}
result = pthread_mutex_unlock(&recMutex);
if(result != 0){
decodeMutexResult(result);
logErr("EnqueueInBuffer", "Unable to release recording mutex");
}
} else {
logErr("EnqueueInBuffer", "Data is NULL");
}
} else {
logErr("EnqueueInBuffer", "Queue is NULL");
}
}
void dequeueFromBuffer(struct bufferQueue* queue, jbyte* returnData){
SLresult result;
result = pthread_mutex_lock(&recMutex);
if(result != 0){
decodeMutexResult(result);
logErr("DequeueFromBuffer", "Unable to acquire recording mutex");
} else {
if(queue->first == NULL){
returnData = NULL;
} else {
returnData = queue->first->data;
struct bufferNode* tmp = queue->first;
if(queue->first == queue->last){
queue->first = queue->last = NULL;
} else {
queue->first = queue->first->next;
}
free(tmp);
queue->size = queue->size - 1;
}
}
result = pthread_mutex_unlock(&recMutex);
if(result != 0){
decodeMutexResult(result);
logErr("DequeueFromBuffer", "Unable to release recording mutex");
}
}
但是当我尝试将音频数据排入队列时,我仍然遇到错误。每当我调用enqueueInBuffer
方法时,我都会收到SIGSEGV本机错误,代码为1(SEGV_MAPERR)。但我似乎无法找到导致错误的原因。当我尝试进行enqueueInBuffer
方法调用(在OpenSL ES Recorder回调中完成,因此同步)时,存在队列和音频数据。
是否有其他因素导致分段错误?可能我对此负责,但我似乎无法找到错误。
答案 0 :(得分:1)
显然,这是由我在OpenSL ES Recorder回调中的一行代码引起的。
回调最初看起来像这样:
void recorderCallback(SLAndroidSimpleBufferQueueItf bq, void *context){
SLresult result;
enqueueInBuffer(&recordingQueue, (*recorderBuffers[queueIndex]));
result = (*bq)->Enqueue(bq, recorderBuffers[queueIndex], RECORDER_FRAMES * sizeof(jbyte));
if(checkError(result, "RecorderCallB", "Unable to enqueue new buffer on recorder") == -1){
return;
}
queueIndex = queueIndex++ % MAX_RECORDER_BUFFERS;
}
但是,似乎回调的最后一行没有正确创建新索引。我使用的缓冲区是一个数组,长4个。
将最后一行更改为
queueIndex = (queueIndex + 1) % MAX_RECORDER_BUFFERS;
似乎修复了错误。