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

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

Issue 10829108: Cap sourceBuffered() on duration and truncate duration on EoS (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Updated test Created 8 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 (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/callback_helpers.h" 8 #include "base/callback_helpers.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/message_loop.h" 10 #include "base/message_loop.h"
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 void EndOfStream(); 192 void EndOfStream();
193 bool CanEndOfStream() const; 193 bool CanEndOfStream() const;
194 void Shutdown(); 194 void Shutdown();
195 195
196 // DemuxerStream methods. 196 // DemuxerStream methods.
197 virtual void Read(const ReadCB& read_cb) OVERRIDE; 197 virtual void Read(const ReadCB& read_cb) OVERRIDE;
198 virtual Type type() OVERRIDE; 198 virtual Type type() OVERRIDE;
199 virtual void EnableBitstreamConverter() OVERRIDE; 199 virtual void EnableBitstreamConverter() OVERRIDE;
200 virtual const AudioDecoderConfig& audio_decoder_config() OVERRIDE; 200 virtual const AudioDecoderConfig& audio_decoder_config() OVERRIDE;
201 virtual const VideoDecoderConfig& video_decoder_config() OVERRIDE; 201 virtual const VideoDecoderConfig& video_decoder_config() OVERRIDE;
202 virtual Ranges<TimeDelta> GetBufferedRanges() OVERRIDE; 202
203 // Returns the range of buffered data in this stream, capped at |duration|.
204 Ranges<TimeDelta> GetBufferedRanges(base::TimeDelta duration) const;
acolwell GONE FROM CHROMIUM 2012/08/01 17:09:45 nit: perhaps move this just below Append() so it's
vrk (LEFT CHROMIUM) 2012/08/02 18:23:00 Done.
203 205
204 protected: 206 protected:
205 virtual ~ChunkDemuxerStream(); 207 virtual ~ChunkDemuxerStream();
206 208
207 private: 209 private:
208 enum State { 210 enum State {
209 RETURNING_DATA_FOR_READS, 211 RETURNING_DATA_FOR_READS,
210 WAITING_FOR_SEEK, 212 WAITING_FOR_SEEK,
211 SHUTDOWN, 213 SHUTDOWN,
212 }; 214 };
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 } 313 }
312 CreateReadDoneClosures_Locked(&closures); 314 CreateReadDoneClosures_Locked(&closures);
313 } 315 }
314 316
315 for (ClosureQueue::iterator it = closures.begin(); it != closures.end(); ++it) 317 for (ClosureQueue::iterator it = closures.begin(); it != closures.end(); ++it)
316 it->Run(); 318 it->Run();
317 319
318 return true; 320 return true;
319 } 321 }
320 322
321 Ranges<TimeDelta> ChunkDemuxerStream::GetBufferedRanges() { 323 Ranges<TimeDelta> ChunkDemuxerStream::GetBufferedRanges(
324 base::TimeDelta duration) const {
322 base::AutoLock auto_lock(lock_); 325 base::AutoLock auto_lock(lock_);
323 return stream_->GetBufferedTime(); 326 Ranges<TimeDelta> range = stream_->GetBufferedTime();
327
328 Ranges<TimeDelta> valid_time_range;
329 valid_time_range.Add(base::TimeDelta(), duration);
acolwell GONE FROM CHROMIUM 2012/08/01 17:09:45 I think base::TimeDelta() needs to be start_time_
330 return range.IntersectionWith(valid_time_range);
acolwell GONE FROM CHROMIUM 2012/08/01 17:09:45 \o/ look who's being tricky. I like it, but this d
vrk (LEFT CHROMIUM) 2012/08/02 18:23:00 haha glad you like! :) commented!
324 } 331 }
325 332
326 bool ChunkDemuxerStream::UpdateAudioConfig(const AudioDecoderConfig& config) { 333 bool ChunkDemuxerStream::UpdateAudioConfig(const AudioDecoderConfig& config) {
327 DCHECK(config.IsValidConfig()); 334 DCHECK(config.IsValidConfig());
328 DCHECK_EQ(type_, AUDIO); 335 DCHECK_EQ(type_, AUDIO);
329 return stream_->UpdateAudioConfig(config); 336 return stream_->UpdateAudioConfig(config);
330 } 337 }
331 338
332 bool ChunkDemuxerStream::UpdateVideoConfig(const VideoDecoderConfig& config) { 339 bool ChunkDemuxerStream::UpdateVideoConfig(const VideoDecoderConfig& config) {
333 DCHECK(config.IsValidConfig()); 340 DCHECK(config.IsValidConfig());
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 671
665 Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges(const std::string& id) const { 672 Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges(const std::string& id) const {
666 DCHECK(!id.empty()); 673 DCHECK(!id.empty());
667 DCHECK(IsValidId(id)); 674 DCHECK(IsValidId(id));
668 DCHECK(id == source_id_audio_ || id == source_id_video_); 675 DCHECK(id == source_id_audio_ || id == source_id_video_);
669 676
670 base::AutoLock auto_lock(lock_); 677 base::AutoLock auto_lock(lock_);
671 678
672 if (id == source_id_audio_ && id != source_id_video_) { 679 if (id == source_id_audio_ && id != source_id_video_) {
673 // Only include ranges that have been buffered in |audio_| 680 // Only include ranges that have been buffered in |audio_|
674 return audio_ ? audio_->GetBufferedRanges() : Ranges<TimeDelta>(); 681 return audio_ ? audio_->GetBufferedRanges(duration_) : Ranges<TimeDelta>();
675 } 682 }
676 683
677 if (id != source_id_audio_ && id == source_id_video_) { 684 if (id != source_id_audio_ && id == source_id_video_) {
678 // Only include ranges that have been buffered in |video_| 685 // Only include ranges that have been buffered in |video_|
679 return video_ ? video_->GetBufferedRanges() : Ranges<TimeDelta>(); 686 return video_ ? video_->GetBufferedRanges(duration_) : Ranges<TimeDelta>();
680 } 687 }
681 688
682 return ComputeIntersection(); 689 return ComputeIntersection();
683 } 690 }
684 691
685 Ranges<TimeDelta> ChunkDemuxer::ComputeIntersection() const { 692 Ranges<TimeDelta> ChunkDemuxer::ComputeIntersection() const {
686 lock_.AssertAcquired(); 693 lock_.AssertAcquired();
687 694
688 if (!audio_ || !video_) 695 if (!audio_ || !video_)
689 return Ranges<TimeDelta>(); 696 return Ranges<TimeDelta>();
690 697
691 // Include ranges that have been buffered in both |audio_| and |video_|. 698 // Include ranges that have been buffered in both |audio_| and |video_|.
692 Ranges<TimeDelta> audio_ranges = audio_->GetBufferedRanges(); 699 Ranges<TimeDelta> audio_ranges = audio_->GetBufferedRanges(duration_);
693 Ranges<TimeDelta> video_ranges = video_->GetBufferedRanges(); 700 Ranges<TimeDelta> video_ranges = video_->GetBufferedRanges(duration_);
694 Ranges<TimeDelta> result = audio_ranges.IntersectionWith(video_ranges); 701 Ranges<TimeDelta> result = audio_ranges.IntersectionWith(video_ranges);
695 702
696 if (state_ == ENDED && result.size() > 0) { 703 if (state_ == ENDED && result.size() > 0) {
697 // If appending has ended, extend the last intersection range to include the 704 // If appending has ended, extend the last intersection range to include the
698 // max end time of the last audio/video range. This allows the buffered 705 // max end time of the last audio/video range. This allows the buffered
699 // information to match the actual time range that will get played out if 706 // information to match the actual time range that will get played out if
700 // the streams have slightly different lengths. 707 // the streams have slightly different lengths.
701 TimeDelta audio_start = audio_ranges.start(audio_ranges.size() - 1); 708 TimeDelta audio_start = audio_ranges.start(audio_ranges.size() - 1);
702 TimeDelta audio_end = audio_ranges.end(audio_ranges.size() - 1); 709 TimeDelta audio_end = audio_ranges.end(audio_ranges.size() - 1);
703 TimeDelta video_start = video_ranges.start(video_ranges.size() - 1); 710 TimeDelta video_start = video_ranges.start(video_ranges.size() - 1);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
756 DVLOG(1) << "AppendData(): called in unexpected state " << state_; 763 DVLOG(1) << "AppendData(): called in unexpected state " << state_;
757 return false; 764 return false;
758 } 765 }
759 766
760 // Check to see if data was appended at the pending seek point. This 767 // Check to see if data was appended at the pending seek point. This
761 // indicates we have parsed enough data to complete the seek. 768 // indicates we have parsed enough data to complete the seek.
762 if (old_seek_pending && !IsSeekPending_Locked() && !seek_cb_.is_null()) { 769 if (old_seek_pending && !IsSeekPending_Locked() && !seek_cb_.is_null()) {
763 std::swap(cb, seek_cb_); 770 std::swap(cb, seek_cb_);
764 } 771 }
765 772
766 if (audio_ && !video_) { 773 ranges = GetBufferedRanges();
767 ranges = audio_->GetBufferedRanges();
768 } else if (!audio_ && video_) {
769 ranges = video_->GetBufferedRanges();
770 } else {
771 ranges = ComputeIntersection();
772 }
773 } 774 }
774 775
775 for (size_t i = 0; i < ranges.size(); ++i) 776 for (size_t i = 0; i < ranges.size(); ++i)
776 host_->AddBufferedTimeRange(ranges.start(i), ranges.end(i)); 777 host_->AddBufferedTimeRange(ranges.start(i), ranges.end(i));
777 778
778 if (!cb.is_null()) 779 if (!cb.is_null())
779 cb.Run(PIPELINE_OK); 780 cb.Run(PIPELINE_OK);
780 781
781 return true; 782 return true;
782 } 783 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
818 819
819 if (!CanEndOfStream_Locked() && status == PIPELINE_OK) 820 if (!CanEndOfStream_Locked() && status == PIPELINE_OK)
820 return false; 821 return false;
821 822
822 if (audio_) 823 if (audio_)
823 audio_->EndOfStream(); 824 audio_->EndOfStream();
824 825
825 if (video_) 826 if (video_)
826 video_->EndOfStream(); 827 video_->EndOfStream();
827 828
828 if (status != PIPELINE_OK) 829 if (status != PIPELINE_OK) {
829 ReportError_Locked(status); 830 ReportError_Locked(status);
830 else 831 } else {
831 ChangeState_Locked(ENDED); 832 ChangeState_Locked(ENDED);
833 DecreaseDurationIfNecessary();
834 }
832 835
833 return true; 836 return true;
834 } 837 }
835 838
836 void ChunkDemuxer::Shutdown() { 839 void ChunkDemuxer::Shutdown() {
837 DVLOG(1) << "Shutdown()"; 840 DVLOG(1) << "Shutdown()";
838 PipelineStatusCB cb; 841 PipelineStatusCB cb;
839 { 842 {
840 base::AutoLock auto_lock(lock_); 843 base::AutoLock auto_lock(lock_);
841 844
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
1114 host_->SetDuration(new_duration); 1117 host_->SetDuration(new_duration);
1115 } 1118 }
1116 1119
1117 void ChunkDemuxer::IncreaseDurationIfNecessary( 1120 void ChunkDemuxer::IncreaseDurationIfNecessary(
1118 const StreamParser::BufferQueue& buffers, 1121 const StreamParser::BufferQueue& buffers,
1119 const scoped_refptr<ChunkDemuxerStream>& stream) { 1122 const scoped_refptr<ChunkDemuxerStream>& stream) {
1120 DCHECK(!buffers.empty()); 1123 DCHECK(!buffers.empty());
1121 if (buffers.back()->GetTimestamp() <= duration_) 1124 if (buffers.back()->GetTimestamp() <= duration_)
1122 return; 1125 return;
1123 1126
1124 Ranges<TimeDelta> ranges = stream->GetBufferedRanges(); 1127 Ranges<TimeDelta> ranges = stream->GetBufferedRanges(kInfiniteDuration());
1125 DCHECK_GT(ranges.size(), 0u); 1128 DCHECK_GT(ranges.size(), 0u);
1126 1129
1127 base::TimeDelta last_timestamp_buffered = ranges.end(ranges.size() - 1); 1130 base::TimeDelta last_timestamp_buffered = ranges.end(ranges.size() - 1);
1128 if (last_timestamp_buffered > duration_) 1131 if (last_timestamp_buffered > duration_)
1129 UpdateDuration(last_timestamp_buffered); 1132 UpdateDuration(last_timestamp_buffered);
1130 } 1133 }
1131 1134
1135 void ChunkDemuxer::DecreaseDurationIfNecessary() {
1136 Ranges<TimeDelta> ranges = GetBufferedRanges();
1137 if (ranges.size() == 0u)
1138 return;
1139
1140 base::TimeDelta last_timestamp_buffered = ranges.end(ranges.size() - 1);
1141 if (last_timestamp_buffered < duration_)
1142 UpdateDuration(last_timestamp_buffered);
1143 }
1144
1145 Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges() const {
vrk (LEFT CHROMIUM) 2012/08/01 00:10:06 This CL adds this guy back again; if it's still ov
acolwell GONE FROM CHROMIUM 2012/08/01 17:09:45 No this is fine here. My original complaint was it
vrk (LEFT CHROMIUM) 2012/08/02 18:23:00 SG!
1146 if (audio_ && !video_)
1147 return audio_->GetBufferedRanges(duration_);
1148 else if (!audio_ && video_)
1149 return video_->GetBufferedRanges(duration_);
1150 return ComputeIntersection();
1151 }
1152
1132 } // namespace media 1153 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698