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

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: response to CR 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_);
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
acolwell GONE FROM CHROMIUM 2012/06/13 00:33:40 nit: remove blank line
annacc 2012/06/13 03:35:43 Done.
618 // If this is the last range and EndOfStream() was called (i.e. all data
619 // has been appended), choose the max end point of the ranges.
620 bool last_range_after_ended =
621 state_ == ENDED &&
622 (audio_ranges_itr + 1) == audio_ranges.end() &&
623 (video_ranges_itr + 1) == video_ranges.end();
624
625 // Audio range start time is within the video range.
626 if ((*audio_ranges_itr).first >= (*video_ranges_itr).first &&
627 (*audio_ranges_itr).first <= (*video_ranges_itr).second) {
628 AddIntersectionRange(*audio_ranges_itr, *video_ranges_itr,
629 last_range_after_ended, ranges_out);
630 audio_ranges_itr++;
631 success = true;
632 continue;
633 }
634
635 // Video range start time is within the audio range.
636 if ((*video_ranges_itr).first >= (*audio_ranges_itr).first &&
637 (*video_ranges_itr).first <= (*audio_ranges_itr).second) {
638 AddIntersectionRange(*video_ranges_itr, *audio_ranges_itr,
639 last_range_after_ended, ranges_out);
640 video_ranges_itr++;
641 success = true;
642 continue;
643 }
644
645 // No overlap was found. Increment the earliest one and keep looking.
646 if ((*audio_ranges_itr).first < (*video_ranges_itr).first)
647 audio_ranges_itr++;
648 else
649 video_ranges_itr++;
650 }
651
652 return success;
653 }
654
655 bool ChunkDemuxer::CopyIntoRanges(
656 const SourceBufferStream::TimespanList& timespans,
657 Ranges* ranges_out) const {
658 bool success = false;
659 for (SourceBufferStream::TimespanList::const_iterator itr = timespans.begin();
660 itr != timespans.end(); ++itr) {
661 ranges_out->push_back(*itr);
662 success = true;
663 }
664 return success;
acolwell GONE FROM CHROMIUM 2012/06/13 00:33:40 nit: You can use !timestamps.empty() here instead.
annacc 2012/06/13 03:35:43 Done.
665 }
666
667 void ChunkDemuxer::AddIntersectionRange(
668 SourceBufferStream::Timespan timespan_a,
669 SourceBufferStream::Timespan timespan_b,
670 bool last_range_after_ended,
671 Ranges* ranges_out) const {
672 base::TimeDelta start = timespan_a.first;
673
674 // If this is the last range after EndOfStream() was called, choose the later
675 // end point of the ranges, otherwise choose the earlier.
676 base::TimeDelta end;
677 if (last_range_after_ended)
678 end = std::max(timespan_a.second, timespan_b.second);
679 else
680 end = std::min(timespan_a.second, timespan_b.second);
681
682 ranges_out->push_back(std::make_pair(start, end));
589 } 683 }
590 684
591 bool ChunkDemuxer::AppendData(const std::string& id, 685 bool ChunkDemuxer::AppendData(const std::string& id,
592 const uint8* data, 686 const uint8* data,
593 size_t length) { 687 size_t length) {
594 DVLOG(1) << "AppendData(" << id << ", " << length << ")"; 688 DVLOG(1) << "AppendData(" << id << ", " << length << ")";
595 689
596 DCHECK(!id.empty()); 690 DCHECK(!id.empty());
597 DCHECK(data); 691 DCHECK(data);
598 DCHECK_GT(length, 0u); 692 DCHECK_GT(length, 0u);
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
885 return true; 979 return true;
886 } 980 }
887 981
888 bool ChunkDemuxer::OnKeyNeeded(scoped_array<uint8> init_data, 982 bool ChunkDemuxer::OnKeyNeeded(scoped_array<uint8> init_data,
889 int init_data_size) { 983 int init_data_size) {
890 client_->KeyNeeded(init_data.Pass(), init_data_size); 984 client_->KeyNeeded(init_data.Pass(), init_data_size);
891 return true; 985 return true;
892 } 986 }
893 987
894 } // namespace media 988 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698