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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 const scoped_refptr<media::VideoFrame>& frame) { | 42 const scoped_refptr<media::VideoFrame>& frame) { |
43 } | 43 } |
44 | 44 |
45 void ResetCallbackOnMainRenderThread( | 45 void ResetCallbackOnMainRenderThread( |
46 scoped_ptr<VideoCaptureDeliverFrameCB> callback) { | 46 scoped_ptr<VideoCaptureDeliverFrameCB> callback) { |
47 // |callback| will be deleted when this exits. | 47 // |callback| will be deleted when this exits. |
48 } | 48 } |
49 | 49 |
50 } // anonymous namespace | 50 } // anonymous namespace |
51 | 51 |
52 // VideoFrameResolutionAdapter is created on and lives on | 52 // VideoFrameResolutionAdapter is created on and lives on the IO-thread. It does |
53 // on the IO-thread. It does the resolution adaptation and delivers frames to | 53 // the resolution adaptation and delivers frames to all registered tracks on the |
54 // all registered tracks on the IO-thread. | 54 // IO-thread. All method calls must be on the IO-thread. |
55 // All method calls must be on the IO-thread. | |
56 class VideoTrackAdapter::VideoFrameResolutionAdapter | 55 class VideoTrackAdapter::VideoFrameResolutionAdapter |
57 : public base::RefCountedThreadSafe<VideoFrameResolutionAdapter> { | 56 : public base::RefCountedThreadSafe<VideoFrameResolutionAdapter> { |
58 public: | 57 public: |
59 // Setting |max_frame_rate| to 0.0, means that no frame rate limitation | 58 // Setting |max_frame_rate| to 0.0, means that no frame rate limitation |
60 // will be done. | 59 // will be done. |
61 VideoFrameResolutionAdapter( | 60 VideoFrameResolutionAdapter( |
62 scoped_refptr<base::SingleThreadTaskRunner> render_message_loop, | 61 scoped_refptr<base::SingleThreadTaskRunner> render_message_loop, |
63 const gfx::Size& max_size, | 62 const gfx::Size& max_size, |
64 double min_aspect_ratio, | 63 double min_aspect_ratio, |
65 double max_aspect_ratio, | 64 double max_aspect_ratio, |
(...skipping 17 matching lines...) Expand all Loading... |
83 double min_aspect_ratio, | 82 double min_aspect_ratio, |
84 double max_aspect_ratio, | 83 double max_aspect_ratio, |
85 double max_frame_rate) const; | 84 double max_frame_rate) const; |
86 | 85 |
87 bool IsEmpty() const; | 86 bool IsEmpty() const; |
88 | 87 |
89 private: | 88 private: |
90 virtual ~VideoFrameResolutionAdapter(); | 89 virtual ~VideoFrameResolutionAdapter(); |
91 friend class base::RefCountedThreadSafe<VideoFrameResolutionAdapter>; | 90 friend class base::RefCountedThreadSafe<VideoFrameResolutionAdapter>; |
92 | 91 |
93 virtual void DoDeliverFrame( | 92 void DoDeliverFrame(const scoped_refptr<media::VideoFrame>& frame, |
94 const scoped_refptr<media::VideoFrame>& frame, | 93 const base::TimeTicks& estimated_capture_time); |
95 const base::TimeTicks& estimated_capture_time); | |
96 | 94 |
97 // Returns |true| if the input frame rate is higher that the requested max | 95 // Returns |true| if the input frame rate is higher that the requested max |
98 // frame rate and |frame| should be dropped. | 96 // frame rate and |frame| should be dropped. |
99 bool MaybeDropFrame(const scoped_refptr<media::VideoFrame>& frame, | 97 bool MaybeDropFrame(const scoped_refptr<media::VideoFrame>& frame, |
100 float source_frame_rate); | 98 float source_frame_rate); |
101 | 99 |
102 // Bound to the IO-thread. | 100 // Bound to the IO-thread. |
103 base::ThreadChecker io_thread_checker_; | 101 base::ThreadChecker io_thread_checker_; |
104 | 102 |
105 // The task runner where we will release VideoCaptureDeliverFrameCB | 103 // The task runner where we will release VideoCaptureDeliverFrameCB |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 } | 250 } |
253 | 251 |
254 bool VideoTrackAdapter::VideoFrameResolutionAdapter::MaybeDropFrame( | 252 bool VideoTrackAdapter::VideoFrameResolutionAdapter::MaybeDropFrame( |
255 const scoped_refptr<media::VideoFrame>& frame, | 253 const scoped_refptr<media::VideoFrame>& frame, |
256 float source_frame_rate) { | 254 float source_frame_rate) { |
257 DCHECK(io_thread_checker_.CalledOnValidThread()); | 255 DCHECK(io_thread_checker_.CalledOnValidThread()); |
258 | 256 |
259 // Do not drop frames if max frame rate hasn't been specified or the source | 257 // Do not drop frames if max frame rate hasn't been specified or the source |
260 // frame rate is known and is lower than max. | 258 // frame rate is known and is lower than max. |
261 if (max_frame_rate_ == 0.0f || | 259 if (max_frame_rate_ == 0.0f || |
262 (source_frame_rate > 0 && | 260 (source_frame_rate > 0 && source_frame_rate <= max_frame_rate_)) { |
263 source_frame_rate <= max_frame_rate_)) { | |
264 return false; | 261 return false; |
265 } | 262 } |
266 | 263 |
267 const double delta_ms = | 264 const double delta_ms = |
268 (frame->timestamp() - last_time_stamp_).InMillisecondsF(); | 265 (frame->timestamp() - last_time_stamp_).InMillisecondsF(); |
269 | 266 |
270 // Check if the time since the last frame is completely off. | 267 // Check if the time since the last frame is completely off. |
271 if (delta_ms < 0 || delta_ms > kMaxTimeInMsBetweenFrames) { | 268 if (delta_ms < 0 || delta_ms > kMaxTimeInMsBetweenFrames) { |
272 // Reset |last_time_stamp_| and fps calculation. | 269 // Reset |last_time_stamp_| and fps calculation. |
273 last_time_stamp_ = frame->timestamp(); | 270 last_time_stamp_ = frame->timestamp(); |
(...skipping 29 matching lines...) Expand all Loading... |
303 keep_frame_counter_ += max_frame_rate_ / frame_rate_; | 300 keep_frame_counter_ += max_frame_rate_ / frame_rate_; |
304 if (keep_frame_counter_ >= 1) { | 301 if (keep_frame_counter_ >= 1) { |
305 keep_frame_counter_ -= 1; | 302 keep_frame_counter_ -= 1; |
306 // Keep the frame. | 303 // Keep the frame. |
307 return false; | 304 return false; |
308 } | 305 } |
309 DVLOG(3) << "Drop frame. Input frame_rate_ " << frame_rate_ << "."; | 306 DVLOG(3) << "Drop frame. Input frame_rate_ " << frame_rate_ << "."; |
310 return true; | 307 return true; |
311 } | 308 } |
312 | 309 |
313 void VideoTrackAdapter:: | 310 void VideoTrackAdapter::VideoFrameResolutionAdapter::DoDeliverFrame( |
314 VideoFrameResolutionAdapter::DoDeliverFrame( | |
315 const scoped_refptr<media::VideoFrame>& frame, | 311 const scoped_refptr<media::VideoFrame>& frame, |
316 const base::TimeTicks& estimated_capture_time) { | 312 const base::TimeTicks& estimated_capture_time) { |
317 DCHECK(io_thread_checker_.CalledOnValidThread()); | 313 DCHECK(io_thread_checker_.CalledOnValidThread()); |
318 for (const auto& entry : callbacks_) | 314 for (const auto& callback : callbacks_) |
319 entry.second.Run(frame, estimated_capture_time); | 315 callback.second.Run(frame, estimated_capture_time); |
320 } | 316 } |
321 | 317 |
322 void VideoTrackAdapter::VideoFrameResolutionAdapter::AddCallback( | 318 void VideoTrackAdapter::VideoFrameResolutionAdapter::AddCallback( |
323 const MediaStreamVideoTrack* track, | 319 const MediaStreamVideoTrack* track, |
324 const VideoCaptureDeliverFrameCB& callback) { | 320 const VideoCaptureDeliverFrameCB& callback) { |
325 DCHECK(io_thread_checker_.CalledOnValidThread()); | 321 DCHECK(io_thread_checker_.CalledOnValidThread()); |
326 callbacks_.push_back(std::make_pair(track, callback)); | 322 callbacks_.push_back(std::make_pair(track, callback)); |
327 } | 323 } |
328 | 324 |
329 void VideoTrackAdapter::VideoFrameResolutionAdapter::RemoveCallback( | 325 void VideoTrackAdapter::VideoFrameResolutionAdapter::RemoveCallback( |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 muted_state_(false), | 368 muted_state_(false), |
373 frame_counter_(0), | 369 frame_counter_(0), |
374 source_frame_rate_(0.0f) { | 370 source_frame_rate_(0.0f) { |
375 DCHECK(io_message_loop_.get()); | 371 DCHECK(io_message_loop_.get()); |
376 } | 372 } |
377 | 373 |
378 VideoTrackAdapter::~VideoTrackAdapter() { | 374 VideoTrackAdapter::~VideoTrackAdapter() { |
379 DCHECK(adapters_.empty()); | 375 DCHECK(adapters_.empty()); |
380 } | 376 } |
381 | 377 |
382 void VideoTrackAdapter::AddTrack( | 378 void VideoTrackAdapter::AddTrack(const MediaStreamVideoTrack* track, |
383 const MediaStreamVideoTrack* track, | 379 VideoCaptureDeliverFrameCB frame_callback, |
384 VideoCaptureDeliverFrameCB frame_callback, | 380 int max_width, |
385 int max_width, | 381 int max_height, |
386 int max_height, | 382 double min_aspect_ratio, |
387 double min_aspect_ratio, | 383 double max_aspect_ratio, |
388 double max_aspect_ratio, | 384 double max_frame_rate) { |
389 double max_frame_rate) { | |
390 DCHECK(thread_checker_.CalledOnValidThread()); | 385 DCHECK(thread_checker_.CalledOnValidThread()); |
391 | 386 |
392 io_message_loop_->PostTask( | 387 io_message_loop_->PostTask( |
393 FROM_HERE, | 388 FROM_HERE, |
394 base::Bind(&VideoTrackAdapter::AddTrackOnIO, | 389 base::Bind(&VideoTrackAdapter::AddTrackOnIO, |
395 this, track, frame_callback, gfx::Size(max_width, max_height), | 390 this, track, frame_callback, gfx::Size(max_width, max_height), |
396 min_aspect_ratio, max_aspect_ratio, max_frame_rate)); | 391 min_aspect_ratio, max_aspect_ratio, max_frame_rate)); |
397 } | 392 } |
398 | 393 |
399 void VideoTrackAdapter::AddTrackOnIO( | 394 void VideoTrackAdapter::AddTrackOnIO(const MediaStreamVideoTrack* track, |
400 const MediaStreamVideoTrack* track, | 395 VideoCaptureDeliverFrameCB frame_callback, |
401 VideoCaptureDeliverFrameCB frame_callback, | 396 const gfx::Size& max_frame_size, |
402 const gfx::Size& max_frame_size, | 397 double min_aspect_ratio, |
403 double min_aspect_ratio, | 398 double max_aspect_ratio, |
404 double max_aspect_ratio, | 399 double max_frame_rate) { |
405 double max_frame_rate) { | |
406 DCHECK(io_message_loop_->BelongsToCurrentThread()); | 400 DCHECK(io_message_loop_->BelongsToCurrentThread()); |
407 scoped_refptr<VideoFrameResolutionAdapter> adapter; | 401 scoped_refptr<VideoFrameResolutionAdapter> adapter; |
408 for (FrameAdapters::const_iterator it = adapters_.begin(); | 402 for (const auto& frame_adapter : adapters_) { |
409 it != adapters_.end(); ++it) { | 403 if (frame_adapter->ConstraintsMatch(max_frame_size, min_aspect_ratio, |
410 if ((*it)->ConstraintsMatch(max_frame_size, min_aspect_ratio, | 404 max_aspect_ratio, max_frame_rate)) { |
411 max_aspect_ratio, max_frame_rate)) { | 405 adapter = frame_adapter.get(); |
412 adapter = it->get(); | |
413 break; | 406 break; |
414 } | 407 } |
415 } | 408 } |
416 if (!adapter.get()) { | 409 if (!adapter.get()) { |
417 adapter = new VideoFrameResolutionAdapter(renderer_task_runner_, | 410 adapter = new VideoFrameResolutionAdapter(renderer_task_runner_, |
418 max_frame_size, | 411 max_frame_size, |
419 min_aspect_ratio, | 412 min_aspect_ratio, |
420 max_aspect_ratio, | 413 max_aspect_ratio, |
421 max_frame_rate); | 414 max_frame_rate); |
422 adapters_.push_back(adapter); | 415 adapters_.push_back(adapter); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
519 } | 512 } |
520 | 513 |
521 io_message_loop_->PostDelayedTask(FROM_HERE, | 514 io_message_loop_->PostDelayedTask(FROM_HERE, |
522 base::Bind(&VideoTrackAdapter::CheckFramesReceivedOnIO, this, | 515 base::Bind(&VideoTrackAdapter::CheckFramesReceivedOnIO, this, |
523 set_muted_state_callback, frame_counter_), | 516 set_muted_state_callback, frame_counter_), |
524 base::TimeDelta::FromSecondsD(kNormalFrameTimeoutInFrameIntervals / | 517 base::TimeDelta::FromSecondsD(kNormalFrameTimeoutInFrameIntervals / |
525 source_frame_rate_)); | 518 source_frame_rate_)); |
526 } | 519 } |
527 | 520 |
528 } // namespace content | 521 } // namespace content |
OLD | NEW |