“错过了SL_PLAYEVENT_HEADATNEWPOS for position”消息

时间:2014-03-05 07:57:46

标签: android audio opensl

我使用OpenSL ES编写了一个音乐播放器。除了来自libOpenSLES库的一条警告消息之外,它工作正常。这是信息。

03-05 00:10:15.367: W/libOpenSLES(12055): Missed SL_PLAYEVENT_HEADATNEWPOS for position 7000; current position 724009
...
03-05 00:10:27.226: W/libOpenSLES(12055): Missed SL_PLAYEVENT_HEADATNEWPOS for position 329015; current position 816013

当我寻找媒体曲目时。有时我可以在没有警告的情况下寻求,有时消息会出现在日志中。

实施非常简单。在初始化时,我选择了搜索控件。

SLObjectItf decoder;
SLSeekItf seek;
...

SLresult result = (*decoder)->GetInterface(decoder, SL_IID_SEEK, &seek);

然后,当用户更改曲目位置时,我会调用SetPosition方法,如下所示。

SLresult result = (*seek)->SetPosition(seek, position, SL_SEEKMODE_ACCURATE);

两个调用都返回成功结果,并且位置更改也一直有效。唯一的问题是上面提到的警告信息。

为什么会出现此消息以及如何避免此消息?

更新:

虽然自动分配了一半赏金,但问题尚未得到解答。我们不知道导致问题的原因以及如何避免这个问题。

1 个答案:

答案 0 :(得分:2)

快速谷歌的部分日志消息发现以下代码剪辑,您的日志打印在中间,(complete source):

    // nextVirtualMarkerMs will be set to the position of the next upcoming virtual marker
    int32_t nextVirtualMarkerMs;
    if (mObservedPositionMs <= virtualMarkerMs && virtualMarkerMs <= positionMs) {
        // we did pass through the virtual marker, now compute the next virtual marker
        mDeliveredNewPosMs = virtualMarkerMs;
        nextVirtualMarkerMs = virtualMarkerMs + mPositionUpdatePeriodMs;
        // re-synchronize if we missed an update
        if (nextVirtualMarkerMs <= positionMs) {
            SL_LOGW("Missed SL_PLAYEVENT_HEADATNEWPOS for position %d; current position %d",
                    nextVirtualMarkerMs, positionMs);
            // try to catch up by setting next goal to current position plus update period
            mDeliveredNewPosMs = positionMs;
            nextVirtualMarkerMs = positionMs + mPositionUpdatePeriodMs;
        }
        notify(PLAYEREVENT_PLAY, (int32_t) SL_PLAYEVENT_HEADATNEWPOS, true /*async*/);

如果您搜索通过某个点,则会有一些赶上(跳转)并且可能缺少更新,这就是日志所说的,我们需要重新同步标记位置。

<强>更新 上面的整个代码片段用于计算oneshot(一个稳定的临时状态)暂停时间,如果解释代码正确,oneshot, row 116的定义:

    // deferred (non-0 timeout) handler for SL_PLAYEVENT_*
    // As used here, "one-shot" is the software equivalent of a "retriggerable monostable
    // multivibrator" from electronics.  Briefly, a one-shot is a timer that can be triggered
    // to fire at some point in the future.  It is "retriggerable" because while the timer
    // is active, it is possible to replace the current timeout value by a new value.
    // This is done by cancelling the current timer (using a generation count),
    // and then posting another timer with the new desired value.

我得到了日志消息,因为我经常跳到常常让代码赶上来,我想。所以尽量不要经常跳?顺便说一下,它是一个警告日志,它将在下一次代码路径中赶上。