- add sources.
[platform/framework/web/crosswalk.git] / src / media / filters / fake_demuxer_stream_unittest.cc
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 "base/basictypes.h"
6 #include "base/bind.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/message_loop/message_loop.h"
9 #include "media/base/decoder_buffer.h"
10 #include "media/base/demuxer_stream.h"
11 #include "media/filters/fake_demuxer_stream.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 namespace media {
15
16 static const int kNumBuffersInOneConfig = 9;
17 static const int kNumBuffersToReadFirst = 5;
18 static const int kNumConfigs = 3;
19 COMPILE_ASSERT(kNumBuffersToReadFirst < kNumBuffersInOneConfig,
20                do_not_read_too_many_buffers);
21 COMPILE_ASSERT(kNumConfigs > 0, need_multiple_configs_to_trigger_config_change);
22
23 class FakeDemuxerStreamTest : public testing::Test {
24  public:
25   FakeDemuxerStreamTest()
26       : status_(DemuxerStream::kAborted),
27         read_pending_(false) {}
28   virtual ~FakeDemuxerStreamTest() {}
29
30   void BufferReady(DemuxerStream::Status status,
31                    const scoped_refptr<DecoderBuffer>& buffer) {
32     DCHECK(read_pending_);
33     read_pending_ = false;
34     status_ = status;
35     buffer_ = buffer;
36   }
37
38   enum ReadResult {
39     OK,
40     ABORTED,
41     CONFIG_CHANGED,
42     EOS,
43     PENDING
44   };
45
46   void EnterNormalReadState() {
47     stream_.reset(
48         new FakeDemuxerStream(kNumConfigs, kNumBuffersInOneConfig, false));
49     for (int i = 0; i < kNumBuffersToReadFirst; ++i)
50       ReadAndExpect(OK);
51   }
52
53   void EnterBeforeEOSState() {
54     stream_.reset(new FakeDemuxerStream(1, kNumBuffersInOneConfig, false));
55     for (int i = 0; i < kNumBuffersInOneConfig; ++i)
56       ReadAndExpect(OK);
57   }
58
59   void ExpectReadResult(ReadResult result) {
60     switch (result) {
61       case OK:
62         EXPECT_FALSE(read_pending_);
63         EXPECT_EQ(DemuxerStream::kOk, status_);
64         ASSERT_TRUE(buffer_.get());
65         EXPECT_FALSE(buffer_->end_of_stream());
66         break;
67
68       case ABORTED:
69         EXPECT_FALSE(read_pending_);
70         EXPECT_EQ(DemuxerStream::kAborted, status_);
71         EXPECT_FALSE(buffer_.get());
72         break;
73
74       case CONFIG_CHANGED:
75         EXPECT_FALSE(read_pending_);
76         EXPECT_EQ(DemuxerStream::kConfigChanged, status_);
77         EXPECT_FALSE(buffer_.get());
78         break;
79
80       case EOS:
81         EXPECT_FALSE(read_pending_);
82         EXPECT_EQ(DemuxerStream::kOk, status_);
83         ASSERT_TRUE(buffer_.get());
84         EXPECT_TRUE(buffer_->end_of_stream());
85         break;
86
87       case PENDING:
88         EXPECT_TRUE(read_pending_);
89         break;
90     }
91   }
92
93   void ReadAndExpect(ReadResult result) {
94     EXPECT_FALSE(read_pending_);
95     read_pending_ = true;
96     stream_->Read(base::Bind(&FakeDemuxerStreamTest::BufferReady,
97                              base::Unretained(this)));
98     message_loop_.RunUntilIdle();
99     ExpectReadResult(result);
100   }
101
102   void ReadUntilPending() {
103     while (1) {
104       read_pending_ = true;
105       stream_->Read(base::Bind(&FakeDemuxerStreamTest::BufferReady,
106                                base::Unretained(this)));
107       message_loop_.RunUntilIdle();
108       if (read_pending_)
109         break;
110     }
111   }
112
113   void SatisfyReadAndExpect(ReadResult result) {
114     EXPECT_TRUE(read_pending_);
115     stream_->SatisfyRead();
116     message_loop_.RunUntilIdle();
117     ExpectReadResult(result);
118   }
119
120   void Reset() {
121     bool had_read_pending = read_pending_;
122     stream_->Reset();
123     message_loop_.RunUntilIdle();
124
125     EXPECT_FALSE(read_pending_);
126     if (had_read_pending)
127       ExpectReadResult(ABORTED);
128   }
129
130   void TestRead(int num_configs,
131                 int num_buffers_in_one_config,
132                 bool is_encrypted) {
133     stream_.reset(new FakeDemuxerStream(
134         num_configs, num_buffers_in_one_config, is_encrypted));
135
136     int num_buffers_received = 0;
137
138     const VideoDecoderConfig& config = stream_->video_decoder_config();
139     EXPECT_TRUE(config.IsValidConfig());
140     EXPECT_EQ(is_encrypted, config.is_encrypted());
141
142     for (int i = 0; i < num_configs; ++i) {
143       for (int j = 0; j < num_buffers_in_one_config; ++j) {
144         ReadAndExpect(OK);
145         num_buffers_received++;
146         EXPECT_EQ(num_buffers_received, stream_->num_buffers_returned());
147       }
148
149       if (i == num_configs - 1)
150         ReadAndExpect(EOS);
151       else
152         ReadAndExpect(CONFIG_CHANGED);
153     }
154
155     // Will always get EOS after we hit EOS.
156     ReadAndExpect(EOS);
157
158     EXPECT_EQ(num_configs * num_buffers_in_one_config, num_buffers_received);
159   }
160
161   base::MessageLoop message_loop_;
162   scoped_ptr<FakeDemuxerStream> stream_;
163
164   DemuxerStream::Status status_;
165   scoped_refptr<DecoderBuffer> buffer_;
166   bool read_pending_;
167   int num_buffers_received_;
168
169  private:
170   DISALLOW_COPY_AND_ASSIGN(FakeDemuxerStreamTest);
171 };
172
173 TEST_F(FakeDemuxerStreamTest, Read_OneConfig) {
174   TestRead(1, 5, false);
175 }
176
177 TEST_F(FakeDemuxerStreamTest, Read_MultipleConfigs) {
178   TestRead(3, 5, false);
179 }
180
181 TEST_F(FakeDemuxerStreamTest, Read_OneBufferPerConfig) {
182   TestRead(3, 1, false);
183 }
184
185 TEST_F(FakeDemuxerStreamTest, Read_Encrypted) {
186   TestRead(6, 3, true);
187 }
188
189 TEST_F(FakeDemuxerStreamTest, HoldRead_Normal) {
190   EnterNormalReadState();
191   stream_->HoldNextRead();
192   ReadAndExpect(PENDING);
193   SatisfyReadAndExpect(OK);
194 }
195
196 TEST_F(FakeDemuxerStreamTest, HoldRead_BeforeConfigChanged) {
197   EnterNormalReadState();
198   stream_->HoldNextConfigChangeRead();
199   ReadUntilPending();
200   SatisfyReadAndExpect(CONFIG_CHANGED);
201 }
202
203 TEST_F(FakeDemuxerStreamTest, HoldRead_BeforeEOS) {
204   EnterBeforeEOSState();
205   stream_->HoldNextRead();
206   ReadAndExpect(PENDING);
207   SatisfyReadAndExpect(EOS);
208 }
209
210 TEST_F(FakeDemuxerStreamTest, Reset_Normal) {
211   EnterNormalReadState();
212   Reset();
213   ReadAndExpect(OK);
214 }
215
216 TEST_F(FakeDemuxerStreamTest, Reset_AfterHoldRead) {
217   EnterNormalReadState();
218   stream_->HoldNextRead();
219   Reset();
220   ReadAndExpect(OK);
221 }
222
223 TEST_F(FakeDemuxerStreamTest, Reset_DuringPendingRead) {
224   EnterNormalReadState();
225   stream_->HoldNextRead();
226   ReadAndExpect(PENDING);
227   Reset();
228   ReadAndExpect(OK);
229 }
230
231 TEST_F(FakeDemuxerStreamTest, Reset_BeforeConfigChanged) {
232   EnterNormalReadState();
233   stream_->HoldNextConfigChangeRead();
234   ReadUntilPending();
235   Reset();
236   ReadAndExpect(CONFIG_CHANGED);
237 }
238
239 TEST_F(FakeDemuxerStreamTest, Reset_BeforeEOS) {
240   EnterBeforeEOSState();
241   stream_->HoldNextRead();
242   ReadAndExpect(PENDING);
243   Reset();
244   ReadAndExpect(EOS);
245 }
246
247 }  // namespace media