Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(600)

Side by Side Diff: media/filters/chunk_demuxer_unittest.cc

Issue 10545066: Implement support for 2 source ids (1 for audio and 1 for video). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/bind.h" 5 #include "base/bind.h"
6 #include "media/base/audio_decoder_config.h" 6 #include "media/base/audio_decoder_config.h"
7 #include "media/base/decoder_buffer.h" 7 #include "media/base/decoder_buffer.h"
8 #include "media/base/mock_callback.h" 8 #include "media/base/mock_callback.h"
9 #include "media/base/mock_demuxer_host.h" 9 #include "media/base/mock_demuxer_host.h"
10 #include "media/base/test_data_util.h" 10 #include "media/base/test_data_util.h"
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 arg->GetTimestamp().InMilliseconds() == timestamp_in_ms; 69 arg->GetTimestamp().InMilliseconds() == timestamp_in_ms;
70 } 70 }
71 71
72 static void OnReadDone(const base::TimeDelta& expected_time, 72 static void OnReadDone(const base::TimeDelta& expected_time,
73 bool* called, 73 bool* called,
74 const scoped_refptr<DecoderBuffer>& buffer) { 74 const scoped_refptr<DecoderBuffer>& buffer) {
75 EXPECT_EQ(expected_time, buffer->GetTimestamp()); 75 EXPECT_EQ(expected_time, buffer->GetTimestamp());
76 *called = true; 76 *called = true;
77 } 77 }
78 78
79 static void OnReadDone_EOSExpected(bool* called,
80 const scoped_refptr<DecoderBuffer>& buffer) {
81 EXPECT_TRUE(buffer->IsEndOfStream());
annacc 2012/06/07 22:42:07 I thought about modifying EndOfStreamHelper to che
82 *called = true;
83 }
84
79 class MockChunkDemuxerClient : public ChunkDemuxerClient { 85 class MockChunkDemuxerClient : public ChunkDemuxerClient {
80 public: 86 public:
81 MockChunkDemuxerClient() {} 87 MockChunkDemuxerClient() {}
82 virtual ~MockChunkDemuxerClient() {} 88 virtual ~MockChunkDemuxerClient() {}
83 89
84 MOCK_METHOD1(DemuxerOpened, void(ChunkDemuxer* demuxer)); 90 MOCK_METHOD1(DemuxerOpened, void(ChunkDemuxer* demuxer));
85 MOCK_METHOD0(DemuxerClosed, void()); 91 MOCK_METHOD0(DemuxerClosed, void());
86 // TODO(xhwang): This is a workaround of the issue that move-only parameters 92 // TODO(xhwang): This is a workaround of the issue that move-only parameters
87 // are not supported in mocked methods. Remove this when the issue is fixed. 93 // are not supported in mocked methods. Remove this when the issue is fixed.
88 // See http://code.google.com/p/googletest/issues/detail?id=395 94 // See http://code.google.com/p/googletest/issues/detail?id=395
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 video_track_entry->GetDataSize() + 174 video_track_entry->GetDataSize() +
169 video_content_encodings->GetDataSize() - 175 video_content_encodings->GetDataSize() -
170 kVideoTrackEntryHeaderSize); 176 kVideoTrackEntryHeaderSize);
171 buf += video_content_encodings->GetDataSize(); 177 buf += video_content_encodings->GetDataSize();
172 } 178 }
173 buf += video_track_entry->GetDataSize(); 179 buf += video_track_entry->GetDataSize();
174 } 180 }
175 } 181 }
176 182
177 ChunkDemuxer::Status AddId() { 183 ChunkDemuxer::Status AddId() {
178 std::vector<std::string> codecs(2); 184 return AddId(kSourceId, true, true);
179 codecs[0] = "vp8"; 185 }
180 codecs[1] = "vorbis"; 186
181 return demuxer_->AddId(kSourceId, "video/webm", codecs); 187 ChunkDemuxer::Status AddId(const std::string& source_id,
188 bool has_audio, bool has_video) {
189 std::vector<std::string> codecs;
190 std::string type;
191
192 if (has_audio) {
193 codecs.push_back("vorbis");
194 type = "audio/webm";
195 }
196
197 if (has_video) {
198 codecs.push_back("vp8");
199 type = "video/webm";
200 }
201
202 if (!has_audio && !has_video) {
203 return AddId(kSourceId, true, true);
204 }
annacc 2012/06/07 22:42:07 This is required because TestInit appends info tra
acolwell GONE FROM CHROMIUM 2012/06/08 00:29:07 This looks right to me.
205
206 return demuxer_->AddId(source_id, type, codecs);
182 } 207 }
183 208
184 bool AppendData(const uint8* data, size_t length) { 209 bool AppendData(const uint8* data, size_t length) {
210 return AppendData(kSourceId, data, length);
211 }
212
213 bool AppendData(const std::string& source_id,
214 const uint8* data, size_t length) {
185 CHECK(length); 215 CHECK(length);
186 EXPECT_CALL(host_, AddBufferedByteRange(_, _)).Times(AnyNumber()) 216 EXPECT_CALL(host_, AddBufferedByteRange(_, _)).Times(AnyNumber())
187 .WillRepeatedly(SaveArg<1>(&buffered_bytes_)); 217 .WillRepeatedly(SaveArg<1>(&buffered_bytes_));
188 EXPECT_CALL(host_, SetNetworkActivity(true)) 218 EXPECT_CALL(host_, SetNetworkActivity(true))
189 .Times(AnyNumber()); 219 .Times(AnyNumber());
190 return demuxer_->AppendData(kSourceId, data, length); 220 return demuxer_->AppendData(source_id, data, length);
191 } 221 }
192 222
193 bool AppendDataInPieces(const uint8* data, size_t length) { 223 bool AppendDataInPieces(const uint8* data, size_t length) {
194 return AppendDataInPieces(data, length, 7); 224 return AppendDataInPieces(data, length, 7);
195 } 225 }
196 226
197 bool AppendDataInPieces(const uint8* data, size_t length, size_t piece_size) { 227 bool AppendDataInPieces(const uint8* data, size_t length, size_t piece_size) {
198 const uint8* start = data; 228 const uint8* start = data;
199 const uint8* end = data + length; 229 const uint8* end = data + length;
200 while (start < end) { 230 while (start < end) {
201 int64 old_buffered_bytes = buffered_bytes_; 231 int64 old_buffered_bytes = buffered_bytes_;
202 size_t append_size = std::min(piece_size, 232 size_t append_size = std::min(piece_size,
203 static_cast<size_t>(end - start)); 233 static_cast<size_t>(end - start));
204 if (!AppendData(start, append_size)) 234 if (!AppendData(start, append_size))
205 return false; 235 return false;
206 start += append_size; 236 start += append_size;
207 237
208 EXPECT_GT(buffered_bytes_, old_buffered_bytes); 238 EXPECT_GT(buffered_bytes_, old_buffered_bytes);
209 } 239 }
210 return true; 240 return true;
211 } 241 }
212 242
213 bool AppendInfoTracks(bool has_audio, bool has_video, 243 bool AppendInfoTracks(bool has_audio, bool has_video,
214 bool video_content_encoded) { 244 bool video_content_encoded) {
245 return AppendInfoTracks(kSourceId, has_audio, has_video,
246 video_content_encoded);
247 }
248
249 bool AppendInfoTracks(const std::string& source_id,
250 bool has_audio, bool has_video,
251 bool video_content_encoded) {
215 scoped_array<uint8> info_tracks; 252 scoped_array<uint8> info_tracks;
216 int info_tracks_size = 0; 253 int info_tracks_size = 0;
217 CreateInfoTracks(has_audio, has_video, video_content_encoded, 254 CreateInfoTracks(has_audio, has_video, video_content_encoded,
218 &info_tracks, &info_tracks_size); 255 &info_tracks, &info_tracks_size);
219 return AppendData(info_tracks.get(), info_tracks_size); 256 return AppendData(source_id, info_tracks.get(), info_tracks_size);
220 } 257 }
221 258
222 void InitDoneCalled(PipelineStatus expected_status, 259 void InitDoneCalled(PipelineStatus expected_status,
223 PipelineStatus status) { 260 PipelineStatus status) {
224 EXPECT_EQ(status, expected_status); 261 EXPECT_EQ(status, expected_status);
225 } 262 }
226 263
227 PipelineStatusCB CreateInitDoneCB(const base::TimeDelta& expected_duration, 264 PipelineStatusCB CreateInitDoneCB(const base::TimeDelta& expected_duration,
228 PipelineStatus expected_status) { 265 PipelineStatus expected_status) {
229 if (expected_status == PIPELINE_OK) 266 if (expected_status == PIPELINE_OK)
230 EXPECT_CALL(host_, SetDuration(expected_duration)); 267 EXPECT_CALL(host_, SetDuration(expected_duration));
231 268
232 return base::Bind(&ChunkDemuxerTest::InitDoneCalled, 269 return base::Bind(&ChunkDemuxerTest::InitDoneCalled,
233 base::Unretained(this), 270 base::Unretained(this),
234 expected_status); 271 expected_status);
235 } 272 }
236 273
237 bool InitDemuxer(bool has_audio, bool has_video, 274 bool InitDemuxer(bool has_audio, bool has_video,
238 bool video_content_encoded) { 275 bool video_content_encoded) {
239 PipelineStatus expected_status = 276 PipelineStatus expected_status =
240 (has_audio || has_video) ? PIPELINE_OK : DEMUXER_ERROR_COULD_NOT_OPEN; 277 (has_audio || has_video) ? PIPELINE_OK : DEMUXER_ERROR_COULD_NOT_OPEN;
241 278
242 EXPECT_CALL(*client_, DemuxerOpened(_)); 279 EXPECT_CALL(*client_, DemuxerOpened(_));
243 demuxer_->Initialize( 280 demuxer_->Initialize(
244 &host_, CreateInitDoneCB(kDefaultDuration(), expected_status)); 281 &host_, CreateInitDoneCB(kDefaultDuration(), expected_status));
245 282
246 if (AddId() != ChunkDemuxer::kOk) 283 if (AddId(kSourceId, has_audio, has_video) != ChunkDemuxer::kOk)
247 return false; 284 return false;
248 285
249 return AppendInfoTracks(has_audio, has_video, video_content_encoded); 286 return AppendInfoTracks(has_audio, has_video, video_content_encoded);
250 } 287 }
251 288
289 bool InitDemuxerAudioAndVideoSources(const std::string& audio_id,
290 const std::string& video_id) {
291 EXPECT_CALL(*client_, DemuxerOpened(_));
292 demuxer_->Initialize(
293 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK));
294
295 if (AddId(audio_id, true, false) != ChunkDemuxer::kOk)
296 return false;
297 if (AddId(video_id, false, true) != ChunkDemuxer::kOk)
298 return false;
299
300 bool success;
301 success = AppendInfoTracks(audio_id, true, false, false);
acolwell GONE FROM CHROMIUM 2012/06/08 00:29:07 Move this assignement to the line above.
annacc 2012/06/08 22:12:23 Done.
302 success = success && AppendInfoTracks(video_id, false, true, false);
acolwell GONE FROM CHROMIUM 2012/06/08 00:29:07 You could use &= here
annacc 2012/06/08 22:12:23 Done.
303 return success;
304 }
305
252 void ShutdownDemuxer() { 306 void ShutdownDemuxer() {
253 if (demuxer_) { 307 if (demuxer_) {
254 EXPECT_CALL(*client_, DemuxerClosed()); 308 EXPECT_CALL(*client_, DemuxerClosed());
255 demuxer_->Shutdown(); 309 demuxer_->Shutdown();
256 } 310 }
257 } 311 }
258 312
259 void AddSimpleBlock(ClusterBuilder* cb, int track_num, int64 timecode) { 313 void AddSimpleBlock(ClusterBuilder* cb, int track_num, int64 timecode) {
260 uint8 data[] = { 0x00 }; 314 uint8 data[] = { 0x00 };
261 cb->AddSimpleBlock(track_num, timecode, 0, data, sizeof(data)); 315 cb->AddSimpleBlock(track_num, timecode, 0, data, sizeof(data));
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 } else { 362 } else {
309 cb.AddBlockGroup(kVideoTrackNum, video_timecode, kVideoBlockDuration, 363 cb.AddBlockGroup(kVideoTrackNum, video_timecode, kVideoBlockDuration,
310 video_flag, data.get(), size); 364 video_flag, data.get(), size);
311 cb.AddBlockGroup(kAudioTrackNum, audio_timecode, kAudioBlockDuration, 365 cb.AddBlockGroup(kAudioTrackNum, audio_timecode, kAudioBlockDuration,
312 kWebMFlagKeyframe, data.get(), size); 366 kWebMFlagKeyframe, data.get(), size);
313 } 367 }
314 368
315 return cb.Finish(); 369 return cb.Finish();
316 } 370 }
317 371
372 scoped_ptr<Cluster> GenerateSingleStreamCluster(int audio_timecode,
acolwell GONE FROM CHROMIUM 2012/06/08 00:29:07 how about just timecode since I don't see anything
annacc 2012/06/08 22:12:23 Whoops, leftover from a previous idea. Done.
373 int block_count,
374 int track_number,
375 int block_duration) {
376 CHECK_GT(block_count, 0);
377
378 int size = 10;
379 scoped_array<uint8> data(new uint8[size]);
380
381 ClusterBuilder cb;
382 cb.SetClusterTimecode(audio_timecode);
383
384 // Create simple blocks for everything except the last block.
385 for (int i = 0; i < block_count - 1; i++) {
386 cb.AddSimpleBlock(track_number, audio_timecode, kWebMFlagKeyframe,
387 data.get(), size);
388 audio_timecode += block_duration;
389 }
390
391 // Make the last block a BlockGroups so that it doesn't get delayed by the
acolwell GONE FROM CHROMIUM 2012/06/08 00:29:07 s/BlockGroups/BlockGroup
annacc 2012/06/08 22:12:23 Done.
392 // block duration calculation logic.
393 cb.AddBlockGroup(track_number, audio_timecode, block_duration,
394 kWebMFlagKeyframe, data.get(), size);
395 return cb.Finish();
396 }
397
318 void GenerateExpectedReads(int timecode, int block_count, 398 void GenerateExpectedReads(int timecode, int block_count,
319 DemuxerStream* audio, 399 DemuxerStream* audio,
320 DemuxerStream* video) { 400 DemuxerStream* video) {
321 CHECK_GT(block_count, 0); 401 CHECK_GT(block_count, 0);
322 int audio_timecode = timecode; 402 int audio_timecode = timecode;
323 int video_timecode = timecode; 403 int video_timecode = timecode;
324 404
325 if (block_count == 1) { 405 if (block_count == 1) {
326 ExpectRead(audio, audio_timecode); 406 ExpectRead(audio, audio_timecode);
327 return; 407 return;
(...skipping 29 matching lines...) Expand all
357 437
358 // Test parsing a WebM file. 438 // Test parsing a WebM file.
359 // |filename| - The name of the file in media/test/data to parse. 439 // |filename| - The name of the file in media/test/data to parse.
360 // |timestamps| - The expected timestamps on the parsed buffers. 440 // |timestamps| - The expected timestamps on the parsed buffers.
361 // a timestamp of kSkip indicates that a Read() call for that stream 441 // a timestamp of kSkip indicates that a Read() call for that stream
362 // shouldn't be made on that iteration of the loop. If both streams have 442 // shouldn't be made on that iteration of the loop. If both streams have
363 // a kSkip then the loop will terminate. 443 // a kSkip then the loop will terminate.
364 bool ParseWebMFile(const std::string& filename, 444 bool ParseWebMFile(const std::string& filename,
365 const BufferTimestamps* timestamps, 445 const BufferTimestamps* timestamps,
366 const base::TimeDelta& duration) { 446 const base::TimeDelta& duration) {
447 return ParseWebMFile(filename, timestamps, duration, true, true);
448 }
449
450 bool ParseWebMFile(const std::string& filename,
451 const BufferTimestamps* timestamps,
452 const base::TimeDelta& duration,
453 bool has_audio, bool has_video) {
367 EXPECT_CALL(*client_, DemuxerOpened(_)); 454 EXPECT_CALL(*client_, DemuxerOpened(_));
368 demuxer_->Initialize( 455 demuxer_->Initialize(
369 &host_, CreateInitDoneCB(duration, PIPELINE_OK)); 456 &host_, CreateInitDoneCB(duration, PIPELINE_OK));
370 457
371 if (AddId() != ChunkDemuxer::kOk) 458 if (AddId(kSourceId, has_audio, has_video) != ChunkDemuxer::kOk)
372 return false; 459 return false;
373 460
374 // Read a WebM file into memory and send the data to the demuxer. 461 // Read a WebM file into memory and send the data to the demuxer.
375 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(filename); 462 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(filename);
376 if (!AppendDataInPieces(buffer->GetData(), buffer->GetDataSize(), 512)) 463 if (!AppendDataInPieces(buffer->GetData(), buffer->GetDataSize(), 512))
377 return false; 464 return false;
378 465
379 scoped_refptr<DemuxerStream> audio = 466 scoped_refptr<DemuxerStream> audio =
380 demuxer_->GetStream(DemuxerStream::AUDIO); 467 demuxer_->GetStream(DemuxerStream::AUDIO);
381 scoped_refptr<DemuxerStream> video = 468 scoped_refptr<DemuxerStream> video =
(...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after
949 struct BufferTimestamps buffer_timestamps[] = { 1036 struct BufferTimestamps buffer_timestamps[] = {
950 {kSkip, 0}, 1037 {kSkip, 0},
951 {kSkip, 3}, 1038 {kSkip, 3},
952 {kSkip, 6}, 1039 {kSkip, 6},
953 {kSkip, 9}, 1040 {kSkip, 9},
954 {kSkip, 12}, 1041 {kSkip, 12},
955 {kSkip, kSkip}, 1042 {kSkip, kSkip},
956 }; 1043 };
957 1044
958 ASSERT_TRUE(ParseWebMFile("bear-320x240-audio-only.webm", buffer_timestamps, 1045 ASSERT_TRUE(ParseWebMFile("bear-320x240-audio-only.webm", buffer_timestamps,
959 base::TimeDelta::FromMilliseconds(2744))); 1046 base::TimeDelta::FromMilliseconds(2744),
1047 true, false));
960 } 1048 }
961 1049
962 TEST_F(ChunkDemuxerTest, TestWebMFile_VideoOnly) { 1050 TEST_F(ChunkDemuxerTest, TestWebMFile_VideoOnly) {
963 struct BufferTimestamps buffer_timestamps[] = { 1051 struct BufferTimestamps buffer_timestamps[] = {
964 {0, kSkip}, 1052 {0, kSkip},
965 {33, kSkip}, 1053 {33, kSkip},
966 {67, kSkip}, 1054 {67, kSkip},
967 {100, kSkip}, 1055 {100, kSkip},
968 {133, kSkip}, 1056 {133, kSkip},
969 {kSkip, kSkip}, 1057 {kSkip, kSkip},
970 }; 1058 };
971 1059
972 ASSERT_TRUE(ParseWebMFile("bear-320x240-video-only.webm", buffer_timestamps, 1060 ASSERT_TRUE(ParseWebMFile("bear-320x240-video-only.webm", buffer_timestamps,
973 base::TimeDelta::FromMilliseconds(2703))); 1061 base::TimeDelta::FromMilliseconds(2703),
1062 false, true));
974 } 1063 }
975 1064
976 TEST_F(ChunkDemuxerTest, TestWebMFile_AltRefFrames) { 1065 TEST_F(ChunkDemuxerTest, TestWebMFile_AltRefFrames) {
977 struct BufferTimestamps buffer_timestamps[] = { 1066 struct BufferTimestamps buffer_timestamps[] = {
978 {0, 0}, 1067 {0, 0},
979 {33, 3}, 1068 {33, 3},
980 {33, 6}, 1069 {33, 6},
981 {67, 9}, 1070 {67, 9},
982 {100, 12}, 1071 {100, 12},
983 {kSkip, kSkip}, 1072 {kSkip, kSkip},
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1089 DEMUXER_ERROR_COULD_NOT_OPEN)); 1178 DEMUXER_ERROR_COULD_NOT_OPEN));
1090 1179
1091 std::vector<std::string> codecs(1); 1180 std::vector<std::string> codecs(1);
1092 codecs[0] = "vp8"; 1181 codecs[0] = "vp8";
1093 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs), 1182 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs),
1094 ChunkDemuxer::kOk); 1183 ChunkDemuxer::kOk);
1095 1184
1096 ASSERT_TRUE(AppendInfoTracks(true, true, false)); 1185 ASSERT_TRUE(AppendInfoTracks(true, true, false));
1097 } 1186 }
1098 1187
1188 TEST_F(ChunkDemuxerTest, TestAddSeparateSourcesForAudioAndVideo) {
1189 std::string audio_id = "audio1";
1190 std::string video_id = "video1";
1191 ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
1192
1193 scoped_refptr<DemuxerStream> audio =
1194 demuxer_->GetStream(DemuxerStream::AUDIO);
1195 scoped_refptr<DemuxerStream> video =
1196 demuxer_->GetStream(DemuxerStream::VIDEO);
1197
1198 bool audio_read_done = false;
1199 bool video_read_done = false;
1200 audio->Read(base::Bind(&OnReadDone,
1201 base::TimeDelta::FromMilliseconds(0),
1202 &audio_read_done));
1203
1204 video->Read(base::Bind(&OnReadDone,
1205 base::TimeDelta::FromMilliseconds(0),
1206 &video_read_done));
1207
1208 scoped_ptr<Cluster> cluster_a(
1209 GenerateSingleStreamCluster(0, 4, kAudioTrackNum, kAudioBlockDuration));
1210
1211 scoped_ptr<Cluster> cluster_v(
1212 GenerateSingleStreamCluster(0, 4, kVideoTrackNum, kVideoBlockDuration));
1213
1214 // Append audio and video data into separate source ids.
1215 ASSERT_TRUE(AppendData(audio_id, cluster_a->data(), cluster_a->size()));
1216 ASSERT_TRUE(AppendData(video_id, cluster_v->data(), cluster_v->size()));
1217
1218 EXPECT_TRUE(audio_read_done);
1219 EXPECT_TRUE(video_read_done);
acolwell GONE FROM CHROMIUM 2012/06/08 00:29:07 Consider creating the single stream equivalent of
annacc 2012/06/08 22:12:23 Done.
1220 }
1221
1222 TEST_F(ChunkDemuxerTest, TestAddIdFailures) {
1223 EXPECT_CALL(*client_, DemuxerOpened(_));
1224 demuxer_->Initialize(
1225 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK));
1226
1227 std::string audio_id = "audio1";
1228 std::string video_id = "video1";
1229
1230 ASSERT_EQ(AddId(audio_id, true, false), ChunkDemuxer::kOk);
1231
1232 // Adding an id with audio/video should fail because we already added audio.
1233 ASSERT_EQ(AddId(), ChunkDemuxer::kReachedIdLimit);
1234
1235 ASSERT_TRUE(AppendInfoTracks(audio_id, true, false, false));
1236
1237 // Adding an id after append should fail.
1238 ASSERT_EQ(AddId(video_id, false, true), ChunkDemuxer::kReachedIdLimit);
1239 }
1240
1241 // Test that Read() calls after a RemoveId() return "end of stream" buffers.
1242 TEST_F(ChunkDemuxerTest, TestRemoveId) {
1243 std::string audio_id = "audio1";
1244 std::string video_id = "video1";
1245 ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
1246
1247 scoped_ptr<Cluster> cluster_a(
1248 GenerateSingleStreamCluster(0, 4, kAudioTrackNum, kAudioBlockDuration));
1249
1250 scoped_ptr<Cluster> cluster_v(
1251 GenerateSingleStreamCluster(0, 4, kVideoTrackNum, kVideoBlockDuration));
1252
1253 // Append audio and video data into separate source ids.
1254 ASSERT_TRUE(AppendData(audio_id, cluster_a->data(), cluster_a->size()));
1255 ASSERT_TRUE(AppendData(video_id, cluster_v->data(), cluster_v->size()));
1256
1257 // Read() from audio should return normal buffers.
1258 bool audio_read_done = false;
1259 scoped_refptr<DemuxerStream> audio =
1260 demuxer_->GetStream(DemuxerStream::AUDIO);
1261 audio->Read(base::Bind(&OnReadDone,
1262 base::TimeDelta::FromMilliseconds(0),
1263 &audio_read_done));
1264 EXPECT_TRUE(audio_read_done);
1265
1266 // Remove the audio id.
1267 demuxer_->RemoveId(audio_id);
1268
1269 // Read() from audio should return "end of stream" buffers.
1270 audio_read_done = false;
1271 audio->Read(base::Bind(&OnReadDone_EOSExpected,
1272 &audio_read_done));
1273 EXPECT_TRUE(audio_read_done);
1274
1275 // Read() from video should still return normal buffers.
1276 bool video_read_done = false;
1277 scoped_refptr<DemuxerStream> video =
1278 demuxer_->GetStream(DemuxerStream::VIDEO);
1279 video->Read(base::Bind(&OnReadDone,
1280 base::TimeDelta::FromMilliseconds(0),
1281 &video_read_done));
1282 EXPECT_TRUE(video_read_done);
1283 }
1284
1285 // Test that Seek() successfully seeks to all source IDs.
1286 TEST_F(ChunkDemuxerTest, TestSeekAudioAndVideoSources) {
1287 std::string audio_id = "audio1";
1288 std::string video_id = "video1";
1289 ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
1290
1291 scoped_ptr<Cluster> cluster_a1(
1292 GenerateSingleStreamCluster(0, 4, kAudioTrackNum, kAudioBlockDuration));
1293
1294 scoped_ptr<Cluster> cluster_v1(
1295 GenerateSingleStreamCluster(0, 4, kVideoTrackNum, kVideoBlockDuration));
1296
1297 ASSERT_TRUE(AppendData(audio_id, cluster_a1->data(), cluster_a1->size()));
1298 ASSERT_TRUE(AppendData(video_id, cluster_v1->data(), cluster_v1->size()));
1299
1300 // Read() should return buffers at 0.
1301 bool audio_read_done = false;
1302 bool video_read_done = false;
1303 scoped_refptr<DemuxerStream> audio =
1304 demuxer_->GetStream(DemuxerStream::AUDIO);
1305 scoped_refptr<DemuxerStream> video =
1306 demuxer_->GetStream(DemuxerStream::VIDEO);
1307
1308 audio->Read(base::Bind(&OnReadDone,
1309 base::TimeDelta::FromMilliseconds(0),
1310 &audio_read_done));
1311 video->Read(base::Bind(&OnReadDone,
1312 base::TimeDelta::FromMilliseconds(0),
1313 &video_read_done));
1314 EXPECT_TRUE(audio_read_done);
1315 EXPECT_TRUE(video_read_done);
1316
1317 // Seek to 3.
acolwell GONE FROM CHROMIUM 2012/06/08 00:29:07 Might want to also indicate that 3 is used because
annacc 2012/06/08 22:12:23 Done.
1318 demuxer_->StartWaitingForSeek();
1319 demuxer_->Seek(base::TimeDelta::FromSeconds(3),
1320 NewExpectedStatusCB(PIPELINE_OK));
1321
1322 scoped_ptr<Cluster> cluster_a2(
1323 GenerateSingleStreamCluster(3000, 4, kAudioTrackNum,
1324 kAudioBlockDuration));
1325
1326 scoped_ptr<Cluster> cluster_v2(
1327 GenerateSingleStreamCluster(3000, 4, kVideoTrackNum,
1328 kVideoBlockDuration));
1329
1330 ASSERT_TRUE(AppendData(audio_id, cluster_a2->data(), cluster_a2->size()));
1331 ASSERT_TRUE(AppendData(video_id, cluster_v2->data(), cluster_v2->size()));
1332
1333 // Read() should return buffers at 3 after the seek.
1334 audio_read_done = false;
1335 video_read_done = false;
1336 audio->Read(base::Bind(&OnReadDone,
acolwell GONE FROM CHROMIUM 2012/06/08 00:29:07 WDYT about putting these reads right above the clu
1337 base::TimeDelta::FromSeconds(3),
1338 &audio_read_done));
1339 video->Read(base::Bind(&OnReadDone,
1340 base::TimeDelta::FromSeconds(3),
1341 &video_read_done));
1342 EXPECT_TRUE(audio_read_done);
1343 EXPECT_TRUE(video_read_done);
1344 }
1345
1099 } // namespace media 1346 } // namespace media
OLDNEW
« media/filters/chunk_demuxer.cc ('K') | « media/filters/chunk_demuxer.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698