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.
5 #include "base/basictypes.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"
16 const int kNumBuffersInOneConfig = 9;
17 const int kNumBuffersToReadFirst = 5;
18 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);
23 class FakeDemuxerStreamTest : public testing::Test {
25 FakeDemuxerStreamTest()
26 : status_(DemuxerStream::kAborted),
28 num_buffers_received_(0) {}
29 ~FakeDemuxerStreamTest() override {}
31 void BufferReady(DemuxerStream::Status status,
32 const scoped_refptr<DecoderBuffer>& buffer) {
33 DCHECK(read_pending_);
34 read_pending_ = false;
37 if (status == DemuxerStream::kOk && !buffer->end_of_stream())
38 num_buffers_received_++;
49 void EnterNormalReadState() {
51 new FakeDemuxerStream(kNumConfigs, kNumBuffersInOneConfig, false));
52 for (int i = 0; i < kNumBuffersToReadFirst; ++i)
54 DCHECK_EQ(kNumBuffersToReadFirst, num_buffers_received_);
57 void EnterBeforeEOSState() {
58 stream_.reset(new FakeDemuxerStream(1, kNumBuffersInOneConfig, false));
59 for (int i = 0; i < kNumBuffersInOneConfig; ++i)
61 DCHECK_EQ(kNumBuffersInOneConfig, num_buffers_received_);
64 void ExpectReadResult(ReadResult result) {
67 EXPECT_FALSE(read_pending_);
68 EXPECT_EQ(DemuxerStream::kOk, status_);
69 ASSERT_TRUE(buffer_.get());
70 EXPECT_FALSE(buffer_->end_of_stream());
74 EXPECT_FALSE(read_pending_);
75 EXPECT_EQ(DemuxerStream::kAborted, status_);
76 EXPECT_FALSE(buffer_.get());
80 EXPECT_TRUE(stream_->SupportsConfigChanges());
81 EXPECT_FALSE(read_pending_);
82 EXPECT_EQ(DemuxerStream::kConfigChanged, status_);
83 EXPECT_FALSE(buffer_.get());
87 EXPECT_FALSE(read_pending_);
88 EXPECT_EQ(DemuxerStream::kOk, status_);
89 ASSERT_TRUE(buffer_.get());
90 EXPECT_TRUE(buffer_->end_of_stream());
94 EXPECT_TRUE(read_pending_);
99 void ReadAndExpect(ReadResult result) {
100 EXPECT_FALSE(read_pending_);
101 read_pending_ = true;
102 stream_->Read(base::Bind(&FakeDemuxerStreamTest::BufferReady,
103 base::Unretained(this)));
104 message_loop_.RunUntilIdle();
105 ExpectReadResult(result);
108 void ReadUntilPending() {
110 read_pending_ = true;
111 stream_->Read(base::Bind(&FakeDemuxerStreamTest::BufferReady,
112 base::Unretained(this)));
113 message_loop_.RunUntilIdle();
119 void SatisfyReadAndExpect(ReadResult result) {
120 EXPECT_TRUE(read_pending_);
121 stream_->SatisfyRead();
122 message_loop_.RunUntilIdle();
123 ExpectReadResult(result);
127 bool had_read_pending = read_pending_;
129 message_loop_.RunUntilIdle();
131 EXPECT_FALSE(read_pending_);
132 if (had_read_pending)
133 ExpectReadResult(ABORTED);
136 void ReadAllBuffers(int num_configs, int num_buffers_in_one_config) {
137 DCHECK_EQ(0, num_buffers_received_);
138 for (int i = 0; i < num_configs; ++i) {
139 for (int j = 0; j < num_buffers_in_one_config; ++j) {
141 EXPECT_EQ(num_buffers_received_, stream_->num_buffers_returned());
144 if (i == num_configs - 1)
147 ReadAndExpect(CONFIG_CHANGED);
150 // Will always get EOS after we hit EOS.
153 EXPECT_EQ(num_configs * num_buffers_in_one_config, num_buffers_received_);
156 void TestRead(int num_configs,
157 int num_buffers_in_one_config,
159 stream_.reset(new FakeDemuxerStream(
160 num_configs, num_buffers_in_one_config, is_encrypted));
162 const VideoDecoderConfig& config = stream_->video_decoder_config();
163 EXPECT_TRUE(config.IsValidConfig());
164 EXPECT_EQ(is_encrypted, config.is_encrypted());
166 ReadAllBuffers(num_configs, num_buffers_in_one_config);
169 base::MessageLoop message_loop_;
170 scoped_ptr<FakeDemuxerStream> stream_;
172 DemuxerStream::Status status_;
173 scoped_refptr<DecoderBuffer> buffer_;
175 int num_buffers_received_;
178 DISALLOW_COPY_AND_ASSIGN(FakeDemuxerStreamTest);
181 TEST_F(FakeDemuxerStreamTest, Read_OneConfig) {
182 TestRead(1, 5, false);
185 TEST_F(FakeDemuxerStreamTest, Read_MultipleConfigs) {
186 TestRead(3, 5, false);
189 TEST_F(FakeDemuxerStreamTest, Read_OneBufferPerConfig) {
190 TestRead(3, 1, false);
193 TEST_F(FakeDemuxerStreamTest, Read_Encrypted) {
194 TestRead(6, 3, true);
197 TEST_F(FakeDemuxerStreamTest, HoldRead_Normal) {
198 EnterNormalReadState();
199 stream_->HoldNextRead();
200 ReadAndExpect(PENDING);
201 SatisfyReadAndExpect(OK);
204 TEST_F(FakeDemuxerStreamTest, HoldRead_BeforeConfigChanged) {
205 EnterNormalReadState();
206 stream_->HoldNextConfigChangeRead();
208 SatisfyReadAndExpect(CONFIG_CHANGED);
211 TEST_F(FakeDemuxerStreamTest, HoldRead_BeforeEOS) {
212 EnterBeforeEOSState();
213 stream_->HoldNextRead();
214 ReadAndExpect(PENDING);
215 SatisfyReadAndExpect(EOS);
218 TEST_F(FakeDemuxerStreamTest, Reset_Normal) {
219 EnterNormalReadState();
224 TEST_F(FakeDemuxerStreamTest, Reset_AfterHoldRead) {
225 EnterNormalReadState();
226 stream_->HoldNextRead();
231 TEST_F(FakeDemuxerStreamTest, Reset_DuringPendingRead) {
232 EnterNormalReadState();
233 stream_->HoldNextRead();
234 ReadAndExpect(PENDING);
239 TEST_F(FakeDemuxerStreamTest, Reset_BeforeConfigChanged) {
240 EnterNormalReadState();
241 stream_->HoldNextConfigChangeRead();
244 ReadAndExpect(CONFIG_CHANGED);
247 TEST_F(FakeDemuxerStreamTest, Reset_BeforeEOS) {
248 EnterBeforeEOSState();
249 stream_->HoldNextRead();
250 ReadAndExpect(PENDING);
255 TEST_F(FakeDemuxerStreamTest, NoConfigChanges) {
257 new FakeDemuxerStream(1, kNumBuffersInOneConfig, false));
258 EXPECT_FALSE(stream_->SupportsConfigChanges());
259 for (int i = 0; i < kNumBuffersInOneConfig; ++i)
264 TEST_F(FakeDemuxerStreamTest, SeekToStart_Normal) {
265 EnterNormalReadState();
266 stream_->SeekToStart();
267 num_buffers_received_ = 0;
268 ReadAllBuffers(kNumConfigs, kNumBuffersInOneConfig);
271 TEST_F(FakeDemuxerStreamTest, SeekToStart_BeforeEOS) {
272 EnterBeforeEOSState();
273 stream_->SeekToStart();
274 num_buffers_received_ = 0;
275 ReadAllBuffers(1, kNumBuffersInOneConfig);
278 TEST_F(FakeDemuxerStreamTest, SeekToStart_AfterEOS) {
279 TestRead(3, 5, false);
280 stream_->SeekToStart();
281 num_buffers_received_ = 0;
282 ReadAllBuffers(3, 5);