OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <deque> | 5 #include <deque> |
6 | 6 |
7 #include "base/file_path.h" | 7 #include "base/file_path.h" |
8 #include "base/path_service.h" | 8 #include "base/path_service.h" |
9 #include "base/threading/thread.h" | 9 #include "base/threading/thread.h" |
10 #include "media/base/filters.h" | 10 #include "media/base/filters.h" |
(...skipping 23 matching lines...) Expand all Loading... | |
34 MATCHER(IsEndOfStreamBuffer, | 34 MATCHER(IsEndOfStreamBuffer, |
35 std::string(negation ? "isn't" : "is") + " end of stream") { | 35 std::string(negation ? "isn't" : "is") + " end of stream") { |
36 return arg->IsEndOfStream(); | 36 return arg->IsEndOfStream(); |
37 } | 37 } |
38 | 38 |
39 // Fixture class to facilitate writing tests. Takes care of setting up the | 39 // Fixture class to facilitate writing tests. Takes care of setting up the |
40 // FFmpeg, pipeline and filter host mocks. | 40 // FFmpeg, pipeline and filter host mocks. |
41 class FFmpegDemuxerTest : public testing::Test { | 41 class FFmpegDemuxerTest : public testing::Test { |
42 protected: | 42 protected: |
43 | 43 |
44 FFmpegDemuxerTest() { | 44 FFmpegDemuxerTest() {} |
45 // Create an FFmpegDemuxer with local data source. | |
46 demuxer_ = new FFmpegDemuxer(&message_loop_, true); | |
47 demuxer_->disable_first_seek_hack_for_testing(); | |
48 | |
49 // Inject a filter host and message loop and prepare a data source. | |
50 demuxer_->set_host(&host_); | |
51 | |
52 EXPECT_CALL(host_, SetTotalBytes(_)).Times(AnyNumber()); | |
53 EXPECT_CALL(host_, SetBufferedBytes(_)).Times(AnyNumber()); | |
54 EXPECT_CALL(host_, SetCurrentReadPosition(_)) | |
55 .WillRepeatedly(SaveArg<0>(¤t_read_position_)); | |
56 } | |
57 | 45 |
58 virtual ~FFmpegDemuxerTest() { | 46 virtual ~FFmpegDemuxerTest() { |
59 if (demuxer_) { | 47 if (demuxer_) { |
60 // Call Stop() to shut down internal threads. | 48 // Call Stop() to shut down internal threads. |
61 demuxer_->Stop(NewExpectedClosure()); | 49 demuxer_->Stop(NewExpectedClosure()); |
62 } | 50 } |
63 | 51 |
64 // Finish up any remaining tasks. | 52 // Finish up any remaining tasks. |
65 message_loop_.RunAllPending(); | 53 message_loop_.RunAllPending(); |
66 // Release the reference to the demuxer. | 54 // Release the reference to the demuxer. |
67 demuxer_ = NULL; | 55 demuxer_ = NULL; |
68 } | 56 } |
69 | 57 |
70 scoped_refptr<FileDataSource> CreateDataSource(const std::string& name) { | 58 void CreateDemuxer(const std::string& name) { |
71 return CreateDataSource(name, false); | 59 CreateDemuxer(name, false); |
72 } | 60 } |
73 | 61 |
74 scoped_refptr<FileDataSource> CreateDataSource(const std::string& name, | 62 void CreateDemuxer(const std::string& name, bool disable_file_size) { |
75 bool disable_file_size) { | 63 CHECK(!demuxer_); |
76 FilePath file_path; | |
77 EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &file_path)); | |
78 | 64 |
79 file_path = file_path.Append(FILE_PATH_LITERAL("media")) | 65 EXPECT_CALL(host_, SetTotalBytes(_)).Times(AnyNumber()); |
80 .Append(FILE_PATH_LITERAL("test")) | 66 EXPECT_CALL(host_, SetBufferedBytes(_)).Times(AnyNumber()); |
81 .Append(FILE_PATH_LITERAL("data")) | 67 EXPECT_CALL(host_, SetCurrentReadPosition(_)) |
82 .AppendASCII(name); | 68 .WillRepeatedly(SaveArg<0>(¤t_read_position_)); |
83 | 69 |
84 scoped_refptr<FileDataSource> data_source = new FileDataSource( | 70 CreateDataSource(name, disable_file_size); |
85 disable_file_size); | |
86 | 71 |
87 EXPECT_EQ(PIPELINE_OK, data_source->Initialize(file_path.MaybeAsASCII())); | 72 // Create an FFmpegDemuxer with local data source. |
73 demuxer_ = new FFmpegDemuxer(&message_loop_, data_source_, true); | |
74 demuxer_->disable_first_seek_hack_for_testing(); | |
88 | 75 |
89 return data_source.get(); | 76 // Inject a filter host and message loop and prepare a data source. |
77 demuxer_->set_host(&host_); | |
90 } | 78 } |
91 | 79 |
92 MOCK_METHOD1(CheckPoint, void(int v)); | 80 MOCK_METHOD1(CheckPoint, void(int v)); |
93 | 81 |
94 // Initializes FFmpegDemuxer. | 82 void InitializeDemuxer() { |
95 void InitializeDemuxer(const scoped_refptr<DataSource>& data_source) { | |
96 EXPECT_CALL(host_, SetDuration(_)); | 83 EXPECT_CALL(host_, SetDuration(_)); |
97 demuxer_->Initialize(data_source, NewExpectedStatusCB(PIPELINE_OK)); | 84 demuxer_->Initialize(NewExpectedStatusCB(PIPELINE_OK)); |
98 message_loop_.RunAllPending(); | 85 message_loop_.RunAllPending(); |
99 } | 86 } |
100 | 87 |
101 // Verifies that |buffer| has a specific |size| and |timestamp|. | 88 // Verifies that |buffer| has a specific |size| and |timestamp|. |
102 // |location| simply indicates where the call to this function was made. | 89 // |location| simply indicates where the call to this function was made. |
103 // This makes it easier to track down where test failures occur. | 90 // This makes it easier to track down where test failures occur. |
104 void ValidateBuffer(const tracked_objects::Location& location, | 91 void ValidateBuffer(const tracked_objects::Location& location, |
105 const scoped_refptr<Buffer>& buffer, | 92 const scoped_refptr<Buffer>& buffer, |
106 int size, int64 timestampInMicroseconds) { | 93 int size, int64 timestampInMicroseconds) { |
107 std::string location_str; | 94 std::string location_str; |
108 location.Write(true, false, &location_str); | 95 location.Write(true, false, &location_str); |
109 location_str += "\n"; | 96 location_str += "\n"; |
110 SCOPED_TRACE(location_str); | 97 SCOPED_TRACE(location_str); |
111 EXPECT_TRUE(buffer.get() != NULL); | 98 EXPECT_TRUE(buffer.get() != NULL); |
112 EXPECT_EQ(size, buffer->GetDataSize()); | 99 EXPECT_EQ(size, buffer->GetDataSize()); |
113 EXPECT_EQ(base::TimeDelta::FromMicroseconds(timestampInMicroseconds), | 100 EXPECT_EQ(base::TimeDelta::FromMicroseconds(timestampInMicroseconds), |
114 buffer->GetTimestamp()); | 101 buffer->GetTimestamp()); |
115 } | 102 } |
116 | 103 |
117 // Creates a data source with the given |file_name|. If |disable_file_size| | 104 // Creates a data source with the given |file_name|. If |disable_file_size| |
118 // then the data source pretends it does not know the file size (e.g. often | 105 // then the data source pretends it does not know the file size (e.g. often |
119 // when streaming video). Uses this data source to initialize a demuxer, then | 106 // when streaming video). Uses this data source to initialize a demuxer, then |
120 // returns true if the bitrate is valid, false otherwise. | 107 // returns true if the bitrate is valid, false otherwise. |
121 bool VideoHasValidBitrate( | 108 bool VideoHasValidBitrate( |
122 const std::string& file_name, bool disable_file_size) { | 109 const std::string& file_name, bool disable_file_size) { |
123 scoped_refptr<FileDataSource> data_source = | 110 CreateDemuxer(file_name, disable_file_size); |
124 CreateDataSource(file_name, disable_file_size); | 111 InitializeDemuxer(); |
125 InitializeDemuxer(data_source); | |
126 return demuxer_->GetBitrate() > 0; | 112 return demuxer_->GetBitrate() > 0; |
127 } | 113 } |
128 | 114 |
129 bool IsStreamStopped(DemuxerStream::Type type) { | 115 bool IsStreamStopped(DemuxerStream::Type type) { |
130 DemuxerStream* stream = demuxer_->GetStream(type); | 116 DemuxerStream* stream = demuxer_->GetStream(type); |
131 CHECK(stream); | 117 CHECK(stream); |
132 return static_cast<FFmpegDemuxerStream*>(stream)->stopped_; | 118 return static_cast<FFmpegDemuxerStream*>(stream)->stopped_; |
133 } | 119 } |
134 | 120 |
135 // Fixture members. | 121 // Fixture members. |
122 scoped_refptr<FileDataSource> data_source_; | |
136 scoped_refptr<FFmpegDemuxer> demuxer_; | 123 scoped_refptr<FFmpegDemuxer> demuxer_; |
137 StrictMock<MockDemuxerHost> host_; | 124 StrictMock<MockDemuxerHost> host_; |
138 MessageLoop message_loop_; | 125 MessageLoop message_loop_; |
139 | 126 |
140 int64 current_read_position_; | 127 int64 current_read_position_; |
141 | 128 |
142 private: | 129 private: |
130 void CreateDataSource(const std::string& name, bool disable_file_size) { | |
131 CHECK(!data_source_); | |
132 | |
133 FilePath file_path; | |
134 EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &file_path)); | |
135 | |
136 file_path = file_path.Append(FILE_PATH_LITERAL("media")) | |
137 .Append(FILE_PATH_LITERAL("test")) | |
138 .Append(FILE_PATH_LITERAL("data")) | |
139 .AppendASCII(name); | |
140 | |
141 data_source_ = new FileDataSource(disable_file_size); | |
142 EXPECT_EQ(PIPELINE_OK, data_source_->Initialize(file_path.MaybeAsASCII())); | |
143 } | |
144 | |
143 DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxerTest); | 145 DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxerTest); |
144 }; | 146 }; |
145 | 147 |
146 TEST_F(FFmpegDemuxerTest, Initialize_OpenFails) { | 148 TEST_F(FFmpegDemuxerTest, Initialize_OpenFails) { |
147 // Simulate avformat_open_input() failing. | 149 // Simulate avformat_open_input() failing. |
150 CreateDemuxer("ten_byte_file"), | |
148 EXPECT_CALL(host_, SetCurrentReadPosition(_)); | 151 EXPECT_CALL(host_, SetCurrentReadPosition(_)); |
149 demuxer_->Initialize(CreateDataSource("ten_byte_file"), | 152 demuxer_->Initialize(NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN)); |
150 NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN)); | |
151 | 153 |
152 message_loop_.RunAllPending(); | 154 message_loop_.RunAllPending(); |
153 } | 155 } |
154 | 156 |
155 // TODO(acolwell): Uncomment this test when we discover a file that passes | 157 // TODO(acolwell): Uncomment this test when we discover a file that passes |
156 // avformat_open_input(), but has avformat_find_stream_info() fail. | 158 // avformat_open_input(), but has avformat_find_stream_info() fail. |
157 // | 159 // |
158 //TEST_F(FFmpegDemuxerTest, Initialize_ParseFails) { | 160 //TEST_F(FFmpegDemuxerTest, Initialize_ParseFails) { |
161 // CreateDemuxer("find_stream_info_fail.webm"); | |
159 // demuxer_->Initialize( | 162 // demuxer_->Initialize( |
160 // CreateDataSource("find_stream_info_fail.webm"), | |
161 // NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_PARSE)); | 163 // NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_PARSE)); |
162 // message_loop_.RunAllPending(); | 164 // message_loop_.RunAllPending(); |
163 //} | 165 //} |
164 | 166 |
165 TEST_F(FFmpegDemuxerTest, Initialize_NoStreams) { | 167 TEST_F(FFmpegDemuxerTest, Initialize_NoStreams) { |
166 // Open a file with no streams whatsoever. | 168 // Open a file with no streams whatsoever. |
169 CreateDemuxer("no_streams.webm"); | |
167 EXPECT_CALL(host_, SetCurrentReadPosition(_)); | 170 EXPECT_CALL(host_, SetCurrentReadPosition(_)); |
168 demuxer_->Initialize( | 171 demuxer_->Initialize( |
169 CreateDataSource("no_streams.webm"), | |
170 NewExpectedStatusCB(DEMUXER_ERROR_NO_SUPPORTED_STREAMS)); | 172 NewExpectedStatusCB(DEMUXER_ERROR_NO_SUPPORTED_STREAMS)); |
171 message_loop_.RunAllPending(); | 173 message_loop_.RunAllPending(); |
172 } | 174 } |
173 | 175 |
174 TEST_F(FFmpegDemuxerTest, Initialize_NoAudioVideo) { | 176 TEST_F(FFmpegDemuxerTest, Initialize_NoAudioVideo) { |
175 // Open a file containing streams but none of which are audio/video streams. | 177 // Open a file containing streams but none of which are audio/video streams. |
178 CreateDemuxer("no_audio_video.webm"); | |
176 demuxer_->Initialize( | 179 demuxer_->Initialize( |
177 CreateDataSource("no_audio_video.webm"), | |
178 NewExpectedStatusCB(DEMUXER_ERROR_NO_SUPPORTED_STREAMS)); | 180 NewExpectedStatusCB(DEMUXER_ERROR_NO_SUPPORTED_STREAMS)); |
179 message_loop_.RunAllPending(); | 181 message_loop_.RunAllPending(); |
180 } | 182 } |
181 | 183 |
182 TEST_F(FFmpegDemuxerTest, Initialize_Successful) { | 184 TEST_F(FFmpegDemuxerTest, Initialize_Successful) { |
183 InitializeDemuxer(CreateDataSource("bear-320x240.webm")); | 185 CreateDemuxer("bear-320x240.webm"); |
186 InitializeDemuxer(); | |
184 | 187 |
185 // Video stream should be present. | 188 // Video stream should be present. |
186 scoped_refptr<DemuxerStream> stream = | 189 scoped_refptr<DemuxerStream> stream = |
187 demuxer_->GetStream(DemuxerStream::VIDEO); | 190 demuxer_->GetStream(DemuxerStream::VIDEO); |
188 ASSERT_TRUE(stream); | 191 ASSERT_TRUE(stream); |
189 EXPECT_EQ(DemuxerStream::VIDEO, stream->type()); | 192 EXPECT_EQ(DemuxerStream::VIDEO, stream->type()); |
190 | 193 |
191 const VideoDecoderConfig& video_config = stream->video_decoder_config(); | 194 const VideoDecoderConfig& video_config = stream->video_decoder_config(); |
192 EXPECT_EQ(kCodecVP8, video_config.codec()); | 195 EXPECT_EQ(kCodecVP8, video_config.codec()); |
193 EXPECT_EQ(VideoFrame::YV12, video_config.format()); | 196 EXPECT_EQ(VideoFrame::YV12, video_config.format()); |
(...skipping 29 matching lines...) Expand all Loading... | |
223 | 226 |
224 TEST_F(FFmpegDemuxerTest, Initialize_Multitrack) { | 227 TEST_F(FFmpegDemuxerTest, Initialize_Multitrack) { |
225 // Open a file containing the following streams: | 228 // Open a file containing the following streams: |
226 // Stream #0: Video (VP8) | 229 // Stream #0: Video (VP8) |
227 // Stream #1: Audio (Vorbis) | 230 // Stream #1: Audio (Vorbis) |
228 // Stream #2: Subtitles (SRT) | 231 // Stream #2: Subtitles (SRT) |
229 // Stream #3: Video (Theora) | 232 // Stream #3: Video (Theora) |
230 // Stream #4: Audio (16-bit signed little endian PCM) | 233 // Stream #4: Audio (16-bit signed little endian PCM) |
231 // | 234 // |
232 // We should only pick the first audio/video streams we come across. | 235 // We should only pick the first audio/video streams we come across. |
233 InitializeDemuxer(CreateDataSource("bear-320x240-multitrack.webm")); | 236 CreateDemuxer("bear-320x240-multitrack.webm"); |
237 InitializeDemuxer(); | |
234 | 238 |
235 // Video stream should be VP8. | 239 // Video stream should be VP8. |
236 scoped_refptr<DemuxerStream> stream = | 240 scoped_refptr<DemuxerStream> stream = |
237 demuxer_->GetStream(DemuxerStream::VIDEO); | 241 demuxer_->GetStream(DemuxerStream::VIDEO); |
238 ASSERT_TRUE(stream); | 242 ASSERT_TRUE(stream); |
239 EXPECT_EQ(DemuxerStream::VIDEO, stream->type()); | 243 EXPECT_EQ(DemuxerStream::VIDEO, stream->type()); |
240 EXPECT_EQ(kCodecVP8, stream->video_decoder_config().codec()); | 244 EXPECT_EQ(kCodecVP8, stream->video_decoder_config().codec()); |
241 | 245 |
242 // Audio stream should be Vorbis. | 246 // Audio stream should be Vorbis. |
243 stream = demuxer_->GetStream(DemuxerStream::AUDIO); | 247 stream = demuxer_->GetStream(DemuxerStream::AUDIO); |
244 ASSERT_TRUE(stream); | 248 ASSERT_TRUE(stream); |
245 EXPECT_EQ(DemuxerStream::AUDIO, stream->type()); | 249 EXPECT_EQ(DemuxerStream::AUDIO, stream->type()); |
246 EXPECT_EQ(kCodecVorbis, stream->audio_decoder_config().codec()); | 250 EXPECT_EQ(kCodecVorbis, stream->audio_decoder_config().codec()); |
247 | 251 |
248 // Unknown stream should never be present. | 252 // Unknown stream should never be present. |
249 EXPECT_FALSE(demuxer_->GetStream(DemuxerStream::UNKNOWN)); | 253 EXPECT_FALSE(demuxer_->GetStream(DemuxerStream::UNKNOWN)); |
250 } | 254 } |
251 | 255 |
252 TEST_F(FFmpegDemuxerTest, Read_Audio) { | 256 TEST_F(FFmpegDemuxerTest, Read_Audio) { |
253 // We test that on a successful audio packet read. | 257 // We test that on a successful audio packet read. |
254 InitializeDemuxer(CreateDataSource("bear-320x240.webm")); | 258 CreateDemuxer("bear-320x240.webm"); |
259 InitializeDemuxer(); | |
255 | 260 |
256 // Attempt a read from the audio stream and run the message loop until done. | 261 // Attempt a read from the audio stream and run the message loop until done. |
257 scoped_refptr<DemuxerStream> audio = | 262 scoped_refptr<DemuxerStream> audio = |
258 demuxer_->GetStream(DemuxerStream::AUDIO); | 263 demuxer_->GetStream(DemuxerStream::AUDIO); |
259 scoped_refptr<DemuxerStreamReader> reader(new DemuxerStreamReader()); | 264 scoped_refptr<DemuxerStreamReader> reader(new DemuxerStreamReader()); |
260 reader->Read(audio); | 265 reader->Read(audio); |
261 message_loop_.RunAllPending(); | 266 message_loop_.RunAllPending(); |
262 EXPECT_TRUE(reader->called()); | 267 EXPECT_TRUE(reader->called()); |
263 ValidateBuffer(FROM_HERE, reader->buffer(), 29, 0); | 268 ValidateBuffer(FROM_HERE, reader->buffer(), 29, 0); |
264 | 269 |
265 reader->Reset(); | 270 reader->Reset(); |
266 reader->Read(audio); | 271 reader->Read(audio); |
267 message_loop_.RunAllPending(); | 272 message_loop_.RunAllPending(); |
268 EXPECT_TRUE(reader->called()); | 273 EXPECT_TRUE(reader->called()); |
269 ValidateBuffer(FROM_HERE, reader->buffer(), 27, 3000); | 274 ValidateBuffer(FROM_HERE, reader->buffer(), 27, 3000); |
270 } | 275 } |
271 | 276 |
272 TEST_F(FFmpegDemuxerTest, Read_Video) { | 277 TEST_F(FFmpegDemuxerTest, Read_Video) { |
273 // We test that on a successful video packet read. | 278 // We test that on a successful video packet read. |
274 InitializeDemuxer(CreateDataSource("bear-320x240.webm")); | 279 CreateDemuxer("bear-320x240.webm"); |
280 InitializeDemuxer(); | |
275 | 281 |
276 // Attempt a read from the video stream and run the message loop until done. | 282 // Attempt a read from the video stream and run the message loop until done. |
277 scoped_refptr<DemuxerStream> video = | 283 scoped_refptr<DemuxerStream> video = |
278 demuxer_->GetStream(DemuxerStream::VIDEO); | 284 demuxer_->GetStream(DemuxerStream::VIDEO); |
279 scoped_refptr<DemuxerStreamReader> reader(new DemuxerStreamReader()); | 285 scoped_refptr<DemuxerStreamReader> reader(new DemuxerStreamReader()); |
280 | 286 |
281 reader->Read(video); | 287 reader->Read(video); |
282 message_loop_.RunAllPending(); | 288 message_loop_.RunAllPending(); |
283 EXPECT_TRUE(reader->called()); | 289 EXPECT_TRUE(reader->called()); |
284 ValidateBuffer(FROM_HERE, reader->buffer(), 22084, 0); | 290 ValidateBuffer(FROM_HERE, reader->buffer(), 22084, 0); |
285 | 291 |
286 reader->Reset(); | 292 reader->Reset(); |
287 reader->Read(video); | 293 reader->Read(video); |
288 message_loop_.RunAllPending(); | 294 message_loop_.RunAllPending(); |
289 EXPECT_TRUE(reader->called()); | 295 EXPECT_TRUE(reader->called()); |
290 ValidateBuffer(FROM_HERE, reader->buffer(), 1057, 33000); | 296 ValidateBuffer(FROM_HERE, reader->buffer(), 1057, 33000); |
291 } | 297 } |
292 | 298 |
293 TEST_F(FFmpegDemuxerTest, Read_VideoNonZeroStart) { | 299 TEST_F(FFmpegDemuxerTest, Read_VideoNonZeroStart) { |
294 // Test the start time is the first timestamp of the video and audio stream. | 300 // Test the start time is the first timestamp of the video and audio stream. |
295 InitializeDemuxer(CreateDataSource("nonzero-start-time.webm")); | 301 CreateDemuxer("nonzero-start-time.webm"); |
302 InitializeDemuxer(); | |
296 | 303 |
297 // Attempt a read from the video stream and run the message loop until done. | 304 // Attempt a read from the video stream and run the message loop until done. |
298 scoped_refptr<DemuxerStream> video = | 305 scoped_refptr<DemuxerStream> video = |
299 demuxer_->GetStream(DemuxerStream::VIDEO); | 306 demuxer_->GetStream(DemuxerStream::VIDEO); |
300 scoped_refptr<DemuxerStream> audio = | 307 scoped_refptr<DemuxerStream> audio = |
301 demuxer_->GetStream(DemuxerStream::AUDIO); | 308 demuxer_->GetStream(DemuxerStream::AUDIO); |
302 scoped_refptr<DemuxerStreamReader> reader(new DemuxerStreamReader()); | 309 scoped_refptr<DemuxerStreamReader> reader(new DemuxerStreamReader()); |
303 | 310 |
304 // Check first buffer in video stream. | 311 // Check first buffer in video stream. |
305 reader->Read(video); | 312 reader->Read(video); |
(...skipping 10 matching lines...) Expand all Loading... | |
316 ValidateBuffer(FROM_HERE, reader->buffer(), 165, 396000); | 323 ValidateBuffer(FROM_HERE, reader->buffer(), 165, 396000); |
317 const base::TimeDelta audio_timestamp = reader->buffer()->GetTimestamp(); | 324 const base::TimeDelta audio_timestamp = reader->buffer()->GetTimestamp(); |
318 | 325 |
319 // Verify that the start time is equal to the lowest timestamp. | 326 // Verify that the start time is equal to the lowest timestamp. |
320 EXPECT_EQ(std::min(audio_timestamp, video_timestamp), | 327 EXPECT_EQ(std::min(audio_timestamp, video_timestamp), |
321 demuxer_->GetStartTime()); | 328 demuxer_->GetStartTime()); |
322 } | 329 } |
323 | 330 |
324 TEST_F(FFmpegDemuxerTest, Read_EndOfStream) { | 331 TEST_F(FFmpegDemuxerTest, Read_EndOfStream) { |
325 // Verify that end of stream buffers are created. | 332 // Verify that end of stream buffers are created. |
326 InitializeDemuxer(CreateDataSource("bear-320x240.webm")); | 333 CreateDemuxer("bear-320x240.webm"); |
334 InitializeDemuxer(); | |
327 | 335 |
328 // We should now expect an end of stream buffer. | 336 // We should now expect an end of stream buffer. |
329 scoped_refptr<DemuxerStream> audio = | 337 scoped_refptr<DemuxerStream> audio = |
330 demuxer_->GetStream(DemuxerStream::AUDIO); | 338 demuxer_->GetStream(DemuxerStream::AUDIO); |
331 scoped_refptr<DemuxerStreamReader> reader(new DemuxerStreamReader()); | 339 scoped_refptr<DemuxerStreamReader> reader(new DemuxerStreamReader()); |
332 | 340 |
333 bool got_eos_buffer = false; | 341 bool got_eos_buffer = false; |
334 const int kMaxBuffers = 170; | 342 const int kMaxBuffers = 170; |
335 for (int i = 0; !got_eos_buffer && i < kMaxBuffers; i++) { | 343 for (int i = 0; !got_eos_buffer && i < kMaxBuffers; i++) { |
336 reader->Read(audio); | 344 reader->Read(audio); |
(...skipping 12 matching lines...) Expand all Loading... | |
349 EXPECT_GT(reader->buffer()->GetDataSize(), 0); | 357 EXPECT_GT(reader->buffer()->GetDataSize(), 0); |
350 reader->Reset(); | 358 reader->Reset(); |
351 } | 359 } |
352 | 360 |
353 EXPECT_TRUE(got_eos_buffer); | 361 EXPECT_TRUE(got_eos_buffer); |
354 } | 362 } |
355 | 363 |
356 TEST_F(FFmpegDemuxerTest, Seek) { | 364 TEST_F(FFmpegDemuxerTest, Seek) { |
357 // We're testing that the demuxer frees all queued packets when it receives | 365 // We're testing that the demuxer frees all queued packets when it receives |
358 // a Seek(). | 366 // a Seek(). |
359 InitializeDemuxer(CreateDataSource("bear-320x240.webm")); | 367 CreateDemuxer("bear-320x240.webm"); |
368 InitializeDemuxer(); | |
360 | 369 |
361 // Get our streams. | 370 // Get our streams. |
362 scoped_refptr<DemuxerStream> video = | 371 scoped_refptr<DemuxerStream> video = |
363 demuxer_->GetStream(DemuxerStream::VIDEO); | 372 demuxer_->GetStream(DemuxerStream::VIDEO); |
364 scoped_refptr<DemuxerStream> audio = | 373 scoped_refptr<DemuxerStream> audio = |
365 demuxer_->GetStream(DemuxerStream::AUDIO); | 374 demuxer_->GetStream(DemuxerStream::AUDIO); |
366 ASSERT_TRUE(video); | 375 ASSERT_TRUE(video); |
367 ASSERT_TRUE(audio); | 376 ASSERT_TRUE(audio); |
368 | 377 |
369 // Read a video packet and release it. | 378 // Read a video packet and release it. |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
427 MOCK_METHOD0(OnDelete, void()); | 436 MOCK_METHOD0(OnDelete, void()); |
428 MOCK_METHOD1(Run, void(const scoped_refptr<Buffer>& buffer)); | 437 MOCK_METHOD1(Run, void(const scoped_refptr<Buffer>& buffer)); |
429 | 438 |
430 private: | 439 private: |
431 DISALLOW_COPY_AND_ASSIGN(MockReadCB); | 440 DISALLOW_COPY_AND_ASSIGN(MockReadCB); |
432 }; | 441 }; |
433 | 442 |
434 TEST_F(FFmpegDemuxerTest, Stop) { | 443 TEST_F(FFmpegDemuxerTest, Stop) { |
435 // Tests that calling Read() on a stopped demuxer stream immediately deletes | 444 // Tests that calling Read() on a stopped demuxer stream immediately deletes |
436 // the callback. | 445 // the callback. |
437 InitializeDemuxer(CreateDataSource("bear-320x240.webm")); | 446 CreateDemuxer("bear-320x240.webm"); |
447 InitializeDemuxer(); | |
438 | 448 |
439 // Get our stream. | 449 // Get our stream. |
440 scoped_refptr<DemuxerStream> audio = | 450 scoped_refptr<DemuxerStream> audio = |
441 demuxer_->GetStream(DemuxerStream::AUDIO); | 451 demuxer_->GetStream(DemuxerStream::AUDIO); |
442 ASSERT_TRUE(audio); | 452 ASSERT_TRUE(audio); |
443 | 453 |
444 demuxer_->Stop(NewExpectedClosure()); | 454 demuxer_->Stop(NewExpectedClosure()); |
445 | 455 |
446 // Expect all calls in sequence. | 456 // Expect all calls in sequence. |
447 InSequence s; | 457 InSequence s; |
(...skipping 15 matching lines...) Expand all Loading... | |
463 | 473 |
464 // ...and verify that |callback| was deleted. | 474 // ...and verify that |callback| was deleted. |
465 CheckPoint(1); | 475 CheckPoint(1); |
466 } | 476 } |
467 | 477 |
468 // The streams can outlive the demuxer because the streams may still be in use | 478 // The streams can outlive the demuxer because the streams may still be in use |
469 // by the decoder when the demuxer is destroyed. | 479 // by the decoder when the demuxer is destroyed. |
470 // This test verifies that DemuxerStream::Read() does not use an invalid demuxer | 480 // This test verifies that DemuxerStream::Read() does not use an invalid demuxer |
471 // pointer (no crash occurs) and calls the callback with an EndOfStream buffer. | 481 // pointer (no crash occurs) and calls the callback with an EndOfStream buffer. |
472 TEST_F(FFmpegDemuxerTest, StreamReadAfterStopAndDemuxerDestruction) { | 482 TEST_F(FFmpegDemuxerTest, StreamReadAfterStopAndDemuxerDestruction) { |
473 InitializeDemuxer(CreateDataSource("bear-320x240.webm")); | 483 CreateDemuxer("bear-320x240.webm"); |
484 InitializeDemuxer(); | |
474 | 485 |
475 // Get our stream. | 486 // Get our stream. |
476 scoped_refptr<DemuxerStream> audio = | 487 scoped_refptr<DemuxerStream> audio = |
477 demuxer_->GetStream(DemuxerStream::AUDIO); | 488 demuxer_->GetStream(DemuxerStream::AUDIO); |
478 ASSERT_TRUE(audio); | 489 ASSERT_TRUE(audio); |
479 | 490 |
480 demuxer_->Stop(NewExpectedClosure()); | 491 demuxer_->Stop(NewExpectedClosure()); |
481 | 492 |
482 // Finish up any remaining tasks. | 493 // Finish up any remaining tasks. |
483 message_loop_.RunAllPending(); | 494 message_loop_.RunAllPending(); |
(...skipping 22 matching lines...) Expand all Loading... | |
506 | 517 |
507 // ...and verify that |callback| was deleted. | 518 // ...and verify that |callback| was deleted. |
508 CheckPoint(1); | 519 CheckPoint(1); |
509 } | 520 } |
510 | 521 |
511 TEST_F(FFmpegDemuxerTest, DisableAudioStream) { | 522 TEST_F(FFmpegDemuxerTest, DisableAudioStream) { |
512 // We are doing the following things here: | 523 // We are doing the following things here: |
513 // 1. Initialize the demuxer with audio and video stream. | 524 // 1. Initialize the demuxer with audio and video stream. |
514 // 2. Send a "disable audio stream" message to the demuxer. | 525 // 2. Send a "disable audio stream" message to the demuxer. |
515 // 3. Demuxer will free audio packets even if audio stream was initialized. | 526 // 3. Demuxer will free audio packets even if audio stream was initialized. |
516 InitializeDemuxer(CreateDataSource("bear-320x240.webm")); | 527 CreateDemuxer("bear-320x240.webm"); |
528 InitializeDemuxer(); | |
517 | 529 |
518 // Submit a "disable audio stream" message to the demuxer. | 530 // Submit a "disable audio stream" message to the demuxer. |
519 demuxer_->OnAudioRendererDisabled(); | 531 demuxer_->OnAudioRendererDisabled(); |
520 message_loop_.RunAllPending(); | 532 message_loop_.RunAllPending(); |
521 | 533 |
522 // Get our streams. | 534 // Get our streams. |
523 scoped_refptr<DemuxerStream> video = | 535 scoped_refptr<DemuxerStream> video = |
524 demuxer_->GetStream(DemuxerStream::VIDEO); | 536 demuxer_->GetStream(DemuxerStream::VIDEO); |
525 scoped_refptr<DemuxerStream> audio = | 537 scoped_refptr<DemuxerStream> audio = |
526 demuxer_->GetStream(DemuxerStream::AUDIO); | 538 demuxer_->GetStream(DemuxerStream::AUDIO); |
(...skipping 14 matching lines...) Expand all Loading... | |
541 // Attempt a read from the audio stream: it should immediately return end of | 553 // Attempt a read from the audio stream: it should immediately return end of |
542 // stream without requiring the message loop to read data. | 554 // stream without requiring the message loop to read data. |
543 reader->Reset(); | 555 reader->Reset(); |
544 reader->Read(audio); | 556 reader->Read(audio); |
545 ASSERT_TRUE(reader->called()); | 557 ASSERT_TRUE(reader->called()); |
546 EXPECT_TRUE(reader->buffer()->IsEndOfStream()); | 558 EXPECT_TRUE(reader->buffer()->IsEndOfStream()); |
547 } | 559 } |
548 | 560 |
549 class MockFFmpegDemuxer : public FFmpegDemuxer { | 561 class MockFFmpegDemuxer : public FFmpegDemuxer { |
550 public: | 562 public: |
551 explicit MockFFmpegDemuxer(MessageLoop* message_loop) | 563 MockFFmpegDemuxer(MessageLoop* message_loop, |
552 : FFmpegDemuxer(message_loop, true) { | 564 const scoped_refptr<DataSource>& data_source) |
565 : FFmpegDemuxer(message_loop, data_source, true) { | |
553 } | 566 } |
554 virtual ~MockFFmpegDemuxer() {} | 567 virtual ~MockFFmpegDemuxer() {} |
555 | 568 |
556 MOCK_METHOD0(WaitForRead, int()); | 569 MOCK_METHOD0(WaitForRead, int()); |
557 MOCK_METHOD1(SignalReadCompleted, void(int size)); | 570 MOCK_METHOD1(SignalReadCompleted, void(int size)); |
558 | 571 |
559 private: | 572 private: |
560 DISALLOW_COPY_AND_ASSIGN(MockFFmpegDemuxer); | 573 DISALLOW_COPY_AND_ASSIGN(MockFFmpegDemuxer); |
561 }; | 574 }; |
562 | 575 |
563 // A gmock helper method to execute the callback and deletes it. | 576 // A gmock helper method to execute the callback and deletes it. |
564 void RunCallback(int size, const DataSource::ReadCB& callback) { | 577 void RunCallback(int size, const DataSource::ReadCB& callback) { |
565 DCHECK(!callback.is_null()); | 578 DCHECK(!callback.is_null()); |
566 callback.Run(size); | 579 callback.Run(size); |
567 } | 580 } |
568 | 581 |
569 TEST_F(FFmpegDemuxerTest, ProtocolRead) { | 582 TEST_F(FFmpegDemuxerTest, ProtocolRead) { |
570 scoped_refptr<StrictMock<MockDataSource> > data_source = | 583 scoped_refptr<StrictMock<MockDataSource> > data_source = |
571 new StrictMock<MockDataSource>(); | 584 new StrictMock<MockDataSource>(); |
572 | 585 |
573 EXPECT_CALL(*data_source, Stop(_)) | 586 EXPECT_CALL(*data_source, Stop(_)) |
574 .WillRepeatedly(Invoke(&RunStopFilterCallback)); | 587 .WillRepeatedly(Invoke(&RunStopFilterCallback)); |
575 | 588 |
576 // Creates a demuxer. | 589 // Creates a demuxer. |
577 scoped_refptr<MockFFmpegDemuxer> demuxer( | 590 scoped_refptr<MockFFmpegDemuxer> demuxer( |
578 new MockFFmpegDemuxer(&message_loop_)); | 591 new MockFFmpegDemuxer(&message_loop_, data_source)); |
579 ASSERT_TRUE(demuxer); | |
580 demuxer->set_host(&host_); | 592 demuxer->set_host(&host_); |
581 demuxer->data_source_ = data_source; | |
582 | 593 |
583 uint8 kBuffer[1]; | 594 uint8 kBuffer[1]; |
584 InSequence s; | 595 InSequence s; |
585 // Actions taken in the first read. | 596 // Actions taken in the first read. |
586 EXPECT_CALL(*data_source, GetSize(_)) | 597 EXPECT_CALL(*data_source, GetSize(_)) |
587 .WillOnce(DoAll(SetArgPointee<0>(1024), Return(true))); | 598 .WillOnce(DoAll(SetArgPointee<0>(1024), Return(true))); |
588 EXPECT_CALL(*data_source, Read(0, 512, kBuffer, _)) | 599 EXPECT_CALL(*data_source, Read(0, 512, kBuffer, _)) |
589 .WillOnce(WithArgs<1, 3>(Invoke(&RunCallback))); | 600 .WillOnce(WithArgs<1, 3>(Invoke(&RunCallback))); |
590 EXPECT_CALL(*demuxer, SignalReadCompleted(512)); | 601 EXPECT_CALL(*demuxer, SignalReadCompleted(512)); |
591 EXPECT_CALL(*demuxer, WaitForRead()) | 602 EXPECT_CALL(*demuxer, WaitForRead()) |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
636 | 647 |
637 TEST_F(FFmpegDemuxerTest, GetBitrate_SetInContainer_NoFileSize) { | 648 TEST_F(FFmpegDemuxerTest, GetBitrate_SetInContainer_NoFileSize) { |
638 EXPECT_TRUE(VideoHasValidBitrate("bear.ogv", true)); | 649 EXPECT_TRUE(VideoHasValidBitrate("bear.ogv", true)); |
639 } | 650 } |
640 | 651 |
641 TEST_F(FFmpegDemuxerTest, GetBitrate_UnsetInContainer_NoFileSize) { | 652 TEST_F(FFmpegDemuxerTest, GetBitrate_UnsetInContainer_NoFileSize) { |
642 EXPECT_TRUE(VideoHasValidBitrate("bear-320x240.webm", true)); | 653 EXPECT_TRUE(VideoHasValidBitrate("bear-320x240.webm", true)); |
643 } | 654 } |
644 | 655 |
645 TEST_F(FFmpegDemuxerTest, ProtocolGetSetPosition) { | 656 TEST_F(FFmpegDemuxerTest, ProtocolGetSetPosition) { |
646 scoped_refptr<DataSource> data_source = CreateDataSource("bear-320x240.webm"); | 657 CreateDemuxer("bear-320x240.webm"); |
647 InitializeDemuxer(data_source); | 658 InitializeDemuxer(); |
648 | 659 |
649 InSequence s; | 660 InSequence s; |
650 | 661 |
651 int64 size; | 662 int64 size; |
652 int64 position; | 663 int64 position; |
653 EXPECT_TRUE(demuxer_->GetSize(&size)); | 664 EXPECT_TRUE(demuxer_->GetSize(&size)); |
654 EXPECT_TRUE(demuxer_->GetPosition(&position)); | 665 EXPECT_TRUE(demuxer_->GetPosition(&position)); |
655 EXPECT_EQ(current_read_position_, position); | 666 EXPECT_EQ(current_read_position_, position); |
656 | 667 |
657 EXPECT_TRUE(demuxer_->SetPosition(512)); | 668 EXPECT_TRUE(demuxer_->SetPosition(512)); |
658 EXPECT_FALSE(demuxer_->SetPosition(size)); | 669 EXPECT_FALSE(demuxer_->SetPosition(size)); |
659 EXPECT_FALSE(demuxer_->SetPosition(size + 1)); | 670 EXPECT_FALSE(demuxer_->SetPosition(size + 1)); |
660 EXPECT_FALSE(demuxer_->SetPosition(-1)); | 671 EXPECT_FALSE(demuxer_->SetPosition(-1)); |
661 EXPECT_TRUE(demuxer_->GetPosition(&position)); | 672 EXPECT_TRUE(demuxer_->GetPosition(&position)); |
662 EXPECT_EQ(512, position); | 673 EXPECT_EQ(512, position); |
663 } | 674 } |
664 | 675 |
665 TEST_F(FFmpegDemuxerTest, ProtocolGetSize) { | 676 TEST_F(FFmpegDemuxerTest, ProtocolGetSize) { |
666 scoped_refptr<DataSource> data_source = CreateDataSource("bear-320x240.webm"); | 677 CreateDemuxer("bear-320x240.webm"); |
667 InitializeDemuxer(data_source); | 678 InitializeDemuxer(); |
668 | 679 |
669 int64 data_source_size = 0; | 680 int64 data_source_size = 0; |
670 int64 demuxer_size = 0; | 681 int64 demuxer_size = 0; |
671 EXPECT_TRUE(data_source->GetSize(&data_source_size)); | 682 EXPECT_TRUE(data_source_->GetSize(&data_source_size)); |
672 EXPECT_TRUE(demuxer_->GetSize(&demuxer_size)); | 683 EXPECT_TRUE(demuxer_->GetSize(&demuxer_size)); |
673 EXPECT_NE(0, data_source_size); | 684 EXPECT_NE(0, data_source_size); |
674 EXPECT_EQ(data_source_size, demuxer_size); | 685 EXPECT_EQ(data_source_size, demuxer_size); |
675 } | 686 } |
676 | 687 |
677 TEST_F(FFmpegDemuxerTest, ProtocolIsStreaming) { | 688 TEST_F(FFmpegDemuxerTest, ProtocolIsStreaming) { |
678 scoped_refptr<DataSource> data_source = CreateDataSource("bear-320x240.webm"); | 689 CreateDemuxer("bear-320x240.webm"); |
679 InitializeDemuxer(data_source); | 690 InitializeDemuxer(); |
680 | 691 |
681 EXPECT_FALSE(data_source->IsStreaming()); | 692 EXPECT_FALSE(data_source_->IsStreaming()); |
682 EXPECT_FALSE(demuxer_->IsStreaming()); | 693 EXPECT_FALSE(demuxer_->IsStreaming()); |
683 } | 694 } |
684 | 695 |
685 // Verify that seek works properly when the WebM cues data is at the start of | 696 // Verify that seek works properly when the WebM cues data is at the start of |
686 // the file instead of at the end. | 697 // the file instead of at the end. |
687 TEST_F(FFmpegDemuxerTest, SeekWithCuesBeforeFirstCluster) { | 698 TEST_F(FFmpegDemuxerTest, SeekWithCuesBeforeFirstCluster) { |
688 InitializeDemuxer(CreateDataSource("bear-320x240-cues-in-front.webm")); | 699 CreateDemuxer("bear-320x240-cues-in-front.webm"); |
700 InitializeDemuxer(); | |
acolwell GONE FROM CHROMIUM
2012/03/27 20:11:35
nit: How about making InitializeDemuxer() just tak
| |
689 | 701 |
690 // Get our streams. | 702 // Get our streams. |
691 scoped_refptr<DemuxerStream> video = | 703 scoped_refptr<DemuxerStream> video = |
692 demuxer_->GetStream(DemuxerStream::VIDEO); | 704 demuxer_->GetStream(DemuxerStream::VIDEO); |
693 scoped_refptr<DemuxerStream> audio = | 705 scoped_refptr<DemuxerStream> audio = |
694 demuxer_->GetStream(DemuxerStream::AUDIO); | 706 demuxer_->GetStream(DemuxerStream::AUDIO); |
695 ASSERT_TRUE(video); | 707 ASSERT_TRUE(video); |
696 ASSERT_TRUE(audio); | 708 ASSERT_TRUE(audio); |
697 | 709 |
698 // Read a video packet and release it. | 710 // Read a video packet and release it. |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
737 message_loop_.RunAllPending(); | 749 message_loop_.RunAllPending(); |
738 EXPECT_TRUE(reader->called()); | 750 EXPECT_TRUE(reader->called()); |
739 ValidateBuffer(FROM_HERE, reader->buffer(), 1740, 2436000); | 751 ValidateBuffer(FROM_HERE, reader->buffer(), 1740, 2436000); |
740 | 752 |
741 // Manually release the last reference to the buffer and verify it was freed. | 753 // Manually release the last reference to the buffer and verify it was freed. |
742 reader->Reset(); | 754 reader->Reset(); |
743 message_loop_.RunAllPending(); | 755 message_loop_.RunAllPending(); |
744 } | 756 } |
745 | 757 |
746 } // namespace media | 758 } // namespace media |
OLD | NEW |