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

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

Issue 2440563004: Switch to using an explicit ended signal instead of time comparison. (Closed)
Patch Set: Fix ended event in ARI. Created 4 years, 1 month 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
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/ffmpeg_demuxer.h" 5 #include "media/filters/ffmpeg_demuxer.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <memory> 8 #include <memory>
9 #include <set> 9 #include <set>
10 #include <utility> 10 #include <utility>
(...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 demuxer_->NotifyBufferingChanged(); 566 demuxer_->NotifyBufferingChanged();
567 } 567 }
568 } 568 }
569 569
570 if (packet.get()->flags & AV_PKT_FLAG_KEY) 570 if (packet.get()->flags & AV_PKT_FLAG_KEY)
571 buffer->set_is_key_frame(true); 571 buffer->set_is_key_frame(true);
572 572
573 last_packet_timestamp_ = buffer->timestamp(); 573 last_packet_timestamp_ = buffer->timestamp();
574 last_packet_duration_ = buffer->duration(); 574 last_packet_duration_ = buffer->duration();
575 575
576 const base::TimeDelta new_duration =
577 last_packet_timestamp_ + last_packet_duration_;
578 if (new_duration > duration_ || duration_ == kNoTimestamp)
579 duration_ = new_duration;
580
576 buffer_queue_.Push(buffer); 581 buffer_queue_.Push(buffer);
577 SatisfyPendingRead(); 582 SatisfyPendingRead();
578 } 583 }
579 584
580 void FFmpegDemuxerStream::SetEndOfStream() { 585 void FFmpegDemuxerStream::SetEndOfStream() {
581 DCHECK(task_runner_->BelongsToCurrentThread()); 586 DCHECK(task_runner_->BelongsToCurrentThread());
582 end_of_stream_ = true; 587 end_of_stream_ = true;
583 SatisfyPendingRead(); 588 SatisfyPendingRead();
584 } 589 }
585 590
(...skipping 855 matching lines...) Expand 10 before | Expand all | Expand 10 after
1441 SetLiveness(DemuxerStream::LIVENESS_LIVE); 1446 SetLiveness(DemuxerStream::LIVENESS_LIVE);
1442 } else if (max_duration != kInfiniteDuration) { 1447 } else if (max_duration != kInfiniteDuration) {
1443 SetLiveness(DemuxerStream::LIVENESS_RECORDED); 1448 SetLiveness(DemuxerStream::LIVENESS_RECORDED);
1444 } else { 1449 } else {
1445 SetLiveness(DemuxerStream::LIVENESS_UNKNOWN); 1450 SetLiveness(DemuxerStream::LIVENESS_UNKNOWN);
1446 } 1451 }
1447 1452
1448 // Good to go: set the duration and bitrate and notify we're done 1453 // Good to go: set the duration and bitrate and notify we're done
1449 // initializing. 1454 // initializing.
1450 host_->SetDuration(max_duration); 1455 host_->SetDuration(max_duration);
1456 duration_ = max_duration;
1451 duration_known_ = (max_duration != kInfiniteDuration); 1457 duration_known_ = (max_duration != kInfiniteDuration);
1452 1458
1453 int64_t filesize_in_bytes = 0; 1459 int64_t filesize_in_bytes = 0;
1454 url_protocol_->GetSize(&filesize_in_bytes); 1460 url_protocol_->GetSize(&filesize_in_bytes);
1455 bitrate_ = CalculateBitrate(format_context, max_duration, filesize_in_bytes); 1461 bitrate_ = CalculateBitrate(format_context, max_duration, filesize_in_bytes);
1456 if (bitrate_ > 0) 1462 if (bitrate_ > 0)
1457 data_source_->SetBitrate(bitrate_); 1463 data_source_->SetBitrate(bitrate_);
1458 1464
1459 LogMetadata(format_context, max_duration); 1465 LogMetadata(format_context, max_duration);
1460 media_tracks_updated_cb_.Run(std::move(media_tracks)); 1466 media_tracks_updated_cb_.Run(std::move(media_tracks));
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
1676 1682
1677 if (!blocking_thread_.IsRunning() || !pending_seek_cb_.is_null()) 1683 if (!blocking_thread_.IsRunning() || !pending_seek_cb_.is_null())
1678 return; 1684 return;
1679 1685
1680 // Consider the stream as ended if: 1686 // Consider the stream as ended if:
1681 // - either underlying ffmpeg returned an error 1687 // - either underlying ffmpeg returned an error
1682 // - or FFMpegDemuxer reached the maximum allowed memory usage. 1688 // - or FFMpegDemuxer reached the maximum allowed memory usage.
1683 if (result < 0 || IsMaxMemoryUsageReached()) { 1689 if (result < 0 || IsMaxMemoryUsageReached()) {
1684 DVLOG(1) << __func__ << " result=" << result 1690 DVLOG(1) << __func__ << " result=" << result
1685 << " IsMaxMemoryUsageReached=" << IsMaxMemoryUsageReached(); 1691 << " IsMaxMemoryUsageReached=" << IsMaxMemoryUsageReached();
1686 // Update the duration based on the highest elapsed time across all streams 1692 // Update the duration based on the highest elapsed time across all streams.
1687 // if it was previously unknown. 1693 base::TimeDelta max_duration;
1688 if (!duration_known_) { 1694 for (const auto& stream : streams_) {
1689 base::TimeDelta max_duration; 1695 if (!stream)
1696 continue;
1690 1697
1691 for (const auto& stream : streams_) { 1698 base::TimeDelta duration =
1692 if (!stream) 1699 duration_known_ ? stream->duration() : stream->GetElapsedTime();
1693 continue; 1700 if (duration != kNoTimestamp && duration > max_duration)
1701 max_duration = duration;
1702 }
1694 1703
1695 base::TimeDelta duration = stream->GetElapsedTime(); 1704 if (duration_ == kInfiniteDuration || max_duration > duration_) {
1696 if (duration != kNoTimestamp && duration > max_duration) 1705 host_->SetDuration(max_duration);
1697 max_duration = duration; 1706 duration_known_ = true;
1698 } 1707 duration_ = max_duration;
1708 }
1699 1709
1700 if (max_duration > base::TimeDelta()) {
1701 host_->SetDuration(max_duration);
1702 duration_known_ = true;
1703 }
1704 }
1705 // If we have reached the end of stream, tell the downstream filters about 1710 // If we have reached the end of stream, tell the downstream filters about
1706 // the event. 1711 // the event.
1707 StreamHasEnded(); 1712 StreamHasEnded();
1708 return; 1713 return;
1709 } 1714 }
1710 1715
1711 // Queue the packet with the appropriate stream. 1716 // Queue the packet with the appropriate stream.
1712 DCHECK_GE(packet->stream_index, 0); 1717 DCHECK_GE(packet->stream_index, 0);
1713 DCHECK_LT(packet->stream_index, static_cast<int>(streams_.size())); 1718 DCHECK_LT(packet->stream_index, static_cast<int>(streams_.size()));
1714 1719
1715 // Defend against ffmpeg giving us a bad stream index. 1720 // Defend against ffmpeg giving us a bad stream index.
1716 if (packet->stream_index >= 0 && 1721 if (packet->stream_index >= 0 &&
1717 packet->stream_index < static_cast<int>(streams_.size()) && 1722 packet->stream_index < static_cast<int>(streams_.size()) &&
1718 streams_[packet->stream_index]) { 1723 streams_[packet->stream_index]) {
1719 // TODO(scherkus): Fix demuxing upstream to never return packets w/o data 1724 // TODO(scherkus): Fix demuxing upstream to never return packets w/o data
1720 // when av_read_frame() returns success code. See bug comment for ideas: 1725 // when av_read_frame() returns success code. See bug comment for ideas:
1721 // 1726 //
1722 // https://code.google.com/p/chromium/issues/detail?id=169133#c10 1727 // https://code.google.com/p/chromium/issues/detail?id=169133#c10
1723 if (!packet->data) { 1728 if (!packet->data) {
1724 ScopedAVPacket new_packet(new AVPacket()); 1729 ScopedAVPacket new_packet(new AVPacket());
1725 av_new_packet(new_packet.get(), 0); 1730 av_new_packet(new_packet.get(), 0);
1726 av_packet_copy_props(new_packet.get(), packet.get()); 1731 av_packet_copy_props(new_packet.get(), packet.get());
1727 packet.swap(new_packet); 1732 packet.swap(new_packet);
1728 } 1733 }
1729 1734
1730 FFmpegDemuxerStream* demuxer_stream = streams_[packet->stream_index].get(); 1735 FFmpegDemuxerStream* demuxer_stream = streams_[packet->stream_index].get();
1731 if (demuxer_stream->enabled()) 1736 if (demuxer_stream->enabled())
1732 demuxer_stream->EnqueuePacket(std::move(packet)); 1737 demuxer_stream->EnqueuePacket(std::move(packet));
1738
1739 // If duration estimate was incorrect, update it and tell higher layers.
1740 if (duration_known_) {
1741 const base::TimeDelta duration = demuxer_stream->duration();
1742 if (duration != kNoTimestamp && duration > duration_) {
1743 duration_ = duration;
1744 host_->SetDuration(duration_);
1745 }
1746 }
1733 } 1747 }
1734 1748
1735 // Keep reading until we've reached capacity. 1749 // Keep reading until we've reached capacity.
1736 ReadFrameIfNeeded(); 1750 ReadFrameIfNeeded();
1737 } 1751 }
1738 1752
1739 bool FFmpegDemuxer::StreamsHaveAvailableCapacity() { 1753 bool FFmpegDemuxer::StreamsHaveAvailableCapacity() {
1740 DCHECK(task_runner_->BelongsToCurrentThread()); 1754 DCHECK(task_runner_->BelongsToCurrentThread());
1741 for (const auto& stream : streams_) { 1755 for (const auto& stream : streams_) {
1742 if (stream && stream->HasAvailableCapacity()) 1756 if (stream && stream->HasAvailableCapacity())
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1779 1793
1780 void FFmpegDemuxer::SetLiveness(DemuxerStream::Liveness liveness) { 1794 void FFmpegDemuxer::SetLiveness(DemuxerStream::Liveness liveness) {
1781 DCHECK(task_runner_->BelongsToCurrentThread()); 1795 DCHECK(task_runner_->BelongsToCurrentThread());
1782 for (const auto& stream : streams_) { 1796 for (const auto& stream : streams_) {
1783 if (stream) 1797 if (stream)
1784 stream->SetLiveness(liveness); 1798 stream->SetLiveness(liveness);
1785 } 1799 }
1786 } 1800 }
1787 1801
1788 } // namespace media 1802 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698