diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-09-12 10:27:29 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-09-12 08:34:13 +0000 |
commit | 53d399fe6415a96ea6986ec0d402a9c07da72453 (patch) | |
tree | ce7dbd5d170326a7d1c5f69f5dcd841c178e0dc0 /chromium/media | |
parent | a3ee7849e3b0ad3d5f9595fa1cfd694c22dcee2a (diff) | |
download | qtwebengine-chromium-53d399fe6415a96ea6986ec0d402a9c07da72453.tar.gz |
BASELINE: Update Chromium to 60.0.3112.116 and Ninja to 1.8.2
Also adds a few devtools and webui files needed for new features.
Change-Id: I431976cc9f4c209d062a925ab6a5d63ec61abcfe
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/media')
19 files changed, 111 insertions, 334 deletions
diff --git a/chromium/media/base/media_switches.cc b/chromium/media/base/media_switches.cc index d3a6b60d6e5..c612c4a36d9 100644 --- a/chromium/media/base/media_switches.cc +++ b/chromium/media/base/media_switches.cc @@ -220,10 +220,6 @@ const base::Feature kMojoCdm{"MojoCdm", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kNewRemotePlaybackPipeline{ "NewRemotePlaybackPipeline", base::FEATURE_DISABLED_BY_DEFAULT}; -// CanPlayThrough issued according to standard. -const base::Feature kSpecCompliantCanPlayThrough{ - "CanPlayThrough", base::FEATURE_DISABLED_BY_DEFAULT}; - // Use shared block-based buffering for media. const base::Feature kUseNewMediaCache{"use-new-media-cache", base::FEATURE_ENABLED_BY_DEFAULT}; diff --git a/chromium/media/base/media_switches.h b/chromium/media/base/media_switches.h index cfef8cf6b43..6ef4f301cbb 100644 --- a/chromium/media/base/media_switches.h +++ b/chromium/media/base/media_switches.h @@ -111,7 +111,6 @@ MEDIA_EXPORT extern const base::Feature kNewAudioRenderingMixingStrategy; MEDIA_EXPORT extern const base::Feature kNewRemotePlaybackPipeline; MEDIA_EXPORT extern const base::Feature kOverlayFullscreenVideo; MEDIA_EXPORT extern const base::Feature kResumeBackgroundVideo; -MEDIA_EXPORT extern const base::Feature kSpecCompliantCanPlayThrough; MEDIA_EXPORT extern const base::Feature kUseAndroidOverlay; MEDIA_EXPORT extern const base::Feature kUseNewMediaCache; MEDIA_EXPORT extern const base::Feature kVideoBlitColorAccuracy; diff --git a/chromium/media/blink/buffered_data_source_host_impl.cc b/chromium/media/blink/buffered_data_source_host_impl.cc index 1b4f8723f7a..30542adcf37 100644 --- a/chromium/media/blink/buffered_data_source_host_impl.cc +++ b/chromium/media/blink/buffered_data_source_host_impl.cc @@ -8,28 +8,9 @@ namespace media { -// We want a relatively small window for estimating bandwidth, -// that way we don't need to worry too much about seeks and pause -// throwing off the estimates. -constexpr base::TimeDelta kDownloadHistoryWindowSeconds = - base::TimeDelta::FromSecondsD(10.0); - -// Limit the number of entries in the rate estimator queue. -// 1024 entries should be more than enough. -constexpr size_t kDownloadHistoryMaxEntries = 1024; - -// Just in case someone gives progress one byte at a time, -// let's aggregate progress updates together until we reach -// at least this many bytes. -constexpr int64_t kDownloadHistoryMinBytesPerEntry = 1000; - -BufferedDataSourceHostImpl::BufferedDataSourceHostImpl( - base::RepeatingClosure progress_cb, - base::TickClock* tick_clock) +BufferedDataSourceHostImpl::BufferedDataSourceHostImpl() : total_bytes_(0), - did_loading_progress_(false), - progress_cb_(std::move(progress_cb)), - tick_clock_(tick_clock) {} + did_loading_progress_(false) { } BufferedDataSourceHostImpl::~BufferedDataSourceHostImpl() { } @@ -37,56 +18,15 @@ void BufferedDataSourceHostImpl::SetTotalBytes(int64_t total_bytes) { total_bytes_ = total_bytes; } -int64_t BufferedDataSourceHostImpl::UnloadedBytesInInterval( - const Interval<int64_t>& interval) const { - int64_t bytes = 0; - auto i = buffered_byte_ranges_.find(interval.begin); - while (i != buffered_byte_ranges_.end()) { - if (i.interval_begin() >= interval.end) - break; - if (!i.value()) { - Interval<int64_t> intersection = i.interval().Intersect(interval); - if (!intersection.Empty()) - bytes += intersection.end - intersection.begin; - } - ++i; - } - return bytes; -} - void BufferedDataSourceHostImpl::AddBufferedByteRange(int64_t start, int64_t end) { - int64_t new_bytes = UnloadedBytesInInterval(Interval<int64_t>(start, end)); - if (new_bytes == 0) { + const auto i = buffered_byte_ranges_.find(start); + if (i.value() && i.interval_end() >= end) { // No change return; } buffered_byte_ranges_.SetInterval(start, end, 1); did_loading_progress_ = true; - - base::TimeTicks now = tick_clock_->NowTicks(); - int64_t bytes_so_far = 0; - if (!download_history_.empty()) - bytes_so_far = download_history_.back().second; - bytes_so_far += new_bytes; - - // If the difference between the last entry and the second to last entry is - // less than kDownloadHistoryMinBytesPerEntry, just overwrite the last entry. - if (download_history_.size() > 1 && - download_history_.back().second - (download_history_.end() - 2)->second < - kDownloadHistoryMinBytesPerEntry) { - download_history_.back() = std::make_pair(now, bytes_so_far); - } else { - download_history_.emplace_back(now, bytes_so_far); - } - DCHECK_GE(download_history_.size(), 1u); - // Drop entries that are too old. - while (download_history_.size() > kDownloadHistoryMaxEntries || - download_history_.back().first - download_history_.front().first > - kDownloadHistoryWindowSeconds) { - download_history_.pop_front(); - } - progress_cb_.Run(); } static base::TimeDelta TimeForByteOffset(int64_t byte_offset, @@ -126,65 +66,4 @@ bool BufferedDataSourceHostImpl::DidLoadingProgress() { return ret; } -double BufferedDataSourceHostImpl::DownloadRate() const { - // If the download history is really small, any estimate we make is going to - // be wildly inaccurate, so let's not make any estimates until we have more - // data. - if (download_history_.size() < 5) - return 0.0; - - // The data we get is bursty, so we get multiple measuring points very close - // together. These bursts will often lead us to over-estimate the download - // rate. By iterating over the beginning of the time series and picking the - // data point that has the lowest download rate, we avoid over-estimating. - const double kVeryLargeRate = 1.0E20; - double download_rate = kVeryLargeRate; - for (int i = 0; i < std::min<int>(20, download_history_.size() - 3); i++) { - int64_t downloaded_bytes = - download_history_.back().second - download_history_[i].second; - base::TimeTicks now = tick_clock_->NowTicks(); - base::TimeDelta downloaded_seconds = now - download_history_[i].first; - if (downloaded_seconds <= base::TimeDelta()) - continue; - download_rate = std::min( - download_rate, downloaded_bytes / downloaded_seconds.InSecondsF()); - } - return download_rate == kVeryLargeRate ? 0.0 : download_rate; -} - -bool BufferedDataSourceHostImpl::CanPlayThrough( - base::TimeDelta current_position, - base::TimeDelta media_duration, - double playback_rate) const { - DCHECK_GE(playback_rate, 0); - if (!total_bytes_ || media_duration <= base::TimeDelta() || - media_duration == kInfiniteDuration) { - return false; - } - if (current_position > media_duration) - return true; - double fraction = current_position.InSecondsF() / media_duration.InSecondsF(); - int64_t byte_pos = total_bytes_ * fraction; - if (byte_pos < 0) - byte_pos = 0; - - int64_t unloaded_bytes = - UnloadedBytesInInterval(Interval<int64_t>(byte_pos, total_bytes_)); - - if (unloaded_bytes == 0) - return true; - - double download_rate = DownloadRate(); - if (download_rate <= 0.0) - return false; - - return unloaded_bytes / download_rate < - (media_duration - current_position).InSecondsF() / playback_rate; -} - -void BufferedDataSourceHostImpl::SetTickClockForTest( - base::TickClock* tick_clock) { - tick_clock_ = tick_clock; -} - } // namespace media diff --git a/chromium/media/blink/buffered_data_source_host_impl.h b/chromium/media/blink/buffered_data_source_host_impl.h index 5f37f762d13..7dc39ea331a 100644 --- a/chromium/media/blink/buffered_data_source_host_impl.h +++ b/chromium/media/blink/buffered_data_source_host_impl.h @@ -6,12 +6,8 @@ #define MEDIA_BLINK_BUFFERED_DATA_SOURCE_HOST_IMPL_H_ #include <stdint.h> -#include <deque> -#include "base/callback.h" -#include "base/gtest_prod_util.h" #include "base/macros.h" -#include "base/time/tick_clock.h" #include "base/time/time.h" #include "media/base/ranges.h" #include "media/blink/interval_map.h" @@ -39,8 +35,7 @@ class MEDIA_BLINK_EXPORT BufferedDataSourceHost { class MEDIA_BLINK_EXPORT BufferedDataSourceHostImpl : public BufferedDataSourceHost { public: - BufferedDataSourceHostImpl(base::Closure progress_cb, - base::TickClock* tick_clock); + BufferedDataSourceHostImpl(); ~BufferedDataSourceHostImpl() override; // BufferedDataSourceHost implementation. @@ -55,23 +50,7 @@ class MEDIA_BLINK_EXPORT BufferedDataSourceHostImpl bool DidLoadingProgress(); - // Returns true if we have enough buffered bytes to play from now - // until the end of media - bool CanPlayThrough(base::TimeDelta current_position, - base::TimeDelta media_duration, - double playback_rate) const; - - // Caller must make sure |tick_clock| is valid for lifetime of this object. - void SetTickClockForTest(base::TickClock* tick_clock); - private: - // Returns number of bytes not yet loaded in the given interval. - int64_t UnloadedBytesInInterval(const Interval<int64_t>& interval) const; - - // Returns an estimate of the download rate. - // Returns 0.0 if an estimate cannot be made. - double DownloadRate() const; - // Total size of the data source. int64_t total_bytes_; @@ -83,16 +62,6 @@ class MEDIA_BLINK_EXPORT BufferedDataSourceHostImpl // DidLoadingProgress(). bool did_loading_progress_; - // Contains how much we had downloaded at a given time. - // Pruned to contain roughly the last 10 seconds of data. - std::deque<std::pair<base::TimeTicks, uint64_t>> download_history_; - base::Closure progress_cb_; - - base::TickClock* tick_clock_; - - FRIEND_TEST_ALL_PREFIXES(BufferedDataSourceHostImplTest, CanPlayThrough); - FRIEND_TEST_ALL_PREFIXES(BufferedDataSourceHostImplTest, - CanPlayThroughSmallAdvances); DISALLOW_COPY_AND_ASSIGN(BufferedDataSourceHostImpl); }; diff --git a/chromium/media/blink/buffered_data_source_host_impl_unittest.cc b/chromium/media/blink/buffered_data_source_host_impl_unittest.cc index b6717d52ac0..54ecf75c3b6 100644 --- a/chromium/media/blink/buffered_data_source_host_impl_unittest.cc +++ b/chromium/media/blink/buffered_data_source_host_impl_unittest.cc @@ -2,33 +2,23 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "media/blink/buffered_data_source_host_impl.h" - -#include "base/bind.h" #include "base/macros.h" -#include "base/test/simple_test_tick_clock.h" +#include "media/blink/buffered_data_source_host_impl.h" #include "testing/gtest/include/gtest/gtest.h" namespace media { class BufferedDataSourceHostImplTest : public testing::Test { public: - BufferedDataSourceHostImplTest() - : host_(base::Bind(&BufferedDataSourceHostImplTest::ProgressCallback, - base::Unretained(this)), - &clock_) {} + BufferedDataSourceHostImplTest() {} void Add() { host_.AddBufferedTimeRanges(&ranges_, base::TimeDelta::FromSeconds(10)); } - void ProgressCallback() { progress_callback_calls_++; } - protected: - int progress_callback_calls_ = 0; BufferedDataSourceHostImpl host_; Ranges<base::TimeDelta> ranges_; - base::SimpleTestTickClock clock_; DISALLOW_COPY_AND_ASSIGN(BufferedDataSourceHostImplTest); }; @@ -83,72 +73,4 @@ TEST_F(BufferedDataSourceHostImplTest, DidLoadingProgress) { EXPECT_FALSE(host_.DidLoadingProgress()); } -TEST_F(BufferedDataSourceHostImplTest, CanPlayThrough) { - host_.SetTotalBytes(100000); - EXPECT_EQ(100000, - host_.UnloadedBytesInInterval(Interval<int64_t>(0, 100000))); - host_.AddBufferedByteRange(0, 10000); - clock_.Advance(base::TimeDelta::FromSeconds(1)); - host_.AddBufferedByteRange(10000, 20000); - clock_.Advance(base::TimeDelta::FromSeconds(1)); - host_.AddBufferedByteRange(20000, 30000); - clock_.Advance(base::TimeDelta::FromSeconds(1)); - host_.AddBufferedByteRange(30000, 40000); - clock_.Advance(base::TimeDelta::FromSeconds(1)); - host_.AddBufferedByteRange(40000, 50000); - clock_.Advance(base::TimeDelta::FromSeconds(1)); - EXPECT_EQ(50000, host_.UnloadedBytesInInterval(Interval<int64_t>(0, 100000))); - host_.AddBufferedByteRange(50000, 60000); - clock_.Advance(base::TimeDelta::FromSeconds(1)); - host_.AddBufferedByteRange(60000, 70000); - clock_.Advance(base::TimeDelta::FromSeconds(1)); - host_.AddBufferedByteRange(70000, 80000); - clock_.Advance(base::TimeDelta::FromSeconds(1)); - host_.AddBufferedByteRange(80000, 90000); - // Download rate is allowed to be estimated low, but not high. - EXPECT_LE(host_.DownloadRate(), 10000.0f); - EXPECT_GE(host_.DownloadRate(), 9000.0f); - EXPECT_EQ(10000, host_.UnloadedBytesInInterval(Interval<int64_t>(0, 100000))); - EXPECT_EQ(9, progress_callback_calls_); - // If the video is 0.1s we can't play through. - EXPECT_FALSE(host_.CanPlayThrough(base::TimeDelta(), - base::TimeDelta::FromSecondsD(0.01), 1.0)); - // If the video is 1000s we can play through. - EXPECT_TRUE(host_.CanPlayThrough(base::TimeDelta(), - base::TimeDelta::FromSecondsD(1000.0), 1.0)); - // No more downloads for 1000 seconds... - clock_.Advance(base::TimeDelta::FromSeconds(1000)); - // Can't play through.. - EXPECT_FALSE(host_.CanPlayThrough(base::TimeDelta(), - base::TimeDelta::FromSecondsD(100.0), 1.0)); - host_.AddBufferedByteRange(90000, 100000); - clock_.Advance(base::TimeDelta::FromSeconds(1)); - EXPECT_EQ(0, host_.UnloadedBytesInInterval(Interval<int64_t>(0, 100000))); - - // Media is fully downloaded, so we can certainly play through, even if - // we only have 0.01 seconds to do it. - EXPECT_TRUE(host_.CanPlayThrough(base::TimeDelta(), - base::TimeDelta::FromSecondsD(0.01), 1.0)); -} - -TEST_F(BufferedDataSourceHostImplTest, CanPlayThroughSmallAdvances) { - host_.SetTotalBytes(20000); - EXPECT_EQ(20000, host_.UnloadedBytesInInterval(Interval<int64_t>(0, 20000))); - for (int j = 1; j <= 100; j++) { - host_.AddBufferedByteRange(0, j * 100); - clock_.Advance(base::TimeDelta::FromSecondsD(0.01)); - } - // Download rate is allowed to be estimated low, but not high. - EXPECT_LE(host_.DownloadRate(), 10000.0f); - EXPECT_GE(host_.DownloadRate(), 9000.0f); - EXPECT_EQ(10000, host_.UnloadedBytesInInterval(Interval<int64_t>(0, 20000))); - EXPECT_EQ(100, progress_callback_calls_); - // If the video is 0.1s we can't play through. - EXPECT_FALSE(host_.CanPlayThrough(base::TimeDelta(), - base::TimeDelta::FromSecondsD(0.01), 1.0)); - // If the video is 1000s we can play through. - EXPECT_TRUE(host_.CanPlayThrough(base::TimeDelta(), - base::TimeDelta::FromSecondsD(1000.0), 1.0)); -} - } // namespace media diff --git a/chromium/media/blink/webmediaplayer_impl.cc b/chromium/media/blink/webmediaplayer_impl.cc index 26aa00e1f76..d4c16dacec1 100644 --- a/chromium/media/blink/webmediaplayer_impl.cc +++ b/chromium/media/blink/webmediaplayer_impl.cc @@ -220,10 +220,6 @@ WebMediaPlayerImpl::WebMediaPlayerImpl( last_reported_memory_usage_(0), supports_save_(true), chunk_demuxer_(NULL), - tick_clock_(new base::DefaultTickClock()), - buffered_data_source_host_( - base::Bind(&WebMediaPlayerImpl::OnProgress, AsWeakPtr()), - tick_clock_.get()), url_index_(url_index), // Threaded compositing isn't enabled universally yet. compositor_task_runner_(params->compositor_task_runner() @@ -259,6 +255,8 @@ WebMediaPlayerImpl::WebMediaPlayerImpl( DCHECK(client_); DCHECK(delegate_); + tick_clock_.reset(new base::DefaultTickClock()); + force_video_overlays_ = base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kForceVideoOverlays); @@ -897,7 +895,24 @@ bool WebMediaPlayerImpl::DidLoadingProgress() { // Note: Separate variables used to ensure both methods are called every time. const bool pipeline_progress = pipeline_controller_.DidLoadingProgress(); const bool data_progress = buffered_data_source_host_.DidLoadingProgress(); - return pipeline_progress || data_progress; + const bool did_loading_progress = pipeline_progress || data_progress; + + if (did_loading_progress && + highest_ready_state_ < ReadyState::kReadyStateHaveFutureData) { + // Reset the preroll attempt clock. + preroll_attempt_pending_ = true; + preroll_attempt_start_time_ = base::TimeTicks(); + + // Clear any 'stale' flag and give the pipeline a chance to resume. If we + // are already resumed, this will cause |preroll_attempt_start_time_| to be + // set. + // TODO(sandersd): Should this be on the same stack? It might be surprising + // that didLoadingProgress() can synchronously change state. + delegate_->ClearStaleFlag(delegate_id_); + UpdatePlayState(); + } + + return did_loading_progress; } void WebMediaPlayerImpl::Paint(blink::WebCanvas* canvas, @@ -1323,41 +1338,6 @@ void WebMediaPlayerImpl::OnMetadata(PipelineMetadata metadata) { UpdatePlayState(); } -void WebMediaPlayerImpl::OnProgress() { - DVLOG(4) << __func__; - if (highest_ready_state_ < ReadyState::kReadyStateHaveFutureData) { - // Reset the preroll attempt clock. - preroll_attempt_pending_ = true; - preroll_attempt_start_time_ = base::TimeTicks(); - - // Clear any 'stale' flag and give the pipeline a chance to resume. If we - // are already resumed, this will cause |preroll_attempt_start_time_| to - // be set. - delegate_->ClearStaleFlag(delegate_id_); - UpdatePlayState(); - } else if (ready_state_ == ReadyState::kReadyStateHaveFutureData && - CanPlayThrough()) { - SetReadyState(WebMediaPlayer::kReadyStateHaveEnoughData); - } -} - -bool WebMediaPlayerImpl::CanPlayThrough() { - if (!base::FeatureList::IsEnabled(kSpecCompliantCanPlayThrough)) - return true; - if (chunk_demuxer_) - return true; - if (data_source_ && data_source_->assume_fully_buffered()) - return true; - // If we're not currently downloading, we have as much buffer as - // we're ever going to get, which means we say we can play through. - if (network_state_ == WebMediaPlayer::kNetworkStateIdle) - return true; - return buffered_data_source_host_.CanPlayThrough( - base::TimeDelta::FromSecondsD(CurrentTime()), - base::TimeDelta::FromSecondsD(Duration()), - playback_rate_ == 0.0 ? 1.0 : playback_rate_); -} - void WebMediaPlayerImpl::OnBufferingStateChange(BufferingState state) { DVLOG(1) << __func__ << "(" << state << ")"; DCHECK(main_task_runner_->BelongsToCurrentThread()); @@ -1377,8 +1357,9 @@ void WebMediaPlayerImpl::OnBufferingStateChange(BufferingState state) { RecordUnderflowDuration(base::TimeDelta()); } - SetReadyState(CanPlayThrough() ? WebMediaPlayer::kReadyStateHaveEnoughData - : WebMediaPlayer::kReadyStateHaveFutureData); + // TODO(chcunningham): Monitor playback position vs buffered. Potentially + // transition to HAVE_FUTURE_DATA here if not enough is buffered. + SetReadyState(WebMediaPlayer::kReadyStateHaveEnoughData); // Let the DataSource know we have enough data. It may use this information // to release unused network connections. @@ -1716,14 +1697,12 @@ void WebMediaPlayerImpl::DataSourceInitialized(bool success) { } void WebMediaPlayerImpl::NotifyDownloading(bool is_downloading) { - DVLOG(1) << __func__ << "(" << is_downloading << ")"; + DVLOG(1) << __func__; if (!is_downloading && network_state_ == WebMediaPlayer::kNetworkStateLoading) SetNetworkState(WebMediaPlayer::kNetworkStateIdle); else if (is_downloading && network_state_ == WebMediaPlayer::kNetworkStateIdle) SetNetworkState(WebMediaPlayer::kNetworkStateLoading); - if (ready_state_ == ReadyState::kReadyStateHaveFutureData && !is_downloading) - SetReadyState(WebMediaPlayer::kReadyStateHaveEnoughData); media_log_->AddEvent( media_log_->CreateBooleanEvent(MediaLogEvent::NETWORK_ACTIVITY_SET, "is_downloading_data", is_downloading)); @@ -2530,9 +2509,4 @@ void WebMediaPlayerImpl::RecordVideoNaturalSize(const gfx::Size& natural_size) { #undef UMA_HISTOGRAM_VIDEO_HEIGHT -void WebMediaPlayerImpl::SetTickClockForTest(base::TickClock* tick_clock) { - tick_clock_.reset(tick_clock); - buffered_data_source_host_.SetTickClockForTest(tick_clock); -} - } // namespace media diff --git a/chromium/media/blink/webmediaplayer_impl.h b/chromium/media/blink/webmediaplayer_impl.h index df65ecbcba6..c98a50eb2af 100644 --- a/chromium/media/blink/webmediaplayer_impl.h +++ b/chromium/media/blink/webmediaplayer_impl.h @@ -473,20 +473,9 @@ class MEDIA_BLINK_EXPORT WebMediaPlayerImpl // handling a src= or MSE based playback. void RecordUnderflowDuration(base::TimeDelta duration); - // Called by the data source when loading progresses. - // Can be called quite often. - void OnProgress(); - - // Returns true when we estimate that we can play the rest of the media - // without buffering. - bool CanPlayThrough(); - // Records |natural_size| to MediaLog and video height to UMA. void RecordVideoNaturalSize(const gfx::Size& natural_size); - // Takes ownership of |tick_clock| - void SetTickClockForTest(base::TickClock* tick_clock); - blink::WebLocalFrame* frame_; // The playback state last reported to |delegate_|, to avoid setting duplicate @@ -611,8 +600,6 @@ class MEDIA_BLINK_EXPORT WebMediaPlayerImpl std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_; - std::unique_ptr<base::TickClock> tick_clock_; - BufferedDataSourceHostImpl buffered_data_source_host_; linked_ptr<UrlIndex> url_index_; @@ -714,6 +701,8 @@ class MEDIA_BLINK_EXPORT WebMediaPlayerImpl bool preroll_attempt_pending_; base::TimeTicks preroll_attempt_start_time_; + std::unique_ptr<base::TickClock> tick_clock_; + // Monitors the player events. base::WeakPtr<MediaObserver> observer_; diff --git a/chromium/media/blink/webmediaplayer_impl_unittest.cc b/chromium/media/blink/webmediaplayer_impl_unittest.cc index efbeaf22df9..573d24e42cd 100644 --- a/chromium/media/blink/webmediaplayer_impl_unittest.cc +++ b/chromium/media/blink/webmediaplayer_impl_unittest.cc @@ -256,9 +256,7 @@ class WebMediaPlayerImplTest : public testing::Test { void SetPaused(bool is_paused) { wmpi_->paused_ = is_paused; } void SetSeeking(bool is_seeking) { wmpi_->seeking_ = is_seeking; } void SetEnded(bool is_ended) { wmpi_->ended_ = is_ended; } - void SetTickClock(base::TickClock* clock) { - wmpi_->SetTickClockForTest(clock); - } + void SetTickClock(base::TickClock* clock) { wmpi_->tick_clock_.reset(clock); } void SetFullscreen(bool is_fullscreen) { wmpi_->overlay_enabled_ = is_fullscreen; diff --git a/chromium/media/gpu/h264_decoder.cc b/chromium/media/gpu/h264_decoder.cc index aed96583748..d5b0aee8f09 100644 --- a/chromium/media/gpu/h264_decoder.cc +++ b/chromium/media/gpu/h264_decoder.cc @@ -177,6 +177,8 @@ bool H264Decoder::InitCurrPicture(const H264SliceHeader* slice_hdr) { sizeof(curr_pic_->ref_pic_marking)); } + curr_pic_->visible_rect = visible_rect_; + return true; } @@ -1124,6 +1126,12 @@ bool H264Decoder::ProcessSPS(int sps_id, bool* need_new_buffers) { dpb_.set_max_num_pics(max_dpb_size); } + gfx::Rect new_visible_rect = sps->GetVisibleRect().value_or(gfx::Rect()); + if (visible_rect_ != new_visible_rect) { + DVLOG(2) << "New visible rect: " << new_visible_rect.ToString(); + visible_rect_ = new_visible_rect; + } + if (!UpdateMaxNumReorderFrames(sps)) return false; DVLOG(1) << "max_num_reorder_frames: " << max_num_reorder_frames_; diff --git a/chromium/media/gpu/h264_decoder.h b/chromium/media/gpu/h264_decoder.h index 1caf662a7a6..a0daf691845 100644 --- a/chromium/media/gpu/h264_decoder.h +++ b/chromium/media/gpu/h264_decoder.h @@ -18,6 +18,7 @@ #include "media/gpu/accelerated_video_decoder.h" #include "media/gpu/h264_dpb.h" #include "media/gpu/media_gpu_export.h" +#include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" namespace media { @@ -266,6 +267,8 @@ class MEDIA_GPU_EXPORT H264Decoder : public AcceleratedVideoDecoder { // Output picture size. gfx::Size pic_size_; + // Output visible cropping rect. + gfx::Rect visible_rect_; // PicOrderCount of the previously outputted frame. int last_output_poc_; diff --git a/chromium/media/gpu/h264_dpb.h b/chromium/media/gpu/h264_dpb.h index aef39a1bc5d..e8f119f6f6a 100644 --- a/chromium/media/gpu/h264_dpb.h +++ b/chromium/media/gpu/h264_dpb.h @@ -15,6 +15,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "media/filters/h264_parser.h" +#include "ui/gfx/geometry/rect.h" namespace media { @@ -84,6 +85,10 @@ class H264Picture : public base::RefCounted<H264Picture> { // Position in DPB (i.e. index in DPB). int dpb_position; + // The visible size of picture. This could be either parsed from SPS, or set + // to gfx::Rect(0, 0) for indicating invalid values or not available. + gfx::Rect visible_rect; + protected: friend class base::RefCounted<H264Picture>; virtual ~H264Picture(); diff --git a/chromium/media/gpu/v4l2_slice_video_decode_accelerator.cc b/chromium/media/gpu/v4l2_slice_video_decode_accelerator.cc index 26223128a91..f4760060578 100644 --- a/chromium/media/gpu/v4l2_slice_video_decode_accelerator.cc +++ b/chromium/media/gpu/v4l2_slice_video_decode_accelerator.cc @@ -89,6 +89,11 @@ class V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface int input_record() const { return input_record_; } int output_record() const { return output_record_; } uint32_t config_store() const { return config_store_; } + gfx::Rect visible_rect() const { return visible_rect_; } + + void set_visible_rect(const gfx::Rect& visible_rect) { + visible_rect_ = visible_rect; + } // Take references to each reference surface and keep them until the // target surface is decoded. @@ -113,6 +118,7 @@ class V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface int input_record_; int output_record_; uint32_t config_store_; + gfx::Rect visible_rect_; bool decoded_; ReleaseCB release_cb_; @@ -800,18 +806,18 @@ bool V4L2SliceVideoDecodeAccelerator::CreateOutputBuffers() { DCHECK(surfaces_at_display_.empty()); DCHECK(surfaces_at_device_.empty()); - visible_size_ = decoder_->GetPicSize(); + gfx::Size pic_size = decoder_->GetPicSize(); size_t num_pictures = decoder_->GetRequiredNumOfPictures(); DCHECK_GT(num_pictures, 0u); - DCHECK(!visible_size_.IsEmpty()); + DCHECK(!pic_size.IsEmpty()); struct v4l2_format format; memset(&format, 0, sizeof(format)); format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; format.fmt.pix_mp.pixelformat = output_format_fourcc_; - format.fmt.pix_mp.width = visible_size_.width(); - format.fmt.pix_mp.height = visible_size_.height(); + format.fmt.pix_mp.width = pic_size.width(); + format.fmt.pix_mp.height = pic_size.height(); format.fmt.pix_mp.num_planes = input_planes_count_; if (device_->Ioctl(VIDIOC_S_FMT, &format) != 0) { @@ -825,14 +831,14 @@ bool V4L2SliceVideoDecodeAccelerator::CreateOutputBuffers() { DCHECK_EQ(coded_size_.width() % 16, 0); DCHECK_EQ(coded_size_.height() % 16, 0); - if (!gfx::Rect(coded_size_).Contains(gfx::Rect(visible_size_))) { + if (!gfx::Rect(coded_size_).Contains(gfx::Rect(pic_size))) { LOGF(ERROR) << "Got invalid adjusted coded size: " << coded_size_.ToString(); return false; } DVLOGF(3) << "buffer_count=" << num_pictures - << ", visible size=" << visible_size_.ToString() + << ", pic size=" << pic_size.ToString() << ", coded size=" << coded_size_.ToString(); // With ALLOCATE mode the client can sample it as RGB and doesn't need to @@ -2529,6 +2535,7 @@ bool V4L2SliceVideoDecodeAccelerator::V4L2H264Accelerator::OutputPicture( const scoped_refptr<H264Picture>& pic) { scoped_refptr<V4L2DecodeSurface> dec_surface = H264PictureToV4L2DecodeSurface(pic); + dec_surface->set_visible_rect(pic->visible_rect); v4l2_dec_->SurfaceReady(dec_surface); return true; } @@ -2760,7 +2767,7 @@ bool V4L2SliceVideoDecodeAccelerator::V4L2VP8Accelerator::OutputPicture( const scoped_refptr<VP8Picture>& pic) { scoped_refptr<V4L2DecodeSurface> dec_surface = VP8PictureToV4L2DecodeSurface(pic); - + dec_surface->set_visible_rect(pic->visible_rect); v4l2_dec_->SurfaceReady(dec_surface); return true; } @@ -3063,7 +3070,7 @@ bool V4L2SliceVideoDecodeAccelerator::V4L2VP9Accelerator::OutputPicture( const scoped_refptr<VP9Picture>& pic) { scoped_refptr<V4L2DecodeSurface> dec_surface = VP9PictureToV4L2DecodeSurface(pic); - + dec_surface->set_visible_rect(pic->visible_rect); v4l2_dec_->SurfaceReady(dec_surface); return true; } @@ -3187,15 +3194,13 @@ void V4L2SliceVideoDecodeAccelerator::OutputSurface( DCHECK_NE(output_record.picture_id, -1); output_record.at_client = true; - // TODO(posciak): Use visible size from decoder here instead - // (crbug.com/402760). Passing (0, 0) results in the client using the - // visible size extracted from the container instead. // TODO(hubbe): Insert correct color space. http://crbug.com/647725 Picture picture(output_record.picture_id, dec_surface->bitstream_id(), - gfx::Rect(0, 0), gfx::ColorSpace(), false); + dec_surface->visible_rect(), gfx::ColorSpace(), false); DVLOGF(3) << dec_surface->ToString() << ", bitstream_id: " << picture.bitstream_buffer_id() - << ", picture_id: " << picture.picture_buffer_id(); + << ", picture_id: " << picture.picture_buffer_id() + << ", visible_rect: " << picture.visible_rect().ToString(); pending_picture_ready_.push(PictureRecord(output_record.cleared, picture)); SendPictureReady(); output_record.cleared = true; diff --git a/chromium/media/gpu/v4l2_slice_video_decode_accelerator.h b/chromium/media/gpu/v4l2_slice_video_decode_accelerator.h index b8525f6716a..311ffe9ace0 100644 --- a/chromium/media/gpu/v4l2_slice_video_decode_accelerator.h +++ b/chromium/media/gpu/v4l2_slice_video_decode_accelerator.h @@ -405,7 +405,6 @@ class MEDIA_GPU_EXPORT V4L2SliceVideoDecodeAccelerator VideoCodecProfile video_profile_; uint32_t input_format_fourcc_; uint32_t output_format_fourcc_; - gfx::Size visible_size_; gfx::Size coded_size_; struct BitstreamBufferRef; diff --git a/chromium/media/gpu/vaapi_video_decode_accelerator.cc b/chromium/media/gpu/vaapi_video_decode_accelerator.cc index 9c6897fa15a..4c80a0dec1f 100644 --- a/chromium/media/gpu/vaapi_video_decode_accelerator.cc +++ b/chromium/media/gpu/vaapi_video_decode_accelerator.cc @@ -67,6 +67,11 @@ class VaapiVideoDecodeAccelerator::VaapiDecodeSurface int32_t bitstream_id() const { return bitstream_id_; } scoped_refptr<VASurface> va_surface() { return va_surface_; } + gfx::Rect visible_rect() const { return visible_rect_; } + + void set_visible_rect(const gfx::Rect& visible_rect) { + visible_rect_ = visible_rect; + } private: friend class base::RefCountedThreadSafe<VaapiDecodeSurface>; @@ -74,6 +79,7 @@ class VaapiVideoDecodeAccelerator::VaapiDecodeSurface int32_t bitstream_id_; scoped_refptr<VASurface> va_surface_; + gfx::Rect visible_rect_; }; VaapiVideoDecodeAccelerator::VaapiDecodeSurface::VaapiDecodeSurface( @@ -409,6 +415,7 @@ bool VaapiVideoDecodeAccelerator::Initialize(const Config& config, void VaapiVideoDecodeAccelerator::OutputPicture( const scoped_refptr<VASurface>& va_surface, int32_t input_id, + gfx::Rect visible_rect, VaapiPicture* picture) { DCHECK(task_runner_->BelongsToCurrentThread()); @@ -427,14 +434,12 @@ void VaapiVideoDecodeAccelerator::OutputPicture( // Notify the client a picture is ready to be displayed. ++num_frames_at_client_; TRACE_COUNTER1("Video Decoder", "Textures at client", num_frames_at_client_); - DVLOG(4) << "Notifying output picture id " << output_id - << " for input " << input_id << " is ready"; - // TODO(posciak): Use visible size from decoder here instead - // (crbug.com/402760). Passing (0, 0) results in the client using the - // visible size extracted from the container instead. + DVLOG(4) << "Notifying output picture id " << output_id << " for input " + << input_id + << " is ready. visible rect: " << visible_rect.ToString(); // TODO(hubbe): Use the correct color space. http://crbug.com/647725 if (client_) - client_->PictureReady(Picture(output_id, input_id, gfx::Rect(0, 0), + client_->PictureReady(Picture(output_id, input_id, visible_rect, gfx::ColorSpace(), picture->AllowOverlay())); } @@ -1143,7 +1148,8 @@ void VaapiVideoDecodeAccelerator::SurfaceReady( pending_output_cbs_.push( base::Bind(&VaapiVideoDecodeAccelerator::OutputPicture, weak_this_, - dec_surface->va_surface(), dec_surface->bitstream_id())); + dec_surface->va_surface(), dec_surface->bitstream_id(), + dec_surface->visible_rect())); TryOutputSurface(); } @@ -1426,7 +1432,7 @@ bool VaapiVideoDecodeAccelerator::VaapiH264Accelerator::OutputPicture( const scoped_refptr<H264Picture>& pic) { scoped_refptr<VaapiDecodeSurface> dec_surface = H264PictureToVaapiDecodeSurface(pic); - + dec_surface->set_visible_rect(pic->visible_rect); vaapi_dec_->SurfaceReady(dec_surface); return true; @@ -1713,7 +1719,7 @@ bool VaapiVideoDecodeAccelerator::VaapiVP8Accelerator::OutputPicture( const scoped_refptr<VP8Picture>& pic) { scoped_refptr<VaapiDecodeSurface> dec_surface = VP8PictureToVaapiDecodeSurface(pic); - + dec_surface->set_visible_rect(pic->visible_rect); vaapi_dec_->SurfaceReady(dec_surface); return true; } @@ -1877,7 +1883,7 @@ bool VaapiVideoDecodeAccelerator::VaapiVP9Accelerator::OutputPicture( const scoped_refptr<VP9Picture>& pic) { scoped_refptr<VaapiDecodeSurface> dec_surface = VP9PictureToVaapiDecodeSurface(pic); - + dec_surface->set_visible_rect(pic->visible_rect); vaapi_dec_->SurfaceReady(dec_surface); return true; } diff --git a/chromium/media/gpu/vaapi_video_decode_accelerator.h b/chromium/media/gpu/vaapi_video_decode_accelerator.h index 241c002d9c5..9edf17077a7 100644 --- a/chromium/media/gpu/vaapi_video_decode_accelerator.h +++ b/chromium/media/gpu/vaapi_video_decode_accelerator.h @@ -145,10 +145,12 @@ class MEDIA_GPU_EXPORT VaapiVideoDecodeAccelerator // Callback to be executed once we have a |va_surface| to be output and // an available |picture| to use for output. - // Puts contents of |va_surface| into given |picture|, releases the - // surface and passes the resulting picture to client for output. + // Puts contents of |va_surface| into given |picture|, releases the surface + // and passes the resulting picture to client to output the given + // |visible_rect| part of it. void OutputPicture(const scoped_refptr<VASurface>& va_surface, int32_t input_id, + gfx::Rect visible_rect, VaapiPicture* picture); // Try to OutputPicture() if we have both a ready surface and picture. diff --git a/chromium/media/gpu/vp8_decoder.cc b/chromium/media/gpu/vp8_decoder.cc index 9d582ed0a62..e7bdfc2ec93 100644 --- a/chromium/media/gpu/vp8_decoder.cc +++ b/chromium/media/gpu/vp8_decoder.cc @@ -94,6 +94,7 @@ VP8Decoder::DecodeResult VP8Decoder::Decode() { if (!curr_pic_) return kRanOutOfSurfaces; + curr_pic_->visible_rect = gfx::Rect(pic_size_); if (!DecodeAndOutputCurrentFrame()) return kDecodeError; diff --git a/chromium/media/gpu/vp8_picture.h b/chromium/media/gpu/vp8_picture.h index 164cf0a2c7e..f31a344bd67 100644 --- a/chromium/media/gpu/vp8_picture.h +++ b/chromium/media/gpu/vp8_picture.h @@ -7,6 +7,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "ui/gfx/geometry/rect.h" namespace media { @@ -20,6 +21,9 @@ class VP8Picture : public base::RefCounted<VP8Picture> { virtual V4L2VP8Picture* AsV4L2VP8Picture(); virtual VaapiVP8Picture* AsVaapiVP8Picture(); + // The visible size of picture. + gfx::Rect visible_rect; + protected: friend class base::RefCounted<VP8Picture>; virtual ~VP8Picture(); diff --git a/chromium/media/gpu/vp9_decoder.cc b/chromium/media/gpu/vp9_decoder.cc index b24f2466846..be7fd85b3d9 100644 --- a/chromium/media/gpu/vp9_decoder.cc +++ b/chromium/media/gpu/vp9_decoder.cc @@ -138,6 +138,18 @@ VP9Decoder::DecodeResult VP9Decoder::Decode() { if (!pic) return kRanOutOfSurfaces; + gfx::Rect new_render_rect(curr_frame_hdr_->render_width, + curr_frame_hdr_->render_height); + // For safety, check the validity of render size or leave it as (0, 0). + if (!gfx::Rect(pic_size_).Contains(new_render_rect)) { + DVLOG(1) << "Render size exceeds picture size. render size: " + << new_render_rect.ToString() + << ", picture size: " << pic_size_.ToString(); + new_render_rect = gfx::Rect(); + } + DVLOG(2) << "Render resolution: " << new_render_rect.ToString(); + + pic->visible_rect = new_render_rect; pic->frame_hdr.reset(curr_frame_hdr_.release()); if (!DecodeAndOutputPicture(pic)) { diff --git a/chromium/media/gpu/vp9_picture.h b/chromium/media/gpu/vp9_picture.h index 7c026fa2ea9..ba95c889086 100644 --- a/chromium/media/gpu/vp9_picture.h +++ b/chromium/media/gpu/vp9_picture.h @@ -10,6 +10,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "media/filters/vp9_parser.h" +#include "ui/gfx/geometry/rect.h" namespace media { @@ -25,6 +26,11 @@ class VP9Picture : public base::RefCounted<VP9Picture> { std::unique_ptr<Vp9FrameHeader> frame_hdr; + // The visible size of picture. This could be either parsed from frame + // header, or set to gfx::Rect(0, 0) for indicating invalid values or + // not available. + gfx::Rect visible_rect; + protected: friend class base::RefCounted<VP9Picture>; virtual ~VP9Picture(); |