| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "content/renderer/media/webmediaplayer_ms_compositor.h" | 5 #include "content/renderer/media/webmediaplayer_ms_compositor.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/hash.h" | 10 #include "base/hash.h" |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 178 if (video_frame_provider_client_ && !stopped_) | 178 if (video_frame_provider_client_ && !stopped_) |
| 179 video_frame_provider_client_->StartRendering(); | 179 video_frame_provider_client_->StartRendering(); |
| 180 } | 180 } |
| 181 | 181 |
| 182 void WebMediaPlayerMSCompositor::EnqueueFrame( | 182 void WebMediaPlayerMSCompositor::EnqueueFrame( |
| 183 const scoped_refptr<media::VideoFrame>& frame) { | 183 const scoped_refptr<media::VideoFrame>& frame) { |
| 184 DCHECK(thread_checker_.CalledOnValidThread()); | 184 DCHECK(thread_checker_.CalledOnValidThread()); |
| 185 base::AutoLock auto_lock(current_frame_lock_); | 185 base::AutoLock auto_lock(current_frame_lock_); |
| 186 ++total_frame_count_; | 186 ++total_frame_count_; |
| 187 | 187 |
| 188 // With algorithm off, just let |current_frame_| hold the incoming |frame|. |
| 188 if (!rendering_frame_buffer_) { | 189 if (!rendering_frame_buffer_) { |
| 189 SetCurrentFrame(frame); | 190 SetCurrentFrame(frame); |
| 190 return; | 191 return; |
| 191 } | 192 } |
| 192 | 193 |
| 193 // This is a signal frame saying that the stream is stopped. | 194 // This is a signal frame saying that the stream is stopped. |
| 194 bool end_of_stream = false; | 195 bool end_of_stream = false; |
| 195 if (frame->metadata()->GetBoolean(media::VideoFrameMetadata::END_OF_STREAM, | 196 if (frame->metadata()->GetBoolean(media::VideoFrameMetadata::END_OF_STREAM, |
| 196 &end_of_stream) && | 197 &end_of_stream) && |
| 197 end_of_stream) { | 198 end_of_stream) { |
| 198 rendering_frame_buffer_.reset(); | 199 rendering_frame_buffer_.reset(); |
| 199 SetCurrentFrame(frame); | 200 SetCurrentFrame(frame); |
| 200 return; | 201 return; |
| 201 } | 202 } |
| 202 | 203 |
| 204 // If we detect a bad frame without |render_time|, we switch off algorithm, |
| 205 // because without |render_time|, algorithm cannot work. |
| 206 // In general, this should not happen. |
| 203 base::TimeTicks render_time; | 207 base::TimeTicks render_time; |
| 204 if (!frame->metadata()->GetTimeTicks( | 208 if (!frame->metadata()->GetTimeTicks( |
| 205 media::VideoFrameMetadata::REFERENCE_TIME, &render_time)) { | 209 media::VideoFrameMetadata::REFERENCE_TIME, &render_time)) { |
| 206 DLOG(WARNING) | 210 DLOG(WARNING) |
| 207 << "Incoming VideoFrames have no REFERENCE_TIME, switching off super " | 211 << "Incoming VideoFrames have no REFERENCE_TIME, switching off super " |
| 208 "sophisticated rendering algorithm"; | 212 "sophisticated rendering algorithm"; |
| 209 rendering_frame_buffer_.reset(); | 213 rendering_frame_buffer_.reset(); |
| 210 SetCurrentFrame(frame); | 214 SetCurrentFrame(frame); |
| 211 return; | 215 return; |
| 212 } | 216 } |
| 213 | 217 |
| 218 // The code below handles the case where UpdateCurrentFrame() callbacks stop. |
| 219 // These callbacks can stop when the tab is hidden or the page area containing |
| 220 // the video frame is scrolled out of view. |
| 221 // Since some hardware decoders only have a limited number of output frames, |
| 222 // we must aggressively release frames in this case. |
| 223 const base::TimeTicks now = base::TimeTicks::Now(); |
| 224 if (now > last_deadline_max_) { |
| 225 // Note: the frame in |rendering_frame_buffer_| with lowest index is the |
| 226 // same as |current_frame_|. Function SetCurrentFrame() handles whether |
| 227 // to increase |dropped_frame_count_| for that frame, so here we should |
| 228 // increase |dropped_frame_count_| by the count of all other frames. |
| 229 dropped_frame_count_ += rendering_frame_buffer_->frames_queued() - 1; |
| 230 rendering_frame_buffer_->Reset(); |
| 231 timestamps_to_clock_times_.clear(); |
| 232 SetCurrentFrame(frame); |
| 233 } |
| 234 |
| 214 timestamps_to_clock_times_[frame->timestamp()] = render_time; | 235 timestamps_to_clock_times_[frame->timestamp()] = render_time; |
| 215 | |
| 216 rendering_frame_buffer_->EnqueueFrame(frame); | 236 rendering_frame_buffer_->EnqueueFrame(frame); |
| 217 | |
| 218 const base::TimeTicks now = base::TimeTicks::Now(); | |
| 219 if (now <= last_deadline_max_) | |
| 220 return; | |
| 221 | |
| 222 // This shows vsyncs stops rendering frames. A probable cause is that the | |
| 223 // tab is not in the front. But we still have to let old frames go. | |
| 224 const base::TimeTicks deadline_max = | |
| 225 std::max(now, last_deadline_max_ + last_render_length_); | |
| 226 | |
| 227 Render(deadline_max - last_render_length_, deadline_max); | |
| 228 } | 237 } |
| 229 | 238 |
| 230 bool WebMediaPlayerMSCompositor::UpdateCurrentFrame( | 239 bool WebMediaPlayerMSCompositor::UpdateCurrentFrame( |
| 231 base::TimeTicks deadline_min, | 240 base::TimeTicks deadline_min, |
| 232 base::TimeTicks deadline_max) { | 241 base::TimeTicks deadline_max) { |
| 233 DCHECK(compositor_task_runner_->BelongsToCurrentThread()); | 242 DCHECK(compositor_task_runner_->BelongsToCurrentThread()); |
| 234 | 243 |
| 235 TRACE_EVENT_BEGIN2("webrtc", "WebMediaPlayerMS::UpdateCurrentFrame", | 244 TRACE_EVENT_BEGIN2("webrtc", "WebMediaPlayerMS::UpdateCurrentFrame", |
| 236 "Actual Render Begin", deadline_min.ToInternalValue(), | 245 "Actual Render Begin", deadline_min.ToInternalValue(), |
| 237 "Actual Render End", deadline_max.ToInternalValue()); | 246 "Actual Render End", deadline_max.ToInternalValue()); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 } | 400 } |
| 392 | 401 |
| 393 if (!rendering_frame_buffer_) { | 402 if (!rendering_frame_buffer_) { |
| 394 rendering_frame_buffer_.reset(new media::VideoRendererAlgorithm( | 403 rendering_frame_buffer_.reset(new media::VideoRendererAlgorithm( |
| 395 base::Bind(&WebMediaPlayerMSCompositor::MapTimestampsToRenderTimeTicks, | 404 base::Bind(&WebMediaPlayerMSCompositor::MapTimestampsToRenderTimeTicks, |
| 396 base::Unretained(this)))); | 405 base::Unretained(this)))); |
| 397 } | 406 } |
| 398 } | 407 } |
| 399 | 408 |
| 400 } // namespace content | 409 } // namespace content |
| OLD | NEW |