Index: media/filters/ffmpeg_demuxer.cc |
diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc |
index 2e296516203378ffdd5809ef496c3570bec4e262..5815724fadb0362fe43e2f26f780e75ace1ac64e 100644 |
--- a/media/filters/ffmpeg_demuxer.cc |
+++ b/media/filters/ffmpeg_demuxer.cc |
@@ -573,6 +573,11 @@ void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) { |
last_packet_timestamp_ = buffer->timestamp(); |
last_packet_duration_ = buffer->duration(); |
+ const base::TimeDelta new_duration = |
+ last_packet_timestamp_ + last_packet_duration_; |
+ if (new_duration > duration_ || duration_ == kNoTimestamp) |
+ duration_ = new_duration; |
+ |
buffer_queue_.Push(buffer); |
SatisfyPendingRead(); |
} |
@@ -1448,6 +1453,7 @@ void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb, |
// Good to go: set the duration and bitrate and notify we're done |
// initializing. |
host_->SetDuration(max_duration); |
+ duration_ = max_duration; |
duration_known_ = (max_duration != kInfiniteDuration); |
int64_t filesize_in_bytes = 0; |
@@ -1683,25 +1689,24 @@ void FFmpegDemuxer::OnReadFrameDone(ScopedAVPacket packet, int result) { |
if (result < 0 || IsMaxMemoryUsageReached()) { |
DVLOG(1) << __func__ << " result=" << result |
<< " IsMaxMemoryUsageReached=" << IsMaxMemoryUsageReached(); |
- // Update the duration based on the highest elapsed time across all streams |
- // if it was previously unknown. |
- if (!duration_known_) { |
- base::TimeDelta max_duration; |
- |
- for (const auto& stream : streams_) { |
- if (!stream) |
- continue; |
+ // Update the duration based on the highest elapsed time across all streams. |
+ base::TimeDelta max_duration; |
+ for (const auto& stream : streams_) { |
+ if (!stream) |
+ continue; |
- base::TimeDelta duration = stream->GetElapsedTime(); |
- if (duration != kNoTimestamp && duration > max_duration) |
- max_duration = duration; |
- } |
+ base::TimeDelta duration = |
+ duration_known_ ? stream->duration() : stream->GetElapsedTime(); |
+ if (duration != kNoTimestamp && duration > max_duration) |
+ max_duration = duration; |
+ } |
- if (max_duration > base::TimeDelta()) { |
- host_->SetDuration(max_duration); |
- duration_known_ = true; |
- } |
+ if (duration_ == kInfiniteDuration || max_duration > duration_) { |
+ host_->SetDuration(max_duration); |
+ duration_known_ = true; |
+ duration_ = max_duration; |
} |
+ |
// If we have reached the end of stream, tell the downstream filters about |
// the event. |
StreamHasEnded(); |
@@ -1730,6 +1735,15 @@ void FFmpegDemuxer::OnReadFrameDone(ScopedAVPacket packet, int result) { |
FFmpegDemuxerStream* demuxer_stream = streams_[packet->stream_index].get(); |
if (demuxer_stream->enabled()) |
demuxer_stream->EnqueuePacket(std::move(packet)); |
+ |
+ // If duration estimate was incorrect, update it and tell higher layers. |
+ if (duration_known_) { |
+ const base::TimeDelta duration = demuxer_stream->duration(); |
+ if (duration != kNoTimestamp && duration > duration_) { |
+ duration_ = duration; |
+ host_->SetDuration(duration_); |
+ } |
+ } |
} |
// Keep reading until we've reached capacity. |