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

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

Issue 447963003: Introduce DecodeTimestamp class to make it easier to distiguish presentation and decode timestamps. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 6 years, 4 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 "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 26 matching lines...) Expand all
37 block_data_size_(-1), 37 block_data_size_(-1),
38 block_duration_(-1), 38 block_duration_(-1),
39 block_add_id_(-1), 39 block_add_id_(-1),
40 block_additional_data_size_(-1), 40 block_additional_data_size_(-1),
41 discard_padding_(-1), 41 discard_padding_(-1),
42 cluster_timecode_(-1), 42 cluster_timecode_(-1),
43 cluster_start_time_(kNoTimestamp()), 43 cluster_start_time_(kNoTimestamp()),
44 cluster_ended_(false), 44 cluster_ended_(false),
45 audio_(audio_track_num, false, audio_default_duration, log_cb), 45 audio_(audio_track_num, false, audio_default_duration, log_cb),
46 video_(video_track_num, true, video_default_duration, log_cb), 46 video_(video_track_num, true, video_default_duration, log_cb),
47 ready_buffer_upper_bound_(kNoTimestamp()), 47 ready_buffer_upper_bound_(kNoDecodeTimestamp()),
48 log_cb_(log_cb) { 48 log_cb_(log_cb) {
49 for (WebMTracksParser::TextTracks::const_iterator it = text_tracks.begin(); 49 for (WebMTracksParser::TextTracks::const_iterator it = text_tracks.begin();
50 it != text_tracks.end(); 50 it != text_tracks.end();
51 ++it) { 51 ++it) {
52 text_track_map_.insert(std::make_pair( 52 text_track_map_.insert(std::make_pair(
53 it->first, Track(it->first, false, kNoTimestamp(), log_cb_))); 53 it->first, Track(it->first, false, kNoTimestamp(), log_cb_)));
54 } 54 }
55 } 55 }
56 56
57 WebMClusterParser::~WebMClusterParser() {} 57 WebMClusterParser::~WebMClusterParser() {}
58 58
59 void WebMClusterParser::Reset() { 59 void WebMClusterParser::Reset() {
60 last_block_timecode_ = -1; 60 last_block_timecode_ = -1;
61 cluster_timecode_ = -1; 61 cluster_timecode_ = -1;
62 cluster_start_time_ = kNoTimestamp(); 62 cluster_start_time_ = kNoTimestamp();
63 cluster_ended_ = false; 63 cluster_ended_ = false;
64 parser_.Reset(); 64 parser_.Reset();
65 audio_.Reset(); 65 audio_.Reset();
66 video_.Reset(); 66 video_.Reset();
67 ResetTextTracks(); 67 ResetTextTracks();
68 ready_buffer_upper_bound_ = kNoTimestamp(); 68 ready_buffer_upper_bound_ = kNoDecodeTimestamp();
69 } 69 }
70 70
71 int WebMClusterParser::Parse(const uint8* buf, int size) { 71 int WebMClusterParser::Parse(const uint8* buf, int size) {
72 audio_.ClearReadyBuffers(); 72 audio_.ClearReadyBuffers();
73 video_.ClearReadyBuffers(); 73 video_.ClearReadyBuffers();
74 ClearTextTrackReadyBuffers(); 74 ClearTextTrackReadyBuffers();
75 ready_buffer_upper_bound_ = kNoTimestamp(); 75 ready_buffer_upper_bound_ = kNoDecodeTimestamp();
76 76
77 int result = parser_.Parse(buf, size); 77 int result = parser_.Parse(buf, size);
78 78
79 if (result < 0) { 79 if (result < 0) {
80 cluster_ended_ = false; 80 cluster_ended_ = false;
81 return result; 81 return result;
82 } 82 }
83 83
84 cluster_ended_ = parser_.IsParsingComplete(); 84 cluster_ended_ = parser_.IsParsingComplete();
85 if (cluster_ended_) { 85 if (cluster_ended_) {
(...skipping 15 matching lines...) Expand all
101 parser_.Reset(); 101 parser_.Reset();
102 102
103 last_block_timecode_ = -1; 103 last_block_timecode_ = -1;
104 cluster_timecode_ = -1; 104 cluster_timecode_ = -1;
105 } 105 }
106 106
107 return result; 107 return result;
108 } 108 }
109 109
110 const WebMClusterParser::BufferQueue& WebMClusterParser::GetAudioBuffers() { 110 const WebMClusterParser::BufferQueue& WebMClusterParser::GetAudioBuffers() {
111 if (ready_buffer_upper_bound_ == kNoTimestamp()) 111 if (ready_buffer_upper_bound_ == kNoDecodeTimestamp())
112 UpdateReadyBuffers(); 112 UpdateReadyBuffers();
113 113
114 return audio_.ready_buffers(); 114 return audio_.ready_buffers();
115 } 115 }
116 116
117 const WebMClusterParser::BufferQueue& WebMClusterParser::GetVideoBuffers() { 117 const WebMClusterParser::BufferQueue& WebMClusterParser::GetVideoBuffers() {
118 if (ready_buffer_upper_bound_ == kNoTimestamp()) 118 if (ready_buffer_upper_bound_ == kNoDecodeTimestamp())
119 UpdateReadyBuffers(); 119 UpdateReadyBuffers();
120 120
121 return video_.ready_buffers(); 121 return video_.ready_buffers();
122 } 122 }
123 123
124 const WebMClusterParser::TextBufferQueueMap& 124 const WebMClusterParser::TextBufferQueueMap&
125 WebMClusterParser::GetTextBuffers() { 125 WebMClusterParser::GetTextBuffers() {
126 if (ready_buffer_upper_bound_ == kNoTimestamp()) 126 if (ready_buffer_upper_bound_ == kNoDecodeTimestamp())
127 UpdateReadyBuffers(); 127 UpdateReadyBuffers();
128 128
129 // Translate our |text_track_map_| into |text_buffers_map_|, inserting rows in 129 // Translate our |text_track_map_| into |text_buffers_map_|, inserting rows in
130 // the output only for non-empty ready_buffer() queues in |text_track_map_|. 130 // the output only for non-empty ready_buffer() queues in |text_track_map_|.
131 text_buffers_map_.clear(); 131 text_buffers_map_.clear();
132 for (TextTrackMap::const_iterator itr = text_track_map_.begin(); 132 for (TextTrackMap::const_iterator itr = text_track_map_.begin();
133 itr != text_track_map_.end(); 133 itr != text_track_map_.end();
134 ++itr) { 134 ++itr) {
135 const BufferQueue& text_buffers = itr->second.ready_buffers(); 135 const BufferQueue& text_buffers = itr->second.ready_buffers();
136 if (!text_buffers.empty()) 136 if (!text_buffers.empty())
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 is_video_(is_video), 432 is_video_(is_video),
433 default_duration_(default_duration), 433 default_duration_(default_duration),
434 estimated_next_frame_duration_(kNoTimestamp()), 434 estimated_next_frame_duration_(kNoTimestamp()),
435 log_cb_(log_cb) { 435 log_cb_(log_cb) {
436 DCHECK(default_duration_ == kNoTimestamp() || 436 DCHECK(default_duration_ == kNoTimestamp() ||
437 default_duration_ > base::TimeDelta()); 437 default_duration_ > base::TimeDelta());
438 } 438 }
439 439
440 WebMClusterParser::Track::~Track() {} 440 WebMClusterParser::Track::~Track() {}
441 441
442 base::TimeDelta WebMClusterParser::Track::GetReadyUpperBound() { 442 DecodeTimestamp WebMClusterParser::Track::GetReadyUpperBound() {
443 DCHECK(ready_buffers_.empty()); 443 DCHECK(ready_buffers_.empty());
444 if (last_added_buffer_missing_duration_) 444 if (last_added_buffer_missing_duration_)
445 return last_added_buffer_missing_duration_->GetDecodeTimestamp(); 445 return last_added_buffer_missing_duration_->GetDecodeTimestamp();
446 446
447 return kInfiniteDuration(); 447 return DecodeTimestamp::FromPresentationTime(base::TimeDelta::Max());
448 } 448 }
449 449
450 void WebMClusterParser::Track::ExtractReadyBuffers( 450 void WebMClusterParser::Track::ExtractReadyBuffers(
451 const base::TimeDelta before_timestamp) { 451 const DecodeTimestamp before_timestamp) {
452 DCHECK(ready_buffers_.empty()); 452 DCHECK(ready_buffers_.empty());
453 DCHECK(base::TimeDelta() <= before_timestamp); 453 DCHECK(DecodeTimestamp() <= before_timestamp);
454 DCHECK(kNoTimestamp() != before_timestamp); 454 DCHECK(kNoDecodeTimestamp() != before_timestamp);
455 455
456 if (buffers_.empty()) 456 if (buffers_.empty())
457 return; 457 return;
458 458
459 if (buffers_.back()->GetDecodeTimestamp() < before_timestamp) { 459 if (buffers_.back()->GetDecodeTimestamp() < before_timestamp) {
460 // All of |buffers_| are ready. 460 // All of |buffers_| are ready.
461 ready_buffers_.swap(buffers_); 461 ready_buffers_.swap(buffers_);
462 DVLOG(3) << __FUNCTION__ << " : " << track_num_ << " All " 462 DVLOG(3) << __FUNCTION__ << " : " << track_num_ << " All "
463 << ready_buffers_.size() << " are ready: before upper bound ts " 463 << ready_buffers_.size() << " are ready: before upper bound ts "
464 << before_timestamp.InSecondsF(); 464 << before_timestamp.InSecondsF();
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
572 return true; 572 return true;
573 } 573 }
574 574
575 bool WebMClusterParser::Track::QueueBuffer( 575 bool WebMClusterParser::Track::QueueBuffer(
576 const scoped_refptr<StreamParserBuffer>& buffer) { 576 const scoped_refptr<StreamParserBuffer>& buffer) {
577 DCHECK(!last_added_buffer_missing_duration_); 577 DCHECK(!last_added_buffer_missing_duration_);
578 578
579 // WebMClusterParser::OnBlock() gives MEDIA_LOG and parse error on decreasing 579 // WebMClusterParser::OnBlock() gives MEDIA_LOG and parse error on decreasing
580 // block timecode detection within a cluster. Therefore, we should not see 580 // block timecode detection within a cluster. Therefore, we should not see
581 // those here. 581 // those here.
582 base::TimeDelta previous_buffers_timestamp = buffers_.empty() ? 582 DecodeTimestamp previous_buffers_timestamp = buffers_.empty() ?
583 base::TimeDelta() : buffers_.back()->GetDecodeTimestamp(); 583 DecodeTimestamp() : buffers_.back()->GetDecodeTimestamp();
584 CHECK(previous_buffers_timestamp <= buffer->GetDecodeTimestamp()); 584 CHECK(previous_buffers_timestamp <= buffer->GetDecodeTimestamp());
585 585
586 base::TimeDelta duration = buffer->duration(); 586 base::TimeDelta duration = buffer->duration();
587 if (duration < base::TimeDelta() || duration == kNoTimestamp()) { 587 if (duration < base::TimeDelta() || duration == kNoTimestamp()) {
588 MEDIA_LOG(log_cb_) << "Invalid buffer duration: " << duration.InSecondsF(); 588 MEDIA_LOG(log_cb_) << "Invalid buffer duration: " << duration.InSecondsF();
589 return false; 589 return false;
590 } 590 }
591 591
592 // The estimated frame duration is the minimum non-zero duration since the 592 // The estimated frame duration is the minimum non-zero duration since the
593 // last initialization segment. The minimum is used to ensure frame durations 593 // last initialization segment. The minimum is used to ensure frame durations
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 void WebMClusterParser::ResetTextTracks() { 637 void WebMClusterParser::ResetTextTracks() {
638 ClearTextTrackReadyBuffers(); 638 ClearTextTrackReadyBuffers();
639 for (TextTrackMap::iterator it = text_track_map_.begin(); 639 for (TextTrackMap::iterator it = text_track_map_.begin();
640 it != text_track_map_.end(); 640 it != text_track_map_.end();
641 ++it) { 641 ++it) {
642 it->second.Reset(); 642 it->second.Reset();
643 } 643 }
644 } 644 }
645 645
646 void WebMClusterParser::UpdateReadyBuffers() { 646 void WebMClusterParser::UpdateReadyBuffers() {
647 DCHECK(ready_buffer_upper_bound_ == kNoTimestamp()); 647 DCHECK(ready_buffer_upper_bound_ == kNoDecodeTimestamp());
648 DCHECK(text_buffers_map_.empty()); 648 DCHECK(text_buffers_map_.empty());
649 649
650 if (cluster_ended_) { 650 if (cluster_ended_) {
651 audio_.ApplyDurationEstimateIfNeeded(); 651 audio_.ApplyDurationEstimateIfNeeded();
652 video_.ApplyDurationEstimateIfNeeded(); 652 video_.ApplyDurationEstimateIfNeeded();
653 // Per OnBlock(), all text buffers should already have valid durations, so 653 // Per OnBlock(), all text buffers should already have valid durations, so
654 // there is no need to call ApplyDurationEstimateIfNeeded() on text tracks 654 // there is no need to call ApplyDurationEstimateIfNeeded() on text tracks
655 // here. 655 // here.
656 ready_buffer_upper_bound_ = kInfiniteDuration(); 656 ready_buffer_upper_bound_ =
657 DecodeTimestamp::FromPresentationTime(base::TimeDelta::Max());
657 DCHECK(ready_buffer_upper_bound_ == audio_.GetReadyUpperBound()); 658 DCHECK(ready_buffer_upper_bound_ == audio_.GetReadyUpperBound());
658 DCHECK(ready_buffer_upper_bound_ == video_.GetReadyUpperBound()); 659 DCHECK(ready_buffer_upper_bound_ == video_.GetReadyUpperBound());
659 } else { 660 } else {
660 ready_buffer_upper_bound_ = std::min(audio_.GetReadyUpperBound(), 661 ready_buffer_upper_bound_ = std::min(audio_.GetReadyUpperBound(),
661 video_.GetReadyUpperBound()); 662 video_.GetReadyUpperBound());
662 DCHECK(base::TimeDelta() <= ready_buffer_upper_bound_); 663 DCHECK(DecodeTimestamp() <= ready_buffer_upper_bound_);
663 DCHECK(kNoTimestamp() != ready_buffer_upper_bound_); 664 DCHECK(kNoDecodeTimestamp() != ready_buffer_upper_bound_);
664 } 665 }
665 666
666 // Prepare each track's ready buffers for retrieval. 667 // Prepare each track's ready buffers for retrieval.
667 audio_.ExtractReadyBuffers(ready_buffer_upper_bound_); 668 audio_.ExtractReadyBuffers(ready_buffer_upper_bound_);
668 video_.ExtractReadyBuffers(ready_buffer_upper_bound_); 669 video_.ExtractReadyBuffers(ready_buffer_upper_bound_);
669 for (TextTrackMap::iterator itr = text_track_map_.begin(); 670 for (TextTrackMap::iterator itr = text_track_map_.begin();
670 itr != text_track_map_.end(); 671 itr != text_track_map_.end();
671 ++itr) { 672 ++itr) {
672 itr->second.ExtractReadyBuffers(ready_buffer_upper_bound_); 673 itr->second.ExtractReadyBuffers(ready_buffer_upper_bound_);
673 } 674 }
674 } 675 }
675 676
676 WebMClusterParser::Track* 677 WebMClusterParser::Track*
677 WebMClusterParser::FindTextTrack(int track_num) { 678 WebMClusterParser::FindTextTrack(int track_num) {
678 const TextTrackMap::iterator it = text_track_map_.find(track_num); 679 const TextTrackMap::iterator it = text_track_map_.find(track_num);
679 680
680 if (it == text_track_map_.end()) 681 if (it == text_track_map_.end())
681 return NULL; 682 return NULL;
682 683
683 return &it->second; 684 return &it->second;
684 } 685 }
685 686
686 } // namespace media 687 } // namespace media
OLDNEW
« media/formats/mp2t/es_parser_adts.cc ('K') | « media/formats/webm/webm_cluster_parser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698