OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/video_track_adapter.h" | 5 #include "content/renderer/media/video_track_adapter.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <limits> | 8 #include <limits> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 virtual ~VideoFrameResolutionAdapter(); | 82 virtual ~VideoFrameResolutionAdapter(); |
83 friend class base::RefCountedThreadSafe<VideoFrameResolutionAdapter>; | 83 friend class base::RefCountedThreadSafe<VideoFrameResolutionAdapter>; |
84 | 84 |
85 virtual void DoDeliverFrame( | 85 virtual void DoDeliverFrame( |
86 const scoped_refptr<media::VideoFrame>& frame, | 86 const scoped_refptr<media::VideoFrame>& frame, |
87 const media::VideoCaptureFormat& format, | 87 const media::VideoCaptureFormat& format, |
88 const base::TimeTicks& estimated_capture_time); | 88 const base::TimeTicks& estimated_capture_time); |
89 | 89 |
90 // Returns |true| if the input frame rate is higher that the requested max | 90 // Returns |true| if the input frame rate is higher that the requested max |
91 // frame rate and |frame| should be dropped. | 91 // frame rate and |frame| should be dropped. |
92 bool MaybeDropFrame(const scoped_refptr<media::VideoFrame>& frame); | 92 bool MaybeDropFrame(const scoped_refptr<media::VideoFrame>& frame, |
| 93 float source_frame_rate); |
93 | 94 |
94 // Bound to the IO-thread. | 95 // Bound to the IO-thread. |
95 base::ThreadChecker io_thread_checker_; | 96 base::ThreadChecker io_thread_checker_; |
96 | 97 |
97 // The task runner where we will release VideoCaptureDeliverFrameCB | 98 // The task runner where we will release VideoCaptureDeliverFrameCB |
98 // registered in AddCallback. | 99 // registered in AddCallback. |
99 scoped_refptr<base::SingleThreadTaskRunner> renderer_task_runner_; | 100 scoped_refptr<base::SingleThreadTaskRunner> renderer_task_runner_; |
100 | 101 |
101 gfx::Size max_frame_size_; | 102 gfx::Size max_frame_size_; |
102 double min_aspect_ratio_; | 103 double min_aspect_ratio_; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 DCHECK(io_thread_checker_.CalledOnValidThread()); | 146 DCHECK(io_thread_checker_.CalledOnValidThread()); |
146 DCHECK(callbacks_.empty()); | 147 DCHECK(callbacks_.empty()); |
147 } | 148 } |
148 | 149 |
149 void VideoTrackAdapter::VideoFrameResolutionAdapter::DeliverFrame( | 150 void VideoTrackAdapter::VideoFrameResolutionAdapter::DeliverFrame( |
150 const scoped_refptr<media::VideoFrame>& frame, | 151 const scoped_refptr<media::VideoFrame>& frame, |
151 const media::VideoCaptureFormat& format, | 152 const media::VideoCaptureFormat& format, |
152 const base::TimeTicks& estimated_capture_time) { | 153 const base::TimeTicks& estimated_capture_time) { |
153 DCHECK(io_thread_checker_.CalledOnValidThread()); | 154 DCHECK(io_thread_checker_.CalledOnValidThread()); |
154 | 155 |
155 if (MaybeDropFrame(frame)) | 156 if (MaybeDropFrame(frame, format.frame_rate)) |
156 return; | 157 return; |
157 | 158 |
158 // TODO(perkj): Allow cropping / scaling of textures once | 159 // TODO(perkj): Allow cropping / scaling of textures once |
159 // http://crbug/362521 is fixed. | 160 // http://crbug/362521 is fixed. |
160 if (frame->format() == media::VideoFrame::NATIVE_TEXTURE) { | 161 if (frame->format() == media::VideoFrame::NATIVE_TEXTURE) { |
161 DoDeliverFrame(frame, format, estimated_capture_time); | 162 DoDeliverFrame(frame, format, estimated_capture_time); |
162 return; | 163 return; |
163 } | 164 } |
164 scoped_refptr<media::VideoFrame> video_frame(frame); | 165 scoped_refptr<media::VideoFrame> video_frame(frame); |
165 double input_ratio = | 166 double input_ratio = |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 DVLOG(3) << "desired size " << desired_size.ToString() | 218 DVLOG(3) << "desired size " << desired_size.ToString() |
218 << " output natural size " | 219 << " output natural size " |
219 << video_frame->natural_size().ToString() | 220 << video_frame->natural_size().ToString() |
220 << " output visible rect " | 221 << " output visible rect " |
221 << video_frame->visible_rect().ToString(); | 222 << video_frame->visible_rect().ToString(); |
222 } | 223 } |
223 DoDeliverFrame(video_frame, format, estimated_capture_time); | 224 DoDeliverFrame(video_frame, format, estimated_capture_time); |
224 } | 225 } |
225 | 226 |
226 bool VideoTrackAdapter::VideoFrameResolutionAdapter::MaybeDropFrame( | 227 bool VideoTrackAdapter::VideoFrameResolutionAdapter::MaybeDropFrame( |
227 const scoped_refptr<media::VideoFrame>& frame) { | 228 const scoped_refptr<media::VideoFrame>& frame, |
228 if (max_frame_rate_ == 0.0f) | 229 float source_frame_rate) { |
| 230 DCHECK(io_thread_checker_.CalledOnValidThread()); |
| 231 |
| 232 // Do not drop frames if max frame rate hasn't been specified or the source |
| 233 // frame rate is known and is lower than max. |
| 234 if (max_frame_rate_ == 0.0f || |
| 235 (source_frame_rate > 0 && |
| 236 source_frame_rate <= max_frame_rate_)) |
229 return false; | 237 return false; |
230 | 238 |
231 base::TimeDelta delta = frame->timestamp() - last_time_stamp_; | 239 base::TimeDelta delta = frame->timestamp() - last_time_stamp_; |
232 if (delta.InMilliseconds() < kMinTimeInMsBetweenFrames) { | 240 if (delta.InMilliseconds() < kMinTimeInMsBetweenFrames) { |
233 // We have seen video frames being delivered from camera devices back to | 241 // We have seen video frames being delivered from camera devices back to |
234 // back. The simple AR filter for frame rate calculation is too short to | 242 // back. The simple AR filter for frame rate calculation is too short to |
235 // handle that. http://crbug/394315 | 243 // handle that. http://crbug/394315 |
236 // TODO(perkj): Can we come up with a way to fix the times stamps and the | 244 // TODO(perkj): Can we come up with a way to fix the times stamps and the |
237 // timing when frames are delivered so all frames can be used? | 245 // timing when frames are delivered so all frames can be used? |
238 // The time stamps are generated by Chrome and not the actual device. | 246 // The time stamps are generated by Chrome and not the actual device. |
239 // Most likely the back to back problem is caused by software and not the | 247 // Most likely the back to back problem is caused by software and not the |
240 // actual camera. | 248 // actual camera. |
241 DVLOG(3) << "Drop frame since delta time since previous frame is " | 249 DVLOG(3) << "Drop frame since delta time since previous frame is " |
242 << delta.InMilliseconds() << "ms."; | 250 << delta.InMilliseconds() << "ms."; |
243 return true; | 251 return true; |
244 } | 252 } |
245 last_time_stamp_ = frame->timestamp(); | 253 last_time_stamp_ = frame->timestamp(); |
246 if (delta == last_time_stamp_) // First received frame. | 254 if (delta == last_time_stamp_) // First received frame. |
247 return false; | 255 return false; |
248 // Calculate the frame rate using a simple AR filter. | 256 // Calculate the frame rate using a simple AR filter. |
249 // Use a simple filter with 0.1 weight of the current sample. | 257 // Use a simple filter with 0.1 weight of the current sample. |
250 frame_rate_ = 100 / delta.InMillisecondsF() + 0.9 * frame_rate_; | 258 frame_rate_ = 100 / delta.InMillisecondsF() + 0.9 * frame_rate_; |
251 | 259 |
252 // Prefer to not drop frames. | 260 // Prefer to not drop frames. |
253 if (max_frame_rate_ + 0.5f > frame_rate_) | 261 if (max_frame_rate_ + 0.5f > frame_rate_) |
254 return false; // Keep this frame. | 262 return false; // Keep this frame. |
255 | 263 |
256 // The input frame rate is higher than requested. | 264 // The input frame rate is higher than requested. |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
453 // Rearm the monitoring while there are active Tracks, i.e. as long as the | 461 // Rearm the monitoring while there are active Tracks, i.e. as long as the |
454 // owner MediaStreamSource is active. | 462 // owner MediaStreamSource is active. |
455 io_message_loop_->PostDelayedTask(FROM_HERE, | 463 io_message_loop_->PostDelayedTask(FROM_HERE, |
456 base::Bind(&VideoTrackAdapter::CheckFramesReceivedOnIO, this, | 464 base::Bind(&VideoTrackAdapter::CheckFramesReceivedOnIO, this, |
457 set_muted_state_callback, frame_counter_), | 465 set_muted_state_callback, frame_counter_), |
458 base::TimeDelta::FromSecondsD(kNormalFrameTimeoutInFrameIntervals / | 466 base::TimeDelta::FromSecondsD(kNormalFrameTimeoutInFrameIntervals / |
459 source_frame_rate_)); | 467 source_frame_rate_)); |
460 } | 468 } |
461 | 469 |
462 } // namespace content | 470 } // namespace content |
OLD | NEW |