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

Side by Side Diff: media/formats/webm/webm_cluster_parser_unittest.cc

Issue 238273002: Adds WebMClusterParserTest coverage for duration default/estimation/fallback logic (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: cast to int to compare enum values in COMPILE_ASSERTs Created 6 years, 8 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
« no previous file with comments | « media/formats/webm/webm_cluster_parser.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 <algorithm> 5 #include <algorithm>
6 #include <cstdlib>
6 7
7 #include "base/bind.h" 8 #include "base/bind.h"
8 #include "base/logging.h" 9 #include "base/logging.h"
9 #include "media/base/decrypt_config.h" 10 #include "media/base/decrypt_config.h"
10 #include "media/formats/webm/cluster_builder.h" 11 #include "media/formats/webm/cluster_builder.h"
11 #include "media/formats/webm/webm_cluster_parser.h" 12 #include "media/formats/webm/webm_cluster_parser.h"
12 #include "media/formats/webm/webm_constants.h" 13 #include "media/formats/webm/webm_constants.h"
13 #include "testing/gmock/include/gmock/gmock.h" 14 #include "testing/gmock/include/gmock/gmock.h"
14 #include "testing/gtest/include/gtest/gtest.h" 15 #include "testing/gtest/include/gtest/gtest.h"
15 16
16 using ::testing::InSequence; 17 using ::testing::InSequence;
17 using ::testing::Return; 18 using ::testing::Return;
18 using ::testing::_; 19 using ::testing::_;
19 20
20 namespace media { 21 namespace media {
21 22
23 typedef WebMTracksParser::TextTracks TextTracks;
24
22 enum { 25 enum {
23 kTimecodeScale = 1000000, // Timecode scale for millisecond timestamps. 26 kTimecodeScale = 1000000, // Timecode scale for millisecond timestamps.
24 kAudioTrackNum = 1, 27 kAudioTrackNum = 1,
25 kVideoTrackNum = 2, 28 kVideoTrackNum = 2,
26 kTextTrackNum = 3, 29 kTextTrackNum = 3,
30 kTestAudioFrameDefaultDurationInMs = 13,
31 kTestVideoFrameDefaultDurationInMs = 17
27 }; 32 };
28 33
34 COMPILE_ASSERT(
35 static_cast<int>(kTestAudioFrameDefaultDurationInMs) !=
36 static_cast<int>(WebMClusterParser::kDefaultAudioBufferDurationInMs),
37 test_default_is_same_as_estimation_fallback_audio_duration);
38 COMPILE_ASSERT(
39 static_cast<int>(kTestVideoFrameDefaultDurationInMs) !=
40 static_cast<int>(WebMClusterParser::kDefaultVideoBufferDurationInMs),
41 test_default_is_same_as_estimation_fallback_video_duration);
42
29 struct BlockInfo { 43 struct BlockInfo {
30 int track_num; 44 int track_num;
31 int timestamp; 45 int timestamp;
46
47 // Negative value is allowed only for block groups (not simple blocks) and
48 // directs CreateCluster() to exclude BlockDuration entry from the cluster for
49 // this BlockGroup. The absolute value is used for parser verification.
50 // For simple blocks, this value must be non-negative, and is used only for
51 // parser verification.
32 int duration; 52 int duration;
33 bool use_simple_block; 53 bool use_simple_block;
34 }; 54 };
35 55
36 static const BlockInfo kDefaultBlockInfo[] = { 56 static const BlockInfo kDefaultBlockInfo[] = {
37 { kAudioTrackNum, 0, 23, true }, 57 { kAudioTrackNum, 0, 23, true },
38 { kAudioTrackNum, 23, 23, true }, 58 { kAudioTrackNum, 23, 23, true },
39 { kVideoTrackNum, 33, 34, true }, // Assumes not using DefaultDuration 59 { kVideoTrackNum, 33, 34, true }, // Assumes not using DefaultDuration
40 { kAudioTrackNum, 46, 23, true }, 60 { kAudioTrackNum, 46, 23, true },
41 { kVideoTrackNum, 67, 33, false }, 61 { kVideoTrackNum, 67, 33, false },
42 { kAudioTrackNum, 69, 23, false }, 62 { kAudioTrackNum, 69, 23, false },
43 { kVideoTrackNum, 100, 33, false }, 63 { kVideoTrackNum, 100, 33, false },
44 }; 64 };
45 65
46 static const uint8 kEncryptedFrame[] = { 66 static const uint8 kEncryptedFrame[] = {
47 0x01, // Block is encrypted 67 0x01, // Block is encrypted
48 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 // IV 68 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 // IV
49 }; 69 };
50 70
51 static scoped_ptr<Cluster> CreateCluster(int timecode, 71 static scoped_ptr<Cluster> CreateCluster(int timecode,
52 const BlockInfo* block_info, 72 const BlockInfo* block_info,
53 int block_count) { 73 int block_count) {
54 ClusterBuilder cb; 74 ClusterBuilder cb;
55 cb.SetClusterTimecode(0); 75 cb.SetClusterTimecode(0);
56 76
57 for (int i = 0; i < block_count; i++) { 77 for (int i = 0; i < block_count; i++) {
58 uint8 data[] = { 0x00 }; 78 uint8 data[] = { 0x00 };
59 if (block_info[i].use_simple_block) { 79 if (block_info[i].use_simple_block) {
80 CHECK_GE(block_info[i].duration, 0);
60 cb.AddSimpleBlock(block_info[i].track_num, 81 cb.AddSimpleBlock(block_info[i].track_num,
61 block_info[i].timestamp, 82 block_info[i].timestamp,
62 0, data, sizeof(data)); 83 0, data, sizeof(data));
63 continue; 84 continue;
64 } 85 }
65 86
66 CHECK_GE(block_info[i].duration, 0); 87 if (block_info[i].duration < 0) {
88 cb.AddBlockGroupWithoutBlockDuration(block_info[i].track_num,
89 block_info[i].timestamp,
90 0, data, sizeof(data));
91 continue;
92 }
93
67 cb.AddBlockGroup(block_info[i].track_num, 94 cb.AddBlockGroup(block_info[i].track_num,
68 block_info[i].timestamp, 95 block_info[i].timestamp,
69 block_info[i].duration, 96 block_info[i].duration,
70 0, data, sizeof(data)); 97 0, data, sizeof(data));
71 } 98 }
72 99
73 return cb.Finish(); 100 return cb.Finish();
74 } 101 }
75 102
76 // Creates a Cluster with one encrypted Block. |bytes_to_write| is number of 103 // Creates a Cluster with one encrypted Block. |bytes_to_write| is number of
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 LOG(ERROR) << "Unexpected track number " << block_info[i].track_num; 141 LOG(ERROR) << "Unexpected track number " << block_info[i].track_num;
115 return false; 142 return false;
116 } 143 }
117 144
118 if (*offset >= buffers->size()) 145 if (*offset >= buffers->size())
119 return false; 146 return false;
120 147
121 scoped_refptr<StreamParserBuffer> buffer = (*buffers)[(*offset)++]; 148 scoped_refptr<StreamParserBuffer> buffer = (*buffers)[(*offset)++];
122 149
123 EXPECT_EQ(block_info[i].timestamp, buffer->timestamp().InMilliseconds()); 150 EXPECT_EQ(block_info[i].timestamp, buffer->timestamp().InMilliseconds());
124 EXPECT_EQ(block_info[i].duration, buffer->duration().InMilliseconds()); 151 EXPECT_EQ(std::abs(block_info[i].duration),
152 buffer->duration().InMilliseconds());
125 EXPECT_EQ(expected_type, buffer->type()); 153 EXPECT_EQ(expected_type, buffer->type());
126 EXPECT_EQ(block_info[i].track_num, buffer->track_id()); 154 EXPECT_EQ(block_info[i].track_num, buffer->track_id());
127 } 155 }
128 156
129 return true; 157 return true;
130 } 158 }
131 159
132 static bool VerifyBuffers(const scoped_ptr<WebMClusterParser>& parser, 160 static bool VerifyBuffers(const scoped_ptr<WebMClusterParser>& parser,
133 const BlockInfo* block_info, 161 const BlockInfo* block_info,
134 int block_count) { 162 int block_count) {
(...skipping 29 matching lines...) Expand all
164 const BlockInfo& block_info = *block_info_ptr++; 192 const BlockInfo& block_info = *block_info_ptr++;
165 193
166 if (block_info.track_num != text_track_num) 194 if (block_info.track_num != text_track_num)
167 continue; 195 continue;
168 196
169 EXPECT_FALSE(block_info.use_simple_block); 197 EXPECT_FALSE(block_info.use_simple_block);
170 EXPECT_FALSE(buffer_iter == buffer_end); 198 EXPECT_FALSE(buffer_iter == buffer_end);
171 199
172 const scoped_refptr<StreamParserBuffer> buffer = *buffer_iter++; 200 const scoped_refptr<StreamParserBuffer> buffer = *buffer_iter++;
173 EXPECT_EQ(block_info.timestamp, buffer->timestamp().InMilliseconds()); 201 EXPECT_EQ(block_info.timestamp, buffer->timestamp().InMilliseconds());
174 EXPECT_EQ(block_info.duration, buffer->duration().InMilliseconds()); 202 EXPECT_EQ(std::abs(block_info.duration),
203 buffer->duration().InMilliseconds());
175 EXPECT_EQ(DemuxerStream::TEXT, buffer->type()); 204 EXPECT_EQ(DemuxerStream::TEXT, buffer->type());
176 EXPECT_EQ(text_track_num, buffer->track_id()); 205 EXPECT_EQ(text_track_num, buffer->track_id());
177 } 206 }
178 207
179 EXPECT_TRUE(buffer_iter == buffer_end); 208 EXPECT_TRUE(buffer_iter == buffer_end);
180 return true; 209 return true;
181 } 210 }
182 211
183 static void VerifyEncryptedBuffer( 212 static void VerifyEncryptedBuffer(
184 scoped_refptr<StreamParserBuffer> buffer) { 213 scoped_refptr<StreamParserBuffer> buffer) {
(...skipping 11 matching lines...) Expand all
196 } 225 }
197 226
198 class WebMClusterParserTest : public testing::Test { 227 class WebMClusterParserTest : public testing::Test {
199 public: 228 public:
200 WebMClusterParserTest() 229 WebMClusterParserTest()
201 : parser_(new WebMClusterParser(kTimecodeScale, 230 : parser_(new WebMClusterParser(kTimecodeScale,
202 kAudioTrackNum, 231 kAudioTrackNum,
203 kNoTimestamp(), 232 kNoTimestamp(),
204 kVideoTrackNum, 233 kVideoTrackNum,
205 kNoTimestamp(), 234 kNoTimestamp(),
206 WebMTracksParser::TextTracks(), 235 TextTracks(),
207 std::set<int64>(), 236 std::set<int64>(),
208 std::string(), 237 std::string(),
209 std::string(), 238 std::string(),
210 LogCB())) {} 239 LogCB())) {}
211 240
212 protected: 241 protected:
242 void ResetParserToHaveDefaultDurations() {
243 base::TimeDelta default_audio_duration = base::TimeDelta::FromMilliseconds(
244 kTestAudioFrameDefaultDurationInMs);
245 base::TimeDelta default_video_duration = base::TimeDelta::FromMilliseconds(
246 kTestVideoFrameDefaultDurationInMs);
247 ASSERT_GE(default_audio_duration, base::TimeDelta());
248 ASSERT_GE(default_video_duration, base::TimeDelta());
249 ASSERT_NE(kNoTimestamp(), default_audio_duration);
250 ASSERT_NE(kNoTimestamp(), default_video_duration);
251
252 parser_.reset(new WebMClusterParser(kTimecodeScale,
253 kAudioTrackNum,
254 default_audio_duration,
255 kVideoTrackNum,
256 default_video_duration,
257 TextTracks(),
258 std::set<int64>(),
259 std::string(),
260 std::string(),
261 LogCB()));
262 }
263
213 scoped_ptr<WebMClusterParser> parser_; 264 scoped_ptr<WebMClusterParser> parser_;
265
266 private:
267 DISALLOW_COPY_AND_ASSIGN(WebMClusterParserTest);
214 }; 268 };
215 269
216 TEST_F(WebMClusterParserTest, Reset) { 270 TEST_F(WebMClusterParserTest, Reset) {
217 InSequence s; 271 InSequence s;
218 272
219 int block_count = arraysize(kDefaultBlockInfo); 273 int block_count = arraysize(kDefaultBlockInfo);
220 scoped_ptr<Cluster> cluster(CreateCluster(0, kDefaultBlockInfo, block_count)); 274 scoped_ptr<Cluster> cluster(CreateCluster(0, kDefaultBlockInfo, block_count));
221 275
222 // Send slightly less than the full cluster so all but the last block is 276 // Send slightly less than the full cluster so all but the last block is
223 // parsed. 277 // parsed.
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 384
331 TEST_F(WebMClusterParserTest, IgnoredTracks) { 385 TEST_F(WebMClusterParserTest, IgnoredTracks) {
332 std::set<int64> ignored_tracks; 386 std::set<int64> ignored_tracks;
333 ignored_tracks.insert(kTextTrackNum); 387 ignored_tracks.insert(kTextTrackNum);
334 388
335 parser_.reset(new WebMClusterParser(kTimecodeScale, 389 parser_.reset(new WebMClusterParser(kTimecodeScale,
336 kAudioTrackNum, 390 kAudioTrackNum,
337 kNoTimestamp(), 391 kNoTimestamp(),
338 kVideoTrackNum, 392 kVideoTrackNum,
339 kNoTimestamp(), 393 kNoTimestamp(),
340 WebMTracksParser::TextTracks(), 394 TextTracks(),
341 ignored_tracks, 395 ignored_tracks,
342 std::string(), 396 std::string(),
343 std::string(), 397 std::string(),
344 LogCB())); 398 LogCB()));
345 399
346 const BlockInfo kInputBlockInfo[] = { 400 const BlockInfo kInputBlockInfo[] = {
347 { kAudioTrackNum, 0, 23, true }, 401 { kAudioTrackNum, 0, 23, true },
348 { kAudioTrackNum, 23, 23, true }, 402 { kAudioTrackNum, 23, 23, true },
349 { kVideoTrackNum, 33, 34, true }, 403 { kVideoTrackNum, 33, 34, true },
350 { kTextTrackNum, 33, 99, true }, 404 { kTextTrackNum, 33, 99, true },
(...skipping 13 matching lines...) Expand all
364 418
365 scoped_ptr<Cluster> cluster( 419 scoped_ptr<Cluster> cluster(
366 CreateCluster(0, kInputBlockInfo, input_block_count)); 420 CreateCluster(0, kInputBlockInfo, input_block_count));
367 421
368 int result = parser_->Parse(cluster->data(), cluster->size()); 422 int result = parser_->Parse(cluster->data(), cluster->size());
369 EXPECT_EQ(cluster->size(), result); 423 EXPECT_EQ(cluster->size(), result);
370 ASSERT_TRUE(VerifyBuffers(parser_, kOutputBlockInfo, output_block_count)); 424 ASSERT_TRUE(VerifyBuffers(parser_, kOutputBlockInfo, output_block_count));
371 } 425 }
372 426
373 TEST_F(WebMClusterParserTest, ParseTextTracks) { 427 TEST_F(WebMClusterParserTest, ParseTextTracks) {
374 typedef WebMTracksParser::TextTracks TextTracks;
375 TextTracks text_tracks; 428 TextTracks text_tracks;
376 429
377 text_tracks.insert(std::make_pair(TextTracks::key_type(kTextTrackNum), 430 text_tracks.insert(std::make_pair(TextTracks::key_type(kTextTrackNum),
378 TextTrackConfig(kTextSubtitles, "", "", 431 TextTrackConfig(kTextSubtitles, "", "",
379 ""))); 432 "")));
380 433
381 parser_.reset(new WebMClusterParser(kTimecodeScale, 434 parser_.reset(new WebMClusterParser(kTimecodeScale,
382 kAudioTrackNum, 435 kAudioTrackNum,
383 kNoTimestamp(), 436 kNoTimestamp(),
384 kVideoTrackNum, 437 kVideoTrackNum,
(...skipping 17 matching lines...) Expand all
402 455
403 scoped_ptr<Cluster> cluster( 456 scoped_ptr<Cluster> cluster(
404 CreateCluster(0, kInputBlockInfo, input_block_count)); 457 CreateCluster(0, kInputBlockInfo, input_block_count));
405 458
406 int result = parser_->Parse(cluster->data(), cluster->size()); 459 int result = parser_->Parse(cluster->data(), cluster->size());
407 EXPECT_EQ(cluster->size(), result); 460 EXPECT_EQ(cluster->size(), result);
408 ASSERT_TRUE(VerifyBuffers(parser_, kInputBlockInfo, input_block_count)); 461 ASSERT_TRUE(VerifyBuffers(parser_, kInputBlockInfo, input_block_count));
409 } 462 }
410 463
411 TEST_F(WebMClusterParserTest, TextTracksSimpleBlock) { 464 TEST_F(WebMClusterParserTest, TextTracksSimpleBlock) {
412 typedef WebMTracksParser::TextTracks TextTracks; 465 TextTracks text_tracks;
413 WebMTracksParser::TextTracks text_tracks;
414 466
415 text_tracks.insert(std::make_pair(TextTracks::key_type(kTextTrackNum), 467 text_tracks.insert(std::make_pair(TextTracks::key_type(kTextTrackNum),
416 TextTrackConfig(kTextSubtitles, "", "", 468 TextTrackConfig(kTextSubtitles, "", "",
417 ""))); 469 "")));
418 470
419 parser_.reset(new WebMClusterParser(kTimecodeScale, 471 parser_.reset(new WebMClusterParser(kTimecodeScale,
420 kAudioTrackNum, 472 kAudioTrackNum,
421 kNoTimestamp(), 473 kNoTimestamp(),
422 kVideoTrackNum, 474 kVideoTrackNum,
423 kNoTimestamp(), 475 kNoTimestamp(),
424 text_tracks, 476 text_tracks,
425 std::set<int64>(), 477 std::set<int64>(),
426 std::string(), 478 std::string(),
427 std::string(), 479 std::string(),
428 LogCB())); 480 LogCB()));
429 481
430 const BlockInfo kInputBlockInfo[] = { 482 const BlockInfo kInputBlockInfo[] = {
431 { kTextTrackNum, 33, 42, true }, 483 { kTextTrackNum, 33, 42, true },
432 }; 484 };
433 int input_block_count = arraysize(kInputBlockInfo); 485 int input_block_count = arraysize(kInputBlockInfo);
434 486
435 scoped_ptr<Cluster> cluster( 487 scoped_ptr<Cluster> cluster(
436 CreateCluster(0, kInputBlockInfo, input_block_count)); 488 CreateCluster(0, kInputBlockInfo, input_block_count));
437 489
438 int result = parser_->Parse(cluster->data(), cluster->size()); 490 int result = parser_->Parse(cluster->data(), cluster->size());
439 EXPECT_LT(result, 0); 491 EXPECT_LT(result, 0);
440 } 492 }
441 493
442 TEST_F(WebMClusterParserTest, ParseMultipleTextTracks) { 494 TEST_F(WebMClusterParserTest, ParseMultipleTextTracks) {
443 typedef WebMTracksParser::TextTracks TextTracks;
444 TextTracks text_tracks; 495 TextTracks text_tracks;
445 496
446 const int kSubtitleTextTrackNum = kTextTrackNum; 497 const int kSubtitleTextTrackNum = kTextTrackNum;
447 const int kCaptionTextTrackNum = kTextTrackNum + 1; 498 const int kCaptionTextTrackNum = kTextTrackNum + 1;
448 499
449 text_tracks.insert(std::make_pair(TextTracks::key_type(kSubtitleTextTrackNum), 500 text_tracks.insert(std::make_pair(TextTracks::key_type(kSubtitleTextTrackNum),
450 TextTrackConfig(kTextSubtitles, "", "", 501 TextTrackConfig(kTextSubtitles, "", "",
451 ""))); 502 "")));
452 503
453 text_tracks.insert(std::make_pair(TextTracks::key_type(kCaptionTextTrackNum), 504 text_tracks.insert(std::make_pair(TextTracks::key_type(kCaptionTextTrackNum),
(...skipping 28 matching lines...) Expand all
482 533
483 int result = parser_->Parse(cluster->data(), cluster->size()); 534 int result = parser_->Parse(cluster->data(), cluster->size());
484 EXPECT_EQ(cluster->size(), result); 535 EXPECT_EQ(cluster->size(), result);
485 536
486 const WebMClusterParser::TextBufferQueueMap& text_map = 537 const WebMClusterParser::TextBufferQueueMap& text_map =
487 parser_->GetTextBuffers(); 538 parser_->GetTextBuffers();
488 for (WebMClusterParser::TextBufferQueueMap::const_iterator itr = 539 for (WebMClusterParser::TextBufferQueueMap::const_iterator itr =
489 text_map.begin(); 540 text_map.begin();
490 itr != text_map.end(); 541 itr != text_map.end();
491 ++itr) { 542 ++itr) {
492 const WebMTracksParser::TextTracks::const_iterator find_result = 543 const TextTracks::const_iterator find_result =
493 text_tracks.find(itr->first); 544 text_tracks.find(itr->first);
494 ASSERT_TRUE(find_result != text_tracks.end()); 545 ASSERT_TRUE(find_result != text_tracks.end());
495 ASSERT_TRUE(VerifyTextBuffers(parser_, kInputBlockInfo, input_block_count, 546 ASSERT_TRUE(VerifyTextBuffers(parser_, kInputBlockInfo, input_block_count,
496 itr->first, itr->second)); 547 itr->first, itr->second));
497 } 548 }
498 } 549 }
499 550
500 TEST_F(WebMClusterParserTest, ParseEncryptedBlock) { 551 TEST_F(WebMClusterParserTest, ParseEncryptedBlock) {
501 scoped_ptr<Cluster> cluster(CreateEncryptedCluster(sizeof(kEncryptedFrame))); 552 scoped_ptr<Cluster> cluster(CreateEncryptedCluster(sizeof(kEncryptedFrame)));
502 553
503 parser_.reset(new WebMClusterParser(kTimecodeScale, 554 parser_.reset(new WebMClusterParser(kTimecodeScale,
504 kAudioTrackNum, 555 kAudioTrackNum,
505 kNoTimestamp(), 556 kNoTimestamp(),
506 kVideoTrackNum, 557 kVideoTrackNum,
507 kNoTimestamp(), 558 kNoTimestamp(),
508 WebMTracksParser::TextTracks(), 559 TextTracks(),
509 std::set<int64>(), 560 std::set<int64>(),
510 std::string(), 561 std::string(),
511 "video_key_id", 562 "video_key_id",
512 LogCB())); 563 LogCB()));
513 int result = parser_->Parse(cluster->data(), cluster->size()); 564 int result = parser_->Parse(cluster->data(), cluster->size());
514 EXPECT_EQ(cluster->size(), result); 565 EXPECT_EQ(cluster->size(), result);
515 ASSERT_EQ(1UL, parser_->GetVideoBuffers().size()); 566 ASSERT_EQ(1UL, parser_->GetVideoBuffers().size());
516 scoped_refptr<StreamParserBuffer> buffer = parser_->GetVideoBuffers()[0]; 567 scoped_refptr<StreamParserBuffer> buffer = parser_->GetVideoBuffers()[0];
517 VerifyEncryptedBuffer(buffer); 568 VerifyEncryptedBuffer(buffer);
518 } 569 }
519 570
520 TEST_F(WebMClusterParserTest, ParseBadEncryptedBlock) { 571 TEST_F(WebMClusterParserTest, ParseBadEncryptedBlock) {
521 scoped_ptr<Cluster> cluster( 572 scoped_ptr<Cluster> cluster(
522 CreateEncryptedCluster(sizeof(kEncryptedFrame) - 1)); 573 CreateEncryptedCluster(sizeof(kEncryptedFrame) - 1));
523 574
524 parser_.reset(new WebMClusterParser(kTimecodeScale, 575 parser_.reset(new WebMClusterParser(kTimecodeScale,
525 kAudioTrackNum, 576 kAudioTrackNum,
526 kNoTimestamp(), 577 kNoTimestamp(),
527 kVideoTrackNum, 578 kVideoTrackNum,
528 kNoTimestamp(), 579 kNoTimestamp(),
529 WebMTracksParser::TextTracks(), 580 TextTracks(),
530 std::set<int64>(), 581 std::set<int64>(),
531 std::string(), 582 std::string(),
532 "video_key_id", 583 "video_key_id",
533 LogCB())); 584 LogCB()));
534 int result = parser_->Parse(cluster->data(), cluster->size()); 585 int result = parser_->Parse(cluster->data(), cluster->size());
535 EXPECT_EQ(-1, result); 586 EXPECT_EQ(-1, result);
536 } 587 }
537 588
538 TEST_F(WebMClusterParserTest, ParseInvalidZeroSizedCluster) { 589 TEST_F(WebMClusterParserTest, ParseInvalidZeroSizedCluster) {
539 const uint8 kBuffer[] = { 590 const uint8 kBuffer[] = {
540 0x1F, 0x43, 0xB6, 0x75, 0x80, // CLUSTER (size = 0) 591 0x1F, 0x43, 0xB6, 0x75, 0x80, // CLUSTER (size = 0)
541 }; 592 };
542 593
543 EXPECT_EQ(-1, parser_->Parse(kBuffer, sizeof(kBuffer))); 594 EXPECT_EQ(-1, parser_->Parse(kBuffer, sizeof(kBuffer)));
544 } 595 }
545 596
546 TEST_F(WebMClusterParserTest, ParseInvalidUnknownButActuallyZeroSizedCluster) { 597 TEST_F(WebMClusterParserTest, ParseInvalidUnknownButActuallyZeroSizedCluster) {
547 const uint8 kBuffer[] = { 598 const uint8 kBuffer[] = {
548 0x1F, 0x43, 0xB6, 0x75, 0xFF, // CLUSTER (size = "unknown") 599 0x1F, 0x43, 0xB6, 0x75, 0xFF, // CLUSTER (size = "unknown")
549 0x1F, 0x43, 0xB6, 0x75, 0x85, // CLUSTER (size = 5) 600 0x1F, 0x43, 0xB6, 0x75, 0x85, // CLUSTER (size = 5)
550 }; 601 };
551 602
552 EXPECT_EQ(-1, parser_->Parse(kBuffer, sizeof(kBuffer))); 603 EXPECT_EQ(-1, parser_->Parse(kBuffer, sizeof(kBuffer)));
553 } 604 }
554 605
606 TEST_F(WebMClusterParserTest, ParseInvalidTextBlockGroupWithoutDuration) {
607 // Text track frames must have explicitly specified BlockGroup BlockDurations.
608 TextTracks text_tracks;
609
610 text_tracks.insert(std::make_pair(TextTracks::key_type(kTextTrackNum),
611 TextTrackConfig(kTextSubtitles, "", "",
612 "")));
613
614 parser_.reset(new WebMClusterParser(kTimecodeScale,
615 kAudioTrackNum,
616 kNoTimestamp(),
617 kVideoTrackNum,
618 kNoTimestamp(),
619 text_tracks,
620 std::set<int64>(),
621 std::string(),
622 std::string(),
623 LogCB()));
624
625 const BlockInfo kBlockInfo[] = {
626 { kTextTrackNum, 33, -42, false },
627 };
628 int block_count = arraysize(kBlockInfo);
629 scoped_ptr<Cluster> cluster(CreateCluster(0, kBlockInfo, block_count));
630 int result = parser_->Parse(cluster->data(), cluster->size());
631 EXPECT_LT(result, 0);
632 }
633
634 TEST_F(WebMClusterParserTest, ParseWithDefaultDurationsSimpleBlocks) {
635 InSequence s;
636 ResetParserToHaveDefaultDurations();
637
638 EXPECT_LT(kTestAudioFrameDefaultDurationInMs, 23);
639 EXPECT_LT(kTestVideoFrameDefaultDurationInMs, 33);
640
641 const BlockInfo kBlockInfo[] = {
642 { kAudioTrackNum, 0, kTestAudioFrameDefaultDurationInMs, true },
643 { kAudioTrackNum, 23, kTestAudioFrameDefaultDurationInMs, true },
644 { kVideoTrackNum, 33, kTestVideoFrameDefaultDurationInMs, true },
645 { kAudioTrackNum, 46, kTestAudioFrameDefaultDurationInMs, true },
646 { kVideoTrackNum, 67, kTestVideoFrameDefaultDurationInMs, true },
647 { kAudioTrackNum, 69, kTestAudioFrameDefaultDurationInMs, true },
648 { kVideoTrackNum, 100, kTestVideoFrameDefaultDurationInMs, true },
649 };
650
651 int block_count = arraysize(kBlockInfo);
652 scoped_ptr<Cluster> cluster(CreateCluster(0, kBlockInfo, block_count));
653
654 // Send slightly less than the full cluster so all but the last block is
655 // parsed. Though all the blocks are simple blocks, none should be held aside
656 // for duration estimation prior to end of cluster detection because all the
657 // tracks have DefaultDurations.
658 int result = parser_->Parse(cluster->data(), cluster->size() - 1);
659 EXPECT_GT(result, 0);
660 EXPECT_LT(result, cluster->size());
661 ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo, block_count - 1));
662
663 parser_->Reset();
664
665 // Now parse a whole cluster to verify that all the blocks will get parsed.
666 result = parser_->Parse(cluster->data(), cluster->size());
667 EXPECT_EQ(cluster->size(), result);
668 ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo, block_count));
669 }
670
671 TEST_F(WebMClusterParserTest, ParseWithoutAnyDurationsSimpleBlocks) {
672 InSequence s;
673
674 // Absent DefaultDuration information, SimpleBlock durations are derived from
675 // inter-buffer track timestamp delta if within the cluster, and are estimated
676 // as the lowest non-zero duration seen so far if the last buffer in the track
677 // in the cluster (independently for each track in the cluster).
678 const BlockInfo kBlockInfo1[] = {
679 { kAudioTrackNum, 0, 23, true },
680 { kAudioTrackNum, 23, 22, true },
681 { kVideoTrackNum, 33, 33, true },
682 { kAudioTrackNum, 45, 23, true },
683 { kVideoTrackNum, 66, 34, true },
684 { kAudioTrackNum, 68, 22, true }, // Estimated from minimum audio dur
685 { kVideoTrackNum, 100, 33, true }, // Estimated from minimum video dur
686 };
687
688 int block_count1 = arraysize(kBlockInfo1);
689 scoped_ptr<Cluster> cluster1(CreateCluster(0, kBlockInfo1, block_count1));
690
691 // Send slightly less than the first full cluster so all but the last video
692 // block is parsed. Verify the last fully parsed audio and video buffer are
693 // both missing from the result (parser should hold them aside for duration
694 // estimation prior to end of cluster detection in the absence of
695 // DefaultDurations.)
696 int result = parser_->Parse(cluster1->data(), cluster1->size() - 1);
697 EXPECT_GT(result, 0);
698 EXPECT_LT(result, cluster1->size());
699 ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo1, block_count1 - 3));
700 EXPECT_EQ(3UL, parser_->GetAudioBuffers().size());
701 EXPECT_EQ(1UL, parser_->GetVideoBuffers().size());
702
703 parser_->Reset();
704
705 // Now parse the full first cluster and verify all the blocks are parsed.
706 result = parser_->Parse(cluster1->data(), cluster1->size());
707 EXPECT_EQ(cluster1->size(), result);
708 ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo1, block_count1));
709
710 // Verify that the estimated frame duration is tracked across clusters for
711 // each track.
712 const BlockInfo kBlockInfo2[] = {
713 { kAudioTrackNum, 200, 22, true }, // Estimate carries over across clusters
714 { kVideoTrackNum, 201, 33, true }, // Estimate carries over across clusters
715 };
716
717 int block_count2 = arraysize(kBlockInfo2);
718 scoped_ptr<Cluster> cluster2(CreateCluster(0, kBlockInfo2, block_count2));
719 result = parser_->Parse(cluster2->data(), cluster2->size());
720 EXPECT_EQ(cluster2->size(), result);
721 ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo2, block_count2));
722 }
723
724 TEST_F(WebMClusterParserTest, ParseWithoutAnyDurationsBlockGroups) {
725 InSequence s;
726
727 // Absent DefaultDuration and BlockDuration information, BlockGroup block
728 // durations are derived from inter-buffer track timestamp delta if within the
729 // cluster, and are estimated as the lowest non-zero duration seen so far if
730 // the last buffer in the track in the cluster (independently for each track
731 // in the cluster).
732 const BlockInfo kBlockInfo1[] = {
733 { kAudioTrackNum, 0, -23, false },
734 { kAudioTrackNum, 23, -22, false },
735 { kVideoTrackNum, 33, -33, false },
736 { kAudioTrackNum, 45, -23, false },
737 { kVideoTrackNum, 66, -34, false },
738 { kAudioTrackNum, 68, -22, false }, // Estimated from minimum audio dur
739 { kVideoTrackNum, 100, -33, false }, // Estimated from minimum video dur
740 };
741
742 int block_count1 = arraysize(kBlockInfo1);
743 scoped_ptr<Cluster> cluster1(CreateCluster(0, kBlockInfo1, block_count1));
744
745 // Send slightly less than the first full cluster so all but the last video
746 // block is parsed. Verify the last fully parsed audio and video buffer are
747 // both missing from the result (parser should hold them aside for duration
748 // estimation prior to end of cluster detection in the absence of
749 // DefaultDurations.)
750 int result = parser_->Parse(cluster1->data(), cluster1->size() - 1);
751 EXPECT_GT(result, 0);
752 EXPECT_LT(result, cluster1->size());
753 ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo1, block_count1 - 3));
754 EXPECT_EQ(3UL, parser_->GetAudioBuffers().size());
755 EXPECT_EQ(1UL, parser_->GetVideoBuffers().size());
756
757 parser_->Reset();
758
759 // Now parse the full first cluster and verify all the blocks are parsed.
760 result = parser_->Parse(cluster1->data(), cluster1->size());
761 EXPECT_EQ(cluster1->size(), result);
762 ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo1, block_count1));
763
764 // Verify that the estimated frame duration is tracked across clusters for
765 // each track.
766 const BlockInfo kBlockInfo2[] = {
767 { kAudioTrackNum, 200, -22, false },
768 { kVideoTrackNum, 201, -33, false },
769 };
770
771 int block_count2 = arraysize(kBlockInfo2);
772 scoped_ptr<Cluster> cluster2(CreateCluster(0, kBlockInfo2, block_count2));
773 result = parser_->Parse(cluster2->data(), cluster2->size());
774 EXPECT_EQ(cluster2->size(), result);
775 ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo2, block_count2));
776 }
777
778 // TODO(wolenetz): Is parser behavior correct? See http://crbug.com/363433.
779 TEST_F(WebMClusterParserTest,
780 ParseWithDefaultDurationsBlockGroupsWithoutDurations) {
781 InSequence s;
782 ResetParserToHaveDefaultDurations();
783
784 EXPECT_LT(kTestAudioFrameDefaultDurationInMs, 23);
785 EXPECT_LT(kTestVideoFrameDefaultDurationInMs, 33);
786
787 const BlockInfo kBlockInfo[] = {
788 { kAudioTrackNum, 0, -kTestAudioFrameDefaultDurationInMs, false },
789 { kAudioTrackNum, 23, -kTestAudioFrameDefaultDurationInMs, false },
790 { kVideoTrackNum, 33, -kTestVideoFrameDefaultDurationInMs, false },
791 { kAudioTrackNum, 46, -kTestAudioFrameDefaultDurationInMs, false },
792 { kVideoTrackNum, 67, -kTestVideoFrameDefaultDurationInMs, false },
793 { kAudioTrackNum, 69, -kTestAudioFrameDefaultDurationInMs, false },
794 { kVideoTrackNum, 100, -kTestVideoFrameDefaultDurationInMs, false },
795 };
796
797 int block_count = arraysize(kBlockInfo);
798 scoped_ptr<Cluster> cluster(CreateCluster(0, kBlockInfo, block_count));
799
800 // Send slightly less than the full cluster so all but the last block is
801 // parsed. None should be held aside for duration estimation prior to end of
802 // cluster detection because all the tracks have DefaultDurations.
803 int result = parser_->Parse(cluster->data(), cluster->size() - 1);
804 EXPECT_GT(result, 0);
805 EXPECT_LT(result, cluster->size());
806 ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo, block_count - 1));
807
808 parser_->Reset();
809
810 // Now parse a whole cluster to verify that all the blocks will get parsed.
811 result = parser_->Parse(cluster->data(), cluster->size());
812 EXPECT_EQ(cluster->size(), result);
813 ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo, block_count));
814 }
815
816 TEST_F(WebMClusterParserTest,
817 ParseDegenerateClusterYieldsHardcodedEstimatedDurations) {
818 const BlockInfo kBlockInfo[] = {
819 {
820 kAudioTrackNum,
821 0,
822 WebMClusterParser::kDefaultAudioBufferDurationInMs,
823 true
824 }, {
825 kVideoTrackNum,
826 0,
827 WebMClusterParser::kDefaultVideoBufferDurationInMs,
828 true
829 },
830 };
831
832 int block_count = arraysize(kBlockInfo);
833 scoped_ptr<Cluster> cluster(CreateCluster(0, kBlockInfo, block_count));
834 int result = parser_->Parse(cluster->data(), cluster->size());
835 EXPECT_EQ(cluster->size(), result);
836 ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo, block_count));
837 }
838
839 TEST_F(WebMClusterParserTest,
840 ParseDegenerateClusterWithDefaultDurationsYieldsDefaultDurations) {
841 ResetParserToHaveDefaultDurations();
842
843 const BlockInfo kBlockInfo[] = {
844 { kAudioTrackNum, 0, kTestAudioFrameDefaultDurationInMs, true },
845 { kVideoTrackNum, 0, kTestVideoFrameDefaultDurationInMs, true },
846 };
847
848 int block_count = arraysize(kBlockInfo);
849 scoped_ptr<Cluster> cluster(CreateCluster(0, kBlockInfo, block_count));
850 int result = parser_->Parse(cluster->data(), cluster->size());
851 EXPECT_EQ(cluster->size(), result);
852 ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo, block_count));
853 }
854
555 } // namespace media 855 } // namespace media
OLDNEW
« no previous file with comments | « media/formats/webm/webm_cluster_parser.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698