OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "media/base/filters.h" | 7 #include "media/base/filters.h" |
8 #include "media/base/mock_ffmpeg.h" | 8 #include "media/base/mock_ffmpeg.h" |
9 #include "media/base/mock_filter_host.h" | 9 #include "media/base/mock_filter_host.h" |
10 #include "media/base/mock_filters.h" | 10 #include "media/base/mock_filters.h" |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 EXPECT_CALL(*MockFFmpeg::get(), AVFindStreamInfo(&format_context_)) | 126 EXPECT_CALL(*MockFFmpeg::get(), AVFindStreamInfo(&format_context_)) |
127 .WillOnce(Return(0)); | 127 .WillOnce(Return(0)); |
128 EXPECT_CALL(*MockFFmpeg::get(), AVCloseInputFile(&format_context_)); | 128 EXPECT_CALL(*MockFFmpeg::get(), AVCloseInputFile(&format_context_)); |
129 } | 129 } |
130 | 130 |
131 // Initializes both MockFFmpeg and FFmpegDemuxer. | 131 // Initializes both MockFFmpeg and FFmpegDemuxer. |
132 void InitializeDemuxer() { | 132 void InitializeDemuxer() { |
133 InitializeDemuxerMocks(); | 133 InitializeDemuxerMocks(); |
134 | 134 |
135 // We expect a successful initialization. | 135 // We expect a successful initialization. |
136 EXPECT_CALL(host_, InitializationComplete()); | 136 EXPECT_CALL(callback_, OnFilterCallback()); |
| 137 EXPECT_CALL(callback_, OnCallbackDestroyed()); |
137 | 138 |
138 // Since we ignore data streams, the duration should be equal to the longest | 139 // Since we ignore data streams, the duration should be equal to the longest |
139 // supported stream's duration (audio, in this case). | 140 // supported stream's duration (audio, in this case). |
140 base::TimeDelta expected_duration = | 141 base::TimeDelta expected_duration = |
141 base::TimeDelta::FromMicroseconds(kDurations[AV_STREAM_AUDIO]); | 142 base::TimeDelta::FromMicroseconds(kDurations[AV_STREAM_AUDIO]); |
142 EXPECT_CALL(host_, SetDuration(expected_duration)); | 143 EXPECT_CALL(host_, SetDuration(expected_duration)); |
143 | 144 |
144 EXPECT_TRUE(demuxer_->Initialize(data_source_.get())); | 145 demuxer_->Initialize(data_source_.get(), callback_.NewCallback()); |
145 message_loop_.RunAllPending(); | 146 message_loop_.RunAllPending(); |
146 } | 147 } |
147 | 148 |
148 // Fixture members. | 149 // Fixture members. |
149 scoped_refptr<FilterFactory> factory_; | 150 scoped_refptr<FilterFactory> factory_; |
150 scoped_refptr<FFmpegDemuxer> demuxer_; | 151 scoped_refptr<FFmpegDemuxer> demuxer_; |
151 scoped_refptr<StrictMock<MockDataSource> > data_source_; | 152 scoped_refptr<StrictMock<MockDataSource> > data_source_; |
152 StrictMock<MockFilterHost> host_; | 153 StrictMock<MockFilterHost> host_; |
| 154 StrictMock<MockFilterCallback> callback_; |
153 MessageLoop message_loop_; | 155 MessageLoop message_loop_; |
154 | 156 |
155 // FFmpeg fixtures. | 157 // FFmpeg fixtures. |
156 AVFormatContext format_context_; | 158 AVFormatContext format_context_; |
157 AVCodecContext codecs_[AV_STREAM_MAX]; | 159 AVCodecContext codecs_[AV_STREAM_MAX]; |
158 AVStream streams_[AV_STREAM_MAX]; | 160 AVStream streams_[AV_STREAM_MAX]; |
159 MockFFmpeg mock_ffmpeg_; | 161 MockFFmpeg mock_ffmpeg_; |
160 | 162 |
161 private: | 163 private: |
162 DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxerTest); | 164 DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxerTest); |
(...skipping 26 matching lines...) Expand all Loading... |
189 mime_type::kApplicationOctetStream); | 191 mime_type::kApplicationOctetStream); |
190 demuxer = factory->Create<Demuxer>(media_format); | 192 demuxer = factory->Create<Demuxer>(media_format); |
191 ASSERT_TRUE(demuxer); | 193 ASSERT_TRUE(demuxer); |
192 } | 194 } |
193 | 195 |
194 TEST_F(FFmpegDemuxerTest, Initialize_OpenFails) { | 196 TEST_F(FFmpegDemuxerTest, Initialize_OpenFails) { |
195 // Simulate av_open_input_file() failing. | 197 // Simulate av_open_input_file() failing. |
196 EXPECT_CALL(*MockFFmpeg::get(), AVOpenInputFile(_, _, NULL, 0, NULL)) | 198 EXPECT_CALL(*MockFFmpeg::get(), AVOpenInputFile(_, _, NULL, 0, NULL)) |
197 .WillOnce(Return(-1)); | 199 .WillOnce(Return(-1)); |
198 EXPECT_CALL(host_, Error(DEMUXER_ERROR_COULD_NOT_OPEN)); | 200 EXPECT_CALL(host_, Error(DEMUXER_ERROR_COULD_NOT_OPEN)); |
| 201 EXPECT_CALL(callback_, OnFilterCallback()); |
| 202 EXPECT_CALL(callback_, OnCallbackDestroyed()); |
199 | 203 |
200 EXPECT_TRUE(demuxer_->Initialize(data_source_.get())); | 204 demuxer_->Initialize(data_source_.get(), callback_.NewCallback()); |
201 message_loop_.RunAllPending(); | 205 message_loop_.RunAllPending(); |
202 } | 206 } |
203 | 207 |
204 TEST_F(FFmpegDemuxerTest, Initialize_ParseFails) { | 208 TEST_F(FFmpegDemuxerTest, Initialize_ParseFails) { |
205 // Simulate av_find_stream_info() failing. | 209 // Simulate av_find_stream_info() failing. |
206 EXPECT_CALL(*MockFFmpeg::get(), AVOpenInputFile(_, _, NULL, 0, NULL)) | 210 EXPECT_CALL(*MockFFmpeg::get(), AVOpenInputFile(_, _, NULL, 0, NULL)) |
207 .WillOnce(DoAll(SetArgumentPointee<0>(&format_context_), Return(0))); | 211 .WillOnce(DoAll(SetArgumentPointee<0>(&format_context_), Return(0))); |
208 EXPECT_CALL(*MockFFmpeg::get(), AVFindStreamInfo(&format_context_)) | 212 EXPECT_CALL(*MockFFmpeg::get(), AVFindStreamInfo(&format_context_)) |
209 .WillOnce(Return(AVERROR_IO)); | 213 .WillOnce(Return(AVERROR_IO)); |
210 EXPECT_CALL(*MockFFmpeg::get(), AVCloseInputFile(&format_context_)); | 214 EXPECT_CALL(*MockFFmpeg::get(), AVCloseInputFile(&format_context_)); |
211 EXPECT_CALL(host_, Error(DEMUXER_ERROR_COULD_NOT_PARSE)); | 215 EXPECT_CALL(host_, Error(DEMUXER_ERROR_COULD_NOT_PARSE)); |
| 216 EXPECT_CALL(callback_, OnFilterCallback()); |
| 217 EXPECT_CALL(callback_, OnCallbackDestroyed()); |
212 | 218 |
213 EXPECT_TRUE(demuxer_->Initialize(data_source_.get())); | 219 demuxer_->Initialize(data_source_.get(), callback_.NewCallback()); |
214 message_loop_.RunAllPending(); | 220 message_loop_.RunAllPending(); |
215 } | 221 } |
216 | 222 |
217 TEST_F(FFmpegDemuxerTest, Initialize_NoStreams) { | 223 TEST_F(FFmpegDemuxerTest, Initialize_NoStreams) { |
218 // Simulate media with no parseable streams. | 224 // Simulate media with no parseable streams. |
219 { | 225 { |
220 SCOPED_TRACE(""); | 226 SCOPED_TRACE(""); |
221 InitializeDemuxerMocks(); | 227 InitializeDemuxerMocks(); |
222 } | 228 } |
223 EXPECT_CALL(host_, Error(DEMUXER_ERROR_NO_SUPPORTED_STREAMS)); | 229 EXPECT_CALL(host_, Error(DEMUXER_ERROR_NO_SUPPORTED_STREAMS)); |
| 230 EXPECT_CALL(callback_, OnFilterCallback()); |
| 231 EXPECT_CALL(callback_, OnCallbackDestroyed()); |
224 format_context_.nb_streams = 0; | 232 format_context_.nb_streams = 0; |
225 | 233 |
226 EXPECT_TRUE(demuxer_->Initialize(data_source_.get())); | 234 demuxer_->Initialize(data_source_.get(), callback_.NewCallback()); |
227 message_loop_.RunAllPending(); | 235 message_loop_.RunAllPending(); |
228 } | 236 } |
229 | 237 |
230 TEST_F(FFmpegDemuxerTest, Initialize_DataStreamOnly) { | 238 TEST_F(FFmpegDemuxerTest, Initialize_DataStreamOnly) { |
231 // Simulate media with a data stream but no audio or video streams. | 239 // Simulate media with a data stream but no audio or video streams. |
232 { | 240 { |
233 SCOPED_TRACE(""); | 241 SCOPED_TRACE(""); |
234 InitializeDemuxerMocks(); | 242 InitializeDemuxerMocks(); |
235 } | 243 } |
236 EXPECT_CALL(host_, Error(DEMUXER_ERROR_NO_SUPPORTED_STREAMS)); | 244 EXPECT_CALL(host_, Error(DEMUXER_ERROR_NO_SUPPORTED_STREAMS)); |
| 245 EXPECT_CALL(callback_, OnFilterCallback()); |
| 246 EXPECT_CALL(callback_, OnCallbackDestroyed()); |
237 EXPECT_EQ(format_context_.streams[0], &streams_[AV_STREAM_DATA]); | 247 EXPECT_EQ(format_context_.streams[0], &streams_[AV_STREAM_DATA]); |
238 format_context_.nb_streams = 1; | 248 format_context_.nb_streams = 1; |
239 | 249 |
240 EXPECT_TRUE(demuxer_->Initialize(data_source_.get())); | 250 demuxer_->Initialize(data_source_.get(), callback_.NewCallback()); |
241 message_loop_.RunAllPending(); | 251 message_loop_.RunAllPending(); |
242 } | 252 } |
243 | 253 |
244 TEST_F(FFmpegDemuxerTest, Initialize_Successful) { | 254 TEST_F(FFmpegDemuxerTest, Initialize_Successful) { |
245 { | 255 { |
246 SCOPED_TRACE(""); | 256 SCOPED_TRACE(""); |
247 InitializeDemuxer(); | 257 InitializeDemuxer(); |
248 } | 258 } |
249 | 259 |
250 // Verify that our demuxer streams were created from our AVStream structures. | 260 // Verify that our demuxer streams were created from our AVStream structures. |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 EXPECT_CALL(*MockFFmpeg::get(), CheckPoint(1)); | 449 EXPECT_CALL(*MockFFmpeg::get(), CheckPoint(1)); |
440 | 450 |
441 // ...then we'll seek, which should release the previously queued packets... | 451 // ...then we'll seek, which should release the previously queued packets... |
442 EXPECT_CALL(*MockFFmpeg::get(), AVFreePacket(_)).WillOnce(FreePacket()); | 452 EXPECT_CALL(*MockFFmpeg::get(), AVFreePacket(_)).WillOnce(FreePacket()); |
443 EXPECT_CALL(*MockFFmpeg::get(), AVFreePacket(_)).WillOnce(FreePacket()); | 453 EXPECT_CALL(*MockFFmpeg::get(), AVFreePacket(_)).WillOnce(FreePacket()); |
444 | 454 |
445 // ...then we'll expect the actual seek call... | 455 // ...then we'll expect the actual seek call... |
446 EXPECT_CALL(*MockFFmpeg::get(), | 456 EXPECT_CALL(*MockFFmpeg::get(), |
447 AVSeekFrame(&format_context_, -1, kExpectedTimestamp, kExpectedFlags)) | 457 AVSeekFrame(&format_context_, -1, kExpectedTimestamp, kExpectedFlags)) |
448 .WillOnce(Return(0)); | 458 .WillOnce(Return(0)); |
| 459 |
| 460 // ...then our callback will be executed... |
| 461 StrictMock<MockFilterCallback> seek_callback; |
| 462 EXPECT_CALL(seek_callback, OnFilterCallback()); |
| 463 EXPECT_CALL(seek_callback, OnCallbackDestroyed()); |
449 EXPECT_CALL(*MockFFmpeg::get(), CheckPoint(2)); | 464 EXPECT_CALL(*MockFFmpeg::get(), CheckPoint(2)); |
450 | 465 |
451 // ...followed by two audio packet reads we'll trigger... | 466 // ...followed by two audio packet reads we'll trigger... |
452 EXPECT_CALL(*MockFFmpeg::get(), AVReadFrame(&format_context_, _)) | 467 EXPECT_CALL(*MockFFmpeg::get(), AVReadFrame(&format_context_, _)) |
453 .WillOnce(CreatePacket(AV_STREAM_AUDIO, kAudioData, kDataSize)); | 468 .WillOnce(CreatePacket(AV_STREAM_AUDIO, kAudioData, kDataSize)); |
454 EXPECT_CALL(*MockFFmpeg::get(), AVFreePacket(_)).WillOnce(FreePacket()); | 469 EXPECT_CALL(*MockFFmpeg::get(), AVFreePacket(_)).WillOnce(FreePacket()); |
455 EXPECT_CALL(*MockFFmpeg::get(), AVReadFrame(&format_context_, _)) | 470 EXPECT_CALL(*MockFFmpeg::get(), AVReadFrame(&format_context_, _)) |
456 .WillOnce(CreatePacket(AV_STREAM_AUDIO, kAudioData, kDataSize)); | 471 .WillOnce(CreatePacket(AV_STREAM_AUDIO, kAudioData, kDataSize)); |
457 EXPECT_CALL(*MockFFmpeg::get(), AVFreePacket(_)).WillOnce(FreePacket()); | 472 EXPECT_CALL(*MockFFmpeg::get(), AVFreePacket(_)).WillOnce(FreePacket()); |
458 | 473 |
(...skipping 17 matching lines...) Expand all Loading... |
476 EXPECT_FALSE(reader->buffer()->IsDiscontinuous()); | 491 EXPECT_FALSE(reader->buffer()->IsDiscontinuous()); |
477 EXPECT_EQ(kVideoData, reader->buffer()->GetData()); | 492 EXPECT_EQ(kVideoData, reader->buffer()->GetData()); |
478 EXPECT_EQ(kDataSize, reader->buffer()->GetDataSize()); | 493 EXPECT_EQ(kDataSize, reader->buffer()->GetDataSize()); |
479 | 494 |
480 // Release the video packet and verify the other packets are still queued. | 495 // Release the video packet and verify the other packets are still queued. |
481 reader->Reset(); | 496 reader->Reset(); |
482 message_loop_.RunAllPending(); | 497 message_loop_.RunAllPending(); |
483 MockFFmpeg::get()->CheckPoint(1); | 498 MockFFmpeg::get()->CheckPoint(1); |
484 | 499 |
485 // Now issue a simple forward seek, which should discard queued packets. | 500 // Now issue a simple forward seek, which should discard queued packets. |
486 demuxer_->Seek(base::TimeDelta::FromMicroseconds(kExpectedTimestamp)); | 501 demuxer_->Seek(base::TimeDelta::FromMicroseconds(kExpectedTimestamp), |
| 502 seek_callback.NewCallback()); |
487 message_loop_.RunAllPending(); | 503 message_loop_.RunAllPending(); |
488 MockFFmpeg::get()->CheckPoint(2); | 504 MockFFmpeg::get()->CheckPoint(2); |
489 | 505 |
490 // The next read from each stream should now be discontinuous, but subsequent | 506 // The next read from each stream should now be discontinuous, but subsequent |
491 // reads should not. | 507 // reads should not. |
492 | 508 |
493 // Audio read #1, should be discontinuous. | 509 // Audio read #1, should be discontinuous. |
494 reader->Read(audio); | 510 reader->Read(audio); |
495 message_loop_.RunAllPending(); | 511 message_loop_.RunAllPending(); |
496 EXPECT_TRUE(reader->called()); | 512 EXPECT_TRUE(reader->called()); |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
640 | 656 |
641 // Attempt the read... | 657 // Attempt the read... |
642 audio->Read(callback.release()); | 658 audio->Read(callback.release()); |
643 message_loop_.RunAllPending(); | 659 message_loop_.RunAllPending(); |
644 | 660 |
645 // ...and verify that |callback| was deleted. | 661 // ...and verify that |callback| was deleted. |
646 MockFFmpeg::get()->CheckPoint(1); | 662 MockFFmpeg::get()->CheckPoint(1); |
647 } | 663 } |
648 | 664 |
649 } // namespace media | 665 } // namespace media |
OLD | NEW |