| OLD | NEW |
| 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 Loading... |
| 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(log_cb_, DEBUG, 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(log_cb_, DEBUG, 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(log_cb_, DEBUG, 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(log_cb_, DEBUG, 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(log_cb_, DEBUG, 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 Loading... |
| 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(log_cb_, ERROR) << "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 Loading... |
| 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(log_cb_, ERROR) << "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(log_cb_, ERROR) << "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(log_cb_, ERROR) << "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(log_cb_, ERROR) << "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 Loading... |
| 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(log_cb_, ERROR) << "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(log_cb_, ERROR) << "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(log_cb_, ERROR) |
| 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(log_cb_, ERROR) << "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 Loading... |
| 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(log_cb_, DEBUG, 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 Loading... |
| 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(log_cb_, ERROR) << "Invalid buffer duration: " |
| 750 << 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 Loading... |
| 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 |
| OLD | NEW |