2

我使用 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);

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

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

更新:

虽然一半的赏金是自动分配的,但问题还没有回答。我们不知道是什么导致了这个问题以及如何避免它。

4

1 回答 1

2

该日志消息的一部分的快速谷歌发现以下代码片段,您的日志打印在中间,(完整源代码):

    // 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 的定义,第 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.

我认为,您会因为经常跳到代码赶上而收到日志消息。所以尽量不要跳得那么频繁?顺便说一句,它是一个警告日志,它会在下一次在此代码路径中赶上。

于 2014-03-07T19:28:17.767 回答