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/threading/thread.h"
13 #include "base/time/time.h"
14 #include "chromecast/media/cma/base/decoder_buffer_base.h"
15 #include "chromecast/media/cma/ipc/media_memory_chunk.h"
16 #include "chromecast/media/cma/ipc/media_message_fifo.h"
17 #include "chromecast/media/cma/ipc_streamer/av_streamer_proxy.h"
18 #include "chromecast/media/cma/ipc_streamer/coded_frame_provider_host.h"
19 #include "chromecast/media/cma/test/frame_generator_for_test.h"
20 #include "chromecast/media/cma/test/mock_frame_consumer.h"
21 #include "chromecast/media/cma/test/mock_frame_provider.h"
22 #include "media/base/audio_decoder_config.h"
23 #include "media/base/decoder_buffer.h"
24 #include "media/base/video_decoder_config.h"
25 #include "testing/gtest/include/gtest/gtest.h"
27 namespace chromecast
{
32 class FifoMemoryChunk
: public MediaMemoryChunk
{
34 FifoMemoryChunk(void* mem
, size_t size
)
35 : mem_(mem
), size_(size
) {}
36 ~FifoMemoryChunk() override
{}
38 void* data() const override
{ return mem_
; }
39 size_t size() const override
{ return size_
; }
40 bool valid() const override
{ return true; }
46 DISALLOW_COPY_AND_ASSIGN(FifoMemoryChunk
);
51 class AvStreamerTest
: public testing::Test
{
54 ~AvStreamerTest() override
;
59 const std::vector
<bool>& provider_delayed_pattern
,
60 const std::vector
<bool>& consumer_delayed_pattern
);
66 scoped_ptr
<uint64
[]> fifo_mem_
;
68 scoped_ptr
<AvStreamerProxy
> av_buffer_proxy_
;
69 scoped_ptr
<CodedFrameProviderHost
> coded_frame_provider_host_
;
70 scoped_ptr
<MockFrameConsumer
> frame_consumer_
;
74 void OnTestCompleted();
79 DISALLOW_COPY_AND_ASSIGN(AvStreamerTest
);
82 AvStreamerTest::AvStreamerTest() {
85 AvStreamerTest::~AvStreamerTest() {
88 void AvStreamerTest::Configure(
90 const std::vector
<bool>& provider_delayed_pattern
,
91 const std::vector
<bool>& consumer_delayed_pattern
) {
92 // Frame generation on the producer and consumer side.
93 std::vector
<FrameGeneratorForTest::FrameSpec
> frame_specs
;
94 frame_specs
.resize(frame_count
);
95 for (size_t k
= 0; k
< frame_specs
.size() - 1; k
++) {
96 frame_specs
[k
].has_config
= (k
== 0);
97 frame_specs
[k
].timestamp
= base::TimeDelta::FromMilliseconds(40) * k
;
98 frame_specs
[k
].size
= 512;
99 frame_specs
[k
].has_decrypt_config
= ((k
% 3) == 0);
101 frame_specs
[frame_specs
.size() - 1].is_eos
= true;
103 scoped_ptr
<FrameGeneratorForTest
> frame_generator_provider(
104 new FrameGeneratorForTest(frame_specs
));
105 scoped_ptr
<FrameGeneratorForTest
> frame_generator_consumer(
106 new FrameGeneratorForTest(frame_specs
));
108 scoped_ptr
<MockFrameProvider
> frame_provider(new MockFrameProvider());
109 frame_provider
->Configure(provider_delayed_pattern
,
110 frame_generator_provider
.Pass());
112 size_t fifo_size_div_8
= 512;
113 fifo_mem_
.reset(new uint64
[fifo_size_div_8
]);
114 scoped_ptr
<MediaMessageFifo
> producer_fifo(
115 new MediaMessageFifo(
116 scoped_ptr
<MediaMemoryChunk
>(
117 new FifoMemoryChunk(&fifo_mem_
[0], fifo_size_div_8
* 8)),
119 scoped_ptr
<MediaMessageFifo
> consumer_fifo(
120 new MediaMessageFifo(
121 scoped_ptr
<MediaMemoryChunk
>(
122 new FifoMemoryChunk(&fifo_mem_
[0], fifo_size_div_8
* 8)),
124 producer_fifo
->ObserveWriteActivity(
125 base::Bind(&AvStreamerTest::OnFifoWrite
, base::Unretained(this)));
126 consumer_fifo
->ObserveReadActivity(
127 base::Bind(&AvStreamerTest::OnFifoRead
, base::Unretained(this)));
129 av_buffer_proxy_
.reset(
130 new AvStreamerProxy());
131 av_buffer_proxy_
->SetCodedFrameProvider(
132 scoped_ptr
<CodedFrameProvider
>(frame_provider
.release()));
133 av_buffer_proxy_
->SetMediaMessageFifo(producer_fifo
.Pass());
135 coded_frame_provider_host_
.reset(
136 new CodedFrameProviderHost(consumer_fifo
.Pass()));
138 frame_consumer_
.reset(
139 new MockFrameConsumer(coded_frame_provider_host_
.get()));
140 frame_consumer_
->Configure(
141 consumer_delayed_pattern
,
143 frame_generator_consumer
.Pass());
146 void AvStreamerTest::Start() {
147 base::MessageLoopProxy::current()->PostTask(
149 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::MessageLoopProxy::current()->PostTask(
170 base::Bind(&CodedFrameProviderHost::OnFifoWriteEvent
,
171 base::Unretained(coded_frame_provider_host_
.get())));
174 void AvStreamerTest::OnFifoRead() {
175 base::MessageLoopProxy::current()->PostTask(
177 base::Bind(&AvStreamerProxy::OnFifoReadEvent
,
178 base::Unretained(av_buffer_proxy_
.get())));
181 TEST_F(AvStreamerTest
, FastProviderSlowConsumer
) {
182 bool provider_delayed_pattern
[] = { false };
183 bool consumer_delayed_pattern
[] = { true };
185 const size_t frame_count
= 100u;
189 provider_delayed_pattern
,
190 provider_delayed_pattern
+ arraysize(provider_delayed_pattern
)),
192 consumer_delayed_pattern
,
193 consumer_delayed_pattern
+ arraysize(consumer_delayed_pattern
)));
195 scoped_ptr
<base::MessageLoop
> message_loop(new base::MessageLoop());
196 message_loop
->PostTask(
198 base::Bind(&AvStreamerTest::Start
, base::Unretained(this)));
202 TEST_F(AvStreamerTest
, SlowProviderFastConsumer
) {
203 bool provider_delayed_pattern
[] = { true };
204 bool consumer_delayed_pattern
[] = { false };
206 const size_t frame_count
= 100u;
210 provider_delayed_pattern
,
211 provider_delayed_pattern
+ arraysize(provider_delayed_pattern
)),
213 consumer_delayed_pattern
,
214 consumer_delayed_pattern
+ arraysize(consumer_delayed_pattern
)));
216 scoped_ptr
<base::MessageLoop
> message_loop(new base::MessageLoop());
217 message_loop
->PostTask(
219 base::Bind(&AvStreamerTest::Start
, base::Unretained(this)));
223 TEST_F(AvStreamerTest
, SlowFastProducerConsumer
) {
224 // Pattern lengths are prime between each other
225 // so that a lot of combinations can be tested.
226 bool provider_delayed_pattern
[] = {
227 true, true, true, true, true,
228 false, false, false, false
230 bool consumer_delayed_pattern
[] = {
231 true, true, true, true, true, true, true,
232 false, false, false, false, false, false, false
235 const size_t frame_count
= 100u;
239 provider_delayed_pattern
,
240 provider_delayed_pattern
+ arraysize(provider_delayed_pattern
)),
242 consumer_delayed_pattern
,
243 consumer_delayed_pattern
+ arraysize(consumer_delayed_pattern
)));
245 scoped_ptr
<base::MessageLoop
> message_loop(new base::MessageLoop());
246 message_loop
->PostTask(
248 base::Bind(&AvStreamerTest::Start
, base::Unretained(this)));
253 } // namespace chromecast