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