| 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 |