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/decoder_buffer_base.h" 15#include "chromecast/media/cma/base/frame_generator_for_test.h" 16#include "chromecast/media/cma/base/mock_frame_consumer.h" 17#include "chromecast/media/cma/base/mock_frame_provider.h" 18#include "chromecast/media/cma/ipc/media_memory_chunk.h" 19#include "chromecast/media/cma/ipc/media_message_fifo.h" 20#include "chromecast/media/cma/ipc_streamer/av_streamer_proxy.h" 21#include "chromecast/media/cma/ipc_streamer/coded_frame_provider_host.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" 26 27namespace chromecast { 28namespace media { 29 30namespace { 31 32class FifoMemoryChunk : public MediaMemoryChunk { 33 public: 34 FifoMemoryChunk(void* mem, size_t size) 35 : mem_(mem), size_(size) {} 36 virtual ~FifoMemoryChunk() {} 37 38 virtual void* data() const OVERRIDE { return mem_; } 39 virtual size_t size() const OVERRIDE { return size_; } 40 virtual bool valid() const OVERRIDE { return true; } 41 42 private: 43 void* mem_; 44 size_t size_; 45 46 DISALLOW_COPY_AND_ASSIGN(FifoMemoryChunk); 47}; 48 49} // namespace 50 51class AvStreamerTest : public testing::Test { 52 public: 53 AvStreamerTest(); 54 virtual ~AvStreamerTest(); 55 56 // Setups the test. 57 void Configure( 58 size_t frame_count, 59 const std::vector<bool>& provider_delayed_pattern, 60 const std::vector<bool>& consumer_delayed_pattern); 61 62 // Starts the test. 63 void Start(); 64 65 protected: 66 scoped_ptr<uint64[]> fifo_mem_; 67 68 scoped_ptr<AvStreamerProxy> av_buffer_proxy_; 69 scoped_ptr<CodedFrameProviderHost> coded_frame_provider_host_; 70 scoped_ptr<MockFrameConsumer> frame_consumer_; 71 72 private: 73 void OnTestTimeout(); 74 void OnTestCompleted(); 75 76 void OnFifoRead(); 77 void OnFifoWrite(); 78 79 DISALLOW_COPY_AND_ASSIGN(AvStreamerTest); 80}; 81 82AvStreamerTest::AvStreamerTest() { 83} 84 85AvStreamerTest::~AvStreamerTest() { 86} 87 88void AvStreamerTest::Configure( 89 size_t frame_count, 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); 100 } 101 frame_specs[frame_specs.size() - 1].is_eos = true; 102 103 scoped_ptr<FrameGeneratorForTest> frame_generator_provider( 104 new FrameGeneratorForTest(frame_specs)); 105 scoped_ptr<FrameGeneratorForTest> frame_generator_consumer( 106 new FrameGeneratorForTest(frame_specs)); 107 108 scoped_ptr<MockFrameProvider> frame_provider(new MockFrameProvider()); 109 frame_provider->Configure(provider_delayed_pattern, 110 frame_generator_provider.Pass()); 111 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)), 118 true)); 119 scoped_ptr<MediaMessageFifo> consumer_fifo( 120 new MediaMessageFifo( 121 scoped_ptr<MediaMemoryChunk>( 122 new FifoMemoryChunk(&fifo_mem_[0], fifo_size_div_8 * 8)), 123 false)); 124 producer_fifo->ObserveWriteActivity( 125 base::Bind(&AvStreamerTest::OnFifoWrite, base::Unretained(this))); 126 consumer_fifo->ObserveReadActivity( 127 base::Bind(&AvStreamerTest::OnFifoRead, base::Unretained(this))); 128 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()); 134 135 coded_frame_provider_host_.reset( 136 new CodedFrameProviderHost(consumer_fifo.Pass())); 137 138 frame_consumer_.reset( 139 new MockFrameConsumer(coded_frame_provider_host_.get())); 140 frame_consumer_->Configure( 141 consumer_delayed_pattern, 142 false, 143 frame_generator_consumer.Pass()); 144} 145 146void AvStreamerTest::Start() { 147 base::MessageLoopProxy::current()->PostTask( 148 FROM_HERE, 149 base::Bind(&AvStreamerProxy::Start, 150 base::Unretained(av_buffer_proxy_.get()))); 151 152 frame_consumer_->Start( 153 base::Bind(&AvStreamerTest::OnTestCompleted, 154 base::Unretained(this))); 155} 156 157void AvStreamerTest::OnTestTimeout() { 158 ADD_FAILURE() << "Test timed out"; 159 if (base::MessageLoop::current()) 160 base::MessageLoop::current()->QuitWhenIdle(); 161} 162 163void AvStreamerTest::OnTestCompleted() { 164 base::MessageLoop::current()->QuitWhenIdle(); 165} 166 167void AvStreamerTest::OnFifoWrite() { 168 base::MessageLoopProxy::current()->PostTask( 169 FROM_HERE, 170 base::Bind(&CodedFrameProviderHost::OnFifoWriteEvent, 171 base::Unretained(coded_frame_provider_host_.get()))); 172} 173 174void AvStreamerTest::OnFifoRead() { 175 base::MessageLoopProxy::current()->PostTask( 176 FROM_HERE, 177 base::Bind(&AvStreamerProxy::OnFifoReadEvent, 178 base::Unretained(av_buffer_proxy_.get()))); 179} 180 181TEST_F(AvStreamerTest, FastProviderSlowConsumer) { 182 bool provider_delayed_pattern[] = { false }; 183 bool consumer_delayed_pattern[] = { true }; 184 185 const size_t frame_count = 100u; 186 Configure( 187 frame_count, 188 std::vector<bool>( 189 provider_delayed_pattern, 190 provider_delayed_pattern + arraysize(provider_delayed_pattern)), 191 std::vector<bool>( 192 consumer_delayed_pattern, 193 consumer_delayed_pattern + arraysize(consumer_delayed_pattern))); 194 195 scoped_ptr<base::MessageLoop> message_loop(new base::MessageLoop()); 196 message_loop->PostTask( 197 FROM_HERE, 198 base::Bind(&AvStreamerTest::Start, base::Unretained(this))); 199 message_loop->Run(); 200}; 201 202TEST_F(AvStreamerTest, SlowProviderFastConsumer) { 203 bool provider_delayed_pattern[] = { true }; 204 bool consumer_delayed_pattern[] = { false }; 205 206 const size_t frame_count = 100u; 207 Configure( 208 frame_count, 209 std::vector<bool>( 210 provider_delayed_pattern, 211 provider_delayed_pattern + arraysize(provider_delayed_pattern)), 212 std::vector<bool>( 213 consumer_delayed_pattern, 214 consumer_delayed_pattern + arraysize(consumer_delayed_pattern))); 215 216 scoped_ptr<base::MessageLoop> message_loop(new base::MessageLoop()); 217 message_loop->PostTask( 218 FROM_HERE, 219 base::Bind(&AvStreamerTest::Start, base::Unretained(this))); 220 message_loop->Run(); 221}; 222 223TEST_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 229 }; 230 bool consumer_delayed_pattern[] = { 231 true, true, true, true, true, true, true, 232 false, false, false, false, false, false, false 233 }; 234 235 const size_t frame_count = 100u; 236 Configure( 237 frame_count, 238 std::vector<bool>( 239 provider_delayed_pattern, 240 provider_delayed_pattern + arraysize(provider_delayed_pattern)), 241 std::vector<bool>( 242 consumer_delayed_pattern, 243 consumer_delayed_pattern + arraysize(consumer_delayed_pattern))); 244 245 scoped_ptr<base::MessageLoop> message_loop(new base::MessageLoop()); 246 message_loop->PostTask( 247 FROM_HERE, 248 base::Bind(&AvStreamerTest::Start, base::Unretained(this))); 249 message_loop->Run(); 250}; 251 252} // namespace media 253} // namespace chromecast 254