| 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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 75 EXPECT_CALL(*data_source_, Stop(NotNull())) | 75 EXPECT_CALL(*data_source_, Stop(NotNull())) |
| 76 .WillRepeatedly(Invoke(&RunStopFilterCallback)); | 76 .WillRepeatedly(Invoke(&RunStopFilterCallback)); |
| 77 | 77 |
| 78 // Initialize FFmpeg fixtures. | 78 // Initialize FFmpeg fixtures. |
| 79 memset(&format_context_, 0, sizeof(format_context_)); | 79 memset(&format_context_, 0, sizeof(format_context_)); |
| 80 memset(&input_format_, 0, sizeof(input_format_)); | 80 memset(&input_format_, 0, sizeof(input_format_)); |
| 81 memset(&streams_, 0, sizeof(streams_)); | 81 memset(&streams_, 0, sizeof(streams_)); |
| 82 memset(&codecs_, 0, sizeof(codecs_)); | 82 memset(&codecs_, 0, sizeof(codecs_)); |
| 83 | 83 |
| 84 // Initialize AVCodecContext structures. | 84 // Initialize AVCodecContext structures. |
| 85 codecs_[AV_STREAM_DATA].codec_type = CODEC_TYPE_DATA; | 85 codecs_[AV_STREAM_DATA].codec_type = AVMEDIA_TYPE_DATA; |
| 86 codecs_[AV_STREAM_DATA].codec_id = CODEC_ID_NONE; | 86 codecs_[AV_STREAM_DATA].codec_id = CODEC_ID_NONE; |
| 87 | 87 |
| 88 codecs_[AV_STREAM_VIDEO].codec_type = CODEC_TYPE_VIDEO; | 88 codecs_[AV_STREAM_VIDEO].codec_type = AVMEDIA_TYPE_VIDEO; |
| 89 codecs_[AV_STREAM_VIDEO].codec_id = CODEC_ID_THEORA; | 89 codecs_[AV_STREAM_VIDEO].codec_id = CODEC_ID_THEORA; |
| 90 codecs_[AV_STREAM_VIDEO].width = kWidth; | 90 codecs_[AV_STREAM_VIDEO].width = kWidth; |
| 91 codecs_[AV_STREAM_VIDEO].height = kHeight; | 91 codecs_[AV_STREAM_VIDEO].height = kHeight; |
| 92 | 92 |
| 93 codecs_[AV_STREAM_AUDIO].codec_type = CODEC_TYPE_AUDIO; | 93 codecs_[AV_STREAM_AUDIO].codec_type = AVMEDIA_TYPE_AUDIO; |
| 94 codecs_[AV_STREAM_AUDIO].codec_id = CODEC_ID_VORBIS; | 94 codecs_[AV_STREAM_AUDIO].codec_id = CODEC_ID_VORBIS; |
| 95 codecs_[AV_STREAM_AUDIO].channels = kChannels; | 95 codecs_[AV_STREAM_AUDIO].channels = kChannels; |
| 96 codecs_[AV_STREAM_AUDIO].sample_rate = kSampleRate; | 96 codecs_[AV_STREAM_AUDIO].sample_rate = kSampleRate; |
| 97 | 97 |
| 98 input_format_.name = "foo"; | 98 input_format_.name = "foo"; |
| 99 format_context_.iformat = &input_format_; | 99 format_context_.iformat = &input_format_; |
| 100 | 100 |
| 101 // Initialize AVStream and AVFormatContext structures. We set the time base | 101 // Initialize AVStream and AVFormatContext structures. We set the time base |
| 102 // of the streams such that duration is reported in microseconds. | 102 // of the streams such that duration is reported in microseconds. |
| 103 format_context_.nb_streams = AV_STREAM_MAX; | 103 format_context_.nb_streams = AV_STREAM_MAX; |
| 104 format_context_.streams = new AVStream*[AV_STREAM_MAX]; |
| 104 for (size_t i = 0; i < AV_STREAM_MAX; ++i) { | 105 for (size_t i = 0; i < AV_STREAM_MAX; ++i) { |
| 105 format_context_.streams[i] = &streams_[i]; | 106 format_context_.streams[i] = &streams_[i]; |
| 106 streams_[i].codec = &codecs_[i]; | 107 streams_[i].codec = &codecs_[i]; |
| 107 streams_[i].duration = kDurations[i]; | 108 streams_[i].duration = kDurations[i]; |
| 108 streams_[i].time_base.den = 1 * base::Time::kMicrosecondsPerSecond; | 109 streams_[i].time_base.den = 1 * base::Time::kMicrosecondsPerSecond; |
| 109 streams_[i].time_base.num = 1; | 110 streams_[i].time_base.num = 1; |
| 110 } | 111 } |
| 111 } | 112 } |
| 112 | 113 |
| 113 virtual ~FFmpegDemuxerTest() { | 114 virtual ~FFmpegDemuxerTest() { |
| 114 // Call Stop() to shut down internal threads. | 115 // Call Stop() to shut down internal threads. |
| 115 demuxer_->Stop(NewExpectedCallback()); | 116 demuxer_->Stop(NewExpectedCallback()); |
| 116 | 117 |
| 117 // Finish up any remaining tasks. | 118 // Finish up any remaining tasks. |
| 118 message_loop_.RunAllPending(); | 119 message_loop_.RunAllPending(); |
| 119 | |
| 120 // Release the reference to the demuxer. | 120 // Release the reference to the demuxer. |
| 121 demuxer_ = NULL; | 121 demuxer_ = NULL; |
| 122 |
| 123 if (format_context_.streams) { |
| 124 delete[] format_context_.streams; |
| 125 format_context_.streams = NULL; |
| 126 format_context_.nb_streams = 0; |
| 127 } |
| 122 } | 128 } |
| 123 | 129 |
| 124 // Sets up MockFFmpeg to allow FFmpegDemuxer to successfully initialize. | 130 // Sets up MockFFmpeg to allow FFmpegDemuxer to successfully initialize. |
| 125 void InitializeDemuxerMocks() { | 131 void InitializeDemuxerMocks() { |
| 126 EXPECT_CALL(mock_ffmpeg_, AVOpenInputFile(_, _, NULL, 0, NULL)) | 132 EXPECT_CALL(mock_ffmpeg_, AVOpenInputFile(_, _, NULL, 0, NULL)) |
| 127 .WillOnce(DoAll(SetArgumentPointee<0>(&format_context_), Return(0))); | 133 .WillOnce(DoAll(SetArgumentPointee<0>(&format_context_), Return(0))); |
| 128 EXPECT_CALL(mock_ffmpeg_, AVFindStreamInfo(&format_context_)) | 134 EXPECT_CALL(mock_ffmpeg_, AVFindStreamInfo(&format_context_)) |
| 129 .WillOnce(Return(0)); | 135 .WillOnce(Return(0)); |
| 130 EXPECT_CALL(mock_ffmpeg_, AVCloseInputFile(&format_context_)); | 136 EXPECT_CALL(mock_ffmpeg_, AVCloseInputFile(&format_context_)); |
| 131 } | 137 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 demuxer_->Initialize(data_source_.get(), | 189 demuxer_->Initialize(data_source_.get(), |
| 184 NewExpectedStatusCallback(DEMUXER_ERROR_COULD_NOT_OPEN)); | 190 NewExpectedStatusCallback(DEMUXER_ERROR_COULD_NOT_OPEN)); |
| 185 message_loop_.RunAllPending(); | 191 message_loop_.RunAllPending(); |
| 186 } | 192 } |
| 187 | 193 |
| 188 TEST_F(FFmpegDemuxerTest, Initialize_ParseFails) { | 194 TEST_F(FFmpegDemuxerTest, Initialize_ParseFails) { |
| 189 // Simulate av_find_stream_info() failing. | 195 // Simulate av_find_stream_info() failing. |
| 190 EXPECT_CALL(mock_ffmpeg_, AVOpenInputFile(_, _, NULL, 0, NULL)) | 196 EXPECT_CALL(mock_ffmpeg_, AVOpenInputFile(_, _, NULL, 0, NULL)) |
| 191 .WillOnce(DoAll(SetArgumentPointee<0>(&format_context_), Return(0))); | 197 .WillOnce(DoAll(SetArgumentPointee<0>(&format_context_), Return(0))); |
| 192 EXPECT_CALL(mock_ffmpeg_, AVFindStreamInfo(&format_context_)) | 198 EXPECT_CALL(mock_ffmpeg_, AVFindStreamInfo(&format_context_)) |
| 193 .WillOnce(Return(AVERROR_IO)); | 199 .WillOnce(Return(AVERROR(EIO))); |
| 194 EXPECT_CALL(mock_ffmpeg_, AVCloseInputFile(&format_context_)); | 200 EXPECT_CALL(mock_ffmpeg_, AVCloseInputFile(&format_context_)); |
| 195 | 201 |
| 196 demuxer_->Initialize( | 202 demuxer_->Initialize( |
| 197 data_source_.get(), | 203 data_source_.get(), |
| 198 NewExpectedStatusCallback(DEMUXER_ERROR_COULD_NOT_PARSE)); | 204 NewExpectedStatusCallback(DEMUXER_ERROR_COULD_NOT_PARSE)); |
| 199 message_loop_.RunAllPending(); | 205 message_loop_.RunAllPending(); |
| 200 } | 206 } |
| 201 | 207 |
| 202 TEST_F(FFmpegDemuxerTest, Initialize_NoStreams) { | 208 TEST_F(FFmpegDemuxerTest, Initialize_NoStreams) { |
| 203 // Simulate media with no parseable streams. | 209 // Simulate media with no parseable streams. |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 | 265 |
| 260 // Ignore all AVFreePacket() calls. We check this elsewhere. | 266 // Ignore all AVFreePacket() calls. We check this elsewhere. |
| 261 EXPECT_CALL(mock_ffmpeg_, AVFreePacket(_)).Times(AnyNumber()); | 267 EXPECT_CALL(mock_ffmpeg_, AVFreePacket(_)).Times(AnyNumber()); |
| 262 | 268 |
| 263 // 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, |
| 264 // followed by a read error to end the reading. | 270 // followed by a read error to end the reading. |
| 265 InSequence s; | 271 InSequence s; |
| 266 EXPECT_CALL(mock_ffmpeg_, AVReadFrame(&format_context_, _)) | 272 EXPECT_CALL(mock_ffmpeg_, AVReadFrame(&format_context_, _)) |
| 267 .WillOnce(CreatePacketNoCount(AV_STREAM_DATA, kNullData, 0)); | 273 .WillOnce(CreatePacketNoCount(AV_STREAM_DATA, kNullData, 0)); |
| 268 EXPECT_CALL(mock_ffmpeg_, AVReadFrame(&format_context_, _)) | 274 EXPECT_CALL(mock_ffmpeg_, AVReadFrame(&format_context_, _)) |
| 269 .WillOnce(Return(AVERROR_IO)); | 275 .WillOnce(Return(AVERROR(EIO))); |
| 270 | 276 |
| 271 // 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. |
| 272 scoped_refptr<DemuxerStream> audio = | 278 scoped_refptr<DemuxerStream> audio = |
| 273 demuxer_->GetStream(DemuxerStream::AUDIO); | 279 demuxer_->GetStream(DemuxerStream::AUDIO); |
| 274 scoped_refptr<DemuxerStreamReader> reader(new DemuxerStreamReader()); | 280 scoped_refptr<DemuxerStreamReader> reader(new DemuxerStreamReader()); |
| 275 reader->Read(audio); | 281 reader->Read(audio); |
| 276 message_loop_.RunAllPending(); | 282 message_loop_.RunAllPending(); |
| 277 | 283 |
| 278 EXPECT_TRUE(reader->called()); | 284 EXPECT_TRUE(reader->called()); |
| 279 ASSERT_TRUE(reader->buffer()); | 285 ASSERT_TRUE(reader->buffer()); |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 467 // indeed inserted. | 473 // indeed inserted. |
| 468 { | 474 { |
| 469 SCOPED_TRACE(""); | 475 SCOPED_TRACE(""); |
| 470 InitializeDemuxer(); | 476 InitializeDemuxer(); |
| 471 } | 477 } |
| 472 | 478 |
| 473 // Ignore all AVFreePacket() calls. We check this via valgrind. | 479 // Ignore all AVFreePacket() calls. We check this via valgrind. |
| 474 EXPECT_CALL(mock_ffmpeg_, AVFreePacket(_)).Times(AnyNumber()); | 480 EXPECT_CALL(mock_ffmpeg_, AVFreePacket(_)).Times(AnyNumber()); |
| 475 | 481 |
| 476 EXPECT_CALL(mock_ffmpeg_, AVReadFrame(&format_context_, _)) | 482 EXPECT_CALL(mock_ffmpeg_, AVReadFrame(&format_context_, _)) |
| 477 .WillOnce(Return(AVERROR_IO)); | 483 .WillOnce(Return(AVERROR(EIO))); |
| 478 | 484 |
| 479 // We should now expect an end of stream buffer. | 485 // We should now expect an end of stream buffer. |
| 480 scoped_refptr<DemuxerStream> audio = | 486 scoped_refptr<DemuxerStream> audio = |
| 481 demuxer_->GetStream(DemuxerStream::AUDIO); | 487 demuxer_->GetStream(DemuxerStream::AUDIO); |
| 482 scoped_refptr<DemuxerStreamReader> reader(new DemuxerStreamReader()); | 488 scoped_refptr<DemuxerStreamReader> reader(new DemuxerStreamReader()); |
| 483 reader->Read(audio); | 489 reader->Read(audio); |
| 484 message_loop_.RunAllPending(); | 490 message_loop_.RunAllPending(); |
| 485 EXPECT_TRUE(reader->called()); | 491 EXPECT_TRUE(reader->called()); |
| 486 ASSERT_TRUE(reader->buffer()); | 492 ASSERT_TRUE(reader->buffer()); |
| 487 EXPECT_TRUE(reader->buffer()->IsEndOfStream()); | 493 EXPECT_TRUE(reader->buffer()->IsEndOfStream()); |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 710 | 716 |
| 711 // Expect all calls in sequence. | 717 // Expect all calls in sequence. |
| 712 InSequence s; | 718 InSequence s; |
| 713 | 719 |
| 714 // The demuxer will read an audio packet which will get immediately freed. | 720 // The demuxer will read an audio packet which will get immediately freed. |
| 715 EXPECT_CALL(mock_ffmpeg_, AVReadFrame(&format_context_, _)) | 721 EXPECT_CALL(mock_ffmpeg_, AVReadFrame(&format_context_, _)) |
| 716 .WillOnce(CreatePacketNoCount(AV_STREAM_AUDIO, kNullData, 0)); | 722 .WillOnce(CreatePacketNoCount(AV_STREAM_AUDIO, kNullData, 0)); |
| 717 | 723 |
| 718 // Then an end-of-stream packet is read. | 724 // Then an end-of-stream packet is read. |
| 719 EXPECT_CALL(mock_ffmpeg_, AVReadFrame(&format_context_, _)) | 725 EXPECT_CALL(mock_ffmpeg_, AVReadFrame(&format_context_, _)) |
| 720 .WillOnce(Return(AVERROR_IO)); | 726 .WillOnce(Return(AVERROR(EIO))); |
| 721 | 727 |
| 722 // Get our streams. | 728 // Get our streams. |
| 723 scoped_refptr<DemuxerStream> video = | 729 scoped_refptr<DemuxerStream> video = |
| 724 demuxer_->GetStream(DemuxerStream::VIDEO); | 730 demuxer_->GetStream(DemuxerStream::VIDEO); |
| 725 ASSERT_TRUE(video); | 731 ASSERT_TRUE(video); |
| 726 | 732 |
| 727 // Attempt a read from the video stream and run the message loop until done. | 733 // Attempt a read from the video stream and run the message loop until done. |
| 728 scoped_refptr<DemuxerStreamReader> reader(new DemuxerStreamReader()); | 734 scoped_refptr<DemuxerStreamReader> reader(new DemuxerStreamReader()); |
| 729 reader->Read(video); | 735 reader->Read(video); |
| 730 message_loop_.RunAllPending(); | 736 message_loop_.RunAllPending(); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 849 { | 855 { |
| 850 SCOPED_TRACE(""); | 856 SCOPED_TRACE(""); |
| 851 InitializeDemuxer(); | 857 InitializeDemuxer(); |
| 852 } | 858 } |
| 853 EXPECT_CALL(*data_source_, IsStreaming()) | 859 EXPECT_CALL(*data_source_, IsStreaming()) |
| 854 .WillOnce(Return(false)); | 860 .WillOnce(Return(false)); |
| 855 EXPECT_FALSE(demuxer_->IsStreaming()); | 861 EXPECT_FALSE(demuxer_->IsStreaming()); |
| 856 } | 862 } |
| 857 | 863 |
| 858 } // namespace media | 864 } // namespace media |
| OLD | NEW |