LibMedia+LibWeb: Indicate playback states' available data with an enum

This allows us to differentiate between having no data available yet,
having current data, and having future data. The main purpose of this
is to allow a new starting state to explicitly force HAVE_METADATA
instead of >= HAVE_CURRENT_DATA.

Note that the SeekingStateHandler returns Current instead of None. This
is deliberate, since the buffered ranges from the demuxer(s) can be
used to inform whether the possibly-current data is actually available
at the seek target.
This commit is contained in:
Zaggy1024 2026-04-18 05:23:13 -05:00 committed by Gregory Bertilson
parent bedcccbdb9
commit e1e752cc28
10 changed files with 37 additions and 18 deletions

View file

@ -410,9 +410,9 @@ PlaybackState PlaybackManager::state()
return m_handler->state();
}
bool PlaybackManager::has_future_data()
AvailableData PlaybackManager::available_data()
{
return m_handler->has_future_data();
return m_handler->available_data();
}
TimeRanges PlaybackManager::buffered_time_ranges() const

View file

@ -84,7 +84,7 @@ public:
bool is_playing();
PlaybackState state();
bool has_future_data();
AvailableData available_data();
TimeRanges buffered_time_ranges() const;
void set_volume(double);

View file

@ -0,0 +1,18 @@
/*
* Copyright (c) 2025-present, the Ladybird developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Types.h>
namespace Media {
enum class AvailableData : u8 {
Current,
Future,
};
}

View file

@ -25,9 +25,9 @@ public:
{
return PlaybackState::Buffering;
}
virtual bool has_future_data() override
virtual AvailableData available_data() override
{
return false;
return AvailableData::Current;
}
virtual void enter_buffering() override

View file

@ -31,9 +31,9 @@ public:
{
return PlaybackState::Paused;
}
virtual bool has_future_data() override
virtual AvailableData available_data() override
{
return true;
return AvailableData::Future;
}
virtual void enter_buffering() override { }

View file

@ -8,6 +8,7 @@
#include <AK/Time.h>
#include <LibMedia/Forward.h>
#include <LibMedia/PlaybackStates/AvailableData.h>
#include <LibMedia/PlaybackStates/PlaybackState.h>
#include <LibMedia/SeekMode.h>
@ -30,7 +31,7 @@ public:
virtual bool is_playing() = 0;
virtual PlaybackState state() = 0;
virtual bool has_future_data() = 0;
virtual AvailableData available_data() = 0;
virtual void enter_buffering() = 0;
virtual void exit_buffering() = 0;

View file

@ -44,9 +44,9 @@ public:
{
return PlaybackState::Playing;
}
virtual bool has_future_data() override
virtual AvailableData available_data() override
{
return true;
return AvailableData::Future;
}
virtual void enter_buffering() override

View file

@ -52,9 +52,9 @@ public:
{
return PlaybackState::Seeking;
}
virtual bool has_future_data() override
virtual AvailableData available_data() override
{
return false;
return AvailableData::Current;
}
virtual void enter_buffering() override { }

View file

@ -58,9 +58,9 @@ public:
{
return PlaybackState::Suspended;
}
virtual bool has_future_data() override
virtual AvailableData available_data() override
{
return true;
return AvailableData::Future;
}
virtual void enter_buffering() override { }

View file

@ -2125,9 +2125,9 @@ void HTMLMediaElement::update_ready_state()
auto current_time = m_playback_manager->current_time();
auto ranges = m_playback_manager->buffered_time_ranges();
auto current_range = ranges.range_at_or_after(current_time);
auto has_future_data = m_playback_manager->has_future_data();
auto available_data = m_playback_manager->available_data();
if (!has_future_data && !current_range.has_value()) {
if (available_data == Media::AvailableData::Current && !current_range.has_value()) {
// 1. Set the HTMLMediaElement's readyState attribute to HAVE_METADATA.
set_ready_state(ReadyState::HaveMetadata);
// 2. Abort these steps.
@ -2146,7 +2146,7 @@ void HTMLMediaElement::update_ready_state()
// -> If HTMLMediaElement's buffered contains a TimeRanges that includes the current playback position and
// enough data to ensure uninterrupted playback:
if (has_future_data && (playable_duration >= have_enough_data_duration || current_range_end >= duration)) {
if (available_data == Media::AvailableData::Future && (playable_duration >= have_enough_data_duration || current_range_end >= duration)) {
// 1. Set the HTMLMediaElement's readyState attribute to HAVE_ENOUGH_DATA.
set_ready_state(ReadyState::HaveEnoughData);
@ -2159,7 +2159,7 @@ void HTMLMediaElement::update_ready_state()
// -> If HTMLMediaElement's buffered contains a TimeRanges that includes the current playback position and
// some time beyond the current playback position:
if (has_future_data && playable_duration > AK::Duration::zero()) {
if (available_data == Media::AvailableData::Future && playable_duration > AK::Duration::zero()) {
// 1. Set the HTMLMediaElement's readyState attribute to HAVE_FUTURE_DATA.
set_ready_state(ReadyState::HaveFutureData);