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

Side by Side Diff: media/filters/chunk_demuxer.cc

Issue 10539115: Calculate the buffered ranges in ChunkDemuxer::GetBufferedRanges() (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 6 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 (c) 2012 The Chromium Authors. All rights reserved. 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 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/filters/chunk_demuxer.h" 5 #include "media/filters/chunk_demuxer.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "media/base/audio_decoder_config.h" 10 #include "media/base/audio_decoder_config.h"
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 126
127 void StartWaitingForSeek(); 127 void StartWaitingForSeek();
128 void Seek(base::TimeDelta time); 128 void Seek(base::TimeDelta time);
129 bool IsSeekPending() const; 129 bool IsSeekPending() const;
130 130
131 // Add buffers to this stream. Buffers are stored in SourceBufferStreams, 131 // Add buffers to this stream. Buffers are stored in SourceBufferStreams,
132 // which handle ordering and overlap resolution. 132 // which handle ordering and overlap resolution.
133 // Returns true if buffers were successfully added. 133 // Returns true if buffers were successfully added.
134 bool Append(const StreamParser::BufferQueue& buffers); 134 bool Append(const StreamParser::BufferQueue& buffers);
135 135
136 // Returns a list of the buffered time ranges.
137 SourceBufferStream::TimespanList GetBufferedTime() const;
138
136 // Called when mid-stream config updates occur. 139 // Called when mid-stream config updates occur.
137 // Returns true if the new config is accepted. 140 // Returns true if the new config is accepted.
138 // Returns false if the new config should trigger an error. 141 // Returns false if the new config should trigger an error.
139 bool UpdateAudioConfig(const AudioDecoderConfig& config); 142 bool UpdateAudioConfig(const AudioDecoderConfig& config);
140 bool UpdateVideoConfig(const VideoDecoderConfig& config); 143 bool UpdateVideoConfig(const VideoDecoderConfig& config);
141 144
142 void EndOfStream(); 145 void EndOfStream();
143 bool CanEndOfStream() const; 146 bool CanEndOfStream() const;
144 void Shutdown(); 147 void Shutdown();
145 148
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 } 242 }
240 CreateReadDoneClosures_Locked(&closures); 243 CreateReadDoneClosures_Locked(&closures);
241 } 244 }
242 245
243 for (ClosureQueue::iterator it = closures.begin(); it != closures.end(); ++it) 246 for (ClosureQueue::iterator it = closures.begin(); it != closures.end(); ++it)
244 it->Run(); 247 it->Run();
245 248
246 return true; 249 return true;
247 } 250 }
248 251
252 SourceBufferStream::TimespanList ChunkDemuxerStream::GetBufferedTime() const {
253 base::AutoLock auto_lock(lock_);
254 return stream_->GetBufferedTime();
255 }
256
249 bool ChunkDemuxerStream::UpdateAudioConfig(const AudioDecoderConfig& config) { 257 bool ChunkDemuxerStream::UpdateAudioConfig(const AudioDecoderConfig& config) {
250 DCHECK(config.IsValidConfig()); 258 DCHECK(config.IsValidConfig());
251 DCHECK_EQ(type_, AUDIO); 259 DCHECK_EQ(type_, AUDIO);
252 260
253 const AudioDecoderConfig& current_config = 261 const AudioDecoderConfig& current_config =
254 stream_->GetCurrentAudioDecoderConfig(); 262 stream_->GetCurrentAudioDecoderConfig();
255 263
256 bool success = (current_config.codec() == config.codec()) && 264 bool success = (current_config.codec() == config.codec()) &&
257 (current_config.bits_per_channel() == config.bits_per_channel()) && 265 (current_config.bits_per_channel() == config.bits_per_channel()) &&
258 (current_config.channel_layout() == config.channel_layout()) && 266 (current_config.channel_layout() == config.channel_layout()) &&
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 audio_->Shutdown(); 581 audio_->Shutdown();
574 582
575 if (source_id_video_ == id && video_) 583 if (source_id_video_ == id && video_)
576 video_->Shutdown(); 584 video_->Shutdown();
577 } 585 }
578 586
579 bool ChunkDemuxer::GetBufferedRanges(const std::string& id, 587 bool ChunkDemuxer::GetBufferedRanges(const std::string& id,
580 Ranges* ranges_out) const { 588 Ranges* ranges_out) const {
581 DCHECK(!id.empty()); 589 DCHECK(!id.empty());
582 DCHECK_GT(stream_parser_map_.count(id), 0u); 590 DCHECK_GT(stream_parser_map_.count(id), 0u);
591 DCHECK(id == source_id_audio_ || id == source_id_video_);
583 DCHECK(ranges_out); 592 DCHECK(ranges_out);
584 593
585 base::AutoLock auto_lock(lock_); 594 base::AutoLock auto_lock(lock_);
595 bool success = false;
586 596
587 // TODO(annacc): Calculate buffered ranges (http://crbug.com/129852 ). 597 if (id == source_id_audio_ && id != source_id_video_) {
588 return false; 598 // Only include ranges that have been buffered in |audio_|
acolwell GONE FROM CHROMIUM 2012/06/12 22:48:13 Move this to a helper method so we don't have dupl
annacc 2012/06/13 00:00:01 Done.
599 SourceBufferStream::TimespanList audio_ranges = audio_->GetBufferedTime();
600 for (SourceBufferStream::TimespanList::iterator itr = audio_ranges.begin();
601 itr != audio_ranges.end(); ++itr) {
602 ranges_out->push_back(*itr);
603 success = true;
604 }
605 return success;
606 }
607
608 if (id != source_id_audio_ && id == source_id_video_) {
609 // Only include ranges that have been buffered in |video_|
610 SourceBufferStream::TimespanList video_ranges = video_->GetBufferedTime();
611 for (SourceBufferStream::TimespanList::iterator itr = video_ranges.begin();
612 itr != video_ranges.end(); ++itr) {
613 ranges_out->push_back(*itr);
614 success = true;
615 }
616 return success;
617 }
618
619 // Include ranges that have been buffered in both |audio_| and |video_|.
620 SourceBufferStream::TimespanList audio_ranges = audio_->GetBufferedTime();
621 SourceBufferStream::TimespanList video_ranges = video_->GetBufferedTime();
622 SourceBufferStream::TimespanList::const_iterator video_ranges_itr =
623 video_ranges.begin();
624 SourceBufferStream::TimespanList::const_iterator audio_ranges_itr =
625 audio_ranges.begin();
626
627 while (audio_ranges_itr != audio_ranges.end() &&
628 video_ranges_itr != video_ranges.end()) {
629
acolwell GONE FROM CHROMIUM 2012/06/12 22:48:13 Precompute the "last ranges" condition into a bool
annacc 2012/06/13 00:00:01 Done.
630 // Audio range start time is within the video range.
631 if ((*audio_ranges_itr).first >= (*video_ranges_itr).first &&
632 (*audio_ranges_itr).first <= (*video_ranges_itr).second) {
633 AddIntersectionRange(audio_ranges_itr, video_ranges_itr,
acolwell GONE FROM CHROMIUM 2012/06/12 22:48:13 How about passing in *xxx_itr instead of the itera
annacc 2012/06/13 00:00:01 I think I've realized your suggestion here, but yo
634 audio_ranges.end(), video_ranges.end(),
635 ranges_out);
636 success = true;
637 continue;
638 }
639
640 // Video range start time is within the audio range.
641 if ((*video_ranges_itr).first >= (*audio_ranges_itr).first &&
642 (*video_ranges_itr).first <= (*audio_ranges_itr).second) {
643 AddIntersectionRange(video_ranges_itr, audio_ranges_itr,
644 video_ranges.end(), audio_ranges.end(),
645 ranges_out);
646 success = true;
647 continue;
648 }
649
650 // No overlap was found. Increment the smallest one and keep looking.
acolwell GONE FROM CHROMIUM 2012/06/12 22:48:13 nit: smallest -> earliest?
annacc 2012/06/13 00:00:01 Done.
651 if ((*audio_ranges_itr).first < (*video_ranges_itr).first)
652 audio_ranges_itr++;
653 else
654 video_ranges_itr++;
655 }
656
657 return success;
658 }
659
660 void ChunkDemuxer::AddIntersectionRange(
661 SourceBufferStream::TimespanList::const_iterator& itr_a,
662 SourceBufferStream::TimespanList::const_iterator& itr_b,
663 SourceBufferStream::TimespanList::const_iterator itr_a_end,
664 SourceBufferStream::TimespanList::const_iterator itr_b_end,
665 Ranges* ranges_out) const {
666 base::TimeDelta start = (*itr_a).first;
667
668 // If this is the last range and EndOfStream() was called (i.e. all data
669 // has been appended), choose the max end point of the ranges.
670 base::TimeDelta end;
671 if (state_ == ENDED &&
672 next(itr_a) == itr_a_end &&
acolwell GONE FROM CHROMIUM 2012/06/12 22:48:13 nit: Use (itr_a + 1) instead.
annacc 2012/06/13 00:00:01 Done.
673 next(itr_b) == itr_b_end) {
674 end = std::max((*itr_a).second, (*itr_b).second);
675 } else {
676 end = std::min((*itr_a).second, (*itr_b).second);
677 }
678
679 ranges_out->push_back(std::make_pair(start, end));
680
681 itr_a++;
682 }
683
684 SourceBufferStream::TimespanList::const_iterator ChunkDemuxer::next(
acolwell GONE FROM CHROMIUM 2012/06/12 22:48:13 nit: I'd prefer you use (itr + 1) instead of defin
annacc 2012/06/13 00:00:01 Done.
685 SourceBufferStream::TimespanList::const_iterator itr) const {
686 return ++itr;
589 } 687 }
590 688
591 bool ChunkDemuxer::AppendData(const std::string& id, 689 bool ChunkDemuxer::AppendData(const std::string& id,
592 const uint8* data, 690 const uint8* data,
593 size_t length) { 691 size_t length) {
594 DVLOG(1) << "AppendData(" << id << ", " << length << ")"; 692 DVLOG(1) << "AppendData(" << id << ", " << length << ")";
595 693
596 DCHECK(!id.empty()); 694 DCHECK(!id.empty());
597 DCHECK(data); 695 DCHECK(data);
598 DCHECK_GT(length, 0u); 696 DCHECK_GT(length, 0u);
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
885 return true; 983 return true;
886 } 984 }
887 985
888 bool ChunkDemuxer::OnKeyNeeded(scoped_array<uint8> init_data, 986 bool ChunkDemuxer::OnKeyNeeded(scoped_array<uint8> init_data,
889 int init_data_size) { 987 int init_data_size) {
890 client_->KeyNeeded(init_data.Pass(), init_data_size); 988 client_->KeyNeeded(init_data.Pass(), init_data_size);
891 return true; 989 return true;
892 } 990 }
893 991
894 } // namespace media 992 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698