Skip to content

Make changing to HAVE_ENOUGH_DATA ready state specification complaint #40740

@tharkum

Description

@tharkum

Describe the bug:
Currently changing ready state of the media element to HAVE_ENOUGH_DATA happens in one possible case if
the media player state is PlaybackState::Paused and ready state is HAVE_METADATA.
https://html.spec.whatwg.org/multipage/media.html#dom-media-have_metadata
https://html.spec.whatwg.org/multipage/media.html#dom-media-have_enough_data

fn playback_state_changed(&self, state: &PlaybackState) {

    fn playback_state_changed(&self, state: &PlaybackState) {
        let mut media_session_playback_state = MediaSessionPlaybackState::None_;
        match *state {
            PlaybackState::Paused => {
                media_session_playback_state = MediaSessionPlaybackState::Paused;
                if self.ready_state.get() == ReadyState::HaveMetadata {
                    self.change_ready_state(ReadyState::HaveEnoughData);
                }
            },
            ...
     }

Need to figure out how to remove gstreamer dependency from the media element carefully and based it on buffering state of the media source?!
https://html.spec.whatwg.org/multipage/media.html#event-media-canplaythrough


For now it works due to some undocumented functionality in servo-media source code
https://github.com/servo/media/blob/main/backends/gstreamer/player.rs#L604

This gst_play_set_rate triggers the unexpected (unnecessary) seek request to current pipeline position (0.0) and changing player state from paused to buffering to paused (the latest one event allows the media element to set ready state to HAVE_ENOUGH_DATA).

Note that changing playback rate make new seek request to current position with new value (with seek completion event afterwards).

gst_play_set_rate
gst_play_set_rate_internal

0:02.62 pid:3989830 HTMLMediaElement (0x7fa1a76c2500) create_media_player gen_id = 1
0:02.62 pid:3989830  GST connect_state_changed: player_state = Buffering
0:02.62 pid:3989830  HTMLMediaElement fetch_request.url = "http://web-platform.test:8000/media/movie_5.mp4?Wed%20Nov%2019%202025%2016:08:30%20GMT+0300%20(Moscow%20Standard%20Time)0.025068950373179355"

0:02.62 pid:3989830  process_response request_id = RequestId(4c040425-65d4-4141-9002-4fd6fba7d41c
0:02.62 pid:3989830  process_response_eof  request_id = RequestId(4c040425-65d4-4141-9002-4fd6fba7d41c) fetched_content_length = 31603

0:02.62 pid:3989830  GST connect_state_changed: player_state = Paused
0:02.68 pid:3989830  GST connect_media_info_updated + SET_RATE
0:02.68 pid:3989830  GST connect_duration_changed: duration = Some(0:00:05.153333333)

0:02.68 pid:3989830  HTMLMediaElement (0x7fa1a76c2500) change_ready_state [HaveNothing -> HaveMetadata]

0:02.68 pid:3989830  GST connect_state_changed: player_state = Buffering
0:02.68 pid:3989830  GST connect_seek_done: position = 0:00:00.000000000
0:02.68 pid:3989830  GST connect_state_changed: player_state = Paused

0:02.68 pid:3989830  HTMLMediaElement (0x7fa1a76c2500) change_ready_state [HaveMetadata -> HaveEnoughData]

To Reproduce:
Run the following test
./mach test-wpt tests/wpt/tests/html/semantics/embedded-content/media-elements/event_timeupdate_noautoplay.html -r --log-mach=-

Platform:
Ubuntu 22.04

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions