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

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

Issue 1041353002: media-internals: Differentiate error, info, and debug log messages (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address reviewer comments Created 5 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
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 "media/formats/webm/webm_cluster_parser.h" 5 #include "media/formats/webm/webm_cluster_parser.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/sys_byteorder.h" 10 #include "base/sys_byteorder.h"
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 int size) { 178 int size) {
179 // Masks and constants for Opus packets. See 179 // Masks and constants for Opus packets. See
180 // https://tools.ietf.org/html/rfc6716#page-14 180 // https://tools.ietf.org/html/rfc6716#page-14
181 static const uint8_t kTocConfigMask = 0xf8; 181 static const uint8_t kTocConfigMask = 0xf8;
182 static const uint8_t kTocFrameCountCodeMask = 0x03; 182 static const uint8_t kTocFrameCountCodeMask = 0x03;
183 static const uint8_t kFrameCountMask = 0x3f; 183 static const uint8_t kFrameCountMask = 0x3f;
184 static const base::TimeDelta kPacketDurationMax = 184 static const base::TimeDelta kPacketDurationMax =
185 base::TimeDelta::FromMilliseconds(120); 185 base::TimeDelta::FromMilliseconds(120);
186 186
187 if (size < 1) { 187 if (size < 1) {
188 LIMITED_MEDIA_LOG(log_cb_, num_duration_errors_, kMaxDurationLogs) 188 LIMITED_MEDIA_LOG(DEBUG, log_cb_, num_duration_errors_, kMaxDurationLogs)
189 << "Invalid zero-byte Opus packet; demuxed block duration may be " 189 << "Invalid zero-byte Opus packet; demuxed block duration may be "
190 "imprecise."; 190 "imprecise.";
191 return kNoTimestamp(); 191 return kNoTimestamp();
192 } 192 }
193 193
194 // Frame count type described by last 2 bits of Opus TOC byte. 194 // Frame count type described by last 2 bits of Opus TOC byte.
195 int frame_count_type = data[0] & kTocFrameCountCodeMask; 195 int frame_count_type = data[0] & kTocFrameCountCodeMask;
196 196
197 int frame_count = 0; 197 int frame_count = 0;
198 switch (frame_count_type) { 198 switch (frame_count_type) {
199 case 0: 199 case 0:
200 frame_count = 1; 200 frame_count = 1;
201 break; 201 break;
202 case 1: 202 case 1:
203 case 2: 203 case 2:
204 frame_count = 2; 204 frame_count = 2;
205 break; 205 break;
206 case 3: 206 case 3:
207 // Type 3 indicates an arbitrary frame count described in the next byte. 207 // Type 3 indicates an arbitrary frame count described in the next byte.
208 if (size < 2) { 208 if (size < 2) {
209 LIMITED_MEDIA_LOG(log_cb_, num_duration_errors_, kMaxDurationLogs) 209 LIMITED_MEDIA_LOG(DEBUG, log_cb_, num_duration_errors_,
210 kMaxDurationLogs)
210 << "Second byte missing from 'Code 3' Opus packet; demuxed block " 211 << "Second byte missing from 'Code 3' Opus packet; demuxed block "
211 "duration may be imprecise."; 212 "duration may be imprecise.";
212 return kNoTimestamp(); 213 return kNoTimestamp();
213 } 214 }
214 215
215 frame_count = data[1] & kFrameCountMask; 216 frame_count = data[1] & kFrameCountMask;
216 217
217 if (frame_count == 0) { 218 if (frame_count == 0) {
218 LIMITED_MEDIA_LOG(log_cb_, num_duration_errors_, kMaxDurationLogs) 219 LIMITED_MEDIA_LOG(DEBUG, log_cb_, num_duration_errors_,
220 kMaxDurationLogs)
219 << "Illegal 'Code 3' Opus packet with frame count zero; demuxed " 221 << "Illegal 'Code 3' Opus packet with frame count zero; demuxed "
220 "block duration may be imprecise."; 222 "block duration may be imprecise.";
221 return kNoTimestamp(); 223 return kNoTimestamp();
222 } 224 }
223 225
224 break; 226 break;
225 default: 227 default:
226 LIMITED_MEDIA_LOG(log_cb_, num_duration_errors_, kMaxDurationLogs) 228 LIMITED_MEDIA_LOG(DEBUG, log_cb_, num_duration_errors_, kMaxDurationLogs)
227 << "Unexpected Opus frame count type: " << frame_count_type << "; " 229 << "Unexpected Opus frame count type: " << frame_count_type << "; "
228 << "demuxed block duration may be imprecise."; 230 << "demuxed block duration may be imprecise.";
229 return kNoTimestamp(); 231 return kNoTimestamp();
230 } 232 }
231 233
232 int opusConfig = (data[0] & kTocConfigMask) >> 3; 234 int opusConfig = (data[0] & kTocConfigMask) >> 3;
233 CHECK_GE(opusConfig, 0); 235 CHECK_GE(opusConfig, 0);
234 CHECK_LT(opusConfig, static_cast<int>(arraysize(kOpusFrameDurationsMu))); 236 CHECK_LT(opusConfig, static_cast<int>(arraysize(kOpusFrameDurationsMu)));
235 237
236 DCHECK_GT(frame_count, 0); 238 DCHECK_GT(frame_count, 0);
237 base::TimeDelta duration = base::TimeDelta::FromMicroseconds( 239 base::TimeDelta duration = base::TimeDelta::FromMicroseconds(
238 kOpusFrameDurationsMu[opusConfig] * frame_count); 240 kOpusFrameDurationsMu[opusConfig] * frame_count);
239 241
240 if (duration > kPacketDurationMax) { 242 if (duration > kPacketDurationMax) {
241 // Intentionally allowing packet to pass through for now. Decoder should 243 // Intentionally allowing packet to pass through for now. Decoder should
242 // either handle or fail gracefully. MEDIA_LOG as breadcrumbs in case 244 // either handle or fail gracefully. MEDIA_LOG as breadcrumbs in case
243 // things go sideways. 245 // things go sideways.
244 LIMITED_MEDIA_LOG(log_cb_, num_duration_errors_, kMaxDurationLogs) 246 LIMITED_MEDIA_LOG(DEBUG, log_cb_, num_duration_errors_, kMaxDurationLogs)
245 << "Warning, demuxed Opus packet with encoded duration: " << duration 247 << "Warning, demuxed Opus packet with encoded duration: " << duration
246 << ". Should be no greater than " << kPacketDurationMax; 248 << ". Should be no greater than " << kPacketDurationMax;
247 } 249 }
248 250
249 return duration; 251 return duration;
250 } 252 }
251 253
252 WebMParserClient* WebMClusterParser::OnListStart(int id) { 254 WebMParserClient* WebMClusterParser::OnListStart(int id) {
253 if (id == kWebMIdCluster) { 255 if (id == kWebMIdCluster) {
254 cluster_timecode_ = -1; 256 cluster_timecode_ = -1;
(...skipping 12 matching lines...) Expand all
267 269
268 return this; 270 return this;
269 } 271 }
270 272
271 bool WebMClusterParser::OnListEnd(int id) { 273 bool WebMClusterParser::OnListEnd(int id) {
272 if (id != kWebMIdBlockGroup) 274 if (id != kWebMIdBlockGroup)
273 return true; 275 return true;
274 276
275 // Make sure the BlockGroup actually had a Block. 277 // Make sure the BlockGroup actually had a Block.
276 if (block_data_size_ == -1) { 278 if (block_data_size_ == -1) {
277 MEDIA_LOG(log_cb_) << "Block missing from BlockGroup."; 279 MEDIA_LOG(ERROR, log_cb_) << "Block missing from BlockGroup.";
278 return false; 280 return false;
279 } 281 }
280 282
281 bool result = ParseBlock(false, block_data_.get(), block_data_size_, 283 bool result = ParseBlock(false, block_data_.get(), block_data_size_,
282 block_additional_data_.get(), 284 block_additional_data_.get(),
283 block_additional_data_size_, block_duration_, 285 block_additional_data_size_, block_duration_,
284 discard_padding_set_ ? discard_padding_ : 0); 286 discard_padding_set_ ? discard_padding_ : 0);
285 block_data_.reset(); 287 block_data_.reset();
286 block_data_size_ = -1; 288 block_data_size_ = -1;
287 block_duration_ = -1; 289 block_duration_ = -1;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 const uint8_t* additional, 322 const uint8_t* additional,
321 int additional_size, 323 int additional_size,
322 int duration, 324 int duration,
323 int64 discard_padding) { 325 int64 discard_padding) {
324 if (size < 4) 326 if (size < 4)
325 return false; 327 return false;
326 328
327 // Return an error if the trackNum > 127. We just aren't 329 // Return an error if the trackNum > 127. We just aren't
328 // going to support large track numbers right now. 330 // going to support large track numbers right now.
329 if (!(buf[0] & 0x80)) { 331 if (!(buf[0] & 0x80)) {
330 MEDIA_LOG(log_cb_) << "TrackNumber over 127 not supported"; 332 MEDIA_LOG(ERROR, log_cb_) << "TrackNumber over 127 not supported";
331 return false; 333 return false;
332 } 334 }
333 335
334 int track_num = buf[0] & 0x7f; 336 int track_num = buf[0] & 0x7f;
335 int timecode = buf[1] << 8 | buf[2]; 337 int timecode = buf[1] << 8 | buf[2];
336 int flags = buf[3] & 0xff; 338 int flags = buf[3] & 0xff;
337 int lacing = (flags >> 1) & 0x3; 339 int lacing = (flags >> 1) & 0x3;
338 340
339 if (lacing) { 341 if (lacing) {
340 MEDIA_LOG(log_cb_) << "Lacing " << lacing << " is not supported yet."; 342 MEDIA_LOG(ERROR, log_cb_) << "Lacing " << lacing
343 << " is not supported yet.";
341 return false; 344 return false;
342 } 345 }
343 346
344 // Sign extend negative timecode offsets. 347 // Sign extend negative timecode offsets.
345 if (timecode & 0x8000) 348 if (timecode & 0x8000)
346 timecode |= ~0xffff; 349 timecode |= ~0xffff;
347 350
348 const uint8_t* frame_data = buf + 4; 351 const uint8_t* frame_data = buf + 4;
349 int frame_size = size - (frame_data - buf); 352 int frame_size = size - (frame_data - buf);
350 return OnBlock(is_simple_block, track_num, timecode, duration, flags, 353 return OnBlock(is_simple_block, track_num, timecode, duration, flags,
351 frame_data, frame_size, additional, additional_size, 354 frame_data, frame_size, additional, additional_size,
352 discard_padding); 355 discard_padding);
353 } 356 }
354 357
355 bool WebMClusterParser::OnBinary(int id, const uint8_t* data, int size) { 358 bool WebMClusterParser::OnBinary(int id, const uint8_t* data, int size) {
356 switch (id) { 359 switch (id) {
357 case kWebMIdSimpleBlock: 360 case kWebMIdSimpleBlock:
358 return ParseBlock(true, data, size, NULL, 0, -1, 0); 361 return ParseBlock(true, data, size, NULL, 0, -1, 0);
359 362
360 case kWebMIdBlock: 363 case kWebMIdBlock:
361 if (block_data_) { 364 if (block_data_) {
362 MEDIA_LOG(log_cb_) << "More than 1 Block in a BlockGroup is not " 365 MEDIA_LOG(ERROR, log_cb_) << "More than 1 Block in a BlockGroup is not "
363 "supported."; 366 "supported.";
364 return false; 367 return false;
365 } 368 }
366 block_data_.reset(new uint8_t[size]); 369 block_data_.reset(new uint8_t[size]);
367 memcpy(block_data_.get(), data, size); 370 memcpy(block_data_.get(), data, size);
368 block_data_size_ = size; 371 block_data_size_ = size;
369 return true; 372 return true;
370 373
371 case kWebMIdBlockAdditional: { 374 case kWebMIdBlockAdditional: {
372 uint64 block_add_id = base::HostToNet64(block_add_id_); 375 uint64 block_add_id = base::HostToNet64(block_add_id_);
373 if (block_additional_data_) { 376 if (block_additional_data_) {
374 // TODO(vigneshv): Technically, more than 1 BlockAdditional is allowed 377 // TODO(vigneshv): Technically, more than 1 BlockAdditional is allowed
375 // as per matroska spec. But for now we don't have a use case to 378 // as per matroska spec. But for now we don't have a use case to
376 // support parsing of such files. Take a look at this again when such a 379 // support parsing of such files. Take a look at this again when such a
377 // case arises. 380 // case arises.
378 MEDIA_LOG(log_cb_) << "More than 1 BlockAdditional in a BlockGroup is " 381 MEDIA_LOG(ERROR, log_cb_) << "More than 1 BlockAdditional in a "
379 "not supported."; 382 "BlockGroup is not supported.";
380 return false; 383 return false;
381 } 384 }
382 // First 8 bytes of side_data in DecoderBuffer is the BlockAddID 385 // First 8 bytes of side_data in DecoderBuffer is the BlockAddID
383 // element's value in Big Endian format. This is done to mimic ffmpeg 386 // element's value in Big Endian format. This is done to mimic ffmpeg
384 // demuxer's behavior. 387 // demuxer's behavior.
385 block_additional_data_size_ = size + sizeof(block_add_id); 388 block_additional_data_size_ = size + sizeof(block_add_id);
386 block_additional_data_.reset(new uint8_t[block_additional_data_size_]); 389 block_additional_data_.reset(new uint8_t[block_additional_data_size_]);
387 memcpy(block_additional_data_.get(), &block_add_id, 390 memcpy(block_additional_data_.get(), &block_add_id,
388 sizeof(block_add_id)); 391 sizeof(block_add_id));
389 memcpy(block_additional_data_.get() + 8, data, size); 392 memcpy(block_additional_data_.get() + 8, data, size);
(...skipping 21 matching lines...) Expand all
411 int timecode, 414 int timecode,
412 int block_duration, 415 int block_duration,
413 int flags, 416 int flags,
414 const uint8_t* data, 417 const uint8_t* data,
415 int size, 418 int size,
416 const uint8_t* additional, 419 const uint8_t* additional,
417 int additional_size, 420 int additional_size,
418 int64 discard_padding) { 421 int64 discard_padding) {
419 DCHECK_GE(size, 0); 422 DCHECK_GE(size, 0);
420 if (cluster_timecode_ == -1) { 423 if (cluster_timecode_ == -1) {
421 MEDIA_LOG(log_cb_) << "Got a block before cluster timecode."; 424 MEDIA_LOG(ERROR, log_cb_) << "Got a block before cluster timecode.";
422 return false; 425 return false;
423 } 426 }
424 427
425 // TODO(acolwell): Should relative negative timecode offsets be rejected? Or 428 // TODO(acolwell): Should relative negative timecode offsets be rejected? Or
426 // only when the absolute timecode is negative? See http://crbug.com/271794 429 // only when the absolute timecode is negative? See http://crbug.com/271794
427 if (timecode < 0) { 430 if (timecode < 0) {
428 MEDIA_LOG(log_cb_) << "Got a block with negative timecode offset " 431 MEDIA_LOG(ERROR, log_cb_) << "Got a block with negative timecode offset "
429 << timecode; 432 << timecode;
430 return false; 433 return false;
431 } 434 }
432 435
433 if (last_block_timecode_ != -1 && timecode < last_block_timecode_) { 436 if (last_block_timecode_ != -1 && timecode < last_block_timecode_) {
434 MEDIA_LOG(log_cb_) 437 MEDIA_LOG(ERROR, log_cb_)
435 << "Got a block with a timecode before the previous block."; 438 << "Got a block with a timecode before the previous block.";
436 return false; 439 return false;
437 } 440 }
438 441
439 Track* track = NULL; 442 Track* track = NULL;
440 StreamParserBuffer::Type buffer_type = DemuxerStream::AUDIO; 443 StreamParserBuffer::Type buffer_type = DemuxerStream::AUDIO;
441 std::string encryption_key_id; 444 std::string encryption_key_id;
442 base::TimeDelta encoded_duration = kNoTimestamp(); 445 base::TimeDelta encoded_duration = kNoTimestamp();
443 if (track_num == audio_.track_num()) { 446 if (track_num == audio_.track_num()) {
444 track = &audio_; 447 track = &audio_;
445 encryption_key_id = audio_encryption_key_id_; 448 encryption_key_id = audio_encryption_key_id_;
446 if (encryption_key_id.empty()) { 449 if (encryption_key_id.empty()) {
447 encoded_duration = TryGetEncodedAudioDuration(data, size); 450 encoded_duration = TryGetEncodedAudioDuration(data, size);
448 } 451 }
449 } else if (track_num == video_.track_num()) { 452 } else if (track_num == video_.track_num()) {
450 track = &video_; 453 track = &video_;
451 encryption_key_id = video_encryption_key_id_; 454 encryption_key_id = video_encryption_key_id_;
452 buffer_type = DemuxerStream::VIDEO; 455 buffer_type = DemuxerStream::VIDEO;
453 } else if (ignored_tracks_.find(track_num) != ignored_tracks_.end()) { 456 } else if (ignored_tracks_.find(track_num) != ignored_tracks_.end()) {
454 return true; 457 return true;
455 } else if (Track* const text_track = FindTextTrack(track_num)) { 458 } else if (Track* const text_track = FindTextTrack(track_num)) {
456 if (is_simple_block) // BlockGroup is required for WebVTT cues 459 if (is_simple_block) // BlockGroup is required for WebVTT cues
457 return false; 460 return false;
458 if (block_duration < 0) // not specified 461 if (block_duration < 0) // not specified
459 return false; 462 return false;
460 track = text_track; 463 track = text_track;
461 buffer_type = DemuxerStream::TEXT; 464 buffer_type = DemuxerStream::TEXT;
462 } else { 465 } else {
463 MEDIA_LOG(log_cb_) << "Unexpected track number " << track_num; 466 MEDIA_LOG(ERROR, log_cb_) << "Unexpected track number " << track_num;
464 return false; 467 return false;
465 } 468 }
466 469
467 last_block_timecode_ = timecode; 470 last_block_timecode_ = timecode;
468 471
469 base::TimeDelta timestamp = base::TimeDelta::FromMicroseconds( 472 base::TimeDelta timestamp = base::TimeDelta::FromMicroseconds(
470 (cluster_timecode_ + timecode) * timecode_multiplier_); 473 (cluster_timecode_ + timecode) * timecode_multiplier_);
471 474
472 scoped_refptr<StreamParserBuffer> buffer; 475 scoped_refptr<StreamParserBuffer> buffer;
473 if (buffer_type != DemuxerStream::TEXT) { 476 if (buffer_type != DemuxerStream::TEXT) {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
551 DVLOG(3) << __FUNCTION__ << " : " 554 DVLOG(3) << __FUNCTION__ << " : "
552 << "Using encoded duration " << encoded_duration.InSecondsF(); 555 << "Using encoded duration " << encoded_duration.InSecondsF();
553 556
554 if (block_duration_time_delta != kNoTimestamp()) { 557 if (block_duration_time_delta != kNoTimestamp()) {
555 base::TimeDelta duration_difference = 558 base::TimeDelta duration_difference =
556 block_duration_time_delta - encoded_duration; 559 block_duration_time_delta - encoded_duration;
557 560
558 const auto kWarnDurationDiff = 561 const auto kWarnDurationDiff =
559 base::TimeDelta::FromMicroseconds(timecode_multiplier_ * 2); 562 base::TimeDelta::FromMicroseconds(timecode_multiplier_ * 2);
560 if (duration_difference.magnitude() > kWarnDurationDiff) { 563 if (duration_difference.magnitude() > kWarnDurationDiff) {
561 LIMITED_MEDIA_LOG(log_cb_, num_duration_errors_, kMaxDurationLogs) 564 LIMITED_MEDIA_LOG(DEBUG, log_cb_, num_duration_errors_,
565 kMaxDurationLogs)
562 << "BlockDuration " 566 << "BlockDuration "
563 << "(" << block_duration_time_delta << ") " 567 << "(" << block_duration_time_delta << ") "
564 << "differs significantly from encoded duration " 568 << "differs significantly from encoded duration "
565 << "(" << encoded_duration << ")."; 569 << "(" << encoded_duration << ").";
566 } 570 }
567 } 571 }
568 } else if (block_duration_time_delta != kNoTimestamp()) { 572 } else if (block_duration_time_delta != kNoTimestamp()) {
569 buffer->set_duration(block_duration_time_delta); 573 buffer->set_duration(block_duration_time_delta);
570 } else { 574 } else {
571 DCHECK_NE(buffer_type, DemuxerStream::TEXT); 575 DCHECK_NE(buffer_type, DemuxerStream::TEXT);
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
735 739
736 // WebMClusterParser::OnBlock() gives MEDIA_LOG and parse error on decreasing 740 // WebMClusterParser::OnBlock() gives MEDIA_LOG and parse error on decreasing
737 // block timecode detection within a cluster. Therefore, we should not see 741 // block timecode detection within a cluster. Therefore, we should not see
738 // those here. 742 // those here.
739 DecodeTimestamp previous_buffers_timestamp = buffers_.empty() ? 743 DecodeTimestamp previous_buffers_timestamp = buffers_.empty() ?
740 DecodeTimestamp() : buffers_.back()->GetDecodeTimestamp(); 744 DecodeTimestamp() : buffers_.back()->GetDecodeTimestamp();
741 CHECK(previous_buffers_timestamp <= buffer->GetDecodeTimestamp()); 745 CHECK(previous_buffers_timestamp <= buffer->GetDecodeTimestamp());
742 746
743 base::TimeDelta duration = buffer->duration(); 747 base::TimeDelta duration = buffer->duration();
744 if (duration < base::TimeDelta() || duration == kNoTimestamp()) { 748 if (duration < base::TimeDelta() || duration == kNoTimestamp()) {
745 MEDIA_LOG(log_cb_) << "Invalid buffer duration: " << duration.InSecondsF(); 749 MEDIA_LOG(ERROR, log_cb_)
750 << "Invalid buffer duration: " << duration.InSecondsF();
746 return false; 751 return false;
747 } 752 }
748 753
749 // The estimated frame duration is the minimum non-zero duration since the 754 // The estimated frame duration is the minimum non-zero duration since the
750 // last initialization segment. The minimum is used to ensure frame durations 755 // last initialization segment. The minimum is used to ensure frame durations
751 // aren't overestimated. 756 // aren't overestimated.
752 if (duration > base::TimeDelta()) { 757 if (duration > base::TimeDelta()) {
753 if (estimated_next_frame_duration_ == kNoTimestamp()) { 758 if (estimated_next_frame_duration_ == kNoTimestamp()) {
754 estimated_next_frame_duration_ = duration; 759 estimated_next_frame_duration_ = duration;
755 } else { 760 } else {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
835 WebMClusterParser::FindTextTrack(int track_num) { 840 WebMClusterParser::FindTextTrack(int track_num) {
836 const TextTrackMap::iterator it = text_track_map_.find(track_num); 841 const TextTrackMap::iterator it = text_track_map_.find(track_num);
837 842
838 if (it == text_track_map_.end()) 843 if (it == text_track_map_.end())
839 return NULL; 844 return NULL;
840 845
841 return &it->second; 846 return &it->second;
842 } 847 }
843 848
844 } // namespace media 849 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698