Improve performance of registering font preferences
[chromium-blink-merge.git] / media / webm / webm_cluster_parser_unittest.cc
blobd12979f2ca1bf08488e9f5552216556a72de5b9a
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
3 // found in the LICENSE file.
5 #include <algorithm>
7 #include "base/logging.h"
8 #include "media/webm/cluster_builder.h"
9 #include "media/webm/webm_cluster_parser.h"
10 #include "media/webm/webm_constants.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
14 using ::testing::InSequence;
15 using ::testing::Return;
16 using ::testing::_;
18 namespace media {
20 enum {
21 kTimecodeScale = 1000000, // Timecode scale for millisecond timestamps.
22 kAudioTrackNum = 1,
23 kVideoTrackNum = 2,
26 struct BlockInfo {
27 int track_num;
28 int timestamp;
29 int duration;
30 bool use_simple_block;
33 const BlockInfo kDefaultBlockInfo[] = {
34 { kAudioTrackNum, 0, 23, true },
35 { kAudioTrackNum, 23, 23, true },
36 { kVideoTrackNum, 33, 34, true },
37 { kAudioTrackNum, 46, 23, true },
38 { kVideoTrackNum, 67, 33, false },
39 { kAudioTrackNum, 69, 23, false },
40 { kVideoTrackNum, 100, 33, false },
43 static scoped_ptr<Cluster> CreateCluster(int timecode,
44 const BlockInfo* block_info,
45 int block_count) {
46 ClusterBuilder cb;
47 cb.SetClusterTimecode(0);
49 for (int i = 0; i < block_count; i++) {
50 uint8 data[] = { 0x00 };
51 if (block_info[i].use_simple_block) {
52 cb.AddSimpleBlock(block_info[i].track_num,
53 block_info[i].timestamp,
54 0, data, sizeof(data));
55 continue;
58 CHECK_GE(block_info[i].duration, 0);
59 cb.AddBlockGroup(block_info[i].track_num,
60 block_info[i].timestamp,
61 block_info[i].duration,
62 0, data, sizeof(data));
65 return cb.Finish();
68 static bool VerifyBuffers(const WebMClusterParser::BufferQueue& audio_buffers,
69 const WebMClusterParser::BufferQueue& video_buffers,
70 const BlockInfo* block_info,
71 int block_count) {
72 size_t audio_offset = 0;
73 size_t video_offset = 0;
74 for (int i = 0; i < block_count; i++) {
75 const WebMClusterParser::BufferQueue* buffers = NULL;
76 size_t* offset;
78 if (block_info[i].track_num == kAudioTrackNum) {
79 buffers = &audio_buffers;
80 offset = &audio_offset;
81 } else if (block_info[i].track_num == kVideoTrackNum) {
82 buffers = &video_buffers;
83 offset = &video_offset;
84 } else {
85 LOG(ERROR) << "Unexpected track number " << block_info[i].track_num;
86 return false;
89 if (*offset >= buffers->size())
90 return false;
92 scoped_refptr<StreamParserBuffer> buffer = (*buffers)[(*offset)++];
95 EXPECT_EQ(buffer->GetTimestamp().InMilliseconds(), block_info[i].timestamp);
97 if (!block_info[i].use_simple_block)
98 EXPECT_NE(buffer->GetDuration(), kNoTimestamp());
100 if (buffer->GetDuration() != kNoTimestamp())
101 EXPECT_EQ(buffer->GetDuration().InMilliseconds(), block_info[i].duration);
104 return true;
107 static bool VerifyBuffers(const scoped_ptr<WebMClusterParser>& parser,
108 const BlockInfo* block_info,
109 int block_count) {
110 return VerifyBuffers(parser->audio_buffers(),
111 parser->video_buffers(),
112 block_info,
113 block_count);
116 static void AppendToEnd(const WebMClusterParser::BufferQueue& src,
117 WebMClusterParser::BufferQueue* dest) {
118 for (WebMClusterParser::BufferQueue::const_iterator itr = src.begin();
119 itr != src.end(); ++itr) {
120 dest->push_back(*itr);
124 class WebMClusterParserTest : public testing::Test {
125 public:
126 WebMClusterParserTest()
127 : parser_(new WebMClusterParser(kTimecodeScale,
128 kAudioTrackNum, kVideoTrackNum,
129 "", "")) {
132 protected:
133 scoped_ptr<WebMClusterParser> parser_;
136 TEST_F(WebMClusterParserTest, TestReset) {
137 InSequence s;
139 int block_count = arraysize(kDefaultBlockInfo);
140 scoped_ptr<Cluster> cluster(CreateCluster(0, kDefaultBlockInfo, block_count));
142 // Send slightly less than the full cluster so all but the last block is
143 // parsed.
144 int result = parser_->Parse(cluster->data(), cluster->size() - 1);
145 EXPECT_GT(result, 0);
146 EXPECT_LT(result, cluster->size());
148 ASSERT_TRUE(VerifyBuffers(parser_, kDefaultBlockInfo, block_count - 1));
149 parser_->Reset();
151 // Now parse a whole cluster to verify that all the blocks will get parsed.
152 result = parser_->Parse(cluster->data(), cluster->size());
153 EXPECT_EQ(result, cluster->size());
154 ASSERT_TRUE(VerifyBuffers(parser_, kDefaultBlockInfo, block_count));
157 TEST_F(WebMClusterParserTest, ParseClusterWithSingleCall) {
158 int block_count = arraysize(kDefaultBlockInfo);
159 scoped_ptr<Cluster> cluster(CreateCluster(0, kDefaultBlockInfo, block_count));
161 int result = parser_->Parse(cluster->data(), cluster->size());
162 EXPECT_EQ(cluster->size(), result);
163 ASSERT_TRUE(VerifyBuffers(parser_, kDefaultBlockInfo, block_count));
166 TEST_F(WebMClusterParserTest, ParseClusterWithMultipleCalls) {
167 int block_count = arraysize(kDefaultBlockInfo);
168 scoped_ptr<Cluster> cluster(CreateCluster(0, kDefaultBlockInfo, block_count));
170 WebMClusterParser::BufferQueue audio_buffers;
171 WebMClusterParser::BufferQueue video_buffers;
173 const uint8* data = cluster->data();
174 int size = cluster->size();
175 int default_parse_size = 3;
176 int parse_size = std::min(default_parse_size, size);
178 while (size > 0) {
179 int result = parser_->Parse(data, parse_size);
180 ASSERT_GE(result, 0);
181 ASSERT_LE(result, parse_size);
183 if (result == 0) {
184 // The parser needs more data so increase the parse_size a little.
185 parse_size += default_parse_size;
186 parse_size = std::min(parse_size, size);
187 continue;
190 AppendToEnd(parser_->audio_buffers(), &audio_buffers);
191 AppendToEnd(parser_->video_buffers(), &video_buffers);
193 parse_size = default_parse_size;
195 data += result;
196 size -= result;
198 ASSERT_TRUE(VerifyBuffers(audio_buffers, video_buffers, kDefaultBlockInfo,
199 block_count));
202 // Verify that both BlockGroups with the BlockDuration before the Block
203 // and BlockGroups with the BlockDuration after the Block are supported
204 // correctly.
205 // Note: Raw bytes are use here because ClusterBuilder only generates
206 // one of these scenarios.
207 TEST_F(WebMClusterParserTest, ParseBlockGroup) {
208 const BlockInfo kBlockInfo[] = {
209 { kAudioTrackNum, 0, 23, false },
210 { kVideoTrackNum, 33, 34, false },
212 int block_count = arraysize(kBlockInfo);
214 const uint8 kClusterData[] = {
215 0x1F, 0x43, 0xB6, 0x75, 0x9B, // Cluster(size=27)
216 0xE7, 0x81, 0x00, // Timecode(size=1, value=0)
217 // BlockGroup with BlockDuration before Block.
218 0xA0, 0x8A, // BlockGroup(size=10)
219 0x9B, 0x81, 0x17, // BlockDuration(size=1, value=23)
220 0xA1, 0x85, 0x81, 0x00, 0x00, 0x00, 0xaa, // Block(size=5, track=1, ts=0)
221 // BlockGroup with BlockDuration after Block.
222 0xA0, 0x8A, // BlockGroup(size=10)
223 0xA1, 0x85, 0x82, 0x00, 0x21, 0x00, 0x55, // Block(size=5, track=2, ts=33)
224 0x9B, 0x81, 0x22, // BlockDuration(size=1, value=34)
226 const int kClusterSize = sizeof(kClusterData);
228 int result = parser_->Parse(kClusterData, kClusterSize);
229 EXPECT_EQ(result, kClusterSize);
230 ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo, block_count));
233 TEST_F(WebMClusterParserTest, ParseSimpleBlockAndBlockGroupMixture) {
234 const BlockInfo kBlockInfo[] = {
235 { kAudioTrackNum, 0, 23, true },
236 { kAudioTrackNum, 23, 23, false },
237 { kVideoTrackNum, 33, 34, true },
238 { kAudioTrackNum, 46, 23, false },
239 { kVideoTrackNum, 67, 33, false },
241 int block_count = arraysize(kBlockInfo);
242 scoped_ptr<Cluster> cluster(CreateCluster(0, kBlockInfo, block_count));
244 int result = parser_->Parse(cluster->data(), cluster->size());
245 EXPECT_EQ(cluster->size(), result);
246 ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo, block_count));
249 } // namespace media