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/renderers/video_renderer_impl.h" | 5 #include "media/renderers/video_renderer_impl.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/callback.h" | 10 #include "base/callback.h" |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 drop_frames_(drop_frames), | 53 drop_frames_(drop_frames), |
54 buffering_state_(BUFFERING_HAVE_NOTHING), | 54 buffering_state_(BUFFERING_HAVE_NOTHING), |
55 frames_decoded_(0), | 55 frames_decoded_(0), |
56 frames_dropped_(0), | 56 frames_dropped_(0), |
57 tick_clock_(new base::DefaultTickClock()), | 57 tick_clock_(new base::DefaultTickClock()), |
58 was_background_rendering_(false), | 58 was_background_rendering_(false), |
59 time_progressing_(false), | 59 time_progressing_(false), |
60 render_first_frame_and_stop_(false), | 60 render_first_frame_and_stop_(false), |
61 posted_maybe_stop_after_first_paint_(false), | 61 posted_maybe_stop_after_first_paint_(false), |
62 last_video_memory_usage_(0), | 62 last_video_memory_usage_(0), |
| 63 have_renderered_frames_(false), |
| 64 last_frame_opaque_(false), |
63 weak_factory_(this) { | 65 weak_factory_(this) { |
64 if (gpu_factories && | 66 if (gpu_factories && |
65 gpu_factories->ShouldUseGpuMemoryBuffersForVideoFrames()) { | 67 gpu_factories->ShouldUseGpuMemoryBuffersForVideoFrames()) { |
66 gpu_memory_buffer_pool_.reset(new GpuMemoryBufferVideoFramePool( | 68 gpu_memory_buffer_pool_.reset(new GpuMemoryBufferVideoFramePool( |
67 media_task_runner, worker_task_runner, gpu_factories)); | 69 media_task_runner, worker_task_runner, gpu_factories)); |
68 } | 70 } |
69 } | 71 } |
70 | 72 |
71 VideoRendererImpl::~VideoRendererImpl() { | 73 VideoRendererImpl::~VideoRendererImpl() { |
72 DCHECK(task_runner_->BelongsToCurrentThread()); | 74 DCHECK(task_runner_->BelongsToCurrentThread()); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 base::AutoLock auto_lock(lock_); | 136 base::AutoLock auto_lock(lock_); |
135 DCHECK(stream); | 137 DCHECK(stream); |
136 DCHECK_EQ(stream->type(), DemuxerStream::VIDEO); | 138 DCHECK_EQ(stream->type(), DemuxerStream::VIDEO); |
137 DCHECK(!init_cb.is_null()); | 139 DCHECK(!init_cb.is_null()); |
138 DCHECK(!wall_clock_time_cb.is_null()); | 140 DCHECK(!wall_clock_time_cb.is_null()); |
139 DCHECK_EQ(kUninitialized, state_); | 141 DCHECK_EQ(kUninitialized, state_); |
140 DCHECK(!render_first_frame_and_stop_); | 142 DCHECK(!render_first_frame_and_stop_); |
141 DCHECK(!posted_maybe_stop_after_first_paint_); | 143 DCHECK(!posted_maybe_stop_after_first_paint_); |
142 DCHECK(!was_background_rendering_); | 144 DCHECK(!was_background_rendering_); |
143 DCHECK(!time_progressing_); | 145 DCHECK(!time_progressing_); |
| 146 DCHECK(!have_renderered_frames_); |
144 | 147 |
145 low_delay_ = (stream->liveness() == DemuxerStream::LIVENESS_LIVE); | 148 low_delay_ = (stream->liveness() == DemuxerStream::LIVENESS_LIVE); |
146 UMA_HISTOGRAM_BOOLEAN("Media.VideoRenderer.LowDelay", low_delay_); | 149 UMA_HISTOGRAM_BOOLEAN("Media.VideoRenderer.LowDelay", low_delay_); |
147 if (low_delay_) | 150 if (low_delay_) |
148 MEDIA_LOG(DEBUG, media_log_) << "Video rendering in low delay mode."; | 151 MEDIA_LOG(DEBUG, media_log_) << "Video rendering in low delay mode."; |
149 | 152 |
150 // Always post |init_cb_| because |this| could be destroyed if initialization | 153 // Always post |init_cb_| because |this| could be destroyed if initialization |
151 // failed. | 154 // failed. |
152 init_cb_ = BindToCurrentLoop(init_cb); | 155 init_cb_ = BindToCurrentLoop(init_cb); |
153 | 156 |
(...skipping 18 matching lines...) Expand all Loading... |
172 DCHECK_EQ(state_, kPlaying); | 175 DCHECK_EQ(state_, kPlaying); |
173 | 176 |
174 size_t frames_dropped = 0; | 177 size_t frames_dropped = 0; |
175 scoped_refptr<VideoFrame> result = | 178 scoped_refptr<VideoFrame> result = |
176 algorithm_->Render(deadline_min, deadline_max, &frames_dropped); | 179 algorithm_->Render(deadline_min, deadline_max, &frames_dropped); |
177 | 180 |
178 // Due to how the |algorithm_| holds frames, this should never be null if | 181 // Due to how the |algorithm_| holds frames, this should never be null if |
179 // we've had a proper startup sequence. | 182 // we've had a proper startup sequence. |
180 DCHECK(result); | 183 DCHECK(result); |
181 | 184 |
| 185 // Notify client of size and opacity changes if this is the first frame |
| 186 // or if those have changed from the last frame. |
| 187 if (!have_renderered_frames_ || |
| 188 (last_frame_natural_size_ != result->natural_size())) { |
| 189 last_frame_natural_size_ = result->natural_size(); |
| 190 task_runner_->PostTask( |
| 191 FROM_HERE, |
| 192 base::Bind(&VideoRendererImpl::OnVideoNaturalSizeChange, |
| 193 weak_factory_.GetWeakPtr(), last_frame_natural_size_)); |
| 194 } |
| 195 if (!have_renderered_frames_ || |
| 196 (last_frame_opaque_ != IsOpaque(result->format()))) { |
| 197 last_frame_opaque_ = IsOpaque(result->format()); |
| 198 task_runner_->PostTask( |
| 199 FROM_HERE, base::Bind(&VideoRendererImpl::OnVideoOpacityChange, |
| 200 weak_factory_.GetWeakPtr(), last_frame_opaque_)); |
| 201 } |
| 202 |
182 // Declare HAVE_NOTHING if we reach a state where we can't progress playback | 203 // Declare HAVE_NOTHING if we reach a state where we can't progress playback |
183 // any further. We don't want to do this if we've already done so, reached | 204 // any further. We don't want to do this if we've already done so, reached |
184 // end of stream, or have frames available. We also don't want to do this in | 205 // end of stream, or have frames available. We also don't want to do this in |
185 // background rendering mode unless this isn't the first background render | 206 // background rendering mode unless this isn't the first background render |
186 // tick and we haven't seen any decoded frames since the last one. | 207 // tick and we haven't seen any decoded frames since the last one. |
187 // | 208 // |
188 // We use the inverse of |render_first_frame_and_stop_| as a proxy for the | 209 // We use the inverse of |render_first_frame_and_stop_| as a proxy for the |
189 // value of |time_progressing_| here since we can't access it from the | 210 // value of |time_progressing_| here since we can't access it from the |
190 // compositor thread. If we're here (in Render()) the sink must have been | 211 // compositor thread. If we're here (in Render()) the sink must have been |
191 // started -- but if it was started only to render the first frame and stop, | 212 // started -- but if it was started only to render the first frame and stop, |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 weak_factory_.GetWeakPtr()), | 251 weak_factory_.GetWeakPtr()), |
231 base::TimeDelta::FromMilliseconds(250)); | 252 base::TimeDelta::FromMilliseconds(250)); |
232 } | 253 } |
233 | 254 |
234 // Always post this task, it will acquire new frames if necessary and since it | 255 // Always post this task, it will acquire new frames if necessary and since it |
235 // happens on another thread, even if we don't have room in the queue now, by | 256 // happens on another thread, even if we don't have room in the queue now, by |
236 // the time it runs (may be delayed up to 50ms for complex decodes!) we might. | 257 // the time it runs (may be delayed up to 50ms for complex decodes!) we might. |
237 task_runner_->PostTask(FROM_HERE, base::Bind(&VideoRendererImpl::AttemptRead, | 258 task_runner_->PostTask(FROM_HERE, base::Bind(&VideoRendererImpl::AttemptRead, |
238 weak_factory_.GetWeakPtr())); | 259 weak_factory_.GetWeakPtr())); |
239 | 260 |
| 261 have_renderered_frames_ = true; |
240 return result; | 262 return result; |
241 } | 263 } |
242 | 264 |
243 void VideoRendererImpl::OnFrameDropped() { | 265 void VideoRendererImpl::OnFrameDropped() { |
244 base::AutoLock auto_lock(lock_); | 266 base::AutoLock auto_lock(lock_); |
245 algorithm_->OnLastFrameDropped(); | 267 algorithm_->OnLastFrameDropped(); |
246 } | 268 } |
247 | 269 |
248 void VideoRendererImpl::OnVideoFrameStreamInitialized(bool success) { | 270 void VideoRendererImpl::OnVideoFrameStreamInitialized(bool success) { |
249 DCHECK(task_runner_->BelongsToCurrentThread()); | 271 DCHECK(task_runner_->BelongsToCurrentThread()); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 void VideoRendererImpl::OnBufferingStateChange(BufferingState state) { | 309 void VideoRendererImpl::OnBufferingStateChange(BufferingState state) { |
288 DCHECK(task_runner_->BelongsToCurrentThread()); | 310 DCHECK(task_runner_->BelongsToCurrentThread()); |
289 client_->OnBufferingStateChange(state); | 311 client_->OnBufferingStateChange(state); |
290 } | 312 } |
291 | 313 |
292 void VideoRendererImpl::OnWaitingForDecryptionKey() { | 314 void VideoRendererImpl::OnWaitingForDecryptionKey() { |
293 DCHECK(task_runner_->BelongsToCurrentThread()); | 315 DCHECK(task_runner_->BelongsToCurrentThread()); |
294 client_->OnWaitingForDecryptionKey(); | 316 client_->OnWaitingForDecryptionKey(); |
295 } | 317 } |
296 | 318 |
| 319 void VideoRendererImpl::OnVideoNaturalSizeChange(const gfx::Size& size) { |
| 320 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 321 client_->OnVideoNaturalSizeChange(size); |
| 322 } |
| 323 |
| 324 void VideoRendererImpl::OnVideoOpacityChange(bool opaque) { |
| 325 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 326 client_->OnVideoOpacityChange(opaque); |
| 327 } |
| 328 |
297 void VideoRendererImpl::SetTickClockForTesting( | 329 void VideoRendererImpl::SetTickClockForTesting( |
298 std::unique_ptr<base::TickClock> tick_clock) { | 330 std::unique_ptr<base::TickClock> tick_clock) { |
299 tick_clock_.swap(tick_clock); | 331 tick_clock_.swap(tick_clock); |
300 } | 332 } |
301 | 333 |
302 void VideoRendererImpl::SetGpuMemoryBufferVideoForTesting( | 334 void VideoRendererImpl::SetGpuMemoryBufferVideoForTesting( |
303 std::unique_ptr<GpuMemoryBufferVideoFramePool> gpu_memory_buffer_pool) { | 335 std::unique_ptr<GpuMemoryBufferVideoFramePool> gpu_memory_buffer_pool) { |
304 gpu_memory_buffer_pool_.swap(gpu_memory_buffer_pool); | 336 gpu_memory_buffer_pool_.swap(gpu_memory_buffer_pool); |
305 } | 337 } |
306 | 338 |
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
693 // the entire queue. Note: this may cause slight inaccuracies in the number | 725 // the entire queue. Note: this may cause slight inaccuracies in the number |
694 // of dropped frames since the frame may have been rendered before. | 726 // of dropped frames since the frame may have been rendered before. |
695 if (!sink_started_ && !algorithm_->effective_frames_queued()) { | 727 if (!sink_started_ && !algorithm_->effective_frames_queued()) { |
696 frames_dropped_ += algorithm_->frames_queued(); | 728 frames_dropped_ += algorithm_->frames_queued(); |
697 algorithm_->Reset( | 729 algorithm_->Reset( |
698 VideoRendererAlgorithm::ResetFlag::kPreserveNextFrameEstimates); | 730 VideoRendererAlgorithm::ResetFlag::kPreserveNextFrameEstimates); |
699 } | 731 } |
700 } | 732 } |
701 | 733 |
702 } // namespace media | 734 } // namespace media |
OLD | NEW |