Upload upstream chromium 120.0.6099.5
[platform/framework/web/chromium-efl.git] / media / renderers / video_renderer_impl_unittest.cc
1 // Copyright 2013 The Chromium Authors
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 <stdint.h>
6
7 #include <memory>
8 #include <utility>
9
10 #include "base/containers/circular_deque.h"
11 #include "base/functional/bind.h"
12 #include "base/functional/callback.h"
13 #include "base/functional/callback_helpers.h"
14 #include "base/memory/ptr_util.h"
15 #include "base/memory/raw_ptr.h"
16 #include "base/run_loop.h"
17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/string_split.h"
19 #include "base/strings/stringprintf.h"
20 #include "base/synchronization/lock.h"
21 #include "base/task/single_thread_task_runner.h"
22 #include "base/test/gmock_callback_support.h"
23 #include "base/test/simple_test_tick_clock.h"
24 #include "base/test/task_environment.h"
25 #include "base/time/time.h"
26 #include "media/base/data_buffer.h"
27 #include "media/base/limits.h"
28 #include "media/base/media_switches.h"
29 #include "media/base/media_util.h"
30 #include "media/base/mock_filters.h"
31 #include "media/base/null_video_sink.h"
32 #include "media/base/test_helpers.h"
33 #include "media/base/video_frame.h"
34 #include "media/base/wall_clock_time_source.h"
35 #include "media/renderers/video_renderer_impl.h"
36 #include "media/video/mock_gpu_memory_buffer_video_frame_pool.h"
37 #include "testing/gtest/include/gtest/gtest.h"
38
39 using ::base::test::RunClosure;
40 using ::base::test::RunOnceCallback;
41 using ::base::test::RunOnceClosure;
42 using ::testing::_;
43 using ::testing::AnyNumber;
44 using ::testing::Combine;
45 using ::testing::DoAll;
46 using ::testing::Invoke;
47 using ::testing::Mock;
48 using ::testing::NiceMock;
49 using ::testing::Return;
50 using ::testing::SaveArg;
51 using ::testing::StrictMock;
52 using ::testing::Values;
53
54 namespace media {
55
56 MATCHER_P(HasTimestampMatcher, ms, "") {
57   *result_listener << "has timestamp " << arg->timestamp().InMilliseconds();
58   return arg->timestamp().InMilliseconds() == ms;
59 }
60
61 class VideoRendererImplTest : public testing::Test {
62  public:
63   std::vector<std::unique_ptr<VideoDecoder>> CreateVideoDecodersForTest() {
64     decoder_ = new NiceMock<MockVideoDecoder>();
65     std::vector<std::unique_ptr<VideoDecoder>> decoders;
66     decoders.push_back(base::WrapUnique(decoder_.get()));
67     ON_CALL(*decoder_, Initialize_(_, _, _, _, _, _))
68         .WillByDefault(
69             DoAll(SaveArg<4>(&output_cb_),
70                   RunOnceCallback<3>(expect_init_success_
71                                          ? DecoderStatus::Codes::kOk
72                                          : DecoderStatus::Codes::kFailed)));
73     // Monitor decodes from the decoder.
74     ON_CALL(*decoder_, Decode_(_, _))
75         .WillByDefault(Invoke(this, &VideoRendererImplTest::DecodeRequested));
76     ON_CALL(*decoder_, Reset_(_))
77         .WillByDefault(Invoke(this, &VideoRendererImplTest::FlushRequested));
78     ON_CALL(*decoder_, GetMaxDecodeRequests()).WillByDefault(Return(1));
79     return decoders;
80   }
81
82   VideoRendererImplTest()
83       : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME),
84         decoder_(nullptr),
85         demuxer_stream_(DemuxerStream::VIDEO),
86         simulate_decode_delay_(false),
87         expect_init_success_(true),
88         time_source_(&tick_clock_) {
89     null_video_sink_ = std::make_unique<NullVideoSink>(
90         false, base::Seconds(1.0 / 60),
91         base::BindRepeating(&MockCB::FrameReceived,
92                             base::Unretained(&mock_cb_)),
93         base::SingleThreadTaskRunner::GetCurrentDefault());
94
95     renderer_ = std::make_unique<VideoRendererImpl>(
96         base::SingleThreadTaskRunner::GetCurrentDefault(),
97         null_video_sink_.get(),
98         base::BindRepeating(&VideoRendererImplTest::CreateVideoDecodersForTest,
99                             base::Unretained(this)),
100         true, &media_log_, nullptr, 0);
101     renderer_->SetTickClockForTesting(&tick_clock_);
102     null_video_sink_->set_tick_clock_for_testing(&tick_clock_);
103
104     // Start wallclock time at a non-zero value.
105     AdvanceWallclockTimeInMs(12345);
106
107     demuxer_stream_.set_video_decoder_config(TestVideoConfig::Normal());
108
109     // We expect these to be called but we don't care how/when. Tests can
110     // customize the provided buffer returned via OnDemuxerRead().
111     ON_CALL(demuxer_stream_, OnRead(_))
112         .WillByDefault(Invoke(this, &VideoRendererImplTest::OnDemuxerRead));
113   }
114
115   VideoRendererImplTest(const VideoRendererImplTest&) = delete;
116   VideoRendererImplTest& operator=(const VideoRendererImplTest&) = delete;
117
118   ~VideoRendererImplTest() override = default;
119
120   void Initialize() {
121     InitializeWithLowDelay(false);
122   }
123
124   void InitializeWithLowDelay(bool low_delay) {
125     // Initialize, we shouldn't have any reads.
126     InitializeRenderer(&demuxer_stream_, low_delay, true);
127   }
128
129   void InitializeRenderer(MockDemuxerStream* demuxer_stream,
130                           bool low_delay,
131                           bool expect_success) {
132     SCOPED_TRACE(base::StringPrintf("InitializeRenderer(%d)", expect_success));
133     expect_init_success_ = expect_success;
134     WaitableMessageLoopEvent event;
135     CallInitialize(demuxer_stream, event.GetPipelineStatusCB(), low_delay,
136                    expect_success);
137     event.RunAndWaitForStatus(expect_success ? PIPELINE_OK
138                                              : DECODER_ERROR_NOT_SUPPORTED);
139   }
140
141   void CallInitialize(MockDemuxerStream* demuxer_stream,
142                       PipelineStatusCallback status_cb,
143                       bool low_delay,
144                       bool expect_success) {
145     if (low_delay)
146       demuxer_stream->set_liveness(StreamLiveness::kLive);
147     EXPECT_CALL(mock_cb_, OnWaiting(_)).Times(0);
148     EXPECT_CALL(mock_cb_, OnAudioConfigChange(_)).Times(0);
149     EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
150     renderer_->Initialize(
151         demuxer_stream, nullptr, &mock_cb_,
152         base::BindRepeating(&WallClockTimeSource::GetWallClockTimes,
153                             base::Unretained(&time_source_)),
154         std::move(status_cb));
155   }
156
157   void StartPlayingFrom(int milliseconds) {
158     SCOPED_TRACE(base::StringPrintf("StartPlayingFrom(%d)", milliseconds));
159     const base::TimeDelta media_time = base::Milliseconds(milliseconds);
160     time_source_.SetMediaTime(media_time);
161     renderer_->StartPlayingFrom(media_time);
162     base::RunLoop().RunUntilIdle();
163   }
164
165   void Flush() {
166     SCOPED_TRACE("Flush()");
167     WaitableMessageLoopEvent event;
168     renderer_->Flush(event.GetClosure());
169     event.RunAndWait();
170   }
171
172   void Destroy() {
173     SCOPED_TRACE("Destroy()");
174     renderer_.reset();
175     base::RunLoop().RunUntilIdle();
176   }
177
178   void OnDemuxerRead(DemuxerStream::ReadCB& read_cb) {
179     if (simulate_demuxer_stall_after_n_reads_ >= 0) {
180       if (simulate_demuxer_stall_after_n_reads_-- == 0) {
181         stalled_demixer_read_cb_ = std::move(read_cb);
182         return;
183       }
184     }
185
186     scoped_refptr<DecoderBuffer> decoder_buffer(new DecoderBuffer(0));
187
188     // Set |decoder_buffer| timestamp such that it won't match any of the
189     // times provided to QueueFrames(). Otherwise the default timestamp of 0 may
190     // match some frames and not others, which causes non-uniform handling in
191     // DecoderStreamTraits.
192     decoder_buffer->set_timestamp(kNoTimestamp);
193
194     // Test hook for to specify a custom buffer duration.
195     decoder_buffer->set_duration(buffer_duration_);
196
197     std::move(read_cb).Run(DemuxerStream::kOk, {std::move(decoder_buffer)});
198   }
199
200   bool IsDemuxerStalled() { return !!stalled_demixer_read_cb_; }
201
202   void UnstallDemuxer() {
203     EXPECT_TRUE(IsDemuxerStalled());
204     OnDemuxerRead(stalled_demixer_read_cb_);
205   }
206
207   // Parses a string representation of video frames and generates corresponding
208   // VideoFrame objects in |decode_results_|.
209   //
210   // Syntax:
211   //   nn - Queue a decoder buffer with timestamp nn * 1000us
212   //   nndmm - Queue a decoder buffer with timestamp nn * 1000us
213   //           and mm * 1000us duration
214   //   abort - Queue an aborted read
215   //   error - Queue a decoder error
216   //
217   // Examples:
218   //   A clip that is four frames long: "0 10 20 30"
219   //   A clip that has a decode error: "60 70 error"
220   void QueueFrames(const std::string& str) {
221     for (base::StringPiece token : base::SplitString(
222              str, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) {
223       if (token == "abort") {
224         scoped_refptr<VideoFrame> null_frame;
225         QueueFrame(DecoderStatus::Codes::kAborted, null_frame);
226         continue;
227       }
228
229       if (token == "error") {
230         scoped_refptr<VideoFrame> null_frame;
231         QueueFrame(DecoderStatus::Codes::kFailed, null_frame);
232         continue;
233       }
234
235       auto ts_tokens = base::SplitStringPiece(token, "d", base::TRIM_WHITESPACE,
236                                               base::SPLIT_WANT_ALL);
237       if (ts_tokens.size() > 1) {
238         token = ts_tokens[0];
239       }
240
241       int timestamp_in_ms = 0;
242       if (base::StringToInt(token, &timestamp_in_ms)) {
243         gfx::Size natural_size = TestVideoConfig::NormalCodedSize();
244         scoped_refptr<VideoFrame> frame = VideoFrame::CreateFrame(
245             PIXEL_FORMAT_I420, natural_size, gfx::Rect(natural_size),
246             natural_size, base::Milliseconds(timestamp_in_ms));
247
248         int duration_in_ms = 0;
249         if (ts_tokens.size() > 1 &&
250             base::StringToInt(ts_tokens[1], &duration_in_ms)) {
251           frame->metadata().frame_duration = base::Milliseconds(duration_in_ms);
252         }
253
254         QueueFrame(DecoderStatus::Codes::kOk, frame);
255         continue;
256       }
257
258       CHECK(false) << "Unrecognized decoder buffer token: " << token;
259     }
260   }
261
262   // Queues video frames to be served by the decoder during rendering.
263   void QueueFrame(DecoderStatus status, scoped_refptr<VideoFrame> frame) {
264     decode_results_.push_back(std::make_pair(status, frame));
265   }
266
267   bool IsDecodePending() { return !!decode_cb_; }
268
269   void WaitForError(PipelineStatus expected) {
270     SCOPED_TRACE(base::StringPrintf("WaitForError(%d)", expected.code()));
271
272     WaitableMessageLoopEvent event;
273     PipelineStatusCallback error_cb = event.GetPipelineStatusCB();
274     EXPECT_CALL(mock_cb_, OnError(_))
275         .WillOnce(Invoke([cb = &error_cb](PipelineStatus status) {
276           std::move(*cb).Run(status);
277         }));
278     event.RunAndWaitForStatus(expected);
279   }
280
281   void WaitForEnded() {
282     SCOPED_TRACE("WaitForEnded()");
283
284     WaitableMessageLoopEvent event;
285     EXPECT_CALL(mock_cb_, OnEnded())
286         .WillOnce(RunOnceClosure(event.GetClosure()));
287     event.RunAndWait();
288   }
289
290   void WaitForPendingDecode() {
291     SCOPED_TRACE("WaitForPendingDecode()");
292     if (decode_cb_)
293       return;
294
295     DCHECK(!wait_for_pending_decode_cb_);
296
297     WaitableMessageLoopEvent event;
298     wait_for_pending_decode_cb_ = event.GetClosure();
299     event.RunAndWait();
300
301     DCHECK(decode_cb_);
302     DCHECK(!wait_for_pending_decode_cb_);
303   }
304
305   void SatisfyPendingDecode() {
306     CHECK(decode_cb_);
307     CHECK(!decode_results_.empty());
308
309     // Post tasks for OutputCB and DecodeCB.
310     scoped_refptr<VideoFrame> frame = decode_results_.front().second;
311     if (frame.get())
312       task_environment_.GetMainThreadTaskRunner()->PostTask(
313           FROM_HERE, base::BindOnce(output_cb_, frame));
314     task_environment_.GetMainThreadTaskRunner()->PostTask(
315         FROM_HERE,
316         base::BindOnce(std::move(decode_cb_), decode_results_.front().first));
317     decode_results_.pop_front();
318   }
319
320   void SatisfyPendingDecodeWithEndOfStream() {
321     DCHECK(decode_cb_);
322
323     // Return EOS buffer to trigger EOS frame.
324     DemuxerStream::DecoderBufferVector buffers;
325     buffers.emplace_back(DecoderBuffer::CreateEOSBuffer());
326     EXPECT_CALL(demuxer_stream_, OnRead(_))
327         .WillOnce(RunOnceCallback<0>(DemuxerStream::kOk, buffers));
328
329     // Satify pending |decode_cb_| to trigger a new DemuxerStream::Read().
330     task_environment_.GetMainThreadTaskRunner()->PostTask(
331         FROM_HERE,
332         base::BindOnce(std::move(decode_cb_), DecoderStatus::Codes::kOk));
333
334     WaitForPendingDecode();
335
336     task_environment_.GetMainThreadTaskRunner()->PostTask(
337         FROM_HERE,
338         base::BindOnce(std::move(decode_cb_), DecoderStatus::Codes::kOk));
339   }
340
341   bool HasQueuedFrames() const { return decode_results_.size() > 0; }
342
343   void AdvanceWallclockTimeInMs(int time_ms) {
344     EXPECT_TRUE(
345         task_environment_.GetMainThreadTaskRunner()->BelongsToCurrentThread());
346     base::AutoLock l(lock_);
347     tick_clock_.Advance(base::Milliseconds(time_ms));
348   }
349
350   void AdvanceTimeInMs(int time_ms) {
351     EXPECT_TRUE(
352         task_environment_.GetMainThreadTaskRunner()->BelongsToCurrentThread());
353     base::AutoLock l(lock_);
354     time_ += base::Milliseconds(time_ms);
355     time_source_.StopTicking();
356     time_source_.SetMediaTime(time_);
357     time_source_.StartTicking();
358   }
359
360   MOCK_METHOD0(OnSimulateDecodeDelay, base::TimeDelta(void));
361
362  protected:
363   base::test::TaskEnvironment task_environment_;
364   NullMediaLog media_log_;
365
366   // Fixture members.
367   std::unique_ptr<VideoRendererImpl> renderer_;
368   base::SimpleTestTickClock tick_clock_;
369   raw_ptr<NiceMock<MockVideoDecoder>, DanglingUntriaged>
370       decoder_;  // Owned by |renderer_|.
371   NiceMock<MockDemuxerStream> demuxer_stream_;
372   bool simulate_decode_delay_;
373
374   bool expect_init_success_;
375
376   // Specifies how many reads should complete before demuxer stalls.
377   int simulate_demuxer_stall_after_n_reads_ = -1;
378   DemuxerStream::ReadCB stalled_demixer_read_cb_;
379
380   // Use StrictMock<T> to catch missing/extra callbacks.
381   class MockCB : public MockRendererClient {
382    public:
383     MOCK_METHOD1(FrameReceived, void(scoped_refptr<VideoFrame>));
384   };
385   StrictMock<MockCB> mock_cb_;
386
387   // Must be destroyed before |renderer_| since they share |tick_clock_|.
388   std::unique_ptr<NullVideoSink> null_video_sink_;
389
390   WallClockTimeSource time_source_;
391
392   // Duration set on DecoderBuffers. See OnDemuxerRead().
393   base::TimeDelta buffer_duration_;
394
395  private:
396   void DecodeRequested(scoped_refptr<DecoderBuffer> buffer,
397                        VideoDecoder::DecodeCB& decode_cb) {
398     EXPECT_TRUE(
399         task_environment_.GetMainThreadTaskRunner()->BelongsToCurrentThread());
400     CHECK(!decode_cb_);
401     decode_cb_ = std::move(decode_cb);
402
403     // Wake up WaitForPendingDecode() if needed.
404     if (wait_for_pending_decode_cb_)
405       std::move(wait_for_pending_decode_cb_).Run();
406
407     if (decode_results_.empty())
408       return;
409
410     if (simulate_decode_delay_)
411       tick_clock_.Advance(OnSimulateDecodeDelay());
412
413     SatisfyPendingDecode();
414   }
415
416   void FlushRequested(base::OnceClosure& callback) {
417     EXPECT_TRUE(
418         task_environment_.GetMainThreadTaskRunner()->BelongsToCurrentThread());
419     decode_results_.clear();
420     if (decode_cb_) {
421       QueueFrames("abort");
422       SatisfyPendingDecode();
423     }
424
425     task_environment_.GetMainThreadTaskRunner()->PostTask(FROM_HERE,
426                                                           std::move(callback));
427   }
428
429   // Used to protect |time_|.
430   base::Lock lock_;
431   base::TimeDelta time_;
432
433   // Used for satisfying reads.
434   VideoDecoder::OutputCB output_cb_;
435   VideoDecoder::DecodeCB decode_cb_;
436   base::TimeDelta next_frame_timestamp_;
437
438   // Run during DecodeRequested() to unblock WaitForPendingDecode().
439   base::OnceClosure wait_for_pending_decode_cb_;
440
441   base::circular_deque<std::pair<DecoderStatus, scoped_refptr<VideoFrame>>>
442       decode_results_;
443 };
444
445 TEST_F(VideoRendererImplTest, DoNothing) {
446   // Test that creation and deletion doesn't depend on calls to Initialize()
447   // and/or Destroy().
448 }
449
450 TEST_F(VideoRendererImplTest, DestroyWithoutInitialize) {
451   Destroy();
452 }
453
454 TEST_F(VideoRendererImplTest, Initialize) {
455   Initialize();
456   Destroy();
457 }
458
459 TEST_F(VideoRendererImplTest, InitializeAndStartPlayingFrom) {
460   Initialize();
461   QueueFrames("0 10 20 30");
462   EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(0)));
463   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _));
464   EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
465   EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1);
466   EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
467   StartPlayingFrom(0);
468   Destroy();
469 }
470
471 TEST_F(VideoRendererImplTest, InitializeAndStartPlayingFromWithDuration) {
472   Initialize();
473   QueueFrames("0d10 10d10 20d10 30d10 40d10");
474   EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(10)));
475   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _));
476   EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
477   EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1);
478   EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
479   EXPECT_CALL(mock_cb_, OnVideoFrameRateChange(absl::optional<int>(100)));
480   StartPlayingFrom(10);
481   Destroy();
482 }
483
484 TEST_F(VideoRendererImplTest, InitializeAndEndOfStream) {
485   Initialize();
486   StartPlayingFrom(0);
487   WaitForPendingDecode();
488   {
489     SCOPED_TRACE("Waiting for BUFFERING_HAVE_ENOUGH");
490     WaitableMessageLoopEvent event;
491     {
492       // Buffering state changes must happen before end of stream.
493       testing::InSequence in_sequence;
494       EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _))
495           .WillOnce(RunOnceClosure(event.GetClosure()));
496       EXPECT_CALL(mock_cb_, OnEnded());
497     }
498     SatisfyPendingDecodeWithEndOfStream();
499     event.RunAndWait();
500   }
501   // Firing a time state changed to true should be ignored...
502   renderer_->OnTimeProgressing();
503   EXPECT_FALSE(null_video_sink_->is_started());
504   Destroy();
505 }
506
507 TEST_F(VideoRendererImplTest, StartPlayingAfterEndOfStream) {
508   Initialize();
509   QueueFrames("0d10 10d10 20d10 30d10 40d10");
510   EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1);
511   EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(40)));
512   EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
513   EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
514   StartPlayingFrom(40);
515   WaitForPendingDecode();
516   {
517     SCOPED_TRACE("Waiting for BUFFERING_HAVE_ENOUGH");
518     WaitableMessageLoopEvent event;
519     {
520       // Buffering state changes must happen before end of stream.
521       testing::InSequence in_sequence;
522       EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _))
523           .WillOnce(RunOnceClosure(event.GetClosure()));
524       EXPECT_CALL(mock_cb_, OnEnded());
525     }
526     SatisfyPendingDecodeWithEndOfStream();
527     event.RunAndWait();
528   }
529   // Firing a time state changed to true should be ignored...
530   renderer_->OnTimeProgressing();
531   EXPECT_FALSE(null_video_sink_->is_started());
532   Destroy();
533 }
534
535 TEST_F(VideoRendererImplTest, InitializeAndEndOfStreamOneStaleFrame) {
536   Initialize();
537   StartPlayingFrom(10000);
538   QueueFrames("0");
539   QueueFrame(DecoderStatus::Codes::kOk, VideoFrame::CreateEOSFrame());
540   WaitForPendingDecode();
541   {
542     SCOPED_TRACE("Waiting for BUFFERING_HAVE_ENOUGH");
543     WaitableMessageLoopEvent event;
544
545     EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1);
546     EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(0)));
547     EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
548     EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
549
550     {
551       // Buffering state changes must happen before end of stream.
552       testing::InSequence in_sequence;
553       EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _))
554           .WillOnce(RunOnceClosure(event.GetClosure()));
555       EXPECT_CALL(mock_cb_, OnEnded());
556     }
557     SatisfyPendingDecode();
558     event.RunAndWait();
559   }
560   // Firing a time state changed to true should be ignored...
561   renderer_->OnTimeProgressing();
562   EXPECT_FALSE(null_video_sink_->is_started());
563   Destroy();
564 }
565
566 TEST_F(VideoRendererImplTest, ReinitializeForAnotherStream) {
567   Initialize();
568   StartPlayingFrom(0);
569   Flush();
570   NiceMock<MockDemuxerStream> new_stream(DemuxerStream::VIDEO);
571   new_stream.set_video_decoder_config(TestVideoConfig::Normal());
572   InitializeRenderer(&new_stream, false, true);
573 }
574
575 TEST_F(VideoRendererImplTest, DestroyWhileInitializing) {
576   CallInitialize(&demuxer_stream_, NewExpectedStatusCB(PIPELINE_ERROR_ABORT),
577                  false, PIPELINE_OK);
578   Destroy();
579 }
580
581 TEST_F(VideoRendererImplTest, DestroyWhileFlushing) {
582   Initialize();
583   QueueFrames("0 10 20 30");
584   EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(0)));
585   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _));
586   EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
587   EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1);
588   EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
589   StartPlayingFrom(0);
590   renderer_->Flush(NewExpectedClosure());
591   Destroy();
592 }
593
594 TEST_F(VideoRendererImplTest, Play) {
595   Initialize();
596   QueueFrames("0 10 20 30");
597   EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(0)));
598   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _));
599   EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
600   EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1);
601   EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
602   StartPlayingFrom(0);
603   Destroy();
604 }
605
606 TEST_F(VideoRendererImplTest, FlushWithNothingBuffered) {
607   Initialize();
608   StartPlayingFrom(0);
609
610   // We shouldn't expect a buffering state change since we never reached
611   // BUFFERING_HAVE_ENOUGH.
612   Flush();
613   Destroy();
614 }
615
616 // Verify that the flush callback is invoked outside of VideoRenderer lock, so
617 // we should be able to call other renderer methods from the Flush callback.
618 static void VideoRendererImplTest_FlushDoneCB(VideoRendererImplTest* test,
619                                               VideoRenderer* renderer,
620                                               base::OnceClosure success_cb) {
621   test->QueueFrames("0 10 20 30");
622   renderer->StartPlayingFrom(base::Seconds(0));
623   std::move(success_cb).Run();
624 }
625
626 TEST_F(VideoRendererImplTest, FlushCallbackNoLock) {
627   Initialize();
628   EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(0)));
629   EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
630   EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1);
631   EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
632   StartPlayingFrom(0);
633   WaitableMessageLoopEvent event;
634   renderer_->Flush(
635       base::BindOnce(&VideoRendererImplTest_FlushDoneCB, base::Unretained(this),
636                      base::Unretained(renderer_.get()), event.GetClosure()));
637   event.RunAndWait();
638   Destroy();
639 }
640
641 TEST_F(VideoRendererImplTest, DecodeError_Playing) {
642   Initialize();
643   QueueFrames("0 10 20 30");
644   EXPECT_CALL(mock_cb_, FrameReceived(_)).Times(testing::AtLeast(1));
645
646   // Consider the case that rendering is faster than we setup the test event.
647   // In that case, when we run out of the frames, BUFFERING_HAVE_NOTHING will
648   // be called.
649   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _));
650   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING, _))
651       .Times(testing::AtMost(1));
652   EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
653   EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1);
654   EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
655
656   StartPlayingFrom(0);
657   renderer_->OnTimeProgressing();
658   time_source_.StartTicking();
659   AdvanceTimeInMs(10);
660
661   QueueFrames("error");
662   SatisfyPendingDecode();
663   WaitForError(PIPELINE_ERROR_DECODE);
664   Destroy();
665 }
666
667 TEST_F(VideoRendererImplTest, DecodeError_DuringStartPlayingFrom) {
668   Initialize();
669   QueueFrames("error");
670   EXPECT_CALL(mock_cb_, OnError(HasStatusCode(PIPELINE_ERROR_DECODE)));
671   EXPECT_CALL(mock_cb_, OnFallback(HasStatusCode(PIPELINE_ERROR_DECODE)));
672   StartPlayingFrom(0);
673   Destroy();
674 }
675
676 TEST_F(VideoRendererImplTest, StartPlayingFrom_Exact) {
677   Initialize();
678   QueueFrames("50 60 70 80 90");
679
680   EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(60)));
681   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _));
682   EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
683   EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1);
684   EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
685   StartPlayingFrom(60);
686   Destroy();
687 }
688
689 TEST_F(VideoRendererImplTest, StartPlayingFrom_RightBefore) {
690   Initialize();
691   QueueFrames("50 60 70 80 90");
692
693   EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(50)));
694   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _));
695   EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
696   EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1);
697   EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
698   EXPECT_CALL(mock_cb_, OnVideoFrameRateChange(absl::optional<int>(100)));
699   StartPlayingFrom(59);
700   Destroy();
701 }
702
703 TEST_F(VideoRendererImplTest, StartPlayingFrom_RightAfter) {
704   Initialize();
705   QueueFrames("50 60 70 80 90");
706
707   EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(60)));
708   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _));
709   EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
710   EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1);
711   EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
712   EXPECT_CALL(mock_cb_, OnVideoFrameRateChange(absl::optional<int>(100)));
713   StartPlayingFrom(61);
714   Destroy();
715 }
716
717 TEST_F(VideoRendererImplTest, StartPlayingFrom_LowDelay) {
718   // In low-delay mode only one frame is required to finish preroll. But frames
719   // prior to the start time will not be used.
720   InitializeWithLowDelay(true);
721   QueueFrames("0 10");
722
723   EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(10)));
724   // Expect some amount of have enough/nothing due to only requiring one frame.
725   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _))
726       .Times(AnyNumber());
727   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING, _))
728       .Times(AnyNumber());
729   EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
730   EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1);
731   EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
732   StartPlayingFrom(10);
733
734   QueueFrames("20");
735   SatisfyPendingDecode();
736
737   renderer_->OnTimeProgressing();
738   time_source_.StartTicking();
739
740   WaitableMessageLoopEvent event;
741   EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(20)))
742       .WillOnce(RunOnceClosure(event.GetClosure()));
743   AdvanceTimeInMs(20);
744   event.RunAndWait();
745
746   Destroy();
747 }
748
749 // Verify that a late decoder response doesn't break invariants in the renderer.
750 TEST_F(VideoRendererImplTest, DestroyDuringOutstandingRead) {
751   Initialize();
752   QueueFrames("0 10 20 30");
753   EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(0)));
754   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _));
755   EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
756   EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1);
757   EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
758   StartPlayingFrom(0);
759
760   // Check that there is an outstanding Read() request.
761   EXPECT_TRUE(IsDecodePending());
762
763   Destroy();
764 }
765
766 // Verifies that the first frame is painted w/o rendering being started.
767 TEST_F(VideoRendererImplTest, RenderingStopsAfterFirstFrame) {
768   InitializeWithLowDelay(true);
769   QueueFrames("0");
770
771   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _));
772   EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
773   EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1);
774   EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
775   EXPECT_CALL(mock_cb_, OnEnded()).Times(0);
776
777   {
778     SCOPED_TRACE("Waiting for first frame to be painted.");
779     WaitableMessageLoopEvent event;
780
781     EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(0)))
782         .WillOnce(RunOnceClosure(event.GetClosure()));
783     StartPlayingFrom(0);
784
785     EXPECT_TRUE(IsDecodePending());
786     SatisfyPendingDecodeWithEndOfStream();
787
788     event.RunAndWait();
789   }
790
791   Destroy();
792 }
793 // Verifies that the first frame is eventually painted even if its not the best.
794 TEST_F(VideoRendererImplTest, PaintFirstFrameOnStall) {
795   Initialize();
796   QueueFrames("0d10");
797   ON_CALL(*decoder_, CanReadWithoutStalling()).WillByDefault(Return(false));
798
799   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _));
800   EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
801   EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1);
802   EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
803   EXPECT_CALL(mock_cb_, OnEnded()).Times(0);
804
805   {
806     SCOPED_TRACE("Waiting for first frame to be painted.");
807     WaitableMessageLoopEvent event;
808
809     EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(0)))
810         .WillOnce(RunOnceClosure(event.GetClosure()));
811     StartPlayingFrom(10);
812
813     EXPECT_TRUE(IsDecodePending());
814
815     event.RunAndWait();
816   }
817
818   Destroy();
819 }
820
821 // Verifies that the sink is stopped after rendering the first frame if
822 // playback has started.
823 TEST_F(VideoRendererImplTest, RenderingStopsAfterOneFrameWithEOS) {
824   InitializeWithLowDelay(true);
825   QueueFrames("0");
826
827   EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(0))).Times(1);
828   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _));
829   EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
830   EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1);
831   EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
832
833   {
834     SCOPED_TRACE("Waiting for sink to stop.");
835     WaitableMessageLoopEvent event;
836
837     null_video_sink_->set_stop_cb(event.GetClosure());
838     StartPlayingFrom(0);
839     renderer_->OnTimeProgressing();
840
841     EXPECT_TRUE(IsDecodePending());
842     SatisfyPendingDecodeWithEndOfStream();
843     WaitForEnded();
844
845     renderer_->OnTimeStopped();
846     event.RunAndWait();
847   }
848
849   Destroy();
850 }
851
852 // Tests the case where the video started and received a single Render() call,
853 // then the video was put into the background.
854 TEST_F(VideoRendererImplTest, RenderingStartedThenStopped) {
855   Initialize();
856   QueueFrames("0 30 60 90");
857
858   // Start the sink and wait for the first callback.  Set statistics to a non
859   // zero value, once we have some decoded frames they should be overwritten.
860   PipelineStatistics last_pipeline_statistics;
861   last_pipeline_statistics.video_frames_dropped = 1;
862   {
863     WaitableMessageLoopEvent event;
864     EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _))
865         .WillOnce(RunOnceClosure(event.GetClosure()));
866     EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_))
867         .Times(5)
868         .WillRepeatedly(SaveArg<0>(&last_pipeline_statistics));
869     EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(0)));
870     EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1);
871     EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
872     StartPlayingFrom(0);
873     event.RunAndWait();
874     Mock::VerifyAndClearExpectations(&mock_cb_);
875   }
876
877   // Four calls to update statistics should have been made, each reporting a
878   // single decoded frame and one frame worth of memory usage. No dropped frames
879   // should be reported later since we're in background rendering mode. These
880   // calls must all have occurred before playback starts.
881   EXPECT_EQ(0u, last_pipeline_statistics.video_frames_dropped);
882   EXPECT_EQ(1u, last_pipeline_statistics.video_frames_decoded);
883
884   // Note: This is not the total, but just the increase in the last call since
885   // the previous call, the total should be 4 * 115200.
886   EXPECT_EQ(115200, last_pipeline_statistics.video_memory_usage);
887
888   EXPECT_EQ(renderer_->GetPreferredRenderInterval(),
889             last_pipeline_statistics.video_frame_duration_average);
890
891   // Consider the case that rendering is faster than we setup the test event.
892   // In that case, when we run out of the frames, BUFFERING_HAVE_NOTHING will
893   // be called. And then during SatisfyPendingDecodeWithEndOfStream,
894   // BUFFER_HAVE_ENOUGH will be called again.
895   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _))
896       .Times(testing::AtMost(1));
897   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING, _))
898       .Times(testing::AtMost(1));
899   renderer_->OnTimeProgressing();
900   time_source_.StartTicking();
901
902   // Suspend all future callbacks and synthetically advance the media time,
903   // because this is a background render, we won't underflow by waiting until
904   // a pending read is ready.
905   null_video_sink_->set_background_render(true);
906   AdvanceTimeInMs(91);
907   EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(90)));
908   WaitForPendingDecode();
909
910   EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_))
911       .WillOnce(SaveArg<0>(&last_pipeline_statistics));
912   SatisfyPendingDecodeWithEndOfStream();
913
914   AdvanceTimeInMs(30);
915   WaitForEnded();
916
917   EXPECT_EQ(0u, last_pipeline_statistics.video_frames_dropped);
918   EXPECT_EQ(0u, last_pipeline_statistics.video_frames_decoded);
919
920   // Memory usage is relative, so the prior lines increased memory usage to
921   // 4 * 115200, so this last one should show we only have 1 frame left.
922   EXPECT_EQ(-3 * 115200, last_pipeline_statistics.video_memory_usage);
923
924   Destroy();
925 }
926
927 // Tests the case where underflow evicts all frames before EOS.
928 TEST_F(VideoRendererImplTest, UnderflowEvictionBeforeEOS) {
929   Initialize();
930   QueueFrames("0 30 60 90 100");
931
932   {
933     SCOPED_TRACE("Waiting for BUFFERING_HAVE_ENOUGH");
934     WaitableMessageLoopEvent event;
935     EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _))
936         .WillOnce(RunOnceClosure(event.GetClosure()));
937     EXPECT_CALL(mock_cb_, FrameReceived(_)).Times(AnyNumber());
938     EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1);
939     EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
940     EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
941     StartPlayingFrom(0);
942     event.RunAndWait();
943   }
944
945   {
946     SCOPED_TRACE("Waiting for BUFFERING_HAVE_NOTHING");
947     WaitableMessageLoopEvent event;
948     EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING, _))
949         .WillOnce(RunOnceClosure(event.GetClosure()));
950     renderer_->OnTimeProgressing();
951     time_source_.StartTicking();
952     // Jump time far enough forward that no frames are valid.
953     AdvanceTimeInMs(1000);
954     event.RunAndWait();
955   }
956
957   WaitForPendingDecode();
958
959   renderer_->OnTimeStopped();
960   time_source_.StopTicking();
961
962   // Providing the end of stream packet should remove all frames and exit.
963   SatisfyPendingDecodeWithEndOfStream();
964   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _));
965   WaitForEnded();
966   Destroy();
967 }
968
969 // Tests the case where underflow evicts all frames in the HAVE_ENOUGH state.
970 TEST_F(VideoRendererImplTest, UnderflowEvictionWhileHaveEnough) {
971   Initialize();
972   QueueFrames("0 30 60 90 100");
973
974   {
975     SCOPED_TRACE("Waiting for BUFFERING_HAVE_ENOUGH");
976     WaitableMessageLoopEvent event;
977     EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _))
978         .WillOnce(RunOnceClosure(event.GetClosure()));
979     EXPECT_CALL(mock_cb_, FrameReceived(_)).Times(AnyNumber());
980     EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1);
981     EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
982     EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
983     StartPlayingFrom(0);
984     event.RunAndWait();
985   }
986
987   // Now wait until we have no effective frames.
988   {
989     SCOPED_TRACE("Waiting for zero effective frames.");
990     WaitableMessageLoopEvent event;
991     null_video_sink_->set_background_render(true);
992     time_source_.StartTicking();
993     AdvanceTimeInMs(1000);
994     renderer_->OnTimeProgressing();
995     EXPECT_CALL(mock_cb_, FrameReceived(_))
996         .WillOnce(RunOnceClosure(event.GetClosure()));
997     event.RunAndWait();
998     ASSERT_EQ(renderer_->effective_frames_queued_for_testing(), 0u);
999   }
1000
1001   // When OnTimeStopped() is called it should transition to HAVE_NOTHING.
1002   {
1003     SCOPED_TRACE("Waiting for BUFFERING_HAVE_NOTHING");
1004     WaitableMessageLoopEvent event;
1005     EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING, _))
1006         .WillOnce(RunOnceClosure(event.GetClosure()));
1007     renderer_->OnTimeStopped();
1008     event.RunAndWait();
1009   }
1010
1011   Destroy();
1012 }
1013
1014 TEST_F(VideoRendererImplTest, StartPlayingFromThenFlushThenEOS) {
1015   Initialize();
1016   QueueFrames("0 30 60 90");
1017
1018   WaitableMessageLoopEvent event;
1019   EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(0)));
1020   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _))
1021       .WillOnce(RunOnceClosure(event.GetClosure()));
1022   EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
1023   EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1);
1024   EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
1025   StartPlayingFrom(0);
1026   event.RunAndWait();
1027
1028   // Cycle ticking so that we get a non-null reference time.
1029   time_source_.StartTicking();
1030   time_source_.StopTicking();
1031
1032   // Flush and simulate a seek past EOS, where some error prevents the decoder
1033   // from returning any frames.
1034   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING, _));
1035   Flush();
1036
1037   StartPlayingFrom(200);
1038   WaitForPendingDecode();
1039   SatisfyPendingDecodeWithEndOfStream();
1040   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _));
1041   WaitForEnded();
1042   Destroy();
1043 }
1044
1045 TEST_F(VideoRendererImplTest, FramesAreNotExpiredDuringPreroll) {
1046   Initialize();
1047   // !CanReadWithoutStalling() puts the renderer in state BUFFERING_HAVE_ENOUGH
1048   // after the first frame.
1049   ON_CALL(*decoder_, CanReadWithoutStalling()).WillByDefault(Return(false));
1050   // Set background rendering to simulate the first couple of Render() calls
1051   // by VFC.
1052   null_video_sink_->set_background_render(true);
1053   QueueFrames("0 10 20");
1054   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _))
1055       .Times(testing::AtMost(1));
1056   EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(0)));
1057   EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
1058   EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1);
1059   EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
1060   StartPlayingFrom(0);
1061
1062   renderer_->OnTimeProgressing();
1063   time_source_.StartTicking();
1064
1065   WaitableMessageLoopEvent event;
1066   // Frame "10" should not have been expired.
1067   EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(10)))
1068       .WillOnce(RunOnceClosure(event.GetClosure()));
1069   AdvanceTimeInMs(10);
1070   event.RunAndWait();
1071
1072   Destroy();
1073 }
1074
1075 TEST_F(VideoRendererImplTest, VideoConfigChange) {
1076   Initialize();
1077
1078   // Configure demuxer stream to allow config changes.
1079   EXPECT_CALL(demuxer_stream_, SupportsConfigChanges())
1080       .WillRepeatedly(Return(true));
1081
1082   // Signal a config change at the next DemuxerStream::Read().
1083   DemuxerStream::DecoderBufferVector buffers;
1084   EXPECT_CALL(demuxer_stream_, OnRead(_))
1085       .WillOnce(RunOnceCallback<0>(DemuxerStream::kConfigChanged, buffers));
1086
1087   // Use LargeEncrypted config (non-default) to ensure its plumbed through to
1088   // callback.
1089   demuxer_stream_.set_video_decoder_config(TestVideoConfig::LargeEncrypted());
1090
1091   EXPECT_CALL(mock_cb_, OnVideoConfigChange(
1092                             DecoderConfigEq(TestVideoConfig::LargeEncrypted())))
1093       .Times(1);
1094
1095   // Start plyaing to trigger DemuxerStream::Read(), surfacing the config change
1096   StartPlayingFrom(0);
1097
1098   Destroy();
1099 }
1100
1101 TEST_F(VideoRendererImplTest, NaturalSizeChange) {
1102   Initialize();
1103
1104   gfx::Size initial_size(8, 8);
1105   gfx::Size larger_size(16, 16);
1106
1107   QueueFrame(DecoderStatus::Codes::kOk,
1108              VideoFrame::CreateFrame(PIXEL_FORMAT_I420, initial_size,
1109                                      gfx::Rect(initial_size), initial_size,
1110                                      base::Milliseconds(0)));
1111   QueueFrame(DecoderStatus::Codes::kOk,
1112              VideoFrame::CreateFrame(PIXEL_FORMAT_I420, larger_size,
1113                                      gfx::Rect(larger_size), larger_size,
1114                                      base::Milliseconds(10)));
1115   QueueFrame(DecoderStatus::Codes::kOk,
1116              VideoFrame::CreateFrame(PIXEL_FORMAT_I420, larger_size,
1117                                      gfx::Rect(larger_size), larger_size,
1118                                      base::Milliseconds(20)));
1119   QueueFrame(DecoderStatus::Codes::kOk,
1120              VideoFrame::CreateFrame(PIXEL_FORMAT_I420, initial_size,
1121                                      gfx::Rect(initial_size), initial_size,
1122                                      base::Milliseconds(30)));
1123
1124   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _));
1125   EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
1126   EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
1127
1128   {
1129     // Callback is fired for the first frame.
1130     EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(initial_size));
1131     EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(0)));
1132     StartPlayingFrom(0);
1133     renderer_->OnTimeProgressing();
1134     time_source_.StartTicking();
1135   }
1136   {
1137     // Callback should be fired once when switching to the larger size.
1138     EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(larger_size));
1139     WaitableMessageLoopEvent event;
1140     EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(10)))
1141         .WillOnce(RunOnceClosure(event.GetClosure()));
1142     AdvanceTimeInMs(10);
1143     event.RunAndWait();
1144   }
1145   {
1146     // Called is not fired because frame size does not change.
1147     WaitableMessageLoopEvent event;
1148     EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(20)))
1149         .WillOnce(RunOnceClosure(event.GetClosure()));
1150     AdvanceTimeInMs(10);
1151     event.RunAndWait();
1152   }
1153   {
1154     // Callback is fired once when switching to the larger size.
1155     EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(initial_size));
1156     WaitableMessageLoopEvent event;
1157     EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(30)))
1158         .WillOnce(RunOnceClosure(event.GetClosure()));
1159     AdvanceTimeInMs(10);
1160     event.RunAndWait();
1161   }
1162
1163   Destroy();
1164 }
1165
1166 TEST_F(VideoRendererImplTest, OpacityChange) {
1167   Initialize();
1168
1169   gfx::Size frame_size(8, 8);
1170   VideoPixelFormat opaque_format = PIXEL_FORMAT_I420;
1171   VideoPixelFormat non_opaque_format = PIXEL_FORMAT_I420A;
1172
1173   QueueFrame(DecoderStatus::Codes::kOk,
1174              VideoFrame::CreateFrame(non_opaque_format, frame_size,
1175                                      gfx::Rect(frame_size), frame_size,
1176                                      base::Milliseconds(0)));
1177   QueueFrame(DecoderStatus::Codes::kOk,
1178              VideoFrame::CreateFrame(non_opaque_format, frame_size,
1179                                      gfx::Rect(frame_size), frame_size,
1180                                      base::Milliseconds(10)));
1181   QueueFrame(
1182       DecoderStatus::Codes::kOk,
1183       VideoFrame::CreateFrame(opaque_format, frame_size, gfx::Rect(frame_size),
1184                               frame_size, base::Milliseconds(20)));
1185   QueueFrame(
1186       DecoderStatus::Codes::kOk,
1187       VideoFrame::CreateFrame(opaque_format, frame_size, gfx::Rect(frame_size),
1188                               frame_size, base::Milliseconds(30)));
1189
1190   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _));
1191   EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
1192   EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(frame_size)).Times(1);
1193
1194   {
1195     // Callback is fired for the first frame.
1196     EXPECT_CALL(mock_cb_, OnVideoOpacityChange(false));
1197     EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(0)));
1198     StartPlayingFrom(0);
1199     renderer_->OnTimeProgressing();
1200     time_source_.StartTicking();
1201   }
1202   {
1203     // Callback is not fired because opacity does not change.
1204     WaitableMessageLoopEvent event;
1205     EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(10)))
1206         .WillOnce(RunOnceClosure(event.GetClosure()));
1207     AdvanceTimeInMs(10);
1208     event.RunAndWait();
1209   }
1210   {
1211     // Called is fired when opacity changes.
1212     EXPECT_CALL(mock_cb_, OnVideoOpacityChange(true));
1213     WaitableMessageLoopEvent event;
1214     EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(20)))
1215         .WillOnce(RunOnceClosure(event.GetClosure()));
1216     AdvanceTimeInMs(10);
1217     event.RunAndWait();
1218   }
1219   {
1220     // Callback is not fired because opacity does not change.
1221     WaitableMessageLoopEvent event;
1222     EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(30)))
1223         .WillOnce(RunOnceClosure(event.GetClosure()));
1224     AdvanceTimeInMs(10);
1225     event.RunAndWait();
1226   }
1227
1228   Destroy();
1229 }
1230
1231 TEST_F(VideoRendererImplTest, VideoFrameRateChange) {
1232   Initialize();
1233
1234   EXPECT_CALL(mock_cb_, FrameReceived(_)).Times(AnyNumber());
1235   EXPECT_CALL(mock_cb_, OnBufferingStateChange(_, _)).Times(AnyNumber());
1236   EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
1237   EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1);
1238   EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
1239
1240   // Send 50fps frames first.
1241   EXPECT_CALL(mock_cb_, OnVideoFrameRateChange(absl::optional<int>(50)));
1242   QueueFrames("0 20 40 60 80 100 120 140 160 180 200");
1243   QueueFrames("220 240 260 280 300 320 340 360 380 400");
1244
1245   // Also queue some frames that aren't at 50fps, so that we get an unknown fps.
1246   EXPECT_CALL(mock_cb_, OnVideoFrameRateChange(absl::optional<int>()));
1247   QueueFrames("500 600");
1248
1249   // Drain everything.
1250   StartPlayingFrom(0);
1251   renderer_->OnTimeProgressing();
1252   time_source_.StartTicking();
1253   // Send in all the frames we queued.
1254   while (HasQueuedFrames()) {
1255     AdvanceTimeInMs(20);
1256     AdvanceWallclockTimeInMs(20);
1257     // This runs the sink callbacks to consume frames.
1258     task_environment_.FastForwardBy(base::Milliseconds(20));
1259     base::RunLoop().RunUntilIdle();
1260   }
1261
1262   Destroy();
1263 }
1264
1265 class VideoRendererImplAsyncAddFrameReadyTest : public VideoRendererImplTest {
1266  public:
1267   void InitializeWithMockGpuMemoryBufferVideoFramePool() {
1268     renderer_ = std::make_unique<VideoRendererImpl>(
1269         base::SingleThreadTaskRunner::GetCurrentDefault(),
1270         null_video_sink_.get(),
1271         base::BindRepeating(&VideoRendererImplAsyncAddFrameReadyTest::
1272                                 CreateVideoDecodersForTest,
1273                             base::Unretained(this)),
1274         true, &media_log_,
1275         std::make_unique<MockGpuMemoryBufferVideoFramePool>(&frame_ready_cbs_),
1276         0);
1277     VideoRendererImplTest::Initialize();
1278   }
1279
1280  protected:
1281   std::vector<base::OnceClosure> frame_ready_cbs_;
1282 };
1283
1284 TEST_F(VideoRendererImplAsyncAddFrameReadyTest, InitializeAndStartPlayingFrom) {
1285   InitializeWithMockGpuMemoryBufferVideoFramePool();
1286   QueueFrames("0 10 20 30");
1287   EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(0)));
1288   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _));
1289   EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
1290   EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1);
1291   EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
1292   StartPlayingFrom(0);
1293   ASSERT_EQ(1u, frame_ready_cbs_.size());
1294
1295   uint32_t frame_ready_index = 0;
1296   while (frame_ready_index < frame_ready_cbs_.size()) {
1297     std::move(frame_ready_cbs_[frame_ready_index++]).Run();
1298     base::RunLoop().RunUntilIdle();
1299   }
1300   Destroy();
1301 }
1302
1303 TEST_F(VideoRendererImplAsyncAddFrameReadyTest, WeakFactoryDiscardsOneFrame) {
1304   InitializeWithMockGpuMemoryBufferVideoFramePool();
1305   QueueFrames("0 10 20 30");
1306   StartPlayingFrom(0);
1307   Flush();
1308   ASSERT_EQ(1u, frame_ready_cbs_.size());
1309   // This frame will be discarded.
1310   std::move(frame_ready_cbs_.front()).Run();
1311   Destroy();
1312 }
1313
1314 enum class UnderflowTestType {
1315   // Renderer will require a default amount of buffering to reach HAVE_ENOUGH.
1316   NORMAL,
1317   // Both of these require only a single frame to reach HAVE_ENOUGH.
1318   LOW_DELAY,
1319   CANT_READ_WITHOUT_STALLING
1320 };
1321
1322 class UnderflowTest
1323     : public VideoRendererImplTest,
1324       public testing::WithParamInterface<
1325           ::std::tuple<UnderflowTestType, BufferingStateChangeReason>> {
1326  protected:
1327   void SetUp() override { std::tie(test_type, underflow_type) = GetParam(); }
1328
1329   void TestBufferToHaveEnoughThenUnderflow() {
1330     InitializeWithLowDelay(test_type == UnderflowTestType::LOW_DELAY);
1331
1332     if (test_type == UnderflowTestType::CANT_READ_WITHOUT_STALLING)
1333       ON_CALL(*decoder_, CanReadWithoutStalling()).WillByDefault(Return(false));
1334
1335     if (underflow_type == DEMUXER_UNDERFLOW) {
1336       simulate_demuxer_stall_after_n_reads_ = 4;
1337     }
1338     QueueFrames("0 20 40 60");
1339
1340     {
1341       WaitableMessageLoopEvent event;
1342       EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(0)));
1343       EXPECT_CALL(mock_cb_,
1344                   OnBufferingStateChange(BUFFERING_HAVE_ENOUGH,
1345                                          BUFFERING_CHANGE_REASON_UNKNOWN))
1346           .WillOnce(RunOnceClosure(event.GetClosure()));
1347       EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
1348       EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1);
1349       EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
1350       StartPlayingFrom(0);
1351       event.RunAndWait();
1352       Mock::VerifyAndClearExpectations(&mock_cb_);
1353     }
1354
1355     // Start playing.
1356     time_source_.StartTicking();
1357     renderer_->OnTimeProgressing();
1358
1359     // Advance time slightly, but enough to exceed the duration of the last
1360     // frame.
1361     // Frames should be dropped and we should NOT signal having nothing.
1362     {
1363       SCOPED_TRACE("Waiting for frame drops");
1364       WaitableMessageLoopEvent event;
1365       EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(20))).Times(0);
1366
1367       EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(40))).Times(0);
1368       EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(60)))
1369           .WillOnce(RunOnceClosure(event.GetClosure()));
1370       EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
1371       AdvanceTimeInMs(61);
1372
1373       event.RunAndWait();
1374       Mock::VerifyAndClearExpectations(&mock_cb_);
1375     }
1376
1377     // Advance time more. Now we should signal having nothing. And put
1378     // the last frame up for display.
1379     {
1380       SCOPED_TRACE("Waiting for BUFFERING_HAVE_NOTHING");
1381       WaitableMessageLoopEvent event;
1382       EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING,
1383                                                    underflow_type))
1384           .WillOnce(RunOnceClosure(event.GetClosure()));
1385       AdvanceTimeInMs(18);
1386       event.RunAndWait();
1387       Mock::VerifyAndClearExpectations(&mock_cb_);
1388     }
1389
1390     EXPECT_EQ(1u, renderer_->frames_queued_for_testing());
1391     time_source_.StopTicking();
1392     renderer_->OnTimeStopped();
1393     EXPECT_EQ(0u, renderer_->frames_queued_for_testing());
1394     ASSERT_EQ(underflow_type == DEMUXER_UNDERFLOW, IsDemuxerStalled());
1395     ASSERT_EQ(underflow_type == DECODER_UNDERFLOW, IsDecodePending());
1396
1397     // Stopping time signals a confirmed underflow to VRI. Verify updates to
1398     // buffering limits.
1399     switch (test_type) {
1400       // In the normal and cant_read modes, min and max buffered frames should
1401       // always be equal, and both should increase upon underflow.
1402       case UnderflowTestType::NORMAL:
1403       case UnderflowTestType::CANT_READ_WITHOUT_STALLING:
1404         EXPECT_EQ(renderer_->min_buffered_frames_for_testing(),
1405                   limits::kMaxVideoFrames + 1);
1406         EXPECT_EQ(renderer_->max_buffered_frames_for_testing(),
1407                   limits::kMaxVideoFrames + 1);
1408         break;
1409       // In low_delay mode only the max should increase while min remains 1.
1410       case UnderflowTestType::LOW_DELAY:
1411         EXPECT_EQ(renderer_->min_buffered_frames_for_testing(), 1);
1412         EXPECT_EQ(renderer_->max_buffered_frames_for_testing(),
1413                   limits::kMaxVideoFrames + 1);
1414         break;
1415     }
1416   }
1417
1418   UnderflowTestType test_type;
1419   BufferingStateChangeReason underflow_type;
1420 };
1421
1422 TEST_P(UnderflowTest, UnderflowAndEosTest) {
1423   TestBufferToHaveEnoughThenUnderflow();
1424
1425   if (IsDemuxerStalled())
1426     UnstallDemuxer();
1427
1428   // Receiving end of stream should signal having enough.
1429   {
1430     SCOPED_TRACE("Waiting for BUFFERING_HAVE_ENOUGH");
1431     WaitableMessageLoopEvent event;
1432     EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(AnyNumber());
1433     EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
1434     EXPECT_CALL(mock_cb_,
1435                 OnBufferingStateChange(BUFFERING_HAVE_ENOUGH,
1436                                        BUFFERING_CHANGE_REASON_UNKNOWN))
1437         .WillOnce(RunOnceClosure(event.GetClosure()));
1438     EXPECT_CALL(mock_cb_, OnEnded());
1439     SatisfyPendingDecodeWithEndOfStream();
1440     event.RunAndWait();
1441   }
1442
1443   Destroy();
1444 }
1445
1446 TEST_P(UnderflowTest, UnderflowAndRecoverTest) {
1447   TestBufferToHaveEnoughThenUnderflow();
1448
1449   if (IsDemuxerStalled())
1450     UnstallDemuxer();
1451
1452   // Queue some frames, satisfy reads, and make sure expired frames are gone
1453   // when the renderer paints the first frame.
1454   {
1455     SCOPED_TRACE("Waiting for BUFFERING_HAVE_ENOUGH");
1456     WaitableMessageLoopEvent event;
1457     EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(80))).Times(1);
1458     EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
1459     EXPECT_CALL(mock_cb_,
1460                 OnBufferingStateChange(BUFFERING_HAVE_ENOUGH,
1461                                        BUFFERING_CHANGE_REASON_UNKNOWN))
1462         .WillOnce(RunOnceClosure(event.GetClosure()));
1463
1464     switch (test_type) {
1465       // In the normal underflow case we queue 5 frames here instead of four
1466       // since the underflow increases the number of required frames to reach
1467       // the have enough state.
1468       case UnderflowTestType::NORMAL:
1469         QueueFrames("80 100 120 140 160");
1470         EXPECT_CALL(mock_cb_, OnVideoFrameRateChange(absl::optional<int>(50)));
1471         break;
1472       // In either of these modes the HAVE_ENOUGH transition should still
1473       // occur with a single frame.
1474       case UnderflowTestType::LOW_DELAY:
1475       case UnderflowTestType::CANT_READ_WITHOUT_STALLING:
1476         QueueFrames("80");
1477         break;
1478     }
1479     SatisfyPendingDecode();
1480     event.RunAndWait();
1481   }
1482
1483   Destroy();
1484 }
1485
1486 INSTANTIATE_TEST_SUITE_P(
1487     ChrisTest,
1488     UnderflowTest,
1489     Combine(Values(UnderflowTestType::NORMAL,
1490                    UnderflowTestType::LOW_DELAY,
1491                    UnderflowTestType::CANT_READ_WITHOUT_STALLING),
1492             Values(DEMUXER_UNDERFLOW, DECODER_UNDERFLOW)));
1493
1494 class VideoRendererLatencyHintTest : public VideoRendererImplTest {
1495  public:
1496   void VerifyDefaultRebufferingBehavior(int start_playing_from) {
1497     // Keep it simple. Only call this if you're starting from empty.
1498     DCHECK_EQ(renderer_->effective_frames_queued_for_testing(), 0u);
1499
1500     // Initial frames should trigger various callbacks.
1501     EXPECT_CALL(mock_cb_,
1502                 FrameReceived(HasTimestampMatcher(start_playing_from)));
1503     EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
1504     EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(AnyNumber());
1505     EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(AnyNumber());
1506     EXPECT_CALL(mock_cb_, OnVideoFrameRateChange(_)).Times(AnyNumber());
1507
1508     // Queue 3 frames, 20 msec apart. Stop 1 shy of min_buffered_frames_.
1509     ASSERT_EQ(renderer_->min_buffered_frames_for_testing(), 4);
1510     int frame_time = start_playing_from;
1511     for (int i = 0; i < 3; i++) {
1512       QueueFrames(base::NumberToString(frame_time));
1513       frame_time += 20;
1514     }
1515
1516     // Verify no transition to HAVE_ENOUGH since 3 < |min_buffered_frames_|
1517     EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _))
1518         .Times(0);
1519
1520     StartPlayingFrom(start_playing_from);
1521     base::RunLoop().RunUntilIdle();
1522     EXPECT_EQ(renderer_->effective_frames_queued_for_testing(), 3u);
1523     Mock::VerifyAndClearExpectations(&mock_cb_);
1524
1525     // Queuing one extra frame should trigger the transition.
1526     QueueFrames(base::NumberToString(frame_time));
1527     SatisfyPendingDecode();
1528     EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
1529     EXPECT_CALL(mock_cb_, OnVideoFrameRateChange(_)).Times(AnyNumber());
1530     EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _));
1531     base::RunLoop().RunUntilIdle();
1532     Mock::VerifyAndClearExpectations(&mock_cb_);
1533   }
1534 };
1535
1536 // Test default HaveEnough transition when no latency hint is set.
1537 TEST_F(VideoRendererLatencyHintTest, HaveEnough_NoLatencyHint) {
1538   Initialize();
1539   VerifyDefaultRebufferingBehavior(0);
1540   Destroy();
1541 }
1542
1543 // Test early HaveEnough transition when low latency hint is set.
1544 TEST_F(VideoRendererLatencyHintTest, HaveEnough_LowLatencyHint) {
1545   Initialize();
1546
1547   // Set latencyHint to bare minimum.
1548   renderer_->SetLatencyHint(base::TimeDelta());
1549
1550   // Initial frames should trigger various callbacks.
1551   EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(0)));
1552   EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(2);
1553   EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1);
1554   EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
1555   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _));
1556
1557   // Only 1 frame should be needed to trigger have enough.
1558   ASSERT_EQ(renderer_->min_buffered_frames_for_testing(), 1);
1559   QueueFrames("0");
1560
1561   StartPlayingFrom(0);
1562   base::RunLoop().RunUntilIdle();
1563   EXPECT_EQ(renderer_->effective_frames_queued_for_testing(), 1u);
1564   Mock::VerifyAndClearExpectations(&mock_cb_);
1565
1566   // Verify latency hint doesn't reduce our ability to buffer beyond the
1567   // 1-frame HAVE_ENOUGH (i.e. don't throttle decoding in the name of latency).
1568   EXPECT_EQ(renderer_->max_buffered_frames_for_testing(), 4);
1569   EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(3);
1570   QueueFrames("10 20 30");
1571   WaitForPendingDecode();
1572   SatisfyPendingDecode();
1573   base::RunLoop().RunUntilIdle();
1574   EXPECT_EQ(renderer_->frames_queued_for_testing(), 4u);
1575
1576   // Unset latencyHint, to verify default behavior.
1577   renderer_->SetLatencyHint(absl::nullopt);
1578
1579   // Flush to return to clean slate.
1580   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING, _));
1581   Flush();
1582
1583   VerifyDefaultRebufferingBehavior(1000);
1584
1585   Destroy();
1586 }
1587
1588 // Test late HaveEnough transition when high latency hint is set.
1589 TEST_F(VideoRendererLatencyHintTest, HaveEnough_HighLatencyHint) {
1590   // We must provide a |buffer_duration_| for the latencyHint to take effect
1591   // immediately. The VideoRendererAlgorithm will eventually provide a PTS-delta
1592   // duration, but not until after we've started rendering.
1593   buffer_duration_ = base::Milliseconds(30);
1594
1595   // Set latencyHint to a large value.
1596   renderer_->SetLatencyHint(base::Milliseconds(400));
1597
1598   // NOTE: other tests will SetLatencyHint after Initialize(). Either way should
1599   // work. Initializing later is especially interesting for "high" hints because
1600   // the renderer will try to set buffering caps based on stream state that
1601   // isn't yet available.
1602   Initialize();
1603
1604   // Initial frames should trigger various callbacks.
1605   EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(0)));
1606   EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1);
1607   EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
1608   EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
1609
1610   // Queue 12 frames, each 30 ms apart. At this framerate, 400ms rounds to 13
1611   // frames, so 12 frames should be 1 shy of the HaveEnough threshold.
1612   EXPECT_CALL(mock_cb_, OnVideoFrameRateChange(absl::optional<int>(33)));
1613   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _))
1614       .Times(0);
1615   QueueFrames("0 30 60 90 120 150 180 210 240 270 300 330");
1616
1617   StartPlayingFrom(0);
1618   base::RunLoop().RunUntilIdle();
1619   ASSERT_EQ(renderer_->min_buffered_frames_for_testing(), 13);
1620   EXPECT_EQ(renderer_->effective_frames_queued_for_testing(), 12u);
1621   Mock::VerifyAndClearExpectations(&mock_cb_);
1622
1623   // Queue 1 additional frame and verify HaveEnough threshold is reached.
1624   EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
1625   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _));
1626   QueueFrames("360");
1627   SatisfyPendingDecode();
1628   base::RunLoop().RunUntilIdle();
1629   Mock::VerifyAndClearExpectations(&mock_cb_);
1630
1631   // Unset latencyHint, to verify default behavior.
1632   renderer_->SetLatencyHint(absl::nullopt);
1633
1634   // Flush to return to clean slate.
1635   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING, _));
1636   Flush();
1637   Mock::VerifyAndClearExpectations(&mock_cb_);
1638
1639   VerifyDefaultRebufferingBehavior(1000);
1640
1641   Destroy();
1642 }
1643
1644 // Test updates to buffering limits upon underflow when latency hint set.
1645 TEST_F(VideoRendererLatencyHintTest,
1646        LatencyHintUnderflowUpdatesMaxBufferingLimit) {
1647   // Enable low delay mode. Low delay mode is tested separately.
1648   InitializeWithLowDelay(true);
1649   EXPECT_EQ(renderer_->min_buffered_frames_for_testing(), 1);
1650
1651   // We must provide a |buffer_duration_| for the latencyHint to take effect
1652   // immediately. The VideoRendererAlgorithm will eventually provide a PTS-delta
1653   // duration, but not until after we've started rendering.
1654   buffer_duration_ = base::Milliseconds(30);
1655
1656   // Set latency hint to a medium value.
1657   renderer_->SetLatencyHint(base::Milliseconds(200));
1658
1659   // Stall the demuxer after 7 frames.
1660   simulate_demuxer_stall_after_n_reads_ = 7;
1661
1662   // Queue up enough frames to trigger HAVE_ENOUGH. Each frame is 30 ms apart.
1663   // At this spacing, 200ms rounds to 7 frames.
1664   EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(0)));
1665   EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1);
1666   EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
1667   EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
1668   EXPECT_CALL(mock_cb_, OnVideoFrameRateChange(absl::optional<int>(33)));
1669   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _));
1670   QueueFrames("0 30 60 90 120 150 180");
1671   StartPlayingFrom(0);
1672   base::RunLoop().RunUntilIdle();
1673   ASSERT_EQ(renderer_->min_buffered_frames_for_testing(), 7);
1674   EXPECT_EQ(renderer_->effective_frames_queued_for_testing(), 7u);
1675   Mock::VerifyAndClearExpectations(&mock_cb_);
1676
1677   // Advance time to trigger HAVE_NOTHING (underflow).
1678   {
1679     SCOPED_TRACE("Waiting for BUFFERING_HAVE_NOTHING");
1680     WaitableMessageLoopEvent event;
1681     EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(180)));
1682     EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING,
1683                                                  DEMUXER_UNDERFLOW))
1684         .WillOnce(RunOnceClosure(event.GetClosure()));
1685     renderer_->OnTimeProgressing();
1686     time_source_.StartTicking();
1687     AdvanceTimeInMs(300);
1688     event.RunAndWait();
1689     Mock::VerifyAndClearExpectations(&mock_cb_);
1690   }
1691
1692   // Simulate delayed buffering state callbacks.
1693   time_source_.StopTicking();
1694   renderer_->OnTimeStopped();
1695
1696   // When latency hint set the max should increase while min remains steady
1697   // (user controls the min via hint).
1698   EXPECT_EQ(renderer_->min_buffered_frames_for_testing(), 7);
1699   EXPECT_EQ(renderer_->max_buffered_frames_for_testing(), 7 + 1);
1700
1701   Destroy();
1702 }
1703
1704 // Test that latency hint overrides low delay mode.
1705 TEST_F(VideoRendererLatencyHintTest, LatencyHintOverridesLowDelay) {
1706   // Enable low delay mode. Low delay mode is tested separately.
1707   InitializeWithLowDelay(true);
1708   EXPECT_EQ(renderer_->min_buffered_frames_for_testing(), 1);
1709
1710   // We must provide a |buffer_duration_| for the latencyHint to take effect
1711   // immediately. The VideoRendererAlgorithm will eventually provide a PTS-delta
1712   // duration, but not until after we've started rendering.
1713   buffer_duration_ = base::Milliseconds(30);
1714
1715   // Set latency hint to a medium value.
1716   renderer_->SetLatencyHint(base::Milliseconds(200));
1717
1718   // Initial frames should trigger various callbacks.
1719   EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(0)));
1720   EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1);
1721   EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
1722   EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
1723
1724   // Queue 6 frames, each 30 ms apart. At this spacing, 200ms rounds to
1725   // 7 frames, so 6 frames should be 1 shy of the HaveEnough threshold. Verify
1726   // that HAVE_ENOUGH is not triggered in spite of being initialized with low
1727   // delay mode.
1728   EXPECT_CALL(mock_cb_, OnVideoFrameRateChange(absl::optional<int>(33)));
1729   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _))
1730       .Times(0);
1731   QueueFrames("0 30 60 90 120 150");
1732   StartPlayingFrom(0);
1733   base::RunLoop().RunUntilIdle();
1734   ASSERT_EQ(renderer_->min_buffered_frames_for_testing(), 7);
1735   EXPECT_EQ(renderer_->effective_frames_queued_for_testing(), 6u);
1736   Mock::VerifyAndClearExpectations(&mock_cb_);
1737
1738   // Queue 1 additional frame and verify HaveEnough threshold is reached.
1739   EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
1740   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _));
1741   QueueFrames("180");
1742   SatisfyPendingDecode();
1743   base::RunLoop().RunUntilIdle();
1744   Mock::VerifyAndClearExpectations(&mock_cb_);
1745
1746   // Unset latencyHint, to verify default behavior. NOTE: low delay mode is not
1747   // restored when latency hint unset.
1748   renderer_->SetLatencyHint(absl::nullopt);
1749
1750   // Flush to return to clean slate.
1751   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING, _));
1752   Flush();
1753   Mock::VerifyAndClearExpectations(&mock_cb_);
1754
1755   VerifyDefaultRebufferingBehavior(1000);
1756
1757   Destroy();
1758 }
1759
1760 // Test that !CanReadWithoutStalling() overrides latency hint.
1761 TEST_F(VideoRendererLatencyHintTest,
1762        CantReadWithoutStallingOverridesLatencyHint) {
1763   Initialize();
1764
1765   // Let decoder indicate that it CANT read without stalling, meaning we should
1766   // enter HAVE_ENOUGH with just one effective frame (waiting for more frames
1767   // will stall the decoder).
1768   ON_CALL(*decoder_, CanReadWithoutStalling()).WillByDefault(Return(false));
1769
1770   // We must provide a |buffer_duration_| for the latencyHint to take effect
1771   // immediately. The VideoRendererAlgorithm will eventually provide a PTS-delta
1772   // duration, but not until after we've started rendering.
1773   buffer_duration_ = base::Milliseconds(30);
1774
1775   // Set latency hint to a medium value. At a spacing of 30ms this would set
1776   // the HAVE_ENOUGH threshold to 4 frames.
1777   renderer_->SetLatencyHint(base::Milliseconds(200));
1778
1779   // Initial frames should trigger various callbacks.
1780   EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(0)));
1781   EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1);
1782   EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
1783   EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
1784
1785   // Queue 1 frame. This is well short of what the latency hint would require,
1786   // but we CANT READ WITHOUT STALLING, so expect a transition to HAVE_ENOUGH
1787   // after just 1 frame.
1788   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _));
1789   QueueFrames("0");
1790   StartPlayingFrom(0);
1791   base::RunLoop().RunUntilIdle();
1792   ASSERT_EQ(renderer_->min_buffered_frames_for_testing(), 7);
1793   EXPECT_EQ(renderer_->effective_frames_queued_for_testing(), 1u);
1794   Mock::VerifyAndClearExpectations(&mock_cb_);
1795
1796   // Queue some additional frames, verify buffering state holds at HAVE_ENOUGH.
1797   QueueFrames("30 60 90 120");
1798   EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
1799   EXPECT_CALL(mock_cb_, OnBufferingStateChange(_, _)).Times(0);
1800   // SatisfyPendingDecode();
1801   base::RunLoop().RunUntilIdle();
1802   Mock::VerifyAndClearExpectations(&mock_cb_);
1803
1804   // Unset latency hint to verify 1-frame HAVE_ENOUGH threshold is maintained.
1805   renderer_->SetLatencyHint(absl::nullopt);
1806
1807   // Flush to return to clean slate.
1808   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING, _));
1809   Flush();
1810   Mock::VerifyAndClearExpectations(&mock_cb_);
1811
1812   // Expect HAVE_ENOUGH (and various other callbacks) again.
1813   EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _));
1814   EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(1000)));
1815   EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
1816   EXPECT_CALL(mock_cb_, OnVideoFrameRateChange(_)).Times(AnyNumber());
1817
1818   // Queue 1 frame.
1819   QueueFrames("1000");
1820   StartPlayingFrom(1000);
1821   base::RunLoop().RunUntilIdle();
1822   ASSERT_EQ(renderer_->min_buffered_frames_for_testing(), 4);
1823   EXPECT_EQ(renderer_->effective_frames_queued_for_testing(), 1u);
1824   Mock::VerifyAndClearExpectations(&mock_cb_);
1825
1826   Destroy();
1827 }
1828
1829 }  // namespace media