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/base/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 static_assert(kNumBuffersToReadFirst
< kNumBuffersInOneConfig
,
20 "do not read too many buffers");
21 static_assert(kNumConfigs
> 0,
22 "need multiple configs to trigger config change");
24 class FakeDemuxerStreamTest
: public testing::Test
{
26 FakeDemuxerStreamTest()
27 : status_(DemuxerStream::kAborted
),
29 num_buffers_received_(0) {}
30 ~FakeDemuxerStreamTest() override
{}
32 void BufferReady(DemuxerStream::Status status
,
33 const scoped_refptr
<DecoderBuffer
>& buffer
) {
34 DCHECK(read_pending_
);
35 read_pending_
= false;
38 if (status
== DemuxerStream::kOk
&& !buffer
->end_of_stream())
39 num_buffers_received_
++;
50 void EnterNormalReadState() {
52 new FakeDemuxerStream(kNumConfigs
, kNumBuffersInOneConfig
, false));
53 for (int i
= 0; i
< kNumBuffersToReadFirst
; ++i
)
55 DCHECK_EQ(kNumBuffersToReadFirst
, num_buffers_received_
);
58 void EnterBeforeEOSState() {
59 stream_
.reset(new FakeDemuxerStream(1, kNumBuffersInOneConfig
, false));
60 for (int i
= 0; i
< kNumBuffersInOneConfig
; ++i
)
62 DCHECK_EQ(kNumBuffersInOneConfig
, num_buffers_received_
);
65 void ExpectReadResult(ReadResult result
) {
68 EXPECT_FALSE(read_pending_
);
69 EXPECT_EQ(DemuxerStream::kOk
, status_
);
70 ASSERT_TRUE(buffer_
.get());
71 EXPECT_FALSE(buffer_
->end_of_stream());
75 EXPECT_FALSE(read_pending_
);
76 EXPECT_EQ(DemuxerStream::kAborted
, status_
);
77 EXPECT_FALSE(buffer_
.get());
81 EXPECT_TRUE(stream_
->SupportsConfigChanges());
82 EXPECT_FALSE(read_pending_
);
83 EXPECT_EQ(DemuxerStream::kConfigChanged
, status_
);
84 EXPECT_FALSE(buffer_
.get());
88 EXPECT_FALSE(read_pending_
);
89 EXPECT_EQ(DemuxerStream::kOk
, status_
);
90 ASSERT_TRUE(buffer_
.get());
91 EXPECT_TRUE(buffer_
->end_of_stream());
95 EXPECT_TRUE(read_pending_
);
100 void ReadAndExpect(ReadResult result
) {
101 EXPECT_FALSE(read_pending_
);
102 read_pending_
= true;
103 stream_
->Read(base::Bind(&FakeDemuxerStreamTest::BufferReady
,
104 base::Unretained(this)));
105 message_loop_
.RunUntilIdle();
106 ExpectReadResult(result
);
109 void ReadUntilPending() {
111 read_pending_
= true;
112 stream_
->Read(base::Bind(&FakeDemuxerStreamTest::BufferReady
,
113 base::Unretained(this)));
114 message_loop_
.RunUntilIdle();
120 void SatisfyReadAndExpect(ReadResult result
) {
121 EXPECT_TRUE(read_pending_
);
122 stream_
->SatisfyRead();
123 message_loop_
.RunUntilIdle();
124 ExpectReadResult(result
);
128 bool had_read_pending
= read_pending_
;
130 message_loop_
.RunUntilIdle();
132 EXPECT_FALSE(read_pending_
);
133 if (had_read_pending
)
134 ExpectReadResult(ABORTED
);
137 void ReadAllBuffers(int num_configs
, int num_buffers_in_one_config
) {
138 DCHECK_EQ(0, num_buffers_received_
);
139 for (int i
= 0; i
< num_configs
; ++i
) {
140 for (int j
= 0; j
< num_buffers_in_one_config
; ++j
) {
142 EXPECT_EQ(num_buffers_received_
, stream_
->num_buffers_returned());
145 if (i
== num_configs
- 1)
148 ReadAndExpect(CONFIG_CHANGED
);
151 // Will always get EOS after we hit EOS.
154 EXPECT_EQ(num_configs
* num_buffers_in_one_config
, num_buffers_received_
);
157 void TestRead(int num_configs
,
158 int num_buffers_in_one_config
,
160 stream_
.reset(new FakeDemuxerStream(
161 num_configs
, num_buffers_in_one_config
, is_encrypted
));
163 const VideoDecoderConfig
& config
= stream_
->video_decoder_config();
164 EXPECT_TRUE(config
.IsValidConfig());
165 EXPECT_EQ(is_encrypted
, config
.is_encrypted());
167 ReadAllBuffers(num_configs
, num_buffers_in_one_config
);
170 base::MessageLoop message_loop_
;
171 scoped_ptr
<FakeDemuxerStream
> stream_
;
173 DemuxerStream::Status status_
;
174 scoped_refptr
<DecoderBuffer
> buffer_
;
176 int num_buffers_received_
;
179 DISALLOW_COPY_AND_ASSIGN(FakeDemuxerStreamTest
);
182 TEST_F(FakeDemuxerStreamTest
, Read_OneConfig
) {
183 TestRead(1, 5, false);
186 TEST_F(FakeDemuxerStreamTest
, Read_MultipleConfigs
) {
187 TestRead(3, 5, false);
190 TEST_F(FakeDemuxerStreamTest
, Read_OneBufferPerConfig
) {
191 TestRead(3, 1, false);
194 TEST_F(FakeDemuxerStreamTest
, Read_Encrypted
) {
195 TestRead(6, 3, true);
198 TEST_F(FakeDemuxerStreamTest
, HoldRead_Normal
) {
199 EnterNormalReadState();
200 stream_
->HoldNextRead();
201 ReadAndExpect(PENDING
);
202 SatisfyReadAndExpect(OK
);
205 TEST_F(FakeDemuxerStreamTest
, HoldRead_BeforeConfigChanged
) {
206 EnterNormalReadState();
207 stream_
->HoldNextConfigChangeRead();
209 SatisfyReadAndExpect(CONFIG_CHANGED
);
212 TEST_F(FakeDemuxerStreamTest
, HoldRead_BeforeEOS
) {
213 EnterBeforeEOSState();
214 stream_
->HoldNextRead();
215 ReadAndExpect(PENDING
);
216 SatisfyReadAndExpect(EOS
);
219 TEST_F(FakeDemuxerStreamTest
, Reset_Normal
) {
220 EnterNormalReadState();
225 TEST_F(FakeDemuxerStreamTest
, Reset_AfterHoldRead
) {
226 EnterNormalReadState();
227 stream_
->HoldNextRead();
232 TEST_F(FakeDemuxerStreamTest
, Reset_DuringPendingRead
) {
233 EnterNormalReadState();
234 stream_
->HoldNextRead();
235 ReadAndExpect(PENDING
);
240 TEST_F(FakeDemuxerStreamTest
, Reset_BeforeConfigChanged
) {
241 EnterNormalReadState();
242 stream_
->HoldNextConfigChangeRead();
245 ReadAndExpect(CONFIG_CHANGED
);
248 TEST_F(FakeDemuxerStreamTest
, Reset_BeforeEOS
) {
249 EnterBeforeEOSState();
250 stream_
->HoldNextRead();
251 ReadAndExpect(PENDING
);
256 TEST_F(FakeDemuxerStreamTest
, NoConfigChanges
) {
258 new FakeDemuxerStream(1, kNumBuffersInOneConfig
, false));
259 EXPECT_FALSE(stream_
->SupportsConfigChanges());
260 for (int i
= 0; i
< kNumBuffersInOneConfig
; ++i
)
265 TEST_F(FakeDemuxerStreamTest
, SeekToStart_Normal
) {
266 EnterNormalReadState();
267 stream_
->SeekToStart();
268 num_buffers_received_
= 0;
269 ReadAllBuffers(kNumConfigs
, kNumBuffersInOneConfig
);
272 TEST_F(FakeDemuxerStreamTest
, SeekToStart_BeforeEOS
) {
273 EnterBeforeEOSState();
274 stream_
->SeekToStart();
275 num_buffers_received_
= 0;
276 ReadAllBuffers(1, kNumBuffersInOneConfig
);
279 TEST_F(FakeDemuxerStreamTest
, SeekToStart_AfterEOS
) {
280 TestRead(3, 5, false);
281 stream_
->SeekToStart();
282 num_buffers_received_
= 0;
283 ReadAllBuffers(3, 5);