1// Copyright 2014 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 <list>
6#include <vector>
7
8#include "base/basictypes.h"
9#include "base/bind.h"
10#include "base/memory/ref_counted.h"
11#include "base/memory/scoped_ptr.h"
12#include "base/threading/thread.h"
13#include "base/time/time.h"
14#include "chromecast/media/cma/base/buffering_frame_provider.h"
15#include "chromecast/media/cma/base/decoder_buffer_base.h"
16#include "chromecast/media/cma/base/frame_generator_for_test.h"
17#include "chromecast/media/cma/base/mock_frame_consumer.h"
18#include "chromecast/media/cma/base/mock_frame_provider.h"
19#include "media/base/audio_decoder_config.h"
20#include "media/base/decoder_buffer.h"
21#include "media/base/video_decoder_config.h"
22#include "testing/gtest/include/gtest/gtest.h"
23
24namespace chromecast {
25namespace media {
26
27class BufferingFrameProviderTest : public testing::Test {
28 public:
29  BufferingFrameProviderTest();
30  virtual ~BufferingFrameProviderTest();
31
32  // Setup the test.
33  void Configure(
34      size_t frame_count,
35      const std::vector<bool>& provider_delayed_pattern,
36      const std::vector<bool>& consumer_delayed_pattern);
37
38  // Start the test.
39  void Start();
40
41 protected:
42  scoped_ptr<BufferingFrameProvider> buffering_frame_provider_;
43  scoped_ptr<MockFrameConsumer> frame_consumer_;
44
45 private:
46  void OnTestTimeout();
47  void OnTestCompleted();
48
49  DISALLOW_COPY_AND_ASSIGN(BufferingFrameProviderTest);
50};
51
52BufferingFrameProviderTest::BufferingFrameProviderTest() {
53}
54
55BufferingFrameProviderTest::~BufferingFrameProviderTest() {
56}
57
58void BufferingFrameProviderTest::Configure(
59    size_t frame_count,
60    const std::vector<bool>& provider_delayed_pattern,
61    const std::vector<bool>& consumer_delayed_pattern) {
62  DCHECK_GE(frame_count, 1u);
63
64  // Frame generation on the producer and consumer side.
65  std::vector<FrameGeneratorForTest::FrameSpec> frame_specs(frame_count);
66  for (size_t k = 0; k < frame_specs.size() - 1; k++) {
67    frame_specs[k].has_config = (k == 0);
68    frame_specs[k].timestamp = base::TimeDelta::FromMilliseconds(40) * k;
69    frame_specs[k].size = 512;
70    frame_specs[k].has_decrypt_config = ((k % 3) == 0);
71  }
72  frame_specs[frame_specs.size() - 1].is_eos = true;
73
74  scoped_ptr<FrameGeneratorForTest> frame_generator_provider(
75      new FrameGeneratorForTest(frame_specs));
76  scoped_ptr<FrameGeneratorForTest> frame_generator_consumer(
77      new FrameGeneratorForTest(frame_specs));
78
79  scoped_ptr<MockFrameProvider> frame_provider(new MockFrameProvider());
80  frame_provider->Configure(provider_delayed_pattern,
81                            frame_generator_provider.Pass());
82
83  size_t max_frame_size = 10 * 1024;
84  size_t buffer_size = 10 * max_frame_size;
85  buffering_frame_provider_.reset(
86      new BufferingFrameProvider(
87          scoped_ptr<CodedFrameProvider>(frame_provider.release()),
88          buffer_size,
89          max_frame_size,
90          BufferingFrameProvider::FrameBufferedCB()));
91
92  frame_consumer_.reset(
93      new MockFrameConsumer(buffering_frame_provider_.get()));
94  frame_consumer_->Configure(
95      consumer_delayed_pattern,
96      false,
97      frame_generator_consumer.Pass());
98}
99
100void BufferingFrameProviderTest::Start() {
101  frame_consumer_->Start(
102      base::Bind(&BufferingFrameProviderTest::OnTestCompleted,
103                 base::Unretained(this)));
104}
105
106void BufferingFrameProviderTest::OnTestTimeout() {
107  ADD_FAILURE() << "Test timed out";
108  if (base::MessageLoop::current())
109    base::MessageLoop::current()->QuitWhenIdle();
110}
111
112void BufferingFrameProviderTest::OnTestCompleted() {
113  base::MessageLoop::current()->QuitWhenIdle();
114}
115
116TEST_F(BufferingFrameProviderTest, FastProviderSlowConsumer) {
117  bool provider_delayed_pattern[] = { false };
118  bool consumer_delayed_pattern[] = { true };
119
120  const size_t frame_count = 100u;
121  Configure(
122      frame_count,
123      std::vector<bool>(
124          provider_delayed_pattern,
125          provider_delayed_pattern + arraysize(provider_delayed_pattern)),
126      std::vector<bool>(
127          consumer_delayed_pattern,
128          consumer_delayed_pattern + arraysize(consumer_delayed_pattern)));
129
130  scoped_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
131  message_loop->PostTask(
132      FROM_HERE,
133      base::Bind(&BufferingFrameProviderTest::Start, base::Unretained(this)));
134  message_loop->Run();
135};
136
137TEST_F(BufferingFrameProviderTest, SlowProviderFastConsumer) {
138  bool provider_delayed_pattern[] = { true };
139  bool consumer_delayed_pattern[] = { false };
140
141  const size_t frame_count = 100u;
142  Configure(
143      frame_count,
144      std::vector<bool>(
145          provider_delayed_pattern,
146          provider_delayed_pattern + arraysize(provider_delayed_pattern)),
147      std::vector<bool>(
148          consumer_delayed_pattern,
149          consumer_delayed_pattern + arraysize(consumer_delayed_pattern)));
150
151  scoped_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
152  message_loop->PostTask(
153      FROM_HERE,
154      base::Bind(&BufferingFrameProviderTest::Start, base::Unretained(this)));
155  message_loop->Run();
156};
157
158TEST_F(BufferingFrameProviderTest, SlowFastProducerConsumer) {
159  // Lengths are prime between each other so we can test a lot of combinations.
160  bool provider_delayed_pattern[] = {
161    true, true, true, true, true,
162    false, false, false, false
163  };
164  bool consumer_delayed_pattern[] = {
165    true, true, true, true, true, true, true,
166    false, false, false, false, false, false, false
167  };
168
169  const size_t frame_count = 100u;
170  Configure(
171      frame_count,
172      std::vector<bool>(
173          provider_delayed_pattern,
174          provider_delayed_pattern + arraysize(provider_delayed_pattern)),
175      std::vector<bool>(
176          consumer_delayed_pattern,
177          consumer_delayed_pattern + arraysize(consumer_delayed_pattern)));
178
179  scoped_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
180  message_loop->PostTask(
181      FROM_HERE,
182      base::Bind(&BufferingFrameProviderTest::Start, base::Unretained(this)));
183  message_loop->Run();
184};
185
186}  // namespace media
187}  // namespace chromecast
188