blob: bcf5e3542a72e79e6ee8b4409c54725269d39984 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MEDIA_GPU_TEST_VIDEO_PLAYER_TEST_VDA_VIDEO_DECODER_H_
#define MEDIA_GPU_TEST_VIDEO_PLAYER_TEST_VDA_VIDEO_DECODER_H_
#include <stdint.h>
#include <map>
#include <memory>
#include "base/containers/mru_cache.h"
#include "base/macros.h"
#include "base/sequence_checker.h"
#include "gpu/ipc/service/gpu_memory_buffer_factory.h"
#include "media/base/video_decoder.h"
#include "media/gpu/test/video_player/video_decoder_client.h"
#include "media/media_buildflags.h"
#include "media/video/video_decode_accelerator.h"
namespace media {
class VideoFrame;
namespace test {
class FrameRenderer;
// The test VDA video decoder translates between the media::VideoDecoder and the
// media::VideoDecodeAccelerator interfaces. This makes it possible to run
// VD-based tests against VDA's.
class TestVDAVideoDecoder : public media::VideoDecoder,
public VideoDecodeAccelerator::Client {
public:
// Constructor for the TestVDAVideoDecoder.
TestVDAVideoDecoder(bool use_vd_vda,
const gfx::ColorSpace& target_color_space,
FrameRenderer* const frame_renderer,
gpu::GpuMemoryBufferFactory* gpu_memory_buffer_factory);
TestVDAVideoDecoder(const TestVDAVideoDecoder&) = delete;
TestVDAVideoDecoder& operator=(const TestVDAVideoDecoder&) = delete;
~TestVDAVideoDecoder() override;
// media::VideoDecoder implementation
VideoDecoderType GetDecoderType() const override;
bool IsPlatformDecoder() const override;
void Initialize(const VideoDecoderConfig& config,
bool low_delay,
CdmContext* cdm_context,
InitCB init_cb,
const OutputCB& output_cb,
const WaitingCB& waiting_cb) override;
void Decode(scoped_refptr<DecoderBuffer> buffer, DecodeCB decode_cb) override;
void Reset(base::OnceClosure reset_cb) override;
bool NeedsBitstreamConversion() const override;
bool CanReadWithoutStalling() const override;
int GetMaxDecodeRequests() const override;
private:
// media::VideoDecodeAccelerator::Client implementation
void NotifyInitializationComplete(Status status) override;
void ProvidePictureBuffers(uint32_t requested_num_of_buffers,
VideoPixelFormat format,
uint32_t textures_per_buffer,
const gfx::Size& dimensions,
uint32_t texture_target) override;
void ProvidePictureBuffersWithVisibleRect(uint32_t requested_num_of_buffers,
VideoPixelFormat format,
uint32_t textures_per_buffer,
const gfx::Size& dimensions,
const gfx::Rect& visible_rect,
uint32_t texture_target) override;
void DismissPictureBuffer(int32_t picture_buffer_id) override;
void PictureReady(const Picture& picture) override;
void ReusePictureBufferTask(int32_t picture_buffer_id);
void NotifyEndOfBitstreamBuffer(int32_t bitstream_buffer_id) override;
void NotifyFlushDone() override;
void NotifyResetDone() override;
void NotifyError(VideoDecodeAccelerator::Error error) override;
// Helper thunk to avoid dereferencing WeakPtrs on the wrong thread.
static void ReusePictureBufferThunk(
absl::optional<base::WeakPtr<TestVDAVideoDecoder>> decoder_client,
scoped_refptr<base::SequencedTaskRunner> task_runner,
int32_t picture_buffer_id);
// Get the next bitstream buffer id to be used.
int32_t GetNextBitstreamBufferId();
// Get the next picture buffer id to be used.
int32_t GetNextPictureBufferId();
// Called when initialization is done. The callback is stored only when VDA
// allows deferred initialization.
InitCB init_cb_;
// Called when a buffer is decoded.
OutputCB output_cb_;
// Called when the decoder finished flushing.
DecodeCB flush_cb_;
// Called when the decoder finished resetting.
base::OnceClosure reset_cb_;
// Whether VdVideoDecodeAccelerator is used.
bool use_vd_vda_;
// Output color space, used as hint to decoder to avoid conversions.
const gfx::ColorSpace target_color_space_;
// Frame renderer used to manage GL context.
FrameRenderer* const frame_renderer_;
#if BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION)
// Owned by VideoDecoderClient.
gpu::GpuMemoryBufferFactory* const gpu_memory_buffer_factory_;
#endif // BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION)
// Map of video frames the decoder uses as output, keyed on picture buffer id.
std::map<int32_t, scoped_refptr<VideoFrame>> video_frames_;
// Map of video frame decoded callbacks, keyed on bitstream buffer id.
std::map<int32_t, DecodeCB> decode_cbs_;
// Records the time at which each bitstream buffer decode operation started.
base::MRUCache<int32_t, base::TimeDelta> decode_start_timestamps_;
int32_t next_bitstream_buffer_id_ = 0;
int32_t next_picture_buffer_id_ = 0;
std::unique_ptr<VideoDecodeAccelerator> decoder_;
scoped_refptr<base::SequencedTaskRunner> vda_wrapper_task_runner_;
SEQUENCE_CHECKER(vda_wrapper_sequence_checker_);
base::WeakPtr<TestVDAVideoDecoder> weak_this_;
base::WeakPtrFactory<TestVDAVideoDecoder> weak_this_factory_{this};
};
} // namespace test
} // namespace media
#endif // MEDIA_GPU_TEST_VIDEO_PLAYER_TEST_VDA_VIDEO_DECODER_H_