| 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.
|
|
|