Index: media/filters/chunk_demuxer.cc |
diff --git a/media/filters/chunk_demuxer.cc b/media/filters/chunk_demuxer.cc |
index 29e31af00d7aae8f5fc64596f357c770e4af7136..06aadb609e188af3aea3c76014fe36c7f14b40b2 100644 |
--- a/media/filters/chunk_demuxer.cc |
+++ b/media/filters/chunk_demuxer.cc |
@@ -499,8 +499,7 @@ ChunkDemuxer::ChunkDemuxer(ChunkDemuxerClient* client) |
DCHECK(client); |
} |
-void ChunkDemuxer::Initialize(DemuxerHost* host, |
- const PipelineStatusCB& cb) { |
+void ChunkDemuxer::Initialize(DemuxerHost* host, const PipelineStatusCB& cb) { |
DVLOG(1) << "Init()"; |
{ |
base::AutoLock auto_lock(lock_); |
@@ -938,15 +937,13 @@ void ChunkDemuxer::OnStreamParserInitDone(bool success, TimeDelta duration) { |
} |
if (duration > duration_) |
acolwell GONE FROM CHROMIUM
2012/07/30 21:37:45
I believe the new spec text specifies that only th
vrk (LEFT CHROMIUM)
2012/07/31 22:39:01
Changed to if (duration != base::TimeDelta() && du
|
- duration_ = duration; |
+ UpdateDuration(duration); |
// Wait until all streams have initialized. |
if ((!source_id_audio_.empty() && !audio_) || |
(!source_id_video_.empty() && !video_)) |
return; |
- host_->SetDuration(duration_); |
- |
ChangeState_Locked(WAITING_FOR_START_TIME); |
} |
@@ -1005,7 +1002,11 @@ bool ChunkDemuxer::OnAudioBuffers(const StreamParser::BufferQueue& buffers) { |
AdjustBufferTimestamps( |
buffers, source_info_map_[source_id_audio_].timestamp_offset); |
- return audio_->Append(buffers); |
+ if (!audio_->Append(buffers)) |
+ return false; |
+ |
+ IncreaseDurationIfNecessary(buffers, audio_); |
+ return true; |
} |
bool ChunkDemuxer::OnVideoBuffers(const StreamParser::BufferQueue& buffers) { |
@@ -1019,7 +1020,11 @@ bool ChunkDemuxer::OnVideoBuffers(const StreamParser::BufferQueue& buffers) { |
AdjustBufferTimestamps( |
buffers, source_info_map_[source_id_video_].timestamp_offset); |
- return video_->Append(buffers); |
+ if (!video_->Append(buffers)) |
+ return false; |
+ |
+ IncreaseDurationIfNecessary(buffers, video_); |
+ return true; |
} |
bool ChunkDemuxer::OnNeedKey(scoped_array<uint8> init_data, |
@@ -1044,6 +1049,13 @@ void ChunkDemuxer::OnNewMediaSegment(const std::string& source_id, |
// Use the first reported media segment start time as the |start_time_| |
// for the demuxer. |
start_time_ = start_timestamp; |
+ |
+ // Ensure |duration_| is never before |start_time_|. |
+ // TODO(vrk): We have to do this because there are places in the code that |
+ // assumes the media duration is the same as the end time of the media |
+ // stream. Fix this once crbug.com/137275 is addressed. |
+ if (start_time_ > duration_) |
+ UpdateDuration(start_time_); |
} |
if (audio_ && source_id == source_id_audio_) |
@@ -1093,4 +1105,25 @@ bool ChunkDemuxer::IsValidId(const std::string& source_id) const { |
stream_parser_map_.count(source_id) > 0u; |
} |
+void ChunkDemuxer::UpdateDuration(base::TimeDelta new_duration) { |
+ DCHECK(duration_ != new_duration); |
+ duration_ = new_duration; |
+ host_->SetDuration(new_duration); |
+} |
+ |
+void ChunkDemuxer::IncreaseDurationIfNecessary( |
+ const StreamParser::BufferQueue& buffers, |
+ const scoped_refptr<ChunkDemuxerStream>& stream) { |
+ DCHECK(!buffers.empty()); |
+ if (buffers.back()->GetTimestamp() <= duration_) |
+ return; |
+ |
+ Ranges<TimeDelta> ranges = stream->GetBufferedRanges(); |
+ DCHECK_GT(ranges.size(), 0u); |
+ |
+ base::TimeDelta last_timestamp_buffered = ranges.end(ranges.size() - 1); |
+ if (last_timestamp_buffered > duration_) |
+ UpdateDuration(last_timestamp_buffered); |
+} |
+ |
} // namespace media |