| 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 "base/base_paths.h" | |
| 6 #include "base/bind.h" | 5 #include "base/bind.h" |
| 7 #include "base/file_util.h" | |
| 8 #include "base/path_service.h" | |
| 9 #include "media/base/media.h" | |
| 10 #include "media/base/mock_callback.h" | 6 #include "media/base/mock_callback.h" |
| 11 #include "media/base/mock_ffmpeg.h" | |
| 12 #include "media/base/mock_filter_host.h" | 7 #include "media/base/mock_filter_host.h" |
| 8 #include "media/base/test_data_util.h" |
| 13 #include "media/filters/chunk_demuxer.h" | 9 #include "media/filters/chunk_demuxer.h" |
| 14 #include "media/filters/chunk_demuxer_client.h" | 10 #include "media/filters/chunk_demuxer_client.h" |
| 15 #include "media/webm/cluster_builder.h" | 11 #include "media/webm/cluster_builder.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 12 #include "testing/gtest/include/gtest/gtest.h" |
| 17 | 13 |
| 18 using ::testing::AnyNumber; | 14 using ::testing::AnyNumber; |
| 19 using ::testing::InSequence; | 15 using ::testing::InSequence; |
| 20 using ::testing::Return; | 16 using ::testing::Return; |
| 21 using ::testing::SetArgumentPointee; | 17 using ::testing::SetArgumentPointee; |
| 22 using ::testing::NiceMock; | 18 using ::testing::NiceMock; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 51 protected: | 47 protected: |
| 52 enum CodecsIndex { | 48 enum CodecsIndex { |
| 53 AUDIO, | 49 AUDIO, |
| 54 VIDEO, | 50 VIDEO, |
| 55 MAX_CODECS_INDEX | 51 MAX_CODECS_INDEX |
| 56 }; | 52 }; |
| 57 | 53 |
| 58 ChunkDemuxerTest() | 54 ChunkDemuxerTest() |
| 59 : client_(new MockChunkDemuxerClient()), | 55 : client_(new MockChunkDemuxerClient()), |
| 60 demuxer_(new ChunkDemuxer(client_.get())) { | 56 demuxer_(new ChunkDemuxer(client_.get())) { |
| 61 memset(&format_context_, 0, sizeof(format_context_)); | |
| 62 memset(&streams_, 0, sizeof(streams_)); | |
| 63 memset(&codecs_, 0, sizeof(codecs_)); | |
| 64 | |
| 65 codecs_[VIDEO].codec_type = AVMEDIA_TYPE_VIDEO; | |
| 66 codecs_[VIDEO].codec_id = CODEC_ID_VP8; | |
| 67 codecs_[VIDEO].width = 320; | |
| 68 codecs_[VIDEO].height = 240; | |
| 69 | |
| 70 codecs_[AUDIO].codec_type = AVMEDIA_TYPE_AUDIO; | |
| 71 codecs_[AUDIO].codec_id = CODEC_ID_VORBIS; | |
| 72 codecs_[AUDIO].channels = 2; | |
| 73 codecs_[AUDIO].sample_rate = 44100; | |
| 74 } | 57 } |
| 75 | 58 |
| 76 virtual ~ChunkDemuxerTest() { | 59 virtual ~ChunkDemuxerTest() { |
| 77 ShutdownDemuxer(); | 60 ShutdownDemuxer(); |
| 78 } | 61 } |
| 79 | 62 |
| 80 void ReadFile(const std::string& name, scoped_array<uint8>* buffer, | |
| 81 int* size) { | |
| 82 FilePath file_path; | |
| 83 EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &file_path)); | |
| 84 file_path = file_path.Append(FILE_PATH_LITERAL("media")) | |
| 85 .Append(FILE_PATH_LITERAL("test")) | |
| 86 .Append(FILE_PATH_LITERAL("data")) | |
| 87 .AppendASCII(name); | |
| 88 | |
| 89 int64 tmp = 0; | |
| 90 EXPECT_TRUE(file_util::GetFileSize(file_path, &tmp)); | |
| 91 EXPECT_LT(tmp, 32768); | |
| 92 int file_size = static_cast<int>(tmp); | |
| 93 | |
| 94 buffer->reset(new uint8[file_size]); | |
| 95 EXPECT_EQ(file_size, | |
| 96 file_util::ReadFile(file_path, | |
| 97 reinterpret_cast<char*>(buffer->get()), | |
| 98 file_size)); | |
| 99 *size = file_size; | |
| 100 } | |
| 101 | |
| 102 void CreateInfoTracks(bool has_audio, bool has_video, | 63 void CreateInfoTracks(bool has_audio, bool has_video, |
| 103 scoped_array<uint8>* buffer, int* size) { | 64 scoped_array<uint8>* buffer, int* size) { |
| 104 scoped_array<uint8> info; | 65 scoped_array<uint8> info; |
| 105 int info_size = 0; | 66 int info_size = 0; |
| 106 scoped_array<uint8> audio_track_entry; | 67 scoped_array<uint8> audio_track_entry; |
| 107 int audio_track_entry_size = 0; | 68 int audio_track_entry_size = 0; |
| 108 scoped_array<uint8> video_track_entry; | 69 scoped_array<uint8> video_track_entry; |
| 109 int video_track_entry_size = 0; | 70 int video_track_entry_size = 0; |
| 110 | 71 |
| 111 ReadFile("webm_info_element", &info, &info_size); | 72 ReadTestDataFile("webm_info_element", &info, &info_size); |
| 112 ReadFile("webm_vorbis_track_entry", &audio_track_entry, | 73 ReadTestDataFile("webm_vorbis_track_entry", &audio_track_entry, |
| 113 &audio_track_entry_size); | 74 &audio_track_entry_size); |
| 114 ReadFile("webm_vp8_track_entry", &video_track_entry, | 75 ReadTestDataFile("webm_vp8_track_entry", &video_track_entry, |
| 115 &video_track_entry_size); | 76 &video_track_entry_size); |
| 116 | 77 |
| 117 int tracks_element_size = 0; | 78 int tracks_element_size = 0; |
| 118 | 79 |
| 119 if (has_audio) | 80 if (has_audio) |
| 120 tracks_element_size += audio_track_entry_size; | 81 tracks_element_size += audio_track_entry_size; |
| 121 | 82 |
| 122 if (has_video) | 83 if (has_video) |
| 123 tracks_element_size += video_track_entry_size; | 84 tracks_element_size += video_track_entry_size; |
| 124 | 85 |
| 125 *size = info_size + kTracksHeaderSize + tracks_element_size; | 86 *size = info_size + kTracksHeaderSize + tracks_element_size; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 152 } | 113 } |
| 153 | 114 |
| 154 void AppendData(const uint8* data, unsigned length) { | 115 void AppendData(const uint8* data, unsigned length) { |
| 155 EXPECT_CALL(mock_filter_host_, SetBufferedBytes(_)).Times(AnyNumber()); | 116 EXPECT_CALL(mock_filter_host_, SetBufferedBytes(_)).Times(AnyNumber()); |
| 156 EXPECT_CALL(mock_filter_host_, SetBufferedTime(_)).Times(AnyNumber()); | 117 EXPECT_CALL(mock_filter_host_, SetBufferedTime(_)).Times(AnyNumber()); |
| 157 EXPECT_CALL(mock_filter_host_, SetNetworkActivity(true)).Times(AnyNumber()); | 118 EXPECT_CALL(mock_filter_host_, SetNetworkActivity(true)).Times(AnyNumber()); |
| 158 EXPECT_TRUE(demuxer_->AppendData(data, length)); | 119 EXPECT_TRUE(demuxer_->AppendData(data, length)); |
| 159 } | 120 } |
| 160 | 121 |
| 161 void AppendInfoTracks(bool has_audio, bool has_video) { | 122 void AppendInfoTracks(bool has_audio, bool has_video) { |
| 162 EXPECT_CALL(mock_ffmpeg_, AVOpenInputFile(_, _, NULL, 0, NULL)) | |
| 163 .WillOnce(DoAll(SetArgumentPointee<0>(&format_context_), | |
| 164 Return(0))); | |
| 165 | |
| 166 EXPECT_CALL(mock_ffmpeg_, AVFindStreamInfo(&format_context_)) | |
| 167 .WillOnce(Return(0)); | |
| 168 | |
| 169 EXPECT_CALL(mock_ffmpeg_, AVCloseInputFile(&format_context_)); | |
| 170 | |
| 171 EXPECT_CALL(mock_ffmpeg_, AVRegisterLockManager(_)) | |
| 172 .WillRepeatedly(Return(0)); | |
| 173 | |
| 174 scoped_array<uint8> info_tracks; | 123 scoped_array<uint8> info_tracks; |
| 175 int info_tracks_size = 0; | 124 int info_tracks_size = 0; |
| 176 CreateInfoTracks(has_audio, has_video, &info_tracks, &info_tracks_size); | 125 CreateInfoTracks(has_audio, has_video, &info_tracks, &info_tracks_size); |
| 177 | 126 |
| 178 SetupAVFormatContext(has_audio, has_video); | |
| 179 | |
| 180 AppendData(info_tracks.get(), info_tracks_size); | 127 AppendData(info_tracks.get(), info_tracks_size); |
| 181 } | 128 } |
| 182 | 129 |
| 183 static void InitDoneCalled(bool* was_called, PipelineStatus expectedStatus, | 130 static void InitDoneCalled(bool* was_called, PipelineStatus expectedStatus, |
| 184 PipelineStatus status) { | 131 PipelineStatus status) { |
| 185 EXPECT_EQ(status, expectedStatus); | 132 EXPECT_EQ(status, expectedStatus); |
| 186 *was_called = true; | 133 *was_called = true; |
| 187 } | 134 } |
| 188 | 135 |
| 189 void InitDemuxer(bool has_audio, bool has_video) { | 136 void InitDemuxer(bool has_audio, bool has_video) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 204 EXPECT_CALL(mock_filter_host_, SetDuration(_)); | 151 EXPECT_CALL(mock_filter_host_, SetDuration(_)); |
| 205 EXPECT_CALL(mock_filter_host_, SetCurrentReadPosition(_)); | 152 EXPECT_CALL(mock_filter_host_, SetCurrentReadPosition(_)); |
| 206 demuxer_->set_host(&mock_filter_host_); | 153 demuxer_->set_host(&mock_filter_host_); |
| 207 } | 154 } |
| 208 | 155 |
| 209 void ShutdownDemuxer() { | 156 void ShutdownDemuxer() { |
| 210 if (demuxer_) { | 157 if (demuxer_) { |
| 211 EXPECT_CALL(*client_, DemuxerClosed()); | 158 EXPECT_CALL(*client_, DemuxerClosed()); |
| 212 demuxer_->Shutdown(); | 159 demuxer_->Shutdown(); |
| 213 } | 160 } |
| 214 | |
| 215 if (format_context_.streams) { | |
| 216 delete[] format_context_.streams; | |
| 217 format_context_.streams = NULL; | |
| 218 format_context_.nb_streams = 0; | |
| 219 } | |
| 220 } | 161 } |
| 221 | 162 |
| 222 void AddSimpleBlock(ClusterBuilder* cb, int track_num, int64 timecode) { | 163 void AddSimpleBlock(ClusterBuilder* cb, int track_num, int64 timecode) { |
| 223 uint8 data[] = { 0x00 }; | 164 uint8 data[] = { 0x00 }; |
| 224 cb->AddSimpleBlock(track_num, timecode, 0, data, sizeof(data)); | 165 cb->AddSimpleBlock(track_num, timecode, 0, data, sizeof(data)); |
| 225 } | 166 } |
| 226 | 167 |
| 227 MOCK_METHOD1(Checkpoint, void(int id)); | 168 MOCK_METHOD1(Checkpoint, void(int id)); |
| 228 | 169 |
| 229 MockFFmpeg mock_ffmpeg_; | |
| 230 MockFilterHost mock_filter_host_; | 170 MockFilterHost mock_filter_host_; |
| 231 | 171 |
| 232 AVFormatContext format_context_; | |
| 233 AVCodecContext codecs_[MAX_CODECS_INDEX]; | |
| 234 AVStream streams_[MAX_CODECS_INDEX]; | |
| 235 | |
| 236 scoped_ptr<MockChunkDemuxerClient> client_; | 172 scoped_ptr<MockChunkDemuxerClient> client_; |
| 237 scoped_refptr<ChunkDemuxer> demuxer_; | 173 scoped_refptr<ChunkDemuxer> demuxer_; |
| 238 | 174 |
| 239 private: | 175 private: |
| 240 void SetupAVFormatContext(bool has_audio, bool has_video) { | |
| 241 int i = 0; | |
| 242 format_context_.streams = new AVStream*[MAX_CODECS_INDEX]; | |
| 243 if (has_audio) { | |
| 244 format_context_.streams[i] = &streams_[i]; | |
| 245 streams_[i].codec = &codecs_[AUDIO]; | |
| 246 streams_[i].duration = 100; | |
| 247 streams_[i].time_base.den = base::Time::kMicrosecondsPerSecond; | |
| 248 streams_[i].time_base.num = 1; | |
| 249 i++; | |
| 250 } | |
| 251 | |
| 252 if (has_video) { | |
| 253 format_context_.streams[i] = &streams_[i]; | |
| 254 streams_[i].codec = &codecs_[VIDEO]; | |
| 255 streams_[i].duration = 100; | |
| 256 streams_[i].time_base.den = base::Time::kMicrosecondsPerSecond; | |
| 257 streams_[i].time_base.num = 1; | |
| 258 i++; | |
| 259 } | |
| 260 | |
| 261 format_context_.nb_streams = i; | |
| 262 } | |
| 263 | |
| 264 DISALLOW_COPY_AND_ASSIGN(ChunkDemuxerTest); | 176 DISALLOW_COPY_AND_ASSIGN(ChunkDemuxerTest); |
| 265 }; | 177 }; |
| 266 | 178 |
| 267 TEST_F(ChunkDemuxerTest, TestInit) { | 179 TEST_F(ChunkDemuxerTest, TestInit) { |
| 268 // Test no streams, audio-only, video-only, and audio & video scenarios. | 180 // Test no streams, audio-only, video-only, and audio & video scenarios. |
| 269 for (int i = 0; i < 4; i++) { | 181 for (int i = 0; i < 4; i++) { |
| 270 bool has_audio = (i & 0x1) != 0; | 182 bool has_audio = (i & 0x1) != 0; |
| 271 bool has_video = (i & 0x2) != 0; | 183 bool has_video = (i & 0x2) != 0; |
| 272 | 184 |
| 273 client_.reset(new MockChunkDemuxerClient()); | 185 client_.reset(new MockChunkDemuxerClient()); |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 546 AddSimpleBlock(&cb, kAudioTrackNum, 23); | 458 AddSimpleBlock(&cb, kAudioTrackNum, 23); |
| 547 AddSimpleBlock(&cb, kVideoTrackNum, 33); | 459 AddSimpleBlock(&cb, kVideoTrackNum, 33); |
| 548 scoped_ptr<Cluster> cluster(cb.Finish()); | 460 scoped_ptr<Cluster> cluster(cb.Finish()); |
| 549 AppendData(cluster->data(), cluster->size()); | 461 AppendData(cluster->data(), cluster->size()); |
| 550 | 462 |
| 551 EXPECT_CALL(mock_filter_host_, SetError(PIPELINE_ERROR_NETWORK)); | 463 EXPECT_CALL(mock_filter_host_, SetError(PIPELINE_ERROR_NETWORK)); |
| 552 demuxer_->EndOfStream(PIPELINE_ERROR_NETWORK); | 464 demuxer_->EndOfStream(PIPELINE_ERROR_NETWORK); |
| 553 } | 465 } |
| 554 | 466 |
| 555 } // namespace media | 467 } // namespace media |
| OLD | NEW |