ladybird/Libraries/LibMedia/ReadonlyBytesCursor.h
Zaggy1024 f62af69dcd LibMedia: Allow MediaStreamCursor to never block on missing data
This is necessary to allow the main thread to read out frames to
determine the buffered ranges, without affecting the request position
of an IncrementallyPopulatedStream or causing a deadlock waiting for
data to come in.
2026-05-28 10:30:20 -05:00

70 lines
2 KiB
C++

/*
* Copyright (c) 2026-present, the Ladybird developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Span.h>
#include <LibMedia/DecoderError.h>
#include <LibMedia/MediaStream.h>
namespace Media {
class ReadonlyBytesCursor final : public MediaStreamCursor {
public:
ReadonlyBytesCursor(ReadonlyBytes data)
: m_data(data)
{
}
virtual void set_is_blocking(bool) override { }
virtual DecoderErrorOr<void> seek(i64 offset, AK::SeekMode mode) override
{
auto target_position = [&] -> size_t {
switch (mode) {
case AK::SeekMode::SetPosition:
return offset;
case AK::SeekMode::FromCurrentPosition:
return m_position + offset;
case AK::SeekMode::FromEndPosition:
return m_data.size() + offset;
}
VERIFY_NOT_REACHED();
}();
if (target_position > m_data.size())
return DecoderError::with_description(DecoderErrorCategory::EndOfStream, "End of buffer"sv);
m_position = target_position;
return {};
}
virtual DecoderErrorOr<size_t> read_into(Bytes bytes) override
{
if (m_position >= m_data.size())
return DecoderError::with_description(DecoderErrorCategory::EndOfStream, "End of buffer"sv);
auto available = m_data.size() - m_position;
if (available < bytes.size())
return DecoderError::with_description(DecoderErrorCategory::EndOfStream, "End of buffer"sv);
auto to_read = bytes.size();
m_data.slice(m_position, to_read).copy_to(bytes);
m_position += to_read;
VERIFY(m_position <= m_data.size());
return to_read;
}
virtual size_t position() const override { return m_position; }
virtual size_t size() const override { return m_data.size(); }
void set_data(ReadonlyBytes data) { m_data = data; }
private:
ReadonlyBytes m_data;
size_t m_position { 0 };
};
}