| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/threading/thread.h" | 7 #include "base/threading/thread.h" |
| 8 #include "media/base/filters.h" | 8 #include "media/base/filters.h" |
| 9 #include "media/base/mock_callback.h" | 9 #include "media/base/mock_callback.h" |
| 10 #include "media/base/mock_ffmpeg.h" | 10 #include "media/base/mock_ffmpeg.h" |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 // Initialize AVStream and AVFormatContext structures. We set the time base | 98 // Initialize AVStream and AVFormatContext structures. We set the time base |
| 99 // of the streams such that duration is reported in microseconds. | 99 // of the streams such that duration is reported in microseconds. |
| 100 format_context_.nb_streams = AV_STREAM_MAX; | 100 format_context_.nb_streams = AV_STREAM_MAX; |
| 101 for (size_t i = 0; i < AV_STREAM_MAX; ++i) { | 101 for (size_t i = 0; i < AV_STREAM_MAX; ++i) { |
| 102 format_context_.streams[i] = &streams_[i]; | 102 format_context_.streams[i] = &streams_[i]; |
| 103 streams_[i].codec = &codecs_[i]; | 103 streams_[i].codec = &codecs_[i]; |
| 104 streams_[i].duration = kDurations[i]; | 104 streams_[i].duration = kDurations[i]; |
| 105 streams_[i].time_base.den = 1 * base::Time::kMicrosecondsPerSecond; | 105 streams_[i].time_base.den = 1 * base::Time::kMicrosecondsPerSecond; |
| 106 streams_[i].time_base.num = 1; | 106 streams_[i].time_base.num = 1; |
| 107 } | 107 } |
| 108 | |
| 109 // Initialize MockFFmpeg. | |
| 110 MockFFmpeg::set(&mock_ffmpeg_); | |
| 111 } | 108 } |
| 112 | 109 |
| 113 virtual ~FFmpegDemuxerTest() { | 110 virtual ~FFmpegDemuxerTest() { |
| 114 // Call Stop() to shut down internal threads. | 111 // Call Stop() to shut down internal threads. |
| 115 demuxer_->Stop(NewExpectedCallback()); | 112 demuxer_->Stop(NewExpectedCallback()); |
| 116 | 113 |
| 117 // Finish up any remaining tasks. | 114 // Finish up any remaining tasks. |
| 118 message_loop_.RunAllPending(); | 115 message_loop_.RunAllPending(); |
| 119 | 116 |
| 120 // Release the reference to the demuxer. | 117 // Release the reference to the demuxer. |
| 121 demuxer_ = NULL; | 118 demuxer_ = NULL; |
| 122 | |
| 123 // Reset MockFFmpeg. | |
| 124 MockFFmpeg::set(NULL); | |
| 125 } | 119 } |
| 126 | 120 |
| 127 // Sets up MockFFmpeg to allow FFmpegDemuxer to successfully initialize. | 121 // Sets up MockFFmpeg to allow FFmpegDemuxer to successfully initialize. |
| 128 void InitializeDemuxerMocks() { | 122 void InitializeDemuxerMocks() { |
| 129 EXPECT_CALL(*MockFFmpeg::get(), AVOpenInputFile(_, _, NULL, 0, NULL)) | 123 EXPECT_CALL(mock_ffmpeg_, AVOpenInputFile(_, _, NULL, 0, NULL)) |
| 130 .WillOnce(DoAll(SetArgumentPointee<0>(&format_context_), Return(0))); | 124 .WillOnce(DoAll(SetArgumentPointee<0>(&format_context_), Return(0))); |
| 131 EXPECT_CALL(*MockFFmpeg::get(), AVFindStreamInfo(&format_context_)) | 125 EXPECT_CALL(mock_ffmpeg_, AVFindStreamInfo(&format_context_)) |
| 132 .WillOnce(Return(0)); | 126 .WillOnce(Return(0)); |
| 133 EXPECT_CALL(*MockFFmpeg::get(), AVCloseInputFile(&format_context_)); | 127 EXPECT_CALL(mock_ffmpeg_, AVCloseInputFile(&format_context_)); |
| 134 } | 128 } |
| 135 | 129 |
| 136 // Initializes both MockFFmpeg and FFmpegDemuxer. | 130 // Initializes both MockFFmpeg and FFmpegDemuxer. |
| 137 void InitializeDemuxer() { | 131 void InitializeDemuxer() { |
| 138 InitializeDemuxerMocks(); | 132 InitializeDemuxerMocks(); |
| 139 | 133 |
| 140 // Since we ignore data streams, the duration should be equal to the longest | 134 // Since we ignore data streams, the duration should be equal to the longest |
| 141 // supported stream's duration (audio, in this case). | 135 // supported stream's duration (audio, in this case). |
| 142 base::TimeDelta expected_duration = | 136 base::TimeDelta expected_duration = |
| 143 base::TimeDelta::FromMicroseconds(kDurations[AV_STREAM_AUDIO]); | 137 base::TimeDelta::FromMicroseconds(kDurations[AV_STREAM_AUDIO]); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 172 const int FFmpegDemuxerTest::kWidth = 1280; | 166 const int FFmpegDemuxerTest::kWidth = 1280; |
| 173 const int FFmpegDemuxerTest::kHeight = 720; | 167 const int FFmpegDemuxerTest::kHeight = 720; |
| 174 | 168 |
| 175 const size_t FFmpegDemuxerTest::kDataSize = 4; | 169 const size_t FFmpegDemuxerTest::kDataSize = 4; |
| 176 const uint8 FFmpegDemuxerTest::kAudioData[kDataSize] = {0, 1, 2, 3}; | 170 const uint8 FFmpegDemuxerTest::kAudioData[kDataSize] = {0, 1, 2, 3}; |
| 177 const uint8 FFmpegDemuxerTest::kVideoData[kDataSize] = {4, 5, 6, 7}; | 171 const uint8 FFmpegDemuxerTest::kVideoData[kDataSize] = {4, 5, 6, 7}; |
| 178 const uint8* FFmpegDemuxerTest::kNullData = NULL; | 172 const uint8* FFmpegDemuxerTest::kNullData = NULL; |
| 179 | 173 |
| 180 TEST_F(FFmpegDemuxerTest, Initialize_OpenFails) { | 174 TEST_F(FFmpegDemuxerTest, Initialize_OpenFails) { |
| 181 // Simulate av_open_input_file() failing. | 175 // Simulate av_open_input_file() failing. |
| 182 EXPECT_CALL(*MockFFmpeg::get(), AVOpenInputFile(_, _, NULL, 0, NULL)) | 176 EXPECT_CALL(mock_ffmpeg_, AVOpenInputFile(_, _, NULL, 0, NULL)) |
| 183 .WillOnce(Return(-1)); | 177 .WillOnce(Return(-1)); |
| 184 EXPECT_CALL(host_, SetError(DEMUXER_ERROR_COULD_NOT_OPEN)); | 178 EXPECT_CALL(host_, SetError(DEMUXER_ERROR_COULD_NOT_OPEN)); |
| 185 | 179 |
| 186 demuxer_->Initialize(data_source_.get(), NewExpectedCallback()); | 180 demuxer_->Initialize(data_source_.get(), NewExpectedCallback()); |
| 187 message_loop_.RunAllPending(); | 181 message_loop_.RunAllPending(); |
| 188 } | 182 } |
| 189 | 183 |
| 190 TEST_F(FFmpegDemuxerTest, Initialize_ParseFails) { | 184 TEST_F(FFmpegDemuxerTest, Initialize_ParseFails) { |
| 191 // Simulate av_find_stream_info() failing. | 185 // Simulate av_find_stream_info() failing. |
| 192 EXPECT_CALL(*MockFFmpeg::get(), AVOpenInputFile(_, _, NULL, 0, NULL)) | 186 EXPECT_CALL(mock_ffmpeg_, AVOpenInputFile(_, _, NULL, 0, NULL)) |
| 193 .WillOnce(DoAll(SetArgumentPointee<0>(&format_context_), Return(0))); | 187 .WillOnce(DoAll(SetArgumentPointee<0>(&format_context_), Return(0))); |
| 194 EXPECT_CALL(*MockFFmpeg::get(), AVFindStreamInfo(&format_context_)) | 188 EXPECT_CALL(mock_ffmpeg_, AVFindStreamInfo(&format_context_)) |
| 195 .WillOnce(Return(AVERROR_IO)); | 189 .WillOnce(Return(AVERROR_IO)); |
| 196 EXPECT_CALL(*MockFFmpeg::get(), AVCloseInputFile(&format_context_)); | 190 EXPECT_CALL(mock_ffmpeg_, AVCloseInputFile(&format_context_)); |
| 197 EXPECT_CALL(host_, SetError(DEMUXER_ERROR_COULD_NOT_PARSE)); | 191 EXPECT_CALL(host_, SetError(DEMUXER_ERROR_COULD_NOT_PARSE)); |
| 198 | 192 |
| 199 demuxer_->Initialize(data_source_.get(), NewExpectedCallback()); | 193 demuxer_->Initialize(data_source_.get(), NewExpectedCallback()); |
| 200 message_loop_.RunAllPending(); | 194 message_loop_.RunAllPending(); |
| 201 } | 195 } |
| 202 | 196 |
| 203 TEST_F(FFmpegDemuxerTest, Initialize_NoStreams) { | 197 TEST_F(FFmpegDemuxerTest, Initialize_NoStreams) { |
| 204 // Simulate media with no parseable streams. | 198 // Simulate media with no parseable streams. |
| 205 { | 199 { |
| 206 SCOPED_TRACE(""); | 200 SCOPED_TRACE(""); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 TEST_F(FFmpegDemuxerTest, Read_DiscardUninteresting) { | 257 TEST_F(FFmpegDemuxerTest, Read_DiscardUninteresting) { |
| 264 // We test that on a successful audio packet read, that the packet is | 258 // We test that on a successful audio packet read, that the packet is |
| 265 // duplicated (FFmpeg memory management safety), and a copy of it ends up in | 259 // duplicated (FFmpeg memory management safety), and a copy of it ends up in |
| 266 // the DemuxerStream. | 260 // the DemuxerStream. |
| 267 { | 261 { |
| 268 SCOPED_TRACE(""); | 262 SCOPED_TRACE(""); |
| 269 InitializeDemuxer(); | 263 InitializeDemuxer(); |
| 270 } | 264 } |
| 271 | 265 |
| 272 // Ignore all AVFreePacket() calls. We check this elsewhere. | 266 // Ignore all AVFreePacket() calls. We check this elsewhere. |
| 273 EXPECT_CALL(*MockFFmpeg::get(), AVFreePacket(_)).Times(AnyNumber()); | 267 EXPECT_CALL(mock_ffmpeg_, AVFreePacket(_)).Times(AnyNumber()); |
| 274 | 268 |
| 275 // The demuxer will read a data packet which will get immediately freed, | 269 // The demuxer will read a data packet which will get immediately freed, |
| 276 // followed by a read error to end the reading. | 270 // followed by a read error to end the reading. |
| 277 InSequence s; | 271 InSequence s; |
| 278 EXPECT_CALL(*MockFFmpeg::get(), AVReadFrame(&format_context_, _)) | 272 EXPECT_CALL(mock_ffmpeg_, AVReadFrame(&format_context_, _)) |
| 279 .WillOnce(CreatePacketNoCount(AV_STREAM_DATA, kNullData, 0)); | 273 .WillOnce(CreatePacketNoCount(AV_STREAM_DATA, kNullData, 0)); |
| 280 EXPECT_CALL(*MockFFmpeg::get(), AVReadFrame(&format_context_, _)) | 274 EXPECT_CALL(mock_ffmpeg_, AVReadFrame(&format_context_, _)) |
| 281 .WillOnce(Return(AVERROR_IO)); | 275 .WillOnce(Return(AVERROR_IO)); |
| 282 | 276 |
| 283 // Attempt a read from the audio stream and run the message loop until done. | 277 // Attempt a read from the audio stream and run the message loop until done. |
| 284 scoped_refptr<DemuxerStream> audio = demuxer_->GetStream(DS_STREAM_AUDIO); | 278 scoped_refptr<DemuxerStream> audio = demuxer_->GetStream(DS_STREAM_AUDIO); |
| 285 scoped_refptr<DemuxerStreamReader> reader(new DemuxerStreamReader()); | 279 scoped_refptr<DemuxerStreamReader> reader(new DemuxerStreamReader()); |
| 286 reader->Read(audio); | 280 reader->Read(audio); |
| 287 message_loop_.RunAllPending(); | 281 message_loop_.RunAllPending(); |
| 288 | 282 |
| 289 EXPECT_TRUE(reader->called()); | 283 EXPECT_TRUE(reader->called()); |
| 290 ASSERT_TRUE(reader->buffer()); | 284 ASSERT_TRUE(reader->buffer()); |
| 291 EXPECT_TRUE(reader->buffer()->IsEndOfStream()); | 285 EXPECT_TRUE(reader->buffer()->IsEndOfStream()); |
| 292 } | 286 } |
| 293 | 287 |
| 294 TEST_F(FFmpegDemuxerTest, Read_Audio) { | 288 TEST_F(FFmpegDemuxerTest, Read_Audio) { |
| 295 // We test that on a successful audio packet read, that the packet is | 289 // We test that on a successful audio packet read, that the packet is |
| 296 // duplicated (FFmpeg memory management safety), and a copy of it ends up in | 290 // duplicated (FFmpeg memory management safety), and a copy of it ends up in |
| 297 // the DemuxerStream. | 291 // the DemuxerStream. |
| 298 { | 292 { |
| 299 SCOPED_TRACE(""); | 293 SCOPED_TRACE(""); |
| 300 InitializeDemuxer(); | 294 InitializeDemuxer(); |
| 301 } | 295 } |
| 302 | 296 |
| 303 // Ignore all AVFreePacket() calls. We check this via valgrind. | 297 // Ignore all AVFreePacket() calls. We check this via valgrind. |
| 304 EXPECT_CALL(*MockFFmpeg::get(), AVFreePacket(_)).Times(AnyNumber()); | 298 EXPECT_CALL(mock_ffmpeg_, AVFreePacket(_)).Times(AnyNumber()); |
| 305 | 299 |
| 306 // The demuxer will read a data packet which will get immediately freed, | 300 // The demuxer will read a data packet which will get immediately freed, |
| 307 // followed by reading an audio packet... | 301 // followed by reading an audio packet... |
| 308 EXPECT_CALL(*MockFFmpeg::get(), AVReadFrame(&format_context_, _)) | 302 EXPECT_CALL(mock_ffmpeg_, AVReadFrame(&format_context_, _)) |
| 309 .WillOnce(CreatePacketNoCount(AV_STREAM_AUDIO, kAudioData, kDataSize)); | 303 .WillOnce(CreatePacketNoCount(AV_STREAM_AUDIO, kAudioData, kDataSize)); |
| 310 EXPECT_CALL(*MockFFmpeg::get(), AVDupPacket(_)) | 304 EXPECT_CALL(mock_ffmpeg_, AVDupPacket(_)) |
| 311 .WillOnce(Return(0)); | 305 .WillOnce(Return(0)); |
| 312 | 306 |
| 313 // Attempt a read from the audio stream and run the message loop until done. | 307 // Attempt a read from the audio stream and run the message loop until done. |
| 314 scoped_refptr<DemuxerStream> audio = demuxer_->GetStream(DS_STREAM_AUDIO); | 308 scoped_refptr<DemuxerStream> audio = demuxer_->GetStream(DS_STREAM_AUDIO); |
| 315 scoped_refptr<DemuxerStreamReader> reader(new DemuxerStreamReader()); | 309 scoped_refptr<DemuxerStreamReader> reader(new DemuxerStreamReader()); |
| 316 reader->Read(audio); | 310 reader->Read(audio); |
| 317 message_loop_.RunAllPending(); | 311 message_loop_.RunAllPending(); |
| 318 | 312 |
| 319 EXPECT_TRUE(reader->called()); | 313 EXPECT_TRUE(reader->called()); |
| 320 ASSERT_TRUE(reader->buffer()); | 314 ASSERT_TRUE(reader->buffer()); |
| 321 ASSERT_EQ(kDataSize, reader->buffer()->GetDataSize()); | 315 ASSERT_EQ(kDataSize, reader->buffer()->GetDataSize()); |
| 322 EXPECT_EQ(0, memcmp(kAudioData, reader->buffer()->GetData(), | 316 EXPECT_EQ(0, memcmp(kAudioData, reader->buffer()->GetData(), |
| 323 reader->buffer()->GetDataSize())); | 317 reader->buffer()->GetDataSize())); |
| 324 } | 318 } |
| 325 | 319 |
| 326 TEST_F(FFmpegDemuxerTest, Read_Video) { | 320 TEST_F(FFmpegDemuxerTest, Read_Video) { |
| 327 // We test that on a successful video packet read, that the packet is | 321 // We test that on a successful video packet read, that the packet is |
| 328 // duplicated (FFmpeg memory management safety), and a copy of it ends up in | 322 // duplicated (FFmpeg memory management safety), and a copy of it ends up in |
| 329 // the DemuxerStream. | 323 // the DemuxerStream. |
| 330 { | 324 { |
| 331 SCOPED_TRACE(""); | 325 SCOPED_TRACE(""); |
| 332 InitializeDemuxer(); | 326 InitializeDemuxer(); |
| 333 } | 327 } |
| 334 | 328 |
| 335 // Ignore all AVFreePacket() calls. We check this via valgrind. | 329 // Ignore all AVFreePacket() calls. We check this via valgrind. |
| 336 EXPECT_CALL(*MockFFmpeg::get(), AVFreePacket(_)).Times(AnyNumber()); | 330 EXPECT_CALL(mock_ffmpeg_, AVFreePacket(_)).Times(AnyNumber()); |
| 337 | 331 |
| 338 // Simulate a successful frame read. | 332 // Simulate a successful frame read. |
| 339 EXPECT_CALL(*MockFFmpeg::get(), AVReadFrame(&format_context_, _)) | 333 EXPECT_CALL(mock_ffmpeg_, AVReadFrame(&format_context_, _)) |
| 340 .WillOnce(CreatePacketNoCount(AV_STREAM_VIDEO, kVideoData, kDataSize)); | 334 .WillOnce(CreatePacketNoCount(AV_STREAM_VIDEO, kVideoData, kDataSize)); |
| 341 EXPECT_CALL(*MockFFmpeg::get(), AVDupPacket(_)) | 335 EXPECT_CALL(mock_ffmpeg_, AVDupPacket(_)) |
| 342 .WillOnce(Return(0)); | 336 .WillOnce(Return(0)); |
| 343 | 337 |
| 344 // Attempt a read from the video stream and run the message loop until done. | 338 // Attempt a read from the video stream and run the message loop until done. |
| 345 scoped_refptr<DemuxerStream> video = demuxer_->GetStream(DS_STREAM_VIDEO); | 339 scoped_refptr<DemuxerStream> video = demuxer_->GetStream(DS_STREAM_VIDEO); |
| 346 scoped_refptr<DemuxerStreamReader> reader(new DemuxerStreamReader()); | 340 scoped_refptr<DemuxerStreamReader> reader(new DemuxerStreamReader()); |
| 347 reader->Read(video); | 341 reader->Read(video); |
| 348 message_loop_.RunAllPending(); | 342 message_loop_.RunAllPending(); |
| 349 | 343 |
| 350 EXPECT_TRUE(reader->called()); | 344 EXPECT_TRUE(reader->called()); |
| 351 ASSERT_TRUE(reader->buffer()); | 345 ASSERT_TRUE(reader->buffer()); |
| 352 ASSERT_EQ(kDataSize, reader->buffer()->GetDataSize()); | 346 ASSERT_EQ(kDataSize, reader->buffer()->GetDataSize()); |
| 353 EXPECT_EQ(0, memcmp(kVideoData, reader->buffer()->GetData(), | 347 EXPECT_EQ(0, memcmp(kVideoData, reader->buffer()->GetData(), |
| 354 reader->buffer()->GetDataSize())); | 348 reader->buffer()->GetDataSize())); |
| 355 } | 349 } |
| 356 | 350 |
| 357 TEST_F(FFmpegDemuxerTest, Read_EndOfStream) { | 351 TEST_F(FFmpegDemuxerTest, Read_EndOfStream) { |
| 358 // On end of stream, a new, empty, AVPackets are created without any data for | 352 // On end of stream, a new, empty, AVPackets are created without any data for |
| 359 // each stream and enqueued into the Buffer stream. Verify that these are | 353 // each stream and enqueued into the Buffer stream. Verify that these are |
| 360 // indeed inserted. | 354 // indeed inserted. |
| 361 { | 355 { |
| 362 SCOPED_TRACE(""); | 356 SCOPED_TRACE(""); |
| 363 InitializeDemuxer(); | 357 InitializeDemuxer(); |
| 364 } | 358 } |
| 365 | 359 |
| 366 // Ignore all AVFreePacket() calls. We check this via valgrind. | 360 // Ignore all AVFreePacket() calls. We check this via valgrind. |
| 367 EXPECT_CALL(*MockFFmpeg::get(), AVFreePacket(_)).Times(AnyNumber()); | 361 EXPECT_CALL(mock_ffmpeg_, AVFreePacket(_)).Times(AnyNumber()); |
| 368 | 362 |
| 369 EXPECT_CALL(*MockFFmpeg::get(), AVReadFrame(&format_context_, _)) | 363 EXPECT_CALL(mock_ffmpeg_, AVReadFrame(&format_context_, _)) |
| 370 .WillOnce(Return(AVERROR_IO)); | 364 .WillOnce(Return(AVERROR_IO)); |
| 371 | 365 |
| 372 // We should now expect an end of stream buffer. | 366 // We should now expect an end of stream buffer. |
| 373 scoped_refptr<DemuxerStream> audio = demuxer_->GetStream(DS_STREAM_AUDIO); | 367 scoped_refptr<DemuxerStream> audio = demuxer_->GetStream(DS_STREAM_AUDIO); |
| 374 scoped_refptr<DemuxerStreamReader> reader(new DemuxerStreamReader()); | 368 scoped_refptr<DemuxerStreamReader> reader(new DemuxerStreamReader()); |
| 375 reader->Read(audio); | 369 reader->Read(audio); |
| 376 message_loop_.RunAllPending(); | 370 message_loop_.RunAllPending(); |
| 377 EXPECT_TRUE(reader->called()); | 371 EXPECT_TRUE(reader->called()); |
| 378 ASSERT_TRUE(reader->buffer()); | 372 ASSERT_TRUE(reader->buffer()); |
| 379 EXPECT_TRUE(reader->buffer()->IsEndOfStream()); | 373 EXPECT_TRUE(reader->buffer()->IsEndOfStream()); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 396 scoped_refptr<DemuxerStream> video = demuxer_->GetStream(DS_STREAM_VIDEO); | 390 scoped_refptr<DemuxerStream> video = demuxer_->GetStream(DS_STREAM_VIDEO); |
| 397 scoped_refptr<DemuxerStream> audio = demuxer_->GetStream(DS_STREAM_AUDIO); | 391 scoped_refptr<DemuxerStream> audio = demuxer_->GetStream(DS_STREAM_AUDIO); |
| 398 ASSERT_TRUE(video); | 392 ASSERT_TRUE(video); |
| 399 ASSERT_TRUE(audio); | 393 ASSERT_TRUE(audio); |
| 400 | 394 |
| 401 // Expected values. | 395 // Expected values. |
| 402 const int64 kExpectedTimestamp = 1234; | 396 const int64 kExpectedTimestamp = 1234; |
| 403 const int64 kExpectedFlags = AVSEEK_FLAG_BACKWARD; | 397 const int64 kExpectedFlags = AVSEEK_FLAG_BACKWARD; |
| 404 | 398 |
| 405 // Ignore all AVFreePacket() calls. We check this via valgrind. | 399 // Ignore all AVFreePacket() calls. We check this via valgrind. |
| 406 EXPECT_CALL(*MockFFmpeg::get(), AVFreePacket(_)).Times(AnyNumber()); | 400 EXPECT_CALL(mock_ffmpeg_, AVFreePacket(_)).Times(AnyNumber()); |
| 407 | 401 |
| 408 // Expect all calls in sequence. | 402 // Expect all calls in sequence. |
| 409 InSequence s; | 403 InSequence s; |
| 410 | 404 |
| 411 // First we'll read a video packet that causes two audio packets to be queued | 405 // First we'll read a video packet that causes two audio packets to be queued |
| 412 // inside FFmpegDemuxer... | 406 // inside FFmpegDemuxer... |
| 413 EXPECT_CALL(*MockFFmpeg::get(), AVReadFrame(&format_context_, _)) | 407 EXPECT_CALL(mock_ffmpeg_, AVReadFrame(&format_context_, _)) |
| 414 .WillOnce(CreatePacketNoCount(AV_STREAM_AUDIO, kAudioData, kDataSize)); | 408 .WillOnce(CreatePacketNoCount(AV_STREAM_AUDIO, kAudioData, kDataSize)); |
| 415 EXPECT_CALL(*MockFFmpeg::get(), AVDupPacket(_)) | 409 EXPECT_CALL(mock_ffmpeg_, AVDupPacket(_)) |
| 416 .WillOnce(Return(0)); | 410 .WillOnce(Return(0)); |
| 417 EXPECT_CALL(*MockFFmpeg::get(), AVReadFrame(&format_context_, _)) | 411 EXPECT_CALL(mock_ffmpeg_, AVReadFrame(&format_context_, _)) |
| 418 .WillOnce(CreatePacketNoCount(AV_STREAM_AUDIO, kAudioData, kDataSize)); | 412 .WillOnce(CreatePacketNoCount(AV_STREAM_AUDIO, kAudioData, kDataSize)); |
| 419 EXPECT_CALL(*MockFFmpeg::get(), AVDupPacket(_)) | 413 EXPECT_CALL(mock_ffmpeg_, AVDupPacket(_)) |
| 420 .WillOnce(Return(0)); | 414 .WillOnce(Return(0)); |
| 421 EXPECT_CALL(*MockFFmpeg::get(), AVReadFrame(&format_context_, _)) | 415 EXPECT_CALL(mock_ffmpeg_, AVReadFrame(&format_context_, _)) |
| 422 .WillOnce(CreatePacketNoCount(AV_STREAM_VIDEO, kVideoData, kDataSize)); | 416 .WillOnce(CreatePacketNoCount(AV_STREAM_VIDEO, kVideoData, kDataSize)); |
| 423 EXPECT_CALL(*MockFFmpeg::get(), AVDupPacket(_)) | 417 EXPECT_CALL(mock_ffmpeg_, AVDupPacket(_)) |
| 424 .WillOnce(Return(0)); | 418 .WillOnce(Return(0)); |
| 425 | 419 |
| 426 EXPECT_CALL(*MockFFmpeg::get(), CheckPoint(1)); | 420 EXPECT_CALL(mock_ffmpeg_, CheckPoint(1)); |
| 427 | 421 |
| 428 // ...then we'll expect a seek call... | 422 // ...then we'll expect a seek call... |
| 429 EXPECT_CALL(*MockFFmpeg::get(), | 423 EXPECT_CALL(mock_ffmpeg_, |
| 430 AVSeekFrame(&format_context_, -1, kExpectedTimestamp, kExpectedFlags)) | 424 AVSeekFrame(&format_context_, -1, kExpectedTimestamp, kExpectedFlags)) |
| 431 .WillOnce(Return(0)); | 425 .WillOnce(Return(0)); |
| 432 | 426 |
| 433 // ...then our callback will be executed... | 427 // ...then our callback will be executed... |
| 434 FilterCallback* seek_callback = NewExpectedCallback(); | 428 FilterCallback* seek_callback = NewExpectedCallback(); |
| 435 EXPECT_CALL(*MockFFmpeg::get(), CheckPoint(2)); | 429 EXPECT_CALL(mock_ffmpeg_, CheckPoint(2)); |
| 436 | 430 |
| 437 // ...followed by two audio packet reads we'll trigger... | 431 // ...followed by two audio packet reads we'll trigger... |
| 438 EXPECT_CALL(*MockFFmpeg::get(), AVReadFrame(&format_context_, _)) | 432 EXPECT_CALL(mock_ffmpeg_, AVReadFrame(&format_context_, _)) |
| 439 .WillOnce(CreatePacketNoCount(AV_STREAM_AUDIO, kAudioData, kDataSize)); | 433 .WillOnce(CreatePacketNoCount(AV_STREAM_AUDIO, kAudioData, kDataSize)); |
| 440 EXPECT_CALL(*MockFFmpeg::get(), AVDupPacket(_)) | 434 EXPECT_CALL(mock_ffmpeg_, AVDupPacket(_)) |
| 441 .WillOnce(Return(0)); | 435 .WillOnce(Return(0)); |
| 442 EXPECT_CALL(*MockFFmpeg::get(), AVReadFrame(&format_context_, _)) | 436 EXPECT_CALL(mock_ffmpeg_, AVReadFrame(&format_context_, _)) |
| 443 .WillOnce(CreatePacketNoCount(AV_STREAM_AUDIO, kAudioData, kDataSize)); | 437 .WillOnce(CreatePacketNoCount(AV_STREAM_AUDIO, kAudioData, kDataSize)); |
| 444 EXPECT_CALL(*MockFFmpeg::get(), AVDupPacket(_)) | 438 EXPECT_CALL(mock_ffmpeg_, AVDupPacket(_)) |
| 445 .WillOnce(Return(0)); | 439 .WillOnce(Return(0)); |
| 446 | 440 |
| 447 // ...followed by two video packet reads... | 441 // ...followed by two video packet reads... |
| 448 EXPECT_CALL(*MockFFmpeg::get(), AVReadFrame(&format_context_, _)) | 442 EXPECT_CALL(mock_ffmpeg_, AVReadFrame(&format_context_, _)) |
| 449 .WillOnce(CreatePacketNoCount(AV_STREAM_VIDEO, kVideoData, kDataSize)); | 443 .WillOnce(CreatePacketNoCount(AV_STREAM_VIDEO, kVideoData, kDataSize)); |
| 450 EXPECT_CALL(*MockFFmpeg::get(), AVDupPacket(_)) | 444 EXPECT_CALL(mock_ffmpeg_, AVDupPacket(_)) |
| 451 .WillOnce(Return(0)); | 445 .WillOnce(Return(0)); |
| 452 EXPECT_CALL(*MockFFmpeg::get(), AVReadFrame(&format_context_, _)) | 446 EXPECT_CALL(mock_ffmpeg_, AVReadFrame(&format_context_, _)) |
| 453 .WillOnce(CreatePacketNoCount(AV_STREAM_VIDEO, kVideoData, kDataSize)); | 447 .WillOnce(CreatePacketNoCount(AV_STREAM_VIDEO, kVideoData, kDataSize)); |
| 454 EXPECT_CALL(*MockFFmpeg::get(), AVDupPacket(_)) | 448 EXPECT_CALL(mock_ffmpeg_, AVDupPacket(_)) |
| 455 .WillOnce(Return(0)); | 449 .WillOnce(Return(0)); |
| 456 | 450 |
| 457 // ...and finally a sanity checkpoint to make sure everything was released. | 451 // ...and finally a sanity checkpoint to make sure everything was released. |
| 458 EXPECT_CALL(*MockFFmpeg::get(), CheckPoint(3)); | 452 EXPECT_CALL(mock_ffmpeg_, CheckPoint(3)); |
| 459 | 453 |
| 460 // Read a video packet and release it. | 454 // Read a video packet and release it. |
| 461 scoped_refptr<DemuxerStreamReader> reader(new DemuxerStreamReader()); | 455 scoped_refptr<DemuxerStreamReader> reader(new DemuxerStreamReader()); |
| 462 reader->Read(video); | 456 reader->Read(video); |
| 463 message_loop_.RunAllPending(); | 457 message_loop_.RunAllPending(); |
| 464 EXPECT_TRUE(reader->called()); | 458 EXPECT_TRUE(reader->called()); |
| 465 ASSERT_TRUE(reader->buffer()); | 459 ASSERT_TRUE(reader->buffer()); |
| 466 ASSERT_EQ(kDataSize, reader->buffer()->GetDataSize()); | 460 ASSERT_EQ(kDataSize, reader->buffer()->GetDataSize()); |
| 467 EXPECT_EQ(0, memcmp(kVideoData, reader->buffer()->GetData(), | 461 EXPECT_EQ(0, memcmp(kVideoData, reader->buffer()->GetData(), |
| 468 reader->buffer()->GetDataSize())); | 462 reader->buffer()->GetDataSize())); |
| 469 | 463 |
| 470 // Release the video packet and verify the other packets are still queued. | 464 // Release the video packet and verify the other packets are still queued. |
| 471 reader->Reset(); | 465 reader->Reset(); |
| 472 message_loop_.RunAllPending(); | 466 message_loop_.RunAllPending(); |
| 473 MockFFmpeg::get()->CheckPoint(1); | 467 mock_ffmpeg_.CheckPoint(1); |
| 474 | 468 |
| 475 // Issue a simple forward seek, which should discard queued packets. | 469 // Issue a simple forward seek, which should discard queued packets. |
| 476 demuxer_->Seek(base::TimeDelta::FromMicroseconds(kExpectedTimestamp), | 470 demuxer_->Seek(base::TimeDelta::FromMicroseconds(kExpectedTimestamp), |
| 477 seek_callback); | 471 seek_callback); |
| 478 message_loop_.RunAllPending(); | 472 message_loop_.RunAllPending(); |
| 479 MockFFmpeg::get()->CheckPoint(2); | 473 mock_ffmpeg_.CheckPoint(2); |
| 480 | 474 |
| 481 // Audio read #1. | 475 // Audio read #1. |
| 482 reader->Read(audio); | 476 reader->Read(audio); |
| 483 message_loop_.RunAllPending(); | 477 message_loop_.RunAllPending(); |
| 484 EXPECT_TRUE(reader->called()); | 478 EXPECT_TRUE(reader->called()); |
| 485 ASSERT_TRUE(reader->buffer()); | 479 ASSERT_TRUE(reader->buffer()); |
| 486 ASSERT_EQ(kDataSize, reader->buffer()->GetDataSize()); | 480 ASSERT_EQ(kDataSize, reader->buffer()->GetDataSize()); |
| 487 EXPECT_EQ(0, memcmp(kAudioData, reader->buffer()->GetData(), | 481 EXPECT_EQ(0, memcmp(kAudioData, reader->buffer()->GetData(), |
| 488 reader->buffer()->GetDataSize())); | 482 reader->buffer()->GetDataSize())); |
| 489 | 483 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 513 message_loop_.RunAllPending(); | 507 message_loop_.RunAllPending(); |
| 514 EXPECT_TRUE(reader->called()); | 508 EXPECT_TRUE(reader->called()); |
| 515 ASSERT_TRUE(reader->buffer()); | 509 ASSERT_TRUE(reader->buffer()); |
| 516 ASSERT_EQ(kDataSize, reader->buffer()->GetDataSize()); | 510 ASSERT_EQ(kDataSize, reader->buffer()->GetDataSize()); |
| 517 EXPECT_EQ(0, memcmp(kVideoData, reader->buffer()->GetData(), | 511 EXPECT_EQ(0, memcmp(kVideoData, reader->buffer()->GetData(), |
| 518 reader->buffer()->GetDataSize())); | 512 reader->buffer()->GetDataSize())); |
| 519 | 513 |
| 520 // Manually release the last reference to the buffer and verify it was freed. | 514 // Manually release the last reference to the buffer and verify it was freed. |
| 521 reader->Reset(); | 515 reader->Reset(); |
| 522 message_loop_.RunAllPending(); | 516 message_loop_.RunAllPending(); |
| 523 MockFFmpeg::get()->CheckPoint(3); | 517 mock_ffmpeg_.CheckPoint(3); |
| 524 } | 518 } |
| 525 | 519 |
| 526 // A mocked callback specialization for calling Read(). Since RunWithParams() | 520 // A mocked callback specialization for calling Read(). Since RunWithParams() |
| 527 // is mocked we don't need to pass in object or method pointers. | 521 // is mocked we don't need to pass in object or method pointers. |
| 528 typedef CallbackImpl<FFmpegDemuxerTest, | 522 typedef CallbackImpl<FFmpegDemuxerTest, |
| 529 void (FFmpegDemuxerTest::*)(Buffer*), | 523 void (FFmpegDemuxerTest::*)(Buffer*), |
| 530 Tuple1<Buffer*> > ReadCallback; | 524 Tuple1<Buffer*> > ReadCallback; |
| 531 class MockReadCallback : public ReadCallback { | 525 class MockReadCallback : public ReadCallback { |
| 532 public: | 526 public: |
| 533 MockReadCallback() | 527 MockReadCallback() |
| (...skipping 27 matching lines...) Expand all Loading... |
| 561 | 555 |
| 562 // Stop the demuxer. | 556 // Stop the demuxer. |
| 563 demuxer_->Stop(NewExpectedCallback()); | 557 demuxer_->Stop(NewExpectedCallback()); |
| 564 | 558 |
| 565 // Expect all calls in sequence. | 559 // Expect all calls in sequence. |
| 566 InSequence s; | 560 InSequence s; |
| 567 | 561 |
| 568 // The callback should be immediately deleted. We'll use a checkpoint to | 562 // The callback should be immediately deleted. We'll use a checkpoint to |
| 569 // verify that it has indeed been deleted. | 563 // verify that it has indeed been deleted. |
| 570 EXPECT_CALL(*callback, OnDelete()); | 564 EXPECT_CALL(*callback, OnDelete()); |
| 571 EXPECT_CALL(*MockFFmpeg::get(), CheckPoint(1)); | 565 EXPECT_CALL(mock_ffmpeg_, CheckPoint(1)); |
| 572 | 566 |
| 573 // Attempt the read... | 567 // Attempt the read... |
| 574 audio->Read(callback.release()); | 568 audio->Read(callback.release()); |
| 575 message_loop_.RunAllPending(); | 569 message_loop_.RunAllPending(); |
| 576 | 570 |
| 577 // ...and verify that |callback| was deleted. | 571 // ...and verify that |callback| was deleted. |
| 578 MockFFmpeg::get()->CheckPoint(1); | 572 mock_ffmpeg_.CheckPoint(1); |
| 579 } | 573 } |
| 580 | 574 |
| 581 TEST_F(FFmpegDemuxerTest, DisableAudioStream) { | 575 TEST_F(FFmpegDemuxerTest, DisableAudioStream) { |
| 582 // We are doing the following things here: | 576 // We are doing the following things here: |
| 583 // 1. Initialize the demuxer with audio and video stream. | 577 // 1. Initialize the demuxer with audio and video stream. |
| 584 // 2. Send a "disable audio stream" message to the demuxer. | 578 // 2. Send a "disable audio stream" message to the demuxer. |
| 585 // 3. Demuxer will free audio packets even if audio stream was initialized. | 579 // 3. Demuxer will free audio packets even if audio stream was initialized. |
| 586 { | 580 { |
| 587 SCOPED_TRACE(""); | 581 SCOPED_TRACE(""); |
| 588 InitializeDemuxer(); | 582 InitializeDemuxer(); |
| 589 } | 583 } |
| 590 | 584 |
| 591 // Submit a "disable audio stream" message to the demuxer. | 585 // Submit a "disable audio stream" message to the demuxer. |
| 592 demuxer_->OnAudioRendererDisabled(); | 586 demuxer_->OnAudioRendererDisabled(); |
| 593 message_loop_.RunAllPending(); | 587 message_loop_.RunAllPending(); |
| 594 | 588 |
| 595 // Ignore all AVFreePacket() calls. We check this via valgrind. | 589 // Ignore all AVFreePacket() calls. We check this via valgrind. |
| 596 EXPECT_CALL(*MockFFmpeg::get(), AVFreePacket(_)).Times(AnyNumber()); | 590 EXPECT_CALL(mock_ffmpeg_, AVFreePacket(_)).Times(AnyNumber()); |
| 597 | 591 |
| 598 // Expect all calls in sequence. | 592 // Expect all calls in sequence. |
| 599 InSequence s; | 593 InSequence s; |
| 600 | 594 |
| 601 // The demuxer will read an audio packet which will get immediately freed. | 595 // The demuxer will read an audio packet which will get immediately freed. |
| 602 EXPECT_CALL(*MockFFmpeg::get(), AVReadFrame(&format_context_, _)) | 596 EXPECT_CALL(mock_ffmpeg_, AVReadFrame(&format_context_, _)) |
| 603 .WillOnce(CreatePacketNoCount(AV_STREAM_AUDIO, kNullData, 0)); | 597 .WillOnce(CreatePacketNoCount(AV_STREAM_AUDIO, kNullData, 0)); |
| 604 | 598 |
| 605 // Then an end-of-stream packet is read. | 599 // Then an end-of-stream packet is read. |
| 606 EXPECT_CALL(*MockFFmpeg::get(), AVReadFrame(&format_context_, _)) | 600 EXPECT_CALL(mock_ffmpeg_, AVReadFrame(&format_context_, _)) |
| 607 .WillOnce(Return(AVERROR_IO)); | 601 .WillOnce(Return(AVERROR_IO)); |
| 608 | 602 |
| 609 // Get our streams. | 603 // Get our streams. |
| 610 scoped_refptr<DemuxerStream> video = demuxer_->GetStream(DS_STREAM_VIDEO); | 604 scoped_refptr<DemuxerStream> video = demuxer_->GetStream(DS_STREAM_VIDEO); |
| 611 ASSERT_TRUE(video); | 605 ASSERT_TRUE(video); |
| 612 | 606 |
| 613 // Attempt a read from the video stream and run the message loop until done. | 607 // Attempt a read from the video stream and run the message loop until done. |
| 614 scoped_refptr<DemuxerStreamReader> reader(new DemuxerStreamReader()); | 608 scoped_refptr<DemuxerStreamReader> reader(new DemuxerStreamReader()); |
| 615 reader->Read(video); | 609 reader->Read(video); |
| 616 message_loop_.RunAllPending(); | 610 message_loop_.RunAllPending(); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 735 { | 729 { |
| 736 SCOPED_TRACE(""); | 730 SCOPED_TRACE(""); |
| 737 InitializeDemuxer(); | 731 InitializeDemuxer(); |
| 738 } | 732 } |
| 739 EXPECT_CALL(*data_source_, IsStreaming()) | 733 EXPECT_CALL(*data_source_, IsStreaming()) |
| 740 .WillOnce(Return(false)); | 734 .WillOnce(Return(false)); |
| 741 EXPECT_FALSE(demuxer_->IsStreaming()); | 735 EXPECT_FALSE(demuxer_->IsStreaming()); |
| 742 } | 736 } |
| 743 | 737 |
| 744 } // namespace media | 738 } // namespace media |
| OLD | NEW |