| Index: media/filters/chunk_demuxer.cc
|
| diff --git a/media/filters/chunk_demuxer.cc b/media/filters/chunk_demuxer.cc
|
| index 29e31af00d7aae8f5fc64596f357c770e4af7136..b1c238940d38405c4e079fb0d60c8cefbf3b41f0 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_);
|
| @@ -937,16 +936,14 @@ void ChunkDemuxer::OnStreamParserInitDone(bool success, TimeDelta duration) {
|
| return;
|
| }
|
|
|
| - if (duration > duration_)
|
| - duration_ = duration;
|
| + if (duration != base::TimeDelta() && duration_ == base::TimeDelta())
|
| + 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_)
|
| @@ -1063,6 +1075,9 @@ void ChunkDemuxer::OnNewMediaSegment(const std::string& source_id,
|
| video_->Seek(start_time_);
|
| }
|
|
|
| + if (duration_ == base::TimeDelta())
|
| + duration_ = kInfiniteDuration();
|
| +
|
| // The demuxer is now initialized after the |start_timestamp_| was set.
|
| ChangeState_Locked(INITIALIZED);
|
| base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK);
|
| @@ -1093,4 +1108,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
|
|
|