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

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

Issue 239343007: MSE: Make WebMClusterParser hold back buffers at or beyond buffer missing duration (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix some errors in comments. 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
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 #include <cstdlib>
7 7
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "media/base/decrypt_config.h" 10 #include "media/base/decrypt_config.h"
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 cb.SetClusterTimecode(0); 110 cb.SetClusterTimecode(0);
111 cb.AddSimpleBlock(kVideoTrackNum, 0, 0, kEncryptedFrame, bytes_to_write); 111 cb.AddSimpleBlock(kVideoTrackNum, 0, 0, kEncryptedFrame, bytes_to_write);
112 return cb.Finish(); 112 return cb.Finish();
113 } 113 }
114 114
115 static bool VerifyBuffers(const WebMClusterParser::BufferQueue& audio_buffers, 115 static bool VerifyBuffers(const WebMClusterParser::BufferQueue& audio_buffers,
116 const WebMClusterParser::BufferQueue& video_buffers, 116 const WebMClusterParser::BufferQueue& video_buffers,
117 const WebMClusterParser::BufferQueue& text_buffers, 117 const WebMClusterParser::BufferQueue& text_buffers,
118 const BlockInfo* block_info, 118 const BlockInfo* block_info,
119 int block_count) { 119 int block_count) {
120 int buffer_count = audio_buffers.size() + video_buffers.size() +
121 text_buffers.size();
122 EXPECT_EQ(block_count, buffer_count);
acolwell GONE FROM CHROMIUM 2014/04/23 22:36:39 nit: put this in a DVLOG below since this conditio
wolenetz 2014/04/25 20:04:21 Done.
123 if (block_count != buffer_count)
124 return false;
125
120 size_t audio_offset = 0; 126 size_t audio_offset = 0;
121 size_t video_offset = 0; 127 size_t video_offset = 0;
122 size_t text_offset = 0; 128 size_t text_offset = 0;
123 for (int i = 0; i < block_count; i++) { 129 for (int i = 0; i < block_count; i++) {
124 const WebMClusterParser::BufferQueue* buffers = NULL; 130 const WebMClusterParser::BufferQueue* buffers = NULL;
125 size_t* offset; 131 size_t* offset;
126 StreamParserBuffer::Type expected_type = DemuxerStream::UNKNOWN; 132 StreamParserBuffer::Type expected_type = DemuxerStream::UNKNOWN;
127 133
128 if (block_info[i].track_num == kAudioTrackNum) { 134 if (block_info[i].track_num == kAudioTrackNum) {
129 buffers = &audio_buffers; 135 buffers = &audio_buffers;
130 offset = &audio_offset; 136 offset = &audio_offset;
131 expected_type = DemuxerStream::AUDIO; 137 expected_type = DemuxerStream::AUDIO;
132 } else if (block_info[i].track_num == kVideoTrackNum) { 138 } else if (block_info[i].track_num == kVideoTrackNum) {
133 buffers = &video_buffers; 139 buffers = &video_buffers;
134 offset = &video_offset; 140 offset = &video_offset;
135 expected_type = DemuxerStream::VIDEO; 141 expected_type = DemuxerStream::VIDEO;
136 } else if (block_info[i].track_num == kTextTrackNum) { 142 } else if (block_info[i].track_num == kTextTrackNum) {
137 buffers = &text_buffers; 143 buffers = &text_buffers;
138 offset = &text_offset; 144 offset = &text_offset;
139 expected_type = DemuxerStream::TEXT; 145 expected_type = DemuxerStream::TEXT;
140 } else { 146 } else {
141 LOG(ERROR) << "Unexpected track number " << block_info[i].track_num; 147 LOG(ERROR) << "Unexpected track number " << block_info[i].track_num;
142 return false; 148 return false;
143 } 149 }
144 150
151 EXPECT_LT(*offset, buffers->size());
acolwell GONE FROM CHROMIUM 2014/04/23 22:36:39 ditto
wolenetz 2014/04/25 20:04:21 Done.
145 if (*offset >= buffers->size()) 152 if (*offset >= buffers->size())
146 return false; 153 return false;
147 154
148 scoped_refptr<StreamParserBuffer> buffer = (*buffers)[(*offset)++]; 155 scoped_refptr<StreamParserBuffer> buffer = (*buffers)[(*offset)++];
149 156
150 EXPECT_EQ(block_info[i].timestamp, buffer->timestamp().InMilliseconds()); 157 EXPECT_EQ(block_info[i].timestamp, buffer->timestamp().InMilliseconds());
151 EXPECT_EQ(std::abs(block_info[i].duration), 158 EXPECT_EQ(std::abs(block_info[i].duration),
152 buffer->duration().InMilliseconds()); 159 buffer->duration().InMilliseconds());
153 EXPECT_EQ(expected_type, buffer->type()); 160 EXPECT_EQ(expected_type, buffer->type());
154 EXPECT_EQ(block_info[i].track_num, buffer->track_id()); 161 EXPECT_EQ(block_info[i].track_num, buffer->track_id());
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 std::string(), 267 std::string(),
261 LogCB())); 268 LogCB()));
262 } 269 }
263 270
264 scoped_ptr<WebMClusterParser> parser_; 271 scoped_ptr<WebMClusterParser> parser_;
265 272
266 private: 273 private:
267 DISALLOW_COPY_AND_ASSIGN(WebMClusterParserTest); 274 DISALLOW_COPY_AND_ASSIGN(WebMClusterParserTest);
268 }; 275 };
269 276
277 TEST_F(WebMClusterParserTest, HeldBackBufferHoldsBackAllTracks) {
278 // If a buffer is missing duration and is being held back, then all other
279 // tracks' buffers that have same or higher (decode) timestamp should be held
280 // back too to keep the timestamps emitted for a cluster monotonically
281 // non-decreasing and in same order as parsed.
282 InSequence s;
283
284 // Reset the parser to have 3 tracks: text, video (no default frame duration),
285 // and audio (with a default frame duration).
286 TextTracks text_tracks;
287 text_tracks.insert(std::make_pair(TextTracks::key_type(kTextTrackNum),
288 TextTrackConfig(kTextSubtitles, "", "",
289 "")));
290 base::TimeDelta default_audio_duration =
291 base::TimeDelta::FromMilliseconds(kTestAudioFrameDefaultDurationInMs);
292 ASSERT_GE(default_audio_duration, base::TimeDelta());
293 ASSERT_NE(kNoTimestamp(), default_audio_duration);
294 parser_.reset(new WebMClusterParser(kTimecodeScale,
295 kAudioTrackNum,
296 default_audio_duration,
297 kVideoTrackNum,
298 kNoTimestamp(),
299 text_tracks,
300 std::set<int64>(),
301 std::string(),
302 std::string(),
303 LogCB()));
304
305 const BlockInfo kBlockInfo[] = {
306 { kVideoTrackNum, 0, 33, true },
307 { kAudioTrackNum, 0, 23, false },
308 { kTextTrackNum, 10, 42, false },
309 { kAudioTrackNum, 23, kTestAudioFrameDefaultDurationInMs, true },
310 { kVideoTrackNum, 33, 33, true },
311 { kAudioTrackNum, 36, kTestAudioFrameDefaultDurationInMs, true },
312 { kVideoTrackNum, 66, 33, true },
313 { kAudioTrackNum, 70, kTestAudioFrameDefaultDurationInMs, true },
314 { kAudioTrackNum, 83, kTestAudioFrameDefaultDurationInMs, true },
315 };
316
317 const int kExpectedBuffersOnPartialCluster[] = {
318 0, // Video simple block without DefaultDuration should be held back
319 0, // Audio buffer ready, but not emitted because its TS >= held back video
320 0, // Text buffer ready, but not emitted because its TS >= held back video
321 0, // 2nd audio buffer ready, also not emitted for same reason as first
322 4, // All previous buffers emitted, 2nd video held back with no duration
323 4, // 2nd video still has no duration, 3rd audio ready but not emitted
324 6, // All previous buffers emitted, 3rd video held back with no duration
325 6, // 3rd video still has no duration, 4th audio ready but not emitted
326 9, // Cluster end emits all buffers and 3rd video's duration is estimated
327 };
328
329 ASSERT_EQ(arraysize(kBlockInfo), arraysize(kExpectedBuffersOnPartialCluster));
330 int block_count = arraysize(kBlockInfo);
331
332 // Iteratively create a cluster containing the first N+1 blocks and parse all
333 // but the last byte of the cluster (except when N==|block_count|, just parse
334 // the whole cluster). Verify that the corresponding entry in
335 // |kExpectedBuffersOnPartialCluster| identifies the exact subset of
336 // |kBlockInfo| returned by the parser.
337 for (int i = 0; i < block_count; ++i) {
338 if (i > 0)
339 parser_->Reset();
340 // Since we don't know exactly the offsets of each block in the full
341 // cluster, build a cluster with exactly one additional block so that
342 // parse of all but one byte should deterministically parse all but the
343 // last full block. Don't |exceed block_count| blocks though.
344 int blocks_in_cluster = std::min(i + 2, block_count);
345 scoped_ptr<Cluster> cluster(CreateCluster(0, kBlockInfo,
346 blocks_in_cluster));
347 // Parse all but the last byte unless we need to parse the full cluster.
348 bool parse_full_cluster = i == (block_count - 1);
349 int result = parser_->Parse(cluster->data(), parse_full_cluster ?
350 cluster->size() : cluster->size() - 1);
351 if (parse_full_cluster) {
352 DVLOG(1) << "Verifying parse result of full cluster of "
353 << blocks_in_cluster << " blocks";
354 EXPECT_EQ(cluster->size(), result);
355 } else {
356 DVLOG(1) << "Verifying parse result of cluster of "
357 << blocks_in_cluster << " blocks with last block incomplete";
358 EXPECT_GT(cluster->size(), result);
359 EXPECT_LT(0, result);
360 }
361
362 EXPECT_TRUE(VerifyBuffers(parser_, kBlockInfo,
363 kExpectedBuffersOnPartialCluster[i]));
364 }
365 }
366
270 TEST_F(WebMClusterParserTest, Reset) { 367 TEST_F(WebMClusterParserTest, Reset) {
271 InSequence s; 368 InSequence s;
272 369
273 int block_count = arraysize(kDefaultBlockInfo); 370 int block_count = arraysize(kDefaultBlockInfo);
274 scoped_ptr<Cluster> cluster(CreateCluster(0, kDefaultBlockInfo, block_count)); 371 scoped_ptr<Cluster> cluster(CreateCluster(0, kDefaultBlockInfo, block_count));
275 372
276 // Send slightly less than the full cluster so all but the last block is 373 // Send slightly less than the full cluster so all but the last block is
277 // parsed. 374 // parsed.
278 int result = parser_->Parse(cluster->data(), cluster->size() - 1); 375 int result = parser_->Parse(cluster->data(), cluster->size() - 1);
279 EXPECT_GT(result, 0); 376 EXPECT_GT(result, 0);
(...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after
846 }; 943 };
847 944
848 int block_count = arraysize(kBlockInfo); 945 int block_count = arraysize(kBlockInfo);
849 scoped_ptr<Cluster> cluster(CreateCluster(0, kBlockInfo, block_count)); 946 scoped_ptr<Cluster> cluster(CreateCluster(0, kBlockInfo, block_count));
850 int result = parser_->Parse(cluster->data(), cluster->size()); 947 int result = parser_->Parse(cluster->data(), cluster->size());
851 EXPECT_EQ(cluster->size(), result); 948 EXPECT_EQ(cluster->size(), result);
852 ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo, block_count)); 949 ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo, block_count));
853 } 950 }
854 951
855 } // namespace media 952 } // namespace media
OLDNEW
« media/formats/webm/webm_cluster_parser.cc ('K') | « 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