| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/blink/webmediaplayer_impl.h" | 5 #include "media/blink/webmediaplayer_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 #include <limits> | 9 #include <limits> |
| 10 #include <string> | 10 #include <string> |
| 11 #include <utility> | 11 #include <utility> |
| 12 | 12 |
| 13 #include "base/bind.h" | 13 #include "base/bind.h" |
| 14 #include "base/bind_helpers.h" | 14 #include "base/bind_helpers.h" |
| 15 #include "base/callback.h" | 15 #include "base/callback.h" |
| 16 #include "base/callback_helpers.h" | 16 #include "base/callback_helpers.h" |
| 17 #include "base/command_line.h" | 17 #include "base/command_line.h" |
| 18 #include "base/debug/alias.h" | 18 #include "base/debug/alias.h" |
| 19 #include "base/debug/crash_logging.h" | 19 #include "base/debug/crash_logging.h" |
| 20 #include "base/location.h" | 20 #include "base/location.h" |
| 21 #include "base/memory/ptr_util.h" |
| 21 #include "base/metrics/histogram_macros.h" | 22 #include "base/metrics/histogram_macros.h" |
| 22 #include "base/single_thread_task_runner.h" | 23 #include "base/single_thread_task_runner.h" |
| 23 #include "base/strings/string_number_conversions.h" | 24 #include "base/strings/string_number_conversions.h" |
| 24 #include "base/task_runner_util.h" | 25 #include "base/task_runner_util.h" |
| 25 #include "base/threading/thread_task_runner_handle.h" | 26 #include "base/threading/thread_task_runner_handle.h" |
| 26 #include "base/trace_event/trace_event.h" | 27 #include "base/trace_event/trace_event.h" |
| 27 #include "build/build_config.h" | 28 #include "build/build_config.h" |
| 28 #include "cc/blink/web_layer_impl.h" | 29 #include "cc/blink/web_layer_impl.h" |
| 29 #include "cc/layers/video_layer.h" | 30 #include "cc/layers/video_layer.h" |
| 30 #include "media/audio/null_audio_sink.h" | 31 #include "media/audio/null_audio_sink.h" |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 230 surface_manager_(params.surface_manager()), | 231 surface_manager_(params.surface_manager()), |
| 231 overlay_surface_id_(SurfaceManager::kNoSurfaceID), | 232 overlay_surface_id_(SurfaceManager::kNoSurfaceID), |
| 232 suppress_destruction_errors_(false), | 233 suppress_destruction_errors_(false), |
| 233 suspend_enabled_(params.allow_suspend()), | 234 suspend_enabled_(params.allow_suspend()), |
| 234 use_fallback_path_(false), | 235 use_fallback_path_(false), |
| 235 is_encrypted_(false), | 236 is_encrypted_(false), |
| 236 underflow_count_(0), | 237 underflow_count_(0), |
| 237 preroll_attempt_pending_(false), | 238 preroll_attempt_pending_(false), |
| 238 observer_(params.media_observer()), | 239 observer_(params.media_observer()), |
| 239 max_keyframe_distance_to_disable_background_video_( | 240 max_keyframe_distance_to_disable_background_video_( |
| 240 params.max_keyframe_distance_to_disable_background_video()) { | 241 params.max_keyframe_distance_to_disable_background_video()), |
| 242 enable_instant_source_buffer_gc_( |
| 243 params.enable_instant_source_buffer_gc()) { |
| 241 DCHECK(!adjust_allocated_memory_cb_.is_null()); | 244 DCHECK(!adjust_allocated_memory_cb_.is_null()); |
| 242 DCHECK(renderer_factory_); | 245 DCHECK(renderer_factory_); |
| 243 DCHECK(client_); | 246 DCHECK(client_); |
| 244 DCHECK(delegate_); | 247 DCHECK(delegate_); |
| 245 | 248 |
| 246 tick_clock_.reset(new base::DefaultTickClock()); | 249 tick_clock_.reset(new base::DefaultTickClock()); |
| 247 | 250 |
| 248 force_video_overlays_ = base::CommandLine::ForCurrentProcess()->HasSwitch( | 251 force_video_overlays_ = base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 249 switches::kForceVideoOverlays); | 252 switches::kForceVideoOverlays); |
| 250 | 253 |
| (...skipping 902 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1153 | 1156 |
| 1154 UpdateBackgroundVideoOptimizationState(); | 1157 UpdateBackgroundVideoOptimizationState(); |
| 1155 } | 1158 } |
| 1156 | 1159 |
| 1157 void WebMediaPlayerImpl::OnDemuxerOpened() { | 1160 void WebMediaPlayerImpl::OnDemuxerOpened() { |
| 1158 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1161 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 1159 client_->mediaSourceOpened( | 1162 client_->mediaSourceOpened( |
| 1160 new WebMediaSourceImpl(chunk_demuxer_, media_log_)); | 1163 new WebMediaSourceImpl(chunk_demuxer_, media_log_)); |
| 1161 } | 1164 } |
| 1162 | 1165 |
| 1166 void WebMediaPlayerImpl::OnMemoryPressure( |
| 1167 base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) { |
| 1168 DVLOG(2) << __func__ << " memory_pressure_level=" << memory_pressure_level; |
| 1169 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 1170 DCHECK(base::FeatureList::IsEnabled(kMemoryPressureBasedSourceBufferGC)); |
| 1171 DCHECK(chunk_demuxer_); |
| 1172 |
| 1173 // The new value of |memory_pressure_level| will take effect on the next |
| 1174 // garbage collection. Typically this means the next SourceBuffer append() |
| 1175 // operation, since per MSE spec, the garbage collection must only occur |
| 1176 // during SourceBuffer append(). But if memory pressure is critical it might |
| 1177 // be better to perform GC immediately rather than wait for the next append |
| 1178 // and potentially get killed due to out-of-memory. |
| 1179 // So if this experiment is enabled and pressure level is critical, we'll pass |
| 1180 // down force_instant_gc==true, which will force immediate GC on |
| 1181 // SourceBufferStreams. |
| 1182 bool force_instant_gc = |
| 1183 (enable_instant_source_buffer_gc_ && |
| 1184 memory_pressure_level == |
| 1185 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL); |
| 1186 |
| 1187 // base::Unretained is safe, since chunk_demuxer_ is actually owned by |
| 1188 // |this| via this->demuxer_. |
| 1189 media_task_runner_->PostTask( |
| 1190 FROM_HERE, base::Bind(&ChunkDemuxer::OnMemoryPressure, |
| 1191 base::Unretained(chunk_demuxer_), |
| 1192 base::TimeDelta::FromSecondsD(currentTime()), |
| 1193 memory_pressure_level, force_instant_gc)); |
| 1194 } |
| 1195 |
| 1163 void WebMediaPlayerImpl::OnError(PipelineStatus status) { | 1196 void WebMediaPlayerImpl::OnError(PipelineStatus status) { |
| 1164 DVLOG(1) << __func__; | 1197 DVLOG(1) << __func__; |
| 1165 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1198 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 1166 DCHECK_NE(status, PIPELINE_OK); | 1199 DCHECK_NE(status, PIPELINE_OK); |
| 1167 | 1200 |
| 1168 if (suppress_destruction_errors_) | 1201 if (suppress_destruction_errors_) |
| 1169 return; | 1202 return; |
| 1170 | 1203 |
| 1171 ReportPipelineError(load_type_, frame_->getSecurityOrigin(), status); | 1204 ReportPipelineError(load_type_, frame_->getSecurityOrigin(), status); |
| 1172 media_log_->AddEvent(media_log_->CreatePipelineErrorEvent(status)); | 1205 media_log_->AddEvent(media_log_->CreatePipelineErrorEvent(status)); |
| (...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1707 #endif | 1740 #endif |
| 1708 } else { | 1741 } else { |
| 1709 DCHECK(!chunk_demuxer_); | 1742 DCHECK(!chunk_demuxer_); |
| 1710 DCHECK(!data_source_); | 1743 DCHECK(!data_source_); |
| 1711 | 1744 |
| 1712 chunk_demuxer_ = new ChunkDemuxer( | 1745 chunk_demuxer_ = new ChunkDemuxer( |
| 1713 BindToCurrentLoop( | 1746 BindToCurrentLoop( |
| 1714 base::Bind(&WebMediaPlayerImpl::OnDemuxerOpened, AsWeakPtr())), | 1747 base::Bind(&WebMediaPlayerImpl::OnDemuxerOpened, AsWeakPtr())), |
| 1715 encrypted_media_init_data_cb, media_log_); | 1748 encrypted_media_init_data_cb, media_log_); |
| 1716 demuxer_.reset(chunk_demuxer_); | 1749 demuxer_.reset(chunk_demuxer_); |
| 1750 |
| 1751 if (base::FeatureList::IsEnabled(kMemoryPressureBasedSourceBufferGC)) { |
| 1752 // base::Unretained is safe because |this| owns memory_pressure_listener_. |
| 1753 memory_pressure_listener_ = |
| 1754 base::MakeUnique<base::MemoryPressureListener>(base::Bind( |
| 1755 &WebMediaPlayerImpl::OnMemoryPressure, base::Unretained(this))); |
| 1756 } |
| 1717 } | 1757 } |
| 1718 | 1758 |
| 1719 // TODO(sandersd): FileSystem objects may also be non-static, but due to our | 1759 // TODO(sandersd): FileSystem objects may also be non-static, but due to our |
| 1720 // caching layer such situations are broken already. http://crbug.com/593159 | 1760 // caching layer such situations are broken already. http://crbug.com/593159 |
| 1721 bool is_static = !chunk_demuxer_; | 1761 bool is_static = !chunk_demuxer_; |
| 1722 bool is_streaming = IsStreaming(); | 1762 bool is_streaming = IsStreaming(); |
| 1723 UMA_HISTOGRAM_BOOLEAN("Media.IsStreaming", is_streaming); | 1763 UMA_HISTOGRAM_BOOLEAN("Media.IsStreaming", is_streaming); |
| 1724 | 1764 |
| 1725 // ... and we're ready to go! | 1765 // ... and we're ready to go! |
| 1726 // TODO(sandersd): On Android, defer Start() if the tab is not visible. | 1766 // TODO(sandersd): On Android, defer Start() if the tab is not visible. |
| (...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2240 UMA_HISTOGRAM_TIMES( | 2280 UMA_HISTOGRAM_TIMES( |
| 2241 "Media.Video.TimeFromForegroundToFirstFrame.DisableTrack", | 2281 "Media.Video.TimeFromForegroundToFirstFrame.DisableTrack", |
| 2242 time_to_first_frame); | 2282 time_to_first_frame); |
| 2243 } else { | 2283 } else { |
| 2244 UMA_HISTOGRAM_TIMES("Media.Video.TimeFromForegroundToFirstFrame.Paused", | 2284 UMA_HISTOGRAM_TIMES("Media.Video.TimeFromForegroundToFirstFrame.Paused", |
| 2245 time_to_first_frame); | 2285 time_to_first_frame); |
| 2246 } | 2286 } |
| 2247 } | 2287 } |
| 2248 | 2288 |
| 2249 } // namespace media | 2289 } // namespace media |
| OLD | NEW |