我创建的一个应用程序导致客户设备上出现大量垃圾日志:
我在 NDK 环境中使用 OpenSL 进行实时音频生成。每次我使用 SLAndroidSimpleBufferQueueItf 的 Enqueue() 函数时,android 都会创建一个日志条目,因为该调用会隐式调用音频接口(interface)上的 play()。
看起来像这样:
........app start........
06-05 21:36:48.619: I/System.out(10081): Debugger has connected
06-05 21:36:48.619: I/System.out(10081): waiting for debugger to settle...
06-05 21:36:48.819: I/System.out(10081): waiting for debugger to settle...
06-05 21:36:50.419: I/System.out(10081): waiting for debugger to settle...
06-05 21:36:50.619: I/System.out(10081): waiting for debugger to settle...
06-05 21:36:50.829: I/System.out(10081): debugger has settled (1491)
// ....some other unimportant logging stuff was here ....
06-05 21:36:53.359: D/execute(10081): Creating audio output OpenSLES
06-05 21:36:53.369: D/AudioOutputOpenSLES(10081): Creating the engine
06-05 21:36:53.369: D/AudioOutputOpenSLES(10081): Realizing engine
06-05 21:36:53.369: D/AudioOutputOpenSLES(10081): retrieving engine interface
06-05 21:36:53.369: D/AudioOutputOpenSLES(10081): Creating output mix
06-05 21:36:53.369: D/AudioOutputOpenSLES(10081): Realizing output mix
06-05 21:36:53.369: D/AudioOutputOpenSLES(10081): Configuring audio source
06-05 21:36:53.369: D/AudioOutputOpenSLES(10081): Configuring audio sink
06-05 21:36:53.369: D/AudioOutputOpenSLES(10081): Creating audio player
06-05 21:36:53.379: D/AudioOutputOpenSLES(10081): realizing the player
// Who is that? I assume Android itself....
06-05 21:36:53.379: D/AudioTrack(10081): Request AudioFlinger to create track
06-05 21:36:53.379: D/AudioOutputOpenSLES(10081): Retrieving play interface
06-05 21:36:53.379: D/AudioOutputOpenSLES(10081): get buffer queue interface
06-05 21:36:53.379: D/AudioOutputOpenSLES(10081): registering buffer queue callback
06-05 21:36:53.379: D/AudioOutputOpenSLES(10081): Retrieving effect send interface
06-05 21:36:53.379: D/AudioOutputOpenSLES(10081): getting volume interface
06-05 21:36:53.379: D/execute(10081): First process call...
06-05 21:36:53.379: D/execute(10081): Will start playback
06-05 21:36:53.379: D/play(10081): Starting playback
// And the show starts here: Every time I Enqueue audio data in my C++ code, this log entry appears.
06-05 21:36:53.379: D/AudioTrack(10081): start 0x1f7bf8
06-05 21:36:53.389: D/AudioTrack(10081): start 0x1f7bf8
06-05 21:36:53.409: D/AudioTrack(10081): start 0x1f7bf8
06-05 21:36:53.609: D/AudioTrack(10081): start 0x1f7bf8
06-05 21:36:53.629: D/AudioTrack(10081): start 0x1f7bf8
06-05 21:36:53.679: D/AudioTrack(10081): start 0x1f7bf8
06-05 21:36:53.739: D/AudioTrack(10081): start 0x1f7bf8
06-05 21:36:53.759: D/AudioTrack(10081): start 0x1f7bf8
06-05 21:36:53.819: D/AudioTrack(10081): start 0x1f7bf8
....... and so on
这就是我将新的音频缓冲区排队到 OpenSLES 的方式:
bool SE::AudioOutputOpenSLES::enqueueBuffer( void* _buffer, unsigned int _byteSize )
{
SLresult result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, _buffer, _byteSize );
return( result == SL_RESULT_SUCCESS );
}
OpenSLES 不会提示该调用并返回 SL_RESULT_SUCCESS。
我用谷歌搜索了一下,发现日志条目来 self 在此处找到的 Android 源 AudioTrack:
start() 函数的开头是日志记录:
LOGV("start %p", this);
但是是什么让 OpenSL 在每次新缓冲区入队时隐式调用 play()?我在这里查看了 OpenSL 的规范:http://www.khronos.org/registry/sles/specs/OpenSL_ES_Specification_1.0.1.pdf
在第 174 页上,他们说“当播放器处于由 SLPlayItf 接口(interface)控制的 SL_PLAYSTATE_PLAYING 状态时 [请参阅第 8.32 节],添加缓冲区将隐式开始播放。在由于队列中缓冲区不足而导致饥饿的情况下, 音频数据的播放停止。播放器保持在 SL_PLAYSTATE_PLAYING 状态。在排队额外的缓冲区时,音频数据的播放恢复。请注意,排队缓冲区的饥饿会导致音频数据流中的声音间隙。在播放器的情况下不在播放状态,添加缓冲区不启动音频播放。”
由于电话没有噼啪声,我认为音频仍然可以很好地播放并且文档中的这个描述对我来说好像他们总是隐式开始播放,这实际上意味着我没有机会阻止这个日志垃圾邮件。
有什么想法吗?
最佳答案
恕我直言,这在很大程度上取决于 Android 的版本和制造商的不同版本。
我不确定为什么最终客户对日志感到困扰,但我只是在 logcat 中创建过滤器以忽略它。简单的解决方案可能是最好的,尤其是当垃圾邮件源在 android 源中时:s
关于Android 2.3.4、OpenSL ES 和巨大的日志垃圾邮件,原因不明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16948749/