mirror of
https://github.com/zebrajr/ladybird.git
synced 2025-12-06 12:20:00 +01:00
130 lines
4.0 KiB
C++
130 lines
4.0 KiB
C++
/*
|
|
* Copyright (c) 2022-2025, Gregory Bertilson <gregory@ladybird.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <AK/AtomicRefCounted.h>
|
|
#include <AK/Forward.h>
|
|
#include <AK/NonnullRefPtr.h>
|
|
#include <AK/Stream.h>
|
|
#include <AK/Time.h>
|
|
#include <AK/Vector.h>
|
|
#include <LibMedia/DecoderError.h>
|
|
#include <LibMedia/Export.h>
|
|
#include <LibMedia/Forward.h>
|
|
#include <LibMedia/Providers/MediaTimeProvider.h>
|
|
#include <LibMedia/Track.h>
|
|
#include <LibThreading/Mutex.h>
|
|
|
|
namespace Media {
|
|
|
|
class MEDIA_API PlaybackManager final : public AtomicRefCounted<PlaybackManager> {
|
|
AK_MAKE_NONCOPYABLE(PlaybackManager);
|
|
AK_MAKE_NONMOVABLE(PlaybackManager);
|
|
|
|
class WeakPlaybackManager;
|
|
|
|
public:
|
|
static constexpr size_t EXPECTED_VIDEO_TRACK_COUNT = 1;
|
|
|
|
using VideoTracks = Vector<Track, EXPECTED_VIDEO_TRACK_COUNT>;
|
|
|
|
static constexpr size_t EXPECTED_AUDIO_TRACK_COUNT = 1;
|
|
|
|
using AudioTracks = Vector<Track, EXPECTED_AUDIO_TRACK_COUNT>;
|
|
|
|
static DecoderErrorOr<NonnullRefPtr<PlaybackManager>> try_create(ReadonlyBytes data);
|
|
~PlaybackManager();
|
|
|
|
AK::Duration current_time() const { return m_time_provider->current_time(); }
|
|
AK::Duration duration() const;
|
|
|
|
VideoTracks const& video_tracks() const { return m_video_tracks; }
|
|
Optional<Track> preferred_video_track();
|
|
|
|
VideoTracks const& audio_tracks() const { return m_audio_tracks; }
|
|
Optional<Track> preferred_audio_track();
|
|
|
|
// Creates a DisplayingVideoSink for the specified track.
|
|
//
|
|
// Note that in order for the current frame to change based on the media time, users must call
|
|
// DisplayingVideoSink::update(). It is recommended to drive this off of vertical sync.
|
|
NonnullRefPtr<DisplayingVideoSink> get_or_create_the_displaying_video_sink_for_track(Track const& track);
|
|
// Removes the DisplayingVideoSink for the specified track. This will prevent the sink from
|
|
// retrieving any subsequent frames from the decoder.
|
|
void remove_the_displaying_video_sink_for_track(Track const& track);
|
|
|
|
void enable_an_audio_track(Track const& track);
|
|
void disable_an_audio_track(Track const& track);
|
|
|
|
void play();
|
|
void pause();
|
|
|
|
Function<void(DecoderError&&)> on_error;
|
|
|
|
private:
|
|
class WeakPlaybackManager : public AtomicRefCounted<WeakPlaybackManager> {
|
|
friend class PlaybackManager;
|
|
|
|
public:
|
|
WeakPlaybackManager() = default;
|
|
|
|
RefPtr<PlaybackManager> take_strong() const
|
|
{
|
|
Threading::MutexLocker locker { m_mutex };
|
|
return m_manager;
|
|
}
|
|
|
|
private:
|
|
void revoke()
|
|
{
|
|
Threading::MutexLocker locker { m_mutex };
|
|
m_manager = nullptr;
|
|
}
|
|
|
|
mutable Threading::Mutex m_mutex;
|
|
PlaybackManager* m_manager { nullptr };
|
|
};
|
|
|
|
struct VideoTrackData {
|
|
Track track;
|
|
NonnullRefPtr<VideoDataProvider> provider;
|
|
RefPtr<DisplayingVideoSink> display;
|
|
};
|
|
using VideoTrackDatas = Vector<VideoTrackData, EXPECTED_VIDEO_TRACK_COUNT>;
|
|
|
|
struct AudioTrackData {
|
|
Track track;
|
|
NonnullRefPtr<AudioDataProvider> provider;
|
|
};
|
|
using AudioTrackDatas = Vector<AudioTrackData, EXPECTED_AUDIO_TRACK_COUNT>;
|
|
|
|
PlaybackManager(NonnullRefPtr<MutexedDemuxer> const&, NonnullRefPtr<WeakPlaybackManager> const&, NonnullRefPtr<MediaTimeProvider> const&, VideoTracks&&, VideoTrackDatas&&, RefPtr<AudioMixingSink> const&, AudioTracks&&, AudioTrackDatas&&);
|
|
|
|
void set_up_error_handlers();
|
|
void dispatch_error(DecoderError&&);
|
|
|
|
VideoTrackData& get_video_data_for_track(Track const& track);
|
|
AudioTrackData& get_audio_data_for_track(Track const& track);
|
|
|
|
NonnullRefPtr<MutexedDemuxer> m_demuxer;
|
|
|
|
NonnullRefPtr<WeakPlaybackManager> m_weak_wrapper;
|
|
|
|
NonnullRefPtr<MediaTimeProvider> m_time_provider;
|
|
|
|
VideoTracks m_video_tracks;
|
|
VideoTrackDatas m_video_track_datas;
|
|
|
|
RefPtr<AudioMixingSink> m_audio_sink;
|
|
AudioTracks m_audio_tracks;
|
|
AudioTrackDatas m_audio_track_datas;
|
|
|
|
bool m_is_in_error_state { false };
|
|
};
|
|
|
|
}
|