我在Android中使用openSLES的原生录音机。记录器工作,但是当调用stop方法时,它似乎继续写缓冲区,因为我继续获取日志:
...
08-07 01:36:43.229: V/AudioRecord(6194): Overrun user: 61400, server: 61c00, flags 0001
08-07 01:36:43.239: V/AudioRecord(6194): Overrun user: 61400, server: 61c00, flags 0001
08-07 01:36:43.249: V/AudioRecord(6194): Overrun user: 61400, server: 61c00, flags 0001
...
我正在使用线程锁定方法来记录缓冲区,但为什么我在停止录制器后获取这些日志,如下所示:
typedef struct opensl_stream {
...
SLObjectItf recorderObject;
SLRecordItf recorderRecord;
SLAndroidSimpleBufferQueueItf recorderBufferQueue;
...
} OPENSL_STREAM;
OPENSL_STREAM *p;
//starting recorder
...
//stopping recorder
if (p->recorderObject != NULL) {
(*p->recorderObject)->Destroy(p->recorderObject);
p->recorderObject = NULL;
p->recorderRecord = NULL;
p->recorderBufferQueue = NULL;
}
在尝试如上所述停止录像机之后,我仍然得到AudioRecord(6194): Overrun user
日志,这意味着缓冲区被读取但未被使用。如何正确停止录制?
答案 0 :(得分:2)
首先,你应该在摧毁它之前停止录音机,但这还不够。
由于从自己的线程调用OpenSL回调,因此从另一个线程停止记录并不意味着所有回调都会立即停止。 (或者不会调用新的回调。)因此,您必须“计算”您排队的缓冲区数量,因此在回调中您可以计算处理的回调数量。
所以伪代码看起来像这样:
SL_RECORDSTATE_STOPPED
来停止记录器,不要将更多缓冲区队列排入队列。当排队缓冲区时,并且在opensl回调结束时,您必须以线程安全的方式自己计算排队/处理的缓冲区队列。
您可以在等待所有处理过程中使用pthread互斥/条件/广播。 (或者你可以使用一个简单的while循环,其中一些在里面睡觉。)