blob: abe529147f67cdaf2d81d40e13a33b77efa8a99b [file] [log] [blame]
// Copyright 2018 The Chromium Authors
// 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_FRAME_RENDERER_DUMMY_H_
#define MEDIA_GPU_TEST_VIDEO_PLAYER_FRAME_RENDERER_DUMMY_H_
#include <memory>
#include "base/cancelable_callback.h"
#include "base/containers/queue.h"
#include "base/sequence_checker.h"
#include "base/synchronization/condition_variable.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
#include "media/base/video_types.h"
#include "ui/gfx/geometry/size.h"
namespace media {
class VideoFrame;
namespace test {
// The dummy frame renderer can be used when we're not interested in rendering
// the decoded frames to screen or file. The renderer can either consume frames
// immediately, or introduce a delay to simulate actual rendering.
class FrameRendererDummy {
public:
FrameRendererDummy(const FrameRendererDummy&) = delete;
FrameRendererDummy& operator=(const FrameRendererDummy&) = delete;
~FrameRendererDummy();
// Create an instance of the dummy frame renderer. |frame_duration| specifies
// how long we will simulate displaying each frame, typically the inverse of
// the stream's frame rate. If 0 no rendering will be simulated and frames
// will be returned to the decoder immediately. |vsync_interval_duration|
// specifies the desired VSync interval. If 0 VSync will be disabled.
static std::unique_ptr<FrameRendererDummy> Create(
base::TimeDelta frame_duration = base::TimeDelta(),
base::TimeDelta vsync_interval_duration = base::TimeDelta());
// Render the specified video frame. Once rendering is done the reference to
// the |video_frame| should be dropped so the video frame can be reused. If
// the specified frame is an EOS frame, the frame renderer will assume the
// next frame received is unrelated to the previous one, and any internal
// state can be reset. This is e.g. important when calculating the frame
// drop rate.
void RenderFrame(scoped_refptr<VideoFrame> video_frame);
// Wait until all currently queued frames are rendered. This function might
// take some time to complete, depending on the number of frames queued.
void WaitUntilRenderingDone();
// Create a texture-backed video frame with specified |pixel_format|, |size|
// and |texture_target|. The texture's id will be put in |texture_id|.
// TODO(dstaessens@) Remove when allocate mode is removed.
scoped_refptr<VideoFrame> CreateVideoFrame(VideoPixelFormat pixel_format,
const gfx::Size& size,
uint32_t texture_target,
uint32_t* texture_id);
// Get the number of frames dropped due to the decoder running behind.
uint64_t FramesDropped() const;
private:
FrameRendererDummy(base::TimeDelta frame_duration,
base::TimeDelta vsync_interval_duration);
// Initialize the frame renderer, performs all rendering-related setup.
bool Initialize();
void Destroy();
// Tasks run on the renderer thread.
void InitializeTask(base::WaitableEvent* done);
void DestroyTask(base::WaitableEvent* done);
void RenderFrameTask();
void ScheduleNextRenderFrameTask() EXCLUSIVE_LOCKS_REQUIRED(renderer_lock_);
// Target duration we will simulate rendering each frame.
const base::TimeDelta frame_duration_;
// The VSync interval to be used.
const base::TimeDelta vsync_interval_duration_;
// Time at which we started displaying frames.
base::TimeTicks vsync_timebase_;
// The frame being displayed, only accessed on |renderer_thread_|.
scoped_refptr<VideoFrame> active_frame_;
// The queue of decoded video frames pending to be displayed.
base::queue<scoped_refptr<VideoFrame>> pending_frames_
GUARDED_BY(renderer_lock_);
// Time at which the next decoded frame should be rendered.
base::TimeTicks next_frame_time_ GUARDED_BY(renderer_lock_);
// Number of frames that need to be dropped because the decoder is too slow.
uint64_t frames_to_drop_decoding_slow_ GUARDED_BY(renderer_lock_);
// Number of frames that need to be dropped because we're rendering at a lower
// rate then the video's frame rate.
uint64_t frames_to_drop_rendering_slow_ GUARDED_BY(renderer_lock_);
// Number of frames dropped due to decoder running behind.
uint64_t frames_dropped_ GUARDED_BY(renderer_lock_);
// Task that simulates rendering a frame to screen.
base::CancelableRepeatingClosure render_task_;
// Thread on which rendering video frames is simulated.
base::Thread renderer_thread_;
mutable base::Lock renderer_lock_;
base::ConditionVariable renderer_cv_;
SEQUENCE_CHECKER(client_sequence_checker_);
SEQUENCE_CHECKER(renderer_sequence_checker_);
};
} // namespace test
} // namespace media
#endif // MEDIA_GPU_TEST_VIDEO_PLAYER_FRAME_RENDERER_DUMMY_H_