Сообщение "Пропущенный SL_PLAYEVENT_HEADATNEWPOS для позиции"
Я написал музыкальный проигрыватель, используя 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 ответ
Быстрый гугл части этого сообщения журнала обнаружил следующий фрагмент кода с распечаткой журнала в середине здесь ( полный исходный код):
// 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*/);
Если вы выполняете поиск, проходя определенную точку, нужно наверстать упущенное (прыжок) и, возможно, обновление было пропущено, это то, что указывает журнал, что нам нужно повторно синхронизировать положение маркера.
Обновление Весь фрагмент кода, приведенный выше, предназначен для расчета времени паузы с однократным выстрелом (стабильное временное состояние), если интерпретировать код правильно, определение сингла, строка 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.
Я думаю, что вы получаете сообщение журнала из-за частого перехода к коду, чтобы наверстать упущенное. Так стараться не прыгать так часто? Между прочим, это журнал предупреждений, который в следующий раз перехватит этот путь кода.