4

我创建的一个应用程序会在客户的设备上引发大量垃圾日志:

我在 NDK 环境中使用 OpenSL 来生成实时音频。每次我使用 SLAndroidSimpleBufferQueueItf 的 Enqueue() 函数时,android 都会创建一个日志条目,因为该调用会隐式调用音频接口上的 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。

我用谷歌搜索了一下,发现日志条目来自 Android 源 AudioTrack,我在这里找到了它:

https://android.googlesource.com/platform/frameworks/base/+/android-2.2.3_r2.1/media/libmedia/AudioTrack.cpp

start() 函数的开头是日志记录:

LOGV("start %p", this);

但是,是什么让 OpenSL 在每次新缓冲区入队时都隐式调用 play() 呢?我在这里查看了 OpenSL 的规范:http ://www.khronos.org/registry/sles/specs/OpenSL_ES_Specification_1.0.1.pdf

在第 174 页上,他们说“当播放器处于 SL_PLAYSTATE_PLAYING 状态时,由 SLPlayItf 接口控制 [参见第 8.32 节],添加缓冲区将隐式开始播放。在由于队列中缓冲区不足而导致饥饿的情况下,播放音频数据停止。播放器保持在 SL_PLAYSTATE_PLAYING 状态。在附加缓冲区排队时,音频数据的播放恢复。请注意,排队缓冲区的饥饿会导致音频数据流中的可听间隙。如果播放器不在播放状态,添加缓冲区不会开始音频播放。"

由于手机没有噼啪作响,我认为音频仍然可以很好地播放,并且文档中的这个描述对我来说听起来好像它们总是隐式地开始播放,这实际上意味着我没有机会阻止这种日志垃圾邮件。

有任何想法吗?

4

2 回答 2

0

恕我直言,这在很大程度上取决于 Android 的版本和版本,从制造商到制造商。

我不确定为什么最终客户会为日志而烦恼,但我只会在 logcat 中进行过滤以忽略它。简单的解决方案可能是最好的,尤其是当垃圾邮件的来源是 android 的来源时:s

于 2013-09-03T07:13:04.813 回答
0

主要取决于设备的供应商。请在不同的设备上尝试,可能您不会看到这些日志,但您可以体验到不同的日志。除了向 LogCat 添加过滤器之外,您不能做任何事情。

于 2013-11-19T07:54:38.987 回答