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

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: final nits 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
« no previous file with comments | « media/filters/chunk_demuxer.h ('k') | media/filters/chunk_demuxer_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_);
586 595
587 // TODO(annacc): Calculate buffered ranges (http://crbug.com/129852 ). 596 if (id == source_id_audio_ && id != source_id_video_) {
588 return false; 597 // Only include ranges that have been buffered in |audio_|
598 return CopyIntoRanges(audio_->GetBufferedTime(), ranges_out);
599 }
600
601 if (id != source_id_audio_ && id == source_id_video_) {
602 // Only include ranges that have been buffered in |video_|
603 return CopyIntoRanges(video_->GetBufferedTime(), ranges_out);
604 }
605
606 // Include ranges that have been buffered in both |audio_| and |video_|.
607 SourceBufferStream::TimespanList audio_ranges = audio_->GetBufferedTime();
608 SourceBufferStream::TimespanList video_ranges = video_->GetBufferedTime();
609 SourceBufferStream::TimespanList::const_iterator video_ranges_itr =
610 video_ranges.begin();
611 SourceBufferStream::TimespanList::const_iterator audio_ranges_itr =
612 audio_ranges.begin();
613 bool success = false;
614
615 while (audio_ranges_itr != audio_ranges.end() &&
616 video_ranges_itr != video_ranges.end()) {
617 // If this is the last range and EndOfStream() was called (i.e. all data
618 // has been appended), choose the max end point of the ranges.
619 bool last_range_after_ended =
620 state_ == ENDED &&
621 (audio_ranges_itr + 1) == audio_ranges.end() &&
622 (video_ranges_itr + 1) == video_ranges.end();
623
624 // Audio range start time is within the video range.
625 if ((*audio_ranges_itr).first >= (*video_ranges_itr).first &&
626 (*audio_ranges_itr).first <= (*video_ranges_itr).second) {
627 AddIntersectionRange(*audio_ranges_itr, *video_ranges_itr,
628 last_range_after_ended, ranges_out);
629 audio_ranges_itr++;
630 success = true;
631 continue;
632 }
633
634 // Video range start time is within the audio range.
635 if ((*video_ranges_itr).first >= (*audio_ranges_itr).first &&
636 (*video_ranges_itr).first <= (*audio_ranges_itr).second) {
637 AddIntersectionRange(*video_ranges_itr, *audio_ranges_itr,
638 last_range_after_ended, ranges_out);
639 video_ranges_itr++;
640 success = true;
641 continue;
642 }
643
644 // No overlap was found. Increment the earliest one and keep looking.
645 if ((*audio_ranges_itr).first < (*video_ranges_itr).first)
646 audio_ranges_itr++;
647 else
648 video_ranges_itr++;
649 }
650
651 return success;
652 }
653
654 bool ChunkDemuxer::CopyIntoRanges(
655 const SourceBufferStream::TimespanList& timespans,
656 Ranges* ranges_out) const {
657 for (SourceBufferStream::TimespanList::const_iterator itr = timespans.begin();
658 itr != timespans.end(); ++itr) {
659 ranges_out->push_back(*itr);
660 }
661 return !timespans.empty();
662 }
663
664 void ChunkDemuxer::AddIntersectionRange(
665 SourceBufferStream::Timespan timespan_a,
666 SourceBufferStream::Timespan timespan_b,
667 bool last_range_after_ended,
668 Ranges* ranges_out) const {
669 base::TimeDelta start = timespan_a.first;
670
671 // If this is the last range after EndOfStream() was called, choose the later
672 // end point of the ranges, otherwise choose the earlier.
673 base::TimeDelta end;
674 if (last_range_after_ended)
675 end = std::max(timespan_a.second, timespan_b.second);
676 else
677 end = std::min(timespan_a.second, timespan_b.second);
678
679 ranges_out->push_back(std::make_pair(start, end));
589 } 680 }
590 681
591 bool ChunkDemuxer::AppendData(const std::string& id, 682 bool ChunkDemuxer::AppendData(const std::string& id,
592 const uint8* data, 683 const uint8* data,
593 size_t length) { 684 size_t length) {
594 DVLOG(1) << "AppendData(" << id << ", " << length << ")"; 685 DVLOG(1) << "AppendData(" << id << ", " << length << ")";
595 686
596 DCHECK(!id.empty()); 687 DCHECK(!id.empty());
597 DCHECK(data); 688 DCHECK(data);
598 DCHECK_GT(length, 0u); 689 DCHECK_GT(length, 0u);
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
885 return true; 976 return true;
886 } 977 }
887 978
888 bool ChunkDemuxer::OnKeyNeeded(scoped_array<uint8> init_data, 979 bool ChunkDemuxer::OnKeyNeeded(scoped_array<uint8> init_data,
889 int init_data_size) { 980 int init_data_size) {
890 client_->KeyNeeded(init_data.Pass(), init_data_size); 981 client_->KeyNeeded(init_data.Pass(), init_data_size);
891 return true; 982 return true;
892 } 983 }
893 984
894 } // namespace media 985 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/chunk_demuxer.h ('k') | media/filters/chunk_demuxer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698