1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "media/gpu/test/video_player/video_player.h"
6
7 #include "base/bind.h"
8 #include "base/memory/ptr_util.h"
9 #include "media/gpu/macros.h"
10 #include "media/gpu/test/video.h"
11 #include "media/gpu/test/video_player/video_decoder_client.h"
12
13 namespace media {
14 namespace test {
15
16 namespace {
17 // Get the name of the specified video player |event|.
EventName(VideoPlayerEvent event)18 const char* EventName(VideoPlayerEvent event) {
19 switch (event) {
20 case VideoPlayerEvent::kInitialized:
21 return "Initialized";
22 case VideoPlayerEvent::kFrameDecoded:
23 return "FrameDecoded";
24 case VideoPlayerEvent::kFlushing:
25 return "Flushing";
26 case VideoPlayerEvent::kFlushDone:
27 return "FlushDone";
28 case VideoPlayerEvent::kResetting:
29 return "Resetting";
30 case VideoPlayerEvent::kResetDone:
31 return "ResetDone";
32 case VideoPlayerEvent::kConfigInfo:
33 return "ConfigInfo";
34 default:
35 return "Unknown";
36 }
37 }
38 } // namespace
39
VideoPlayer()40 VideoPlayer::VideoPlayer()
41 : event_cv_(&event_lock_), video_player_event_counts_{}, event_id_(0) {}
42
~VideoPlayer()43 VideoPlayer::~VideoPlayer() {
44 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
45 DVLOGF(4);
46
47 Destroy();
48 }
49
50 // static
Create(const VideoDecoderClientConfig & config,gpu::GpuMemoryBufferFactory * gpu_memory_buffer_factory,std::unique_ptr<FrameRenderer> frame_renderer,std::vector<std::unique_ptr<VideoFrameProcessor>> frame_processors)51 std::unique_ptr<VideoPlayer> VideoPlayer::Create(
52 const VideoDecoderClientConfig& config,
53 gpu::GpuMemoryBufferFactory* gpu_memory_buffer_factory,
54 std::unique_ptr<FrameRenderer> frame_renderer,
55 std::vector<std::unique_ptr<VideoFrameProcessor>> frame_processors) {
56 auto video_player = base::WrapUnique(new VideoPlayer());
57 if (!video_player->CreateDecoderClient(config, gpu_memory_buffer_factory,
58 std::move(frame_renderer),
59 std::move(frame_processors))) {
60 return nullptr;
61 }
62 return video_player;
63 }
64
CreateDecoderClient(const VideoDecoderClientConfig & config,gpu::GpuMemoryBufferFactory * gpu_memory_buffer_factory,std::unique_ptr<FrameRenderer> frame_renderer,std::vector<std::unique_ptr<VideoFrameProcessor>> frame_processors)65 bool VideoPlayer::CreateDecoderClient(
66 const VideoDecoderClientConfig& config,
67 gpu::GpuMemoryBufferFactory* gpu_memory_buffer_factory,
68 std::unique_ptr<FrameRenderer> frame_renderer,
69 std::vector<std::unique_ptr<VideoFrameProcessor>> frame_processors) {
70 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
71 DCHECK_EQ(video_player_state_, VideoPlayerState::kUninitialized);
72 DCHECK(frame_renderer);
73 DVLOGF(4);
74
75 // base::Unretained is safe here as we will never receive callbacks after
76 // destroying the video player, since the video decoder client will be
77 // destroyed first.
78 EventCallback event_cb =
79 base::BindRepeating(&VideoPlayer::NotifyEvent, base::Unretained(this));
80
81 decoder_client_ = VideoDecoderClient::Create(
82 event_cb, gpu_memory_buffer_factory, std::move(frame_renderer),
83 std::move(frame_processors), config);
84 if (!decoder_client_) {
85 VLOGF(1) << "Failed to create video decoder client";
86 return false;
87 }
88
89 return true;
90 }
91
Destroy()92 void VideoPlayer::Destroy() {
93 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
94 DCHECK_NE(video_player_state_, VideoPlayerState::kDestroyed);
95 DVLOGF(4);
96
97 decoder_client_.reset();
98 video_player_state_ = VideoPlayerState::kDestroyed;
99 }
100
SetEventWaitTimeout(base::TimeDelta timeout)101 void VideoPlayer::SetEventWaitTimeout(base::TimeDelta timeout) {
102 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
103 DVLOGF(4);
104
105 event_timeout_ = timeout;
106 }
107
Initialize(const Video * video)108 bool VideoPlayer::Initialize(const Video* video) {
109 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
110 DCHECK(video_player_state_ == VideoPlayerState::kUninitialized ||
111 video_player_state_ == VideoPlayerState::kIdle);
112 DCHECK(video);
113 DVLOGF(4);
114
115 decoder_client_->Initialize(video);
116
117 // Wait until the video decoder is initialized.
118 if (!WaitForEvent(VideoPlayerEvent::kInitialized))
119 return false;
120
121 video_ = video;
122 video_player_state_ = VideoPlayerState::kIdle;
123 return true;
124 }
125
Play()126 void VideoPlayer::Play() {
127 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
128 DCHECK_EQ(video_player_state_, VideoPlayerState::kIdle);
129 DVLOGF(4);
130
131 // Play until the end of the video.
132 PlayUntil(VideoPlayerEvent::kNumEvents, std::numeric_limits<size_t>::max());
133 }
134
PlayUntil(VideoPlayerEvent event,size_t event_count)135 void VideoPlayer::PlayUntil(VideoPlayerEvent event, size_t event_count) {
136 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
137 DCHECK_EQ(video_player_state_, VideoPlayerState::kIdle);
138 DCHECK(video_);
139 DVLOGF(4);
140
141 // Start decoding the video.
142 play_until_ = std::make_pair(event, event_count);
143 video_player_state_ = VideoPlayerState::kDecoding;
144 decoder_client_->Play();
145 }
146
Reset()147 void VideoPlayer::Reset() {
148 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
149 DVLOGF(4);
150
151 decoder_client_->Reset();
152 }
153
Flush()154 void VideoPlayer::Flush() {
155 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
156 DVLOGF(4);
157
158 decoder_client_->Flush();
159 }
160
GetCurrentTime() const161 base::TimeDelta VideoPlayer::GetCurrentTime() const {
162 NOTIMPLEMENTED();
163 return base::TimeDelta();
164 }
165
GetCurrentFrame() const166 size_t VideoPlayer::GetCurrentFrame() const {
167 NOTIMPLEMENTED();
168 return 0;
169 }
170
GetState() const171 VideoPlayerState VideoPlayer::GetState() const {
172 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
173
174 base::AutoLock auto_lock(event_lock_);
175 return video_player_state_;
176 }
177
GetFrameRenderer() const178 FrameRenderer* VideoPlayer::GetFrameRenderer() const {
179 return decoder_client_->GetFrameRenderer();
180 }
181
WaitForEvent(VideoPlayerEvent event,size_t times)182 bool VideoPlayer::WaitForEvent(VideoPlayerEvent event, size_t times) {
183 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
184 DCHECK_GE(times, 1u);
185 DVLOGF(4) << "Event: " << EventName(event);
186
187 base::TimeDelta time_waiting;
188 base::AutoLock auto_lock(event_lock_);
189 while (true) {
190 // TODO(dstaessens@) Investigate whether we really need to keep the full
191 // list of events for more complex testcases.
192 // Go through list of events since last wait, looking for the event we're
193 // interested in.
194 for (; event_id_ < video_player_events_.size(); ++event_id_) {
195 if (video_player_events_[event_id_] == event)
196 times--;
197 if (times == 0) {
198 event_id_++;
199 return true;
200 }
201 }
202
203 // Check whether we've exceeded the maximum time we're allowed to wait.
204 if (time_waiting >= event_timeout_) {
205 LOG(ERROR) << "Timeout while waiting for '" << EventName(event)
206 << "' event";
207 return false;
208 }
209
210 const base::TimeTicks start_time = base::TimeTicks::Now();
211 event_cv_.TimedWait(event_timeout_ - time_waiting);
212 time_waiting += base::TimeTicks::Now() - start_time;
213 }
214 }
215
WaitForFlushDone()216 bool VideoPlayer::WaitForFlushDone() {
217 return WaitForEvent(VideoPlayerEvent::kFlushDone);
218 }
219
WaitForResetDone()220 bool VideoPlayer::WaitForResetDone() {
221 return WaitForEvent(VideoPlayerEvent::kResetDone);
222 }
223
WaitForFrameDecoded(size_t times)224 bool VideoPlayer::WaitForFrameDecoded(size_t times) {
225 return WaitForEvent(VideoPlayerEvent::kFrameDecoded, times);
226 }
227
GetEventCount(VideoPlayerEvent event) const228 size_t VideoPlayer::GetEventCount(VideoPlayerEvent event) const {
229 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
230
231 base::AutoLock auto_lock(event_lock_);
232 return video_player_event_counts_[static_cast<size_t>(event)];
233 }
234
WaitForFrameProcessors()235 bool VideoPlayer::WaitForFrameProcessors() {
236 return !decoder_client_ || decoder_client_->WaitForFrameProcessors();
237 }
238
WaitForRenderer()239 void VideoPlayer::WaitForRenderer() {
240 if (decoder_client_)
241 decoder_client_->WaitForRenderer();
242 }
243
GetFlushDoneCount() const244 size_t VideoPlayer::GetFlushDoneCount() const {
245 return GetEventCount(VideoPlayerEvent::kFlushDone);
246 }
247
GetResetDoneCount() const248 size_t VideoPlayer::GetResetDoneCount() const {
249 return GetEventCount(VideoPlayerEvent::kResetDone);
250 }
251
GetFrameDecodedCount() const252 size_t VideoPlayer::GetFrameDecodedCount() const {
253 return GetEventCount(VideoPlayerEvent::kFrameDecoded);
254 }
255
NotifyEvent(VideoPlayerEvent event)256 bool VideoPlayer::NotifyEvent(VideoPlayerEvent event) {
257 base::AutoLock auto_lock(event_lock_);
258 if (event == VideoPlayerEvent::kFlushDone ||
259 event == VideoPlayerEvent::kResetDone) {
260 video_player_state_ = VideoPlayerState::kIdle;
261 }
262
263 video_player_events_.push_back(event);
264 video_player_event_counts_[static_cast<size_t>(event)]++;
265 event_cv_.Signal();
266
267 // Check whether video playback should be paused after this event.
268 if (play_until_.first == event &&
269 play_until_.second ==
270 video_player_event_counts_[static_cast<size_t>(event)]) {
271 video_player_state_ = VideoPlayerState::kIdle;
272 return false;
273 }
274 return true;
275 }
276
277 } // namespace test
278 } // namespace media
279