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

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

Issue 2645953004: Update duration when demuxed packets exceed known duration. (Closed)
Patch Set: Remux and encode test.ogv. Fixes bad duration. Created 3 years, 11 months 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
« no previous file with comments | « media/filters/ffmpeg_demuxer.h ('k') | media/filters/ffmpeg_demuxer_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 548 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 demuxer_->NotifyBufferingChanged(); 559 demuxer_->NotifyBufferingChanged();
560 } 560 }
561 } 561 }
562 562
563 if (packet.get()->flags & AV_PKT_FLAG_KEY) 563 if (packet.get()->flags & AV_PKT_FLAG_KEY)
564 buffer->set_is_key_frame(true); 564 buffer->set_is_key_frame(true);
565 565
566 last_packet_timestamp_ = buffer->timestamp(); 566 last_packet_timestamp_ = buffer->timestamp();
567 last_packet_duration_ = buffer->duration(); 567 last_packet_duration_ = buffer->duration();
568 568
569 const base::TimeDelta new_duration = last_packet_timestamp_;
chcunningham 2017/01/23 19:14:10 Should this be last_packet_timestamp_ + last_packe
DaleCurtis 2017/01/24 02:05:19 Adding duration explodes a lot of stuff in our tes
570 if (new_duration > duration_ || duration_ == kNoTimestamp)
571 duration_ = new_duration;
572
569 buffer_queue_.Push(buffer); 573 buffer_queue_.Push(buffer);
570 SatisfyPendingRead(); 574 SatisfyPendingRead();
571 } 575 }
572 576
573 void FFmpegDemuxerStream::SetEndOfStream() { 577 void FFmpegDemuxerStream::SetEndOfStream() {
574 DCHECK(task_runner_->BelongsToCurrentThread()); 578 DCHECK(task_runner_->BelongsToCurrentThread());
575 end_of_stream_ = true; 579 end_of_stream_ = true;
576 SatisfyPendingRead(); 580 SatisfyPendingRead();
577 } 581 }
578 582
(...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after
1438 SetLiveness(DemuxerStream::LIVENESS_LIVE); 1442 SetLiveness(DemuxerStream::LIVENESS_LIVE);
1439 } else if (max_duration != kInfiniteDuration) { 1443 } else if (max_duration != kInfiniteDuration) {
1440 SetLiveness(DemuxerStream::LIVENESS_RECORDED); 1444 SetLiveness(DemuxerStream::LIVENESS_RECORDED);
1441 } else { 1445 } else {
1442 SetLiveness(DemuxerStream::LIVENESS_UNKNOWN); 1446 SetLiveness(DemuxerStream::LIVENESS_UNKNOWN);
1443 } 1447 }
1444 1448
1445 // Good to go: set the duration and bitrate and notify we're done 1449 // Good to go: set the duration and bitrate and notify we're done
1446 // initializing. 1450 // initializing.
1447 host_->SetDuration(max_duration); 1451 host_->SetDuration(max_duration);
1452 duration_ = max_duration;
1448 duration_known_ = (max_duration != kInfiniteDuration); 1453 duration_known_ = (max_duration != kInfiniteDuration);
1449 1454
1450 int64_t filesize_in_bytes = 0; 1455 int64_t filesize_in_bytes = 0;
1451 url_protocol_->GetSize(&filesize_in_bytes); 1456 url_protocol_->GetSize(&filesize_in_bytes);
1452 bitrate_ = CalculateBitrate(format_context, max_duration, filesize_in_bytes); 1457 bitrate_ = CalculateBitrate(format_context, max_duration, filesize_in_bytes);
1453 if (bitrate_ > 0) 1458 if (bitrate_ > 0)
1454 data_source_->SetBitrate(bitrate_); 1459 data_source_->SetBitrate(bitrate_);
1455 1460
1456 LogMetadata(format_context, max_duration); 1461 LogMetadata(format_context, max_duration);
1457 media_tracks_updated_cb_.Run(std::move(media_tracks)); 1462 media_tracks_updated_cb_.Run(std::move(media_tracks));
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
1699 1704
1700 if (!blocking_thread_.IsRunning() || !pending_seek_cb_.is_null()) 1705 if (!blocking_thread_.IsRunning() || !pending_seek_cb_.is_null())
1701 return; 1706 return;
1702 1707
1703 // Consider the stream as ended if: 1708 // Consider the stream as ended if:
1704 // - either underlying ffmpeg returned an error 1709 // - either underlying ffmpeg returned an error
1705 // - or FFMpegDemuxer reached the maximum allowed memory usage. 1710 // - or FFMpegDemuxer reached the maximum allowed memory usage.
1706 if (result < 0 || IsMaxMemoryUsageReached()) { 1711 if (result < 0 || IsMaxMemoryUsageReached()) {
1707 DVLOG(1) << __func__ << " result=" << result 1712 DVLOG(1) << __func__ << " result=" << result
1708 << " IsMaxMemoryUsageReached=" << IsMaxMemoryUsageReached(); 1713 << " IsMaxMemoryUsageReached=" << IsMaxMemoryUsageReached();
1709 // Update the duration based on the highest elapsed time across all streams 1714 // Update the duration based on the highest elapsed time across all streams.
1710 // if it was previously unknown. 1715 base::TimeDelta max_duration;
1711 if (!duration_known_) { 1716 for (const auto& stream : streams_) {
1712 base::TimeDelta max_duration; 1717 if (!stream)
1718 continue;
1713 1719
1714 for (const auto& stream : streams_) { 1720 base::TimeDelta duration =
1715 if (!stream) 1721 duration_known_ ? stream->duration() : stream->GetElapsedTime();
chcunningham 2017/01/23 19:14:10 It seems like now that stream->duration() is autom
DaleCurtis 2017/01/24 02:05:19 This fails a couple tests, so I'll take a closer l
1716 continue; 1722 if (duration != kNoTimestamp && duration > max_duration)
1723 max_duration = duration;
1724 }
1717 1725
1718 base::TimeDelta duration = stream->GetElapsedTime(); 1726 if (duration_ == kInfiniteDuration || max_duration > duration_) {
1719 if (duration != kNoTimestamp && duration > max_duration) 1727 host_->SetDuration(max_duration);
1720 max_duration = duration; 1728 duration_known_ = true;
1721 } 1729 duration_ = max_duration;
1730 }
1722 1731
1723 if (max_duration > base::TimeDelta()) {
1724 host_->SetDuration(max_duration);
1725 duration_known_ = true;
1726 }
1727 }
1728 // If we have reached the end of stream, tell the downstream filters about 1732 // If we have reached the end of stream, tell the downstream filters about
1729 // the event. 1733 // the event.
1730 StreamHasEnded(); 1734 StreamHasEnded();
1731 return; 1735 return;
1732 } 1736 }
1733 1737
1734 // Queue the packet with the appropriate stream. 1738 // Queue the packet with the appropriate stream.
1735 DCHECK_GE(packet->stream_index, 0); 1739 DCHECK_GE(packet->stream_index, 0);
1736 DCHECK_LT(packet->stream_index, static_cast<int>(streams_.size())); 1740 DCHECK_LT(packet->stream_index, static_cast<int>(streams_.size()));
1737 1741
1738 // Defend against ffmpeg giving us a bad stream index. 1742 // Defend against ffmpeg giving us a bad stream index.
1739 if (packet->stream_index >= 0 && 1743 if (packet->stream_index >= 0 &&
1740 packet->stream_index < static_cast<int>(streams_.size()) && 1744 packet->stream_index < static_cast<int>(streams_.size()) &&
1741 streams_[packet->stream_index]) { 1745 streams_[packet->stream_index]) {
1742 // TODO(scherkus): Fix demuxing upstream to never return packets w/o data 1746 // TODO(scherkus): Fix demuxing upstream to never return packets w/o data
1743 // when av_read_frame() returns success code. See bug comment for ideas: 1747 // when av_read_frame() returns success code. See bug comment for ideas:
1744 // 1748 //
1745 // https://code.google.com/p/chromium/issues/detail?id=169133#c10 1749 // https://code.google.com/p/chromium/issues/detail?id=169133#c10
1746 if (!packet->data) { 1750 if (!packet->data) {
1747 ScopedAVPacket new_packet(new AVPacket()); 1751 ScopedAVPacket new_packet(new AVPacket());
1748 av_new_packet(new_packet.get(), 0); 1752 av_new_packet(new_packet.get(), 0);
1749 av_packet_copy_props(new_packet.get(), packet.get()); 1753 av_packet_copy_props(new_packet.get(), packet.get());
1750 packet.swap(new_packet); 1754 packet.swap(new_packet);
1751 } 1755 }
1752 1756
1753 FFmpegDemuxerStream* demuxer_stream = streams_[packet->stream_index].get(); 1757 FFmpegDemuxerStream* demuxer_stream = streams_[packet->stream_index].get();
1754 if (demuxer_stream->enabled()) 1758 if (demuxer_stream->enabled())
1755 demuxer_stream->EnqueuePacket(std::move(packet)); 1759 demuxer_stream->EnqueuePacket(std::move(packet));
1760
1761 // If duration estimate was incorrect, update it and tell higher layers.
1762 if (duration_known_) {
1763 const base::TimeDelta duration = demuxer_stream->duration();
1764 if (duration != kNoTimestamp && duration > duration_) {
1765 duration_ = duration;
1766 host_->SetDuration(duration_);
1767 }
1768 }
1756 } 1769 }
1757 1770
1758 // Keep reading until we've reached capacity. 1771 // Keep reading until we've reached capacity.
1759 ReadFrameIfNeeded(); 1772 ReadFrameIfNeeded();
1760 } 1773 }
1761 1774
1762 bool FFmpegDemuxer::StreamsHaveAvailableCapacity() { 1775 bool FFmpegDemuxer::StreamsHaveAvailableCapacity() {
1763 DCHECK(task_runner_->BelongsToCurrentThread()); 1776 DCHECK(task_runner_->BelongsToCurrentThread());
1764 for (const auto& stream : streams_) { 1777 for (const auto& stream : streams_) {
1765 if (stream && stream->HasAvailableCapacity()) 1778 if (stream && stream->HasAvailableCapacity())
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1808 1821
1809 void FFmpegDemuxer::SetLiveness(DemuxerStream::Liveness liveness) { 1822 void FFmpegDemuxer::SetLiveness(DemuxerStream::Liveness liveness) {
1810 DCHECK(task_runner_->BelongsToCurrentThread()); 1823 DCHECK(task_runner_->BelongsToCurrentThread());
1811 for (const auto& stream : streams_) { 1824 for (const auto& stream : streams_) {
1812 if (stream) 1825 if (stream)
1813 stream->SetLiveness(liveness); 1826 stream->SetLiveness(liveness);
1814 } 1827 }
1815 } 1828 }
1816 1829
1817 } // namespace media 1830 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/ffmpeg_demuxer.h ('k') | media/filters/ffmpeg_demuxer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698