• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 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 "media/base/test_helpers.h"
6 
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/pickle.h"
11 #include "base/test/test_timeouts.h"
12 #include "base/time/time.h"
13 #include "base/timer/timer.h"
14 #include "media/base/audio_buffer.h"
15 #include "media/base/bind_to_current_loop.h"
16 #include "media/base/decoder_buffer.h"
17 #include "ui/gfx/rect.h"
18 
19 using ::testing::_;
20 using ::testing::StrictMock;
21 
22 namespace media {
23 
24 // Utility mock for testing methods expecting Closures and PipelineStatusCBs.
25 class MockCallback : public base::RefCountedThreadSafe<MockCallback> {
26  public:
27   MockCallback();
28   MOCK_METHOD0(Run, void());
29   MOCK_METHOD1(RunWithStatus, void(PipelineStatus));
30 
31  protected:
32   friend class base::RefCountedThreadSafe<MockCallback>;
33   virtual ~MockCallback();
34 
35  private:
36   DISALLOW_COPY_AND_ASSIGN(MockCallback);
37 };
38 
MockCallback()39 MockCallback::MockCallback() {}
~MockCallback()40 MockCallback::~MockCallback() {}
41 
NewExpectedClosure()42 base::Closure NewExpectedClosure() {
43   StrictMock<MockCallback>* callback = new StrictMock<MockCallback>();
44   EXPECT_CALL(*callback, Run());
45   return base::Bind(&MockCallback::Run, callback);
46 }
47 
NewExpectedStatusCB(PipelineStatus status)48 PipelineStatusCB NewExpectedStatusCB(PipelineStatus status) {
49   StrictMock<MockCallback>* callback = new StrictMock<MockCallback>();
50   EXPECT_CALL(*callback, RunWithStatus(status));
51   return base::Bind(&MockCallback::RunWithStatus, callback);
52 }
53 
WaitableMessageLoopEvent()54 WaitableMessageLoopEvent::WaitableMessageLoopEvent()
55     : message_loop_(base::MessageLoop::current()),
56       signaled_(false),
57       status_(PIPELINE_OK) {
58   DCHECK(message_loop_);
59 }
60 
~WaitableMessageLoopEvent()61 WaitableMessageLoopEvent::~WaitableMessageLoopEvent() {}
62 
GetClosure()63 base::Closure WaitableMessageLoopEvent::GetClosure() {
64   DCHECK_EQ(message_loop_, base::MessageLoop::current());
65   return BindToCurrentLoop(base::Bind(
66       &WaitableMessageLoopEvent::OnCallback, base::Unretained(this),
67       PIPELINE_OK));
68 }
69 
GetPipelineStatusCB()70 PipelineStatusCB WaitableMessageLoopEvent::GetPipelineStatusCB() {
71   DCHECK_EQ(message_loop_, base::MessageLoop::current());
72   return BindToCurrentLoop(base::Bind(
73       &WaitableMessageLoopEvent::OnCallback, base::Unretained(this)));
74 }
75 
RunAndWait()76 void WaitableMessageLoopEvent::RunAndWait() {
77   RunAndWaitForStatus(PIPELINE_OK);
78 }
79 
RunAndWaitForStatus(PipelineStatus expected)80 void WaitableMessageLoopEvent::RunAndWaitForStatus(PipelineStatus expected) {
81   DCHECK_EQ(message_loop_, base::MessageLoop::current());
82   if (signaled_) {
83     EXPECT_EQ(expected, status_);
84     return;
85   }
86 
87   base::Timer timer(false, false);
88   timer.Start(FROM_HERE, TestTimeouts::action_timeout(), base::Bind(
89       &WaitableMessageLoopEvent::OnTimeout, base::Unretained(this)));
90 
91   message_loop_->Run();
92   EXPECT_TRUE(signaled_);
93   EXPECT_EQ(expected, status_);
94 }
95 
OnCallback(PipelineStatus status)96 void WaitableMessageLoopEvent::OnCallback(PipelineStatus status) {
97   DCHECK_EQ(message_loop_, base::MessageLoop::current());
98   signaled_ = true;
99   status_ = status;
100   message_loop_->QuitWhenIdle();
101 }
102 
OnTimeout()103 void WaitableMessageLoopEvent::OnTimeout() {
104   DCHECK_EQ(message_loop_, base::MessageLoop::current());
105   ADD_FAILURE() << "Timed out waiting for message loop to quit";
106   message_loop_->QuitWhenIdle();
107 }
108 
GetTestConfig(VideoCodec codec,gfx::Size coded_size,bool is_encrypted)109 static VideoDecoderConfig GetTestConfig(VideoCodec codec,
110                                         gfx::Size coded_size,
111                                         bool is_encrypted) {
112   gfx::Rect visible_rect(coded_size.width(), coded_size.height());
113   gfx::Size natural_size = coded_size;
114 
115   return VideoDecoderConfig(codec, VIDEO_CODEC_PROFILE_UNKNOWN,
116       VideoFrame::YV12, coded_size, visible_rect, natural_size,
117       NULL, 0, is_encrypted);
118 }
119 
120 static const gfx::Size kNormalSize(320, 240);
121 static const gfx::Size kLargeSize(640, 480);
122 
Invalid()123 VideoDecoderConfig TestVideoConfig::Invalid() {
124   return GetTestConfig(kUnknownVideoCodec, kNormalSize, false);
125 }
126 
Normal()127 VideoDecoderConfig TestVideoConfig::Normal() {
128   return GetTestConfig(kCodecVP8, kNormalSize, false);
129 }
130 
NormalEncrypted()131 VideoDecoderConfig TestVideoConfig::NormalEncrypted() {
132   return GetTestConfig(kCodecVP8, kNormalSize, true);
133 }
134 
Large()135 VideoDecoderConfig TestVideoConfig::Large() {
136   return GetTestConfig(kCodecVP8, kLargeSize, false);
137 }
138 
LargeEncrypted()139 VideoDecoderConfig TestVideoConfig::LargeEncrypted() {
140   return GetTestConfig(kCodecVP8, kLargeSize, true);
141 }
142 
NormalCodedSize()143 gfx::Size TestVideoConfig::NormalCodedSize() {
144   return kNormalSize;
145 }
146 
LargeCodedSize()147 gfx::Size TestVideoConfig::LargeCodedSize() {
148   return kLargeSize;
149 }
150 
151 template <class T>
MakeAudioBuffer(SampleFormat format,ChannelLayout channel_layout,size_t channel_count,int sample_rate,T start,T increment,size_t frames,base::TimeDelta timestamp)152 scoped_refptr<AudioBuffer> MakeAudioBuffer(SampleFormat format,
153                                            ChannelLayout channel_layout,
154                                            size_t channel_count,
155                                            int sample_rate,
156                                            T start,
157                                            T increment,
158                                            size_t frames,
159                                            base::TimeDelta timestamp) {
160   const size_t channels = ChannelLayoutToChannelCount(channel_layout);
161   scoped_refptr<AudioBuffer> output =
162       AudioBuffer::CreateBuffer(format,
163                                 channel_layout,
164                                 static_cast<int>(channel_count),
165                                 sample_rate,
166                                 static_cast<int>(frames));
167   output->set_timestamp(timestamp);
168 
169   const bool is_planar =
170       format == kSampleFormatPlanarS16 || format == kSampleFormatPlanarF32;
171 
172   // Values in channel 0 will be:
173   //   start
174   //   start + increment
175   //   start + 2 * increment, ...
176   // While, values in channel 1 will be:
177   //   start + frames * increment
178   //   start + (frames + 1) * increment
179   //   start + (frames + 2) * increment, ...
180   for (size_t ch = 0; ch < channels; ++ch) {
181     T* buffer =
182         reinterpret_cast<T*>(output->channel_data()[is_planar ? ch : 0]);
183     const T v = static_cast<T>(start + ch * frames * increment);
184     for (size_t i = 0; i < frames; ++i) {
185       buffer[is_planar ? i : ch + i * channels] =
186           static_cast<T>(v + i * increment);
187     }
188   }
189   return output;
190 }
191 
192 // Instantiate all the types of MakeAudioBuffer() and
193 // MakeAudioBuffer() needed.
194 #define DEFINE_MAKE_AUDIO_BUFFER_INSTANCE(type)              \
195   template scoped_refptr<AudioBuffer> MakeAudioBuffer<type>( \
196       SampleFormat format,                                   \
197       ChannelLayout channel_layout,                          \
198       size_t channel_count,                                  \
199       int sample_rate,                                       \
200       type start,                                            \
201       type increment,                                        \
202       size_t frames,                                         \
203       base::TimeDelta start_time)
204 DEFINE_MAKE_AUDIO_BUFFER_INSTANCE(uint8);
205 DEFINE_MAKE_AUDIO_BUFFER_INSTANCE(int16);
206 DEFINE_MAKE_AUDIO_BUFFER_INSTANCE(int32);
207 DEFINE_MAKE_AUDIO_BUFFER_INSTANCE(float);
208 
209 static const char kFakeVideoBufferHeader[] = "FakeVideoBufferForTest";
210 
CreateFakeVideoBufferForTest(const VideoDecoderConfig & config,base::TimeDelta timestamp,base::TimeDelta duration)211 scoped_refptr<DecoderBuffer> CreateFakeVideoBufferForTest(
212     const VideoDecoderConfig& config,
213     base::TimeDelta timestamp, base::TimeDelta duration) {
214   Pickle pickle;
215   pickle.WriteString(kFakeVideoBufferHeader);
216   pickle.WriteInt(config.coded_size().width());
217   pickle.WriteInt(config.coded_size().height());
218   pickle.WriteInt64(timestamp.InMilliseconds());
219 
220   scoped_refptr<DecoderBuffer> buffer = DecoderBuffer::CopyFrom(
221       static_cast<const uint8*>(pickle.data()),
222       static_cast<int>(pickle.size()));
223   buffer->set_timestamp(timestamp);
224   buffer->set_duration(duration);
225 
226   return buffer;
227 }
228 
VerifyFakeVideoBufferForTest(const scoped_refptr<DecoderBuffer> & buffer,const VideoDecoderConfig & config)229 bool VerifyFakeVideoBufferForTest(
230     const scoped_refptr<DecoderBuffer>& buffer,
231     const VideoDecoderConfig& config) {
232   // Check if the input |buffer| matches the |config|.
233   PickleIterator pickle(Pickle(reinterpret_cast<const char*>(buffer->data()),
234                                buffer->data_size()));
235   std::string header;
236   int width = 0;
237   int height = 0;
238   bool success = pickle.ReadString(&header) && pickle.ReadInt(&width) &&
239                  pickle.ReadInt(&height);
240   return (success && header == kFakeVideoBufferHeader &&
241           width == config.coded_size().width() &&
242           height == config.coded_size().height());
243 }
244 
CallbackPairChecker()245 CallbackPairChecker::CallbackPairChecker() : expecting_b_(false) {
246 }
247 
~CallbackPairChecker()248 CallbackPairChecker::~CallbackPairChecker() {
249   EXPECT_FALSE(expecting_b_);
250 }
251 
RecordACalled()252 void CallbackPairChecker::RecordACalled() {
253   EXPECT_FALSE(expecting_b_);
254   expecting_b_ = true;
255 }
256 
RecordBCalled()257 void CallbackPairChecker::RecordBCalled() {
258   EXPECT_TRUE(expecting_b_);
259   expecting_b_ = false;
260 }
261 
262 }  // namespace media
263