#ifndef MEDIA_GPU_TEST_VIDEO_PLAYER_DECODER_WRAPPER_H_
#define MEDIA_GPU_TEST_VIDEO_PLAYER_DECODER_WRAPPER_H_
#include <stdint.h>
#include <map>
#include <memory>
#include <vector>
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "base/synchronization/waitable_event.h"
#include "base/task/single_thread_task_runner.h"
#include "media/base/decoder_status.h"
#include "media/base/video_decoder.h"
#include "media/base/video_decoder_config.h"
#include "media/gpu/test/video_player/decoder_listener.h"
namespace media {
class VideoFrame;
namespace test {
class VideoBitstream;
class EncodedDataHelper;
class FrameRendererDummy;
class VideoFrameProcessor;
enum class DecoderImplementation {
kVDA,
kVD,
kVDVDA,
};
struct DecoderWrapperConfig {
size_t max_outstanding_decode_requests = 1;
DecoderImplementation implementation = DecoderImplementation::kVDA;
bool linear_output = false;
bool ignore_resolution_changes_to_smaller_vp9 = false;
};
class DecoderWrapper {
public:
DecoderWrapper(const DecoderWrapper&) = delete;
DecoderWrapper& operator=(const DecoderWrapper&) = delete;
~DecoderWrapper();
static std::unique_ptr<DecoderWrapper> Create(
const DecoderListener::EventCallback& event_cb,
std::unique_ptr<FrameRendererDummy> frame_renderer,
std::vector<std::unique_ptr<VideoFrameProcessor>> frame_processors,
const DecoderWrapperConfig& config);
bool WaitForFrameProcessors();
void WaitForRenderer();
void Initialize(const VideoBitstream* video);
void Play();
void Flush();
void Reset();
private:
enum class DecoderWrapperState : size_t {
kUninitialized = 0,
kIdle,
kDecoding,
kFlushing,
kResetting,
};
DecoderWrapper(
const DecoderListener::EventCallback& event_cb,
std::unique_ptr<FrameRendererDummy> renderer,
std::vector<std::unique_ptr<VideoFrameProcessor>> frame_processors,
const DecoderWrapperConfig& config);
void CreateDecoder();
void CreateDecoderTask(base::WaitableEvent* done);
void DestroyDecoderTask(base::WaitableEvent* done);
void InitializeTask(const VideoBitstream* video, base::WaitableEvent* done);
void PlayTask();
void FlushTask();
void ResetTask();
void DecodeNextFragmentTask();
void OnDecoderInitializedTask(DecoderStatus status);
void OnDecodeDoneTask(DecoderStatus status);
void OnFrameReadyTask(scoped_refptr<VideoFrame> video_frame);
void OnFlushDoneTask(DecoderStatus status);
void OnResetDoneTask();
bool OnResolutionChangedTask();
bool FireEvent(DecoderListener::Event event);
SEQUENCE_CHECKER(parent_sequence_checker_);
SEQUENCE_CHECKER(worker_sequence_checker_);
DecoderListener::EventCallback event_cb_;
std::unique_ptr<FrameRendererDummy> frame_renderer_;
std::vector<std::unique_ptr<VideoFrameProcessor>> frame_processors_;
std::unique_ptr<media::VideoDecoder> decoder_
GUARDED_BY_CONTEXT(worker_sequence_checker_);
const DecoderWrapperConfig decoder_wrapper_config_;
const scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner_;
DecoderWrapperState state_ GUARDED_BY_CONTEXT(worker_sequence_checker_);
size_t current_frame_index_ = 0;
size_t num_outstanding_decode_requests_ = 0;
std::unique_ptr<media::test::EncodedDataHelper> encoded_data_helper_;
VideoCodec input_video_codec_;
VideoCodecProfile input_video_profile_;
base::WeakPtr<DecoderWrapper> weak_this_;
base::WeakPtrFactory<DecoderWrapper> weak_this_factory_{this};
};
}
}
#endif