Skip to content

[wpe-2.38] Premature "finishSeek" call on "seek" operation with progressive playback #1456

@filipe-norte-red

Description

@filipe-norte-red

When performing a seek operation, the HTMLMediaElement::finishSeek() call may be triggered too early, with a "seeked" event being raised to the app at a wrong time.

The attached app reproduces the issue: test.zip

Below are logs captured using the test app (logs starting with XXX are app specific logs):

[Log] XXX: Pause video at 3.833333 (test.html, line 19)

[Log] HTMLMediaElement::pause(DC6B46A3)
[Log] HTMLMediaElement::pauseInternal(DC6B46A3)
[Log] MediaElementSession::clientWillPausePlayback(DC6B46A3)
[Log] MediaElementSession::processClientWillPausePlayback(DC6B46A3) state = Playing
[Log] MediaElementSession::setState(DC6B46A3) Paused
[Log] PlatformMediaSessionManager::sessionWillEndPlayback(0) (DC6B46A3)
[Log] HTMLMediaElement::setAutoplayEventPlaybackState(DC6B46A3) None
[Log] HTMLMediaElement::updatePlayState(DC6B46A3) shouldBePlaying = false, playerPaused = false
[Log] HTMLMediaElement::updateMediaPlayer(DC6B46A3)
[Log] PlatformMediaSessionManager::sessionCanProduceAudioChanged(0)
[Log] HTMLMediaElement::updateMediaPlayer(DC6B46A3)
[Log] HTMLMediaElement::updateMediaPlayer(DC6B46A3)
[Log] HTMLMediaElement::updateMediaPlayer(DC6B46A3)

[Log] XXX: Seek video from 3.833333 to 303.833333 (test.html, line 35)

[Log] HTMLMediaElement::seek(DC6B46A3)  – {value: 303.833333}
[Log] HTMLMediaElement::setNetworkState(DC6B46A3) new state = Loading, current state = NETWORK_IDLE
[Log] HTMLMediaElement::setReadyState(DC6B46A3) new state = HaveFutureData, current state = HAVE_ENOUGH_DATA

[Log] HTMLMediaElement::finishSeek(DC6B46A3) current time =  – {value: 3.875, numerator: 3875000000, denominator: 1000000000, …}

[Log] XXX: onSeekedEvent - SEEKED. Current time: 3.875, duration: 596.473333333 (test.html, line 59)

The code sequence that causes this is as follows:

The seek triggers a call to MediaPlayerPrivateGStreamer::doSeek(), which calls updateBufferingStatus() before performing the seek at the gst pipeline level. The updateBufferingStatus() will call updateStates() just before exiting, which in turn notifies the player of a ready state change via the call to m_player->readyStateChanged(). HTMLMediaElement::setReadyState() will be called, which will evaluate the expression below:

      if (m_seekRequested && !m_player->seeking() && m_readyState >= HAVE_CURRENT_DATA) 
          finishSeek();

The finishSeek() will be called, because the m_player->seeking() is still returning false, because the seeking state was not yet changed at the player level (m_isSeeking). It will be changed only after the doSeek() call returns, which has not happened yet

This seems to have been introduced with commit de3425a ("[GStreamer] Buffering hysteresis and buffering improvements for Broadcom")

Metadata

Metadata

Assignees

Labels

upstreamRelated to an upstream bug (or should be at some point)wpe-2.38

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions