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.
8 #include "base/basictypes.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/thread_task_runner_handle.h"
13 #include "base/threading/thread.h"
14 #include "base/time/time.h"
15 #include "chromecast/media/cma/base/decoder_buffer_base.h"
16 #include "chromecast/media/cma/ipc/media_memory_chunk.h"
17 #include "chromecast/media/cma/ipc/media_message_fifo.h"
18 #include "chromecast/media/cma/ipc_streamer/av_streamer_proxy.h"
19 #include "chromecast/media/cma/ipc_streamer/coded_frame_provider_host.h"
20 #include "chromecast/media/cma/test/frame_generator_for_test.h"
21 #include "chromecast/media/cma/test/mock_frame_consumer.h"
22 #include "chromecast/media/cma/test/mock_frame_provider.h"
23 #include "media/base/audio_decoder_config.h"
24 #include "media/base/decoder_buffer.h"
25 #include "media/base/video_decoder_config.h"
26 #include "testing/gtest/include/gtest/gtest.h"
28 namespace chromecast
{
33 class FifoMemoryChunk
: public MediaMemoryChunk
{
35 FifoMemoryChunk(void* mem
, size_t size
)
36 : mem_(mem
), size_(size
) {}
37 ~FifoMemoryChunk() override
{}
39 void* data() const override
{ return mem_
; }
40 size_t size() const override
{ return size_
; }
41 bool valid() const override
{ return true; }
47 DISALLOW_COPY_AND_ASSIGN(FifoMemoryChunk
);
52 class AvStreamerTest
: public testing::Test
{
55 ~AvStreamerTest() override
;
60 const std::vector
<bool>& provider_delayed_pattern
,
61 const std::vector
<bool>& consumer_delayed_pattern
);
67 scoped_ptr
<uint64
[]> fifo_mem_
;
69 scoped_ptr
<AvStreamerProxy
> av_buffer_proxy_
;
70 scoped_ptr
<CodedFrameProviderHost
> coded_frame_provider_host_
;
71 scoped_ptr
<MockFrameConsumer
> frame_consumer_
;
75 void OnTestCompleted();
80 DISALLOW_COPY_AND_ASSIGN(AvStreamerTest
);
83 AvStreamerTest::AvStreamerTest() {
86 AvStreamerTest::~AvStreamerTest() {
89 void AvStreamerTest::Configure(
91 const std::vector
<bool>& provider_delayed_pattern
,
92 const std::vector
<bool>& consumer_delayed_pattern
) {
93 // Frame generation on the producer and consumer side.
94 std::vector
<FrameGeneratorForTest::FrameSpec
> frame_specs
;
95 frame_specs
.resize(frame_count
);
96 for (size_t k
= 0; k
< frame_specs
.size() - 1; k
++) {
97 frame_specs
[k
].has_config
= (k
== 0);
98 frame_specs
[k
].timestamp
= base::TimeDelta::FromMilliseconds(40) * k
;
99 frame_specs
[k
].size
= 512;
100 frame_specs
[k
].has_decrypt_config
= ((k
% 3) == 0);
102 frame_specs
[frame_specs
.size() - 1].is_eos
= true;
104 scoped_ptr
<FrameGeneratorForTest
> frame_generator_provider(
105 new FrameGeneratorForTest(frame_specs
));
106 scoped_ptr
<FrameGeneratorForTest
> frame_generator_consumer(
107 new FrameGeneratorForTest(frame_specs
));
109 scoped_ptr
<MockFrameProvider
> frame_provider(new MockFrameProvider());
110 frame_provider
->Configure(provider_delayed_pattern
,
111 frame_generator_provider
.Pass());
113 size_t fifo_size_div_8
= 512;
114 fifo_mem_
.reset(new uint64
[fifo_size_div_8
]);
115 scoped_ptr
<MediaMessageFifo
> producer_fifo(
116 new MediaMessageFifo(
117 scoped_ptr
<MediaMemoryChunk
>(
118 new FifoMemoryChunk(&fifo_mem_
[0], fifo_size_div_8
* 8)),
120 scoped_ptr
<MediaMessageFifo
> consumer_fifo(
121 new MediaMessageFifo(
122 scoped_ptr
<MediaMemoryChunk
>(
123 new FifoMemoryChunk(&fifo_mem_
[0], fifo_size_div_8
* 8)),
125 producer_fifo
->ObserveWriteActivity(
126 base::Bind(&AvStreamerTest::OnFifoWrite
, base::Unretained(this)));
127 consumer_fifo
->ObserveReadActivity(
128 base::Bind(&AvStreamerTest::OnFifoRead
, base::Unretained(this)));
130 av_buffer_proxy_
.reset(
131 new AvStreamerProxy());
132 av_buffer_proxy_
->SetCodedFrameProvider(
133 scoped_ptr
<CodedFrameProvider
>(frame_provider
.release()));
134 av_buffer_proxy_
->SetMediaMessageFifo(producer_fifo
.Pass());
136 coded_frame_provider_host_
.reset(
137 new CodedFrameProviderHost(consumer_fifo
.Pass()));
139 frame_consumer_
.reset(
140 new MockFrameConsumer(coded_frame_provider_host_
.get()));
141 frame_consumer_
->Configure(
142 consumer_delayed_pattern
,
144 frame_generator_consumer
.Pass());
147 void AvStreamerTest::Start() {
148 base::ThreadTaskRunnerHandle::Get()->PostTask(
149 FROM_HERE
, base::Bind(&AvStreamerProxy::Start
,
150 base::Unretained(av_buffer_proxy_
.get())));
152 frame_consumer_
->Start(
153 base::Bind(&AvStreamerTest::OnTestCompleted
,
154 base::Unretained(this)));
157 void AvStreamerTest::OnTestTimeout() {
158 ADD_FAILURE() << "Test timed out";
159 if (base::MessageLoop::current())
160 base::MessageLoop::current()->QuitWhenIdle();
163 void AvStreamerTest::OnTestCompleted() {
164 base::MessageLoop::current()->QuitWhenIdle();
167 void AvStreamerTest::OnFifoWrite() {
168 base::ThreadTaskRunnerHandle::Get()->PostTask(
170 base::Bind(&CodedFrameProviderHost::OnFifoWriteEvent
,
171 base::Unretained(coded_frame_provider_host_
.get())));
174 void AvStreamerTest::OnFifoRead() {
175 base::ThreadTaskRunnerHandle::Get()->PostTask(
176 FROM_HERE
, base::Bind(&AvStreamerProxy::OnFifoReadEvent
,
177 base::Unretained(av_buffer_proxy_
.get())));
180 TEST_F(AvStreamerTest
, FastProviderSlowConsumer
) {
181 bool provider_delayed_pattern
[] = { false };
182 bool consumer_delayed_pattern
[] = { true };
184 const size_t frame_count
= 100u;
188 provider_delayed_pattern
,
189 provider_delayed_pattern
+ arraysize(provider_delayed_pattern
)),
191 consumer_delayed_pattern
,
192 consumer_delayed_pattern
+ arraysize(consumer_delayed_pattern
)));
194 scoped_ptr
<base::MessageLoop
> message_loop(new base::MessageLoop());
195 message_loop
->PostTask(
197 base::Bind(&AvStreamerTest::Start
, base::Unretained(this)));
201 TEST_F(AvStreamerTest
, SlowProviderFastConsumer
) {
202 bool provider_delayed_pattern
[] = { true };
203 bool consumer_delayed_pattern
[] = { false };
205 const size_t frame_count
= 100u;
209 provider_delayed_pattern
,
210 provider_delayed_pattern
+ arraysize(provider_delayed_pattern
)),
212 consumer_delayed_pattern
,
213 consumer_delayed_pattern
+ arraysize(consumer_delayed_pattern
)));
215 scoped_ptr
<base::MessageLoop
> message_loop(new base::MessageLoop());
216 message_loop
->PostTask(
218 base::Bind(&AvStreamerTest::Start
, base::Unretained(this)));
222 TEST_F(AvStreamerTest
, SlowFastProducerConsumer
) {
223 // Pattern lengths are prime between each other
224 // so that a lot of combinations can be tested.
225 bool provider_delayed_pattern
[] = {
226 true, true, true, true, true,
227 false, false, false, false
229 bool consumer_delayed_pattern
[] = {
230 true, true, true, true, true, true, true,
231 false, false, false, false, false, false, false
234 const size_t frame_count
= 100u;
238 provider_delayed_pattern
,
239 provider_delayed_pattern
+ arraysize(provider_delayed_pattern
)),
241 consumer_delayed_pattern
,
242 consumer_delayed_pattern
+ arraysize(consumer_delayed_pattern
)));
244 scoped_ptr
<base::MessageLoop
> message_loop(new base::MessageLoop());
245 message_loop
->PostTask(
247 base::Bind(&AvStreamerTest::Start
, base::Unretained(this)));
252 } // namespace chromecast