| 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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 69   // |callback| will however be released on the main render thread. | 69   // |callback| will however be released on the main render thread. | 
| 70   void AddCallback(const MediaStreamVideoTrack* track, | 70   void AddCallback(const MediaStreamVideoTrack* track, | 
| 71                    const VideoCaptureDeliverFrameCB& callback); | 71                    const VideoCaptureDeliverFrameCB& callback); | 
| 72 | 72 | 
| 73   // Removes |callback| associated with |track| from receiving video frames if | 73   // Removes |callback| associated with |track| from receiving video frames if | 
| 74   // |track| has been added. It is ok to call RemoveCallback even if the |track| | 74   // |track| has been added. It is ok to call RemoveCallback even if the |track| | 
| 75   // has not been added. The |callback| is released on the main render thread. | 75   // has not been added. The |callback| is released on the main render thread. | 
| 76   void RemoveCallback(const MediaStreamVideoTrack* track); | 76   void RemoveCallback(const MediaStreamVideoTrack* track); | 
| 77 | 77 | 
| 78   void DeliverFrame(const scoped_refptr<media::VideoFrame>& frame, | 78   void DeliverFrame(const scoped_refptr<media::VideoFrame>& frame, | 
| 79                     const media::VideoCaptureFormat& format, |  | 
| 80                     const base::TimeTicks& estimated_capture_time); | 79                     const base::TimeTicks& estimated_capture_time); | 
| 81 | 80 | 
| 82   // Returns true if all arguments match with the output of this adapter. | 81   // Returns true if all arguments match with the output of this adapter. | 
| 83   bool ConstraintsMatch(const gfx::Size& max_size, | 82   bool ConstraintsMatch(const gfx::Size& max_size, | 
| 84                         double min_aspect_ratio, | 83                         double min_aspect_ratio, | 
| 85                         double max_aspect_ratio, | 84                         double max_aspect_ratio, | 
| 86                         double max_frame_rate) const; | 85                         double max_frame_rate) const; | 
| 87 | 86 | 
| 88   bool IsEmpty() const; | 87   bool IsEmpty() const; | 
| 89 | 88 | 
| 90  private: | 89  private: | 
| 91   virtual ~VideoFrameResolutionAdapter(); | 90   virtual ~VideoFrameResolutionAdapter(); | 
| 92   friend class base::RefCountedThreadSafe<VideoFrameResolutionAdapter>; | 91   friend class base::RefCountedThreadSafe<VideoFrameResolutionAdapter>; | 
| 93 | 92 | 
| 94   virtual void DoDeliverFrame( | 93   virtual void DoDeliverFrame( | 
| 95       const scoped_refptr<media::VideoFrame>& frame, | 94       const scoped_refptr<media::VideoFrame>& frame, | 
| 96       const media::VideoCaptureFormat& format, |  | 
| 97       const base::TimeTicks& estimated_capture_time); | 95       const base::TimeTicks& estimated_capture_time); | 
| 98 | 96 | 
| 99   // Returns |true| if the input frame rate is higher that the requested max | 97   // Returns |true| if the input frame rate is higher that the requested max | 
| 100   // frame rate and |frame| should be dropped. | 98   // frame rate and |frame| should be dropped. | 
| 101   bool MaybeDropFrame(const scoped_refptr<media::VideoFrame>& frame, | 99   bool MaybeDropFrame(const scoped_refptr<media::VideoFrame>& frame, | 
| 102                       float source_frame_rate); | 100                       float source_frame_rate); | 
| 103 | 101 | 
| 104   // Bound to the IO-thread. | 102   // Bound to the IO-thread. | 
| 105   base::ThreadChecker io_thread_checker_; | 103   base::ThreadChecker io_thread_checker_; | 
| 106 | 104 | 
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 167 } | 165 } | 
| 168 | 166 | 
| 169 VideoTrackAdapter:: | 167 VideoTrackAdapter:: | 
| 170 VideoFrameResolutionAdapter::~VideoFrameResolutionAdapter() { | 168 VideoFrameResolutionAdapter::~VideoFrameResolutionAdapter() { | 
| 171   DCHECK(io_thread_checker_.CalledOnValidThread()); | 169   DCHECK(io_thread_checker_.CalledOnValidThread()); | 
| 172   DCHECK(callbacks_.empty()); | 170   DCHECK(callbacks_.empty()); | 
| 173 } | 171 } | 
| 174 | 172 | 
| 175 void VideoTrackAdapter::VideoFrameResolutionAdapter::DeliverFrame( | 173 void VideoTrackAdapter::VideoFrameResolutionAdapter::DeliverFrame( | 
| 176     const scoped_refptr<media::VideoFrame>& frame, | 174     const scoped_refptr<media::VideoFrame>& frame, | 
| 177     const media::VideoCaptureFormat& format, |  | 
| 178     const base::TimeTicks& estimated_capture_time) { | 175     const base::TimeTicks& estimated_capture_time) { | 
| 179   DCHECK(io_thread_checker_.CalledOnValidThread()); | 176   DCHECK(io_thread_checker_.CalledOnValidThread()); | 
| 180 | 177 | 
| 181   if (MaybeDropFrame(frame, format.frame_rate)) | 178   double frame_rate; | 
|  | 179   if (!frame->metadata()->GetDouble(media::VideoFrameMetadata::FRAME_RATE, | 
|  | 180                                     &frame_rate)) { | 
|  | 181     frame_rate = MediaStreamVideoSource::kUnknownFrameRate; | 
|  | 182   } | 
|  | 183   if (MaybeDropFrame(frame, frame_rate)) | 
| 182     return; | 184     return; | 
| 183 | 185 | 
| 184   // TODO(perkj): Allow cropping / scaling of textures once | 186   // TODO(perkj): Allow cropping / scaling of textures once | 
| 185   // http://crbug/362521 is fixed. | 187   // http://crbug/362521 is fixed. | 
| 186   if (frame->format() == media::VideoFrame::NATIVE_TEXTURE) { | 188   if (frame->format() == media::VideoFrame::NATIVE_TEXTURE) { | 
| 187     DoDeliverFrame(frame, format, estimated_capture_time); | 189     DoDeliverFrame(frame, estimated_capture_time); | 
| 188     return; | 190     return; | 
| 189   } | 191   } | 
| 190   scoped_refptr<media::VideoFrame> video_frame(frame); | 192   scoped_refptr<media::VideoFrame> video_frame(frame); | 
| 191   double input_ratio = | 193   double input_ratio = | 
| 192       static_cast<double>(frame->natural_size().width()) / | 194       static_cast<double>(frame->natural_size().width()) / | 
| 193       frame->natural_size().height(); | 195       frame->natural_size().height(); | 
| 194 | 196 | 
| 195   // If |frame| has larger width or height than requested, or the aspect ratio | 197   // If |frame| has larger width or height than requested, or the aspect ratio | 
| 196   // does not match the requested, we want to create a wrapped version of this | 198   // does not match the requested, we want to create a wrapped version of this | 
| 197   // frame with a size that fulfills the constraints. | 199   // frame with a size that fulfills the constraints. | 
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 239         region_in_frame, | 241         region_in_frame, | 
| 240         desired_size, | 242         desired_size, | 
| 241         base::Bind(&ReleaseOriginalFrame, frame)); | 243         base::Bind(&ReleaseOriginalFrame, frame)); | 
| 242 | 244 | 
| 243     DVLOG(3) << "desired size  " << desired_size.ToString() | 245     DVLOG(3) << "desired size  " << desired_size.ToString() | 
| 244              << " output natural size " | 246              << " output natural size " | 
| 245              << video_frame->natural_size().ToString() | 247              << video_frame->natural_size().ToString() | 
| 246              << " output visible rect  " | 248              << " output visible rect  " | 
| 247              << video_frame->visible_rect().ToString(); | 249              << video_frame->visible_rect().ToString(); | 
| 248   } | 250   } | 
| 249   DoDeliverFrame(video_frame, format, estimated_capture_time); | 251   DoDeliverFrame(video_frame, estimated_capture_time); | 
| 250 } | 252 } | 
| 251 | 253 | 
| 252 bool VideoTrackAdapter::VideoFrameResolutionAdapter::MaybeDropFrame( | 254 bool VideoTrackAdapter::VideoFrameResolutionAdapter::MaybeDropFrame( | 
| 253     const scoped_refptr<media::VideoFrame>& frame, | 255     const scoped_refptr<media::VideoFrame>& frame, | 
| 254     float source_frame_rate) { | 256     float source_frame_rate) { | 
| 255   DCHECK(io_thread_checker_.CalledOnValidThread()); | 257   DCHECK(io_thread_checker_.CalledOnValidThread()); | 
| 256 | 258 | 
| 257   // Do not drop frames if max frame rate hasn't been specified or the source | 259   // Do not drop frames if max frame rate hasn't been specified or the source | 
| 258   // frame rate is known and is lower than max. | 260   // frame rate is known and is lower than max. | 
| 259   if (max_frame_rate_ == 0.0f || | 261   if (max_frame_rate_ == 0.0f || | 
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 304     // Keep the frame. | 306     // Keep the frame. | 
| 305     return false; | 307     return false; | 
| 306   } | 308   } | 
| 307   DVLOG(3) << "Drop frame. Input frame_rate_ " << frame_rate_ << "."; | 309   DVLOG(3) << "Drop frame. Input frame_rate_ " << frame_rate_ << "."; | 
| 308   return true; | 310   return true; | 
| 309 } | 311 } | 
| 310 | 312 | 
| 311 void VideoTrackAdapter:: | 313 void VideoTrackAdapter:: | 
| 312 VideoFrameResolutionAdapter::DoDeliverFrame( | 314 VideoFrameResolutionAdapter::DoDeliverFrame( | 
| 313     const scoped_refptr<media::VideoFrame>& frame, | 315     const scoped_refptr<media::VideoFrame>& frame, | 
| 314     const media::VideoCaptureFormat& format, |  | 
| 315     const base::TimeTicks& estimated_capture_time) { | 316     const base::TimeTicks& estimated_capture_time) { | 
| 316   DCHECK(io_thread_checker_.CalledOnValidThread()); | 317   DCHECK(io_thread_checker_.CalledOnValidThread()); | 
| 317   for (std::vector<VideoIdCallbackPair>::const_iterator it = callbacks_.begin(); | 318   for (const auto& entry : callbacks_) | 
| 318        it != callbacks_.end(); ++it) { | 319     entry.second.Run(frame, estimated_capture_time); | 
| 319     it->second.Run(frame, format, estimated_capture_time); |  | 
| 320   } |  | 
| 321 } | 320 } | 
| 322 | 321 | 
| 323 void VideoTrackAdapter::VideoFrameResolutionAdapter::AddCallback( | 322 void VideoTrackAdapter::VideoFrameResolutionAdapter::AddCallback( | 
| 324     const MediaStreamVideoTrack* track, | 323     const MediaStreamVideoTrack* track, | 
| 325     const VideoCaptureDeliverFrameCB& callback) { | 324     const VideoCaptureDeliverFrameCB& callback) { | 
| 326   DCHECK(io_thread_checker_.CalledOnValidThread()); | 325   DCHECK(io_thread_checker_.CalledOnValidThread()); | 
| 327   callbacks_.push_back(std::make_pair(track, callback)); | 326   callbacks_.push_back(std::make_pair(track, callback)); | 
| 328 } | 327 } | 
| 329 | 328 | 
| 330 void VideoTrackAdapter::VideoFrameResolutionAdapter::RemoveCallback( | 329 void VideoTrackAdapter::VideoFrameResolutionAdapter::RemoveCallback( | 
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 487     (*it)->RemoveCallback(track); | 486     (*it)->RemoveCallback(track); | 
| 488     if ((*it)->IsEmpty()) { | 487     if ((*it)->IsEmpty()) { | 
| 489       adapters_.erase(it); | 488       adapters_.erase(it); | 
| 490       break; | 489       break; | 
| 491     } | 490     } | 
| 492   } | 491   } | 
| 493 } | 492 } | 
| 494 | 493 | 
| 495 void VideoTrackAdapter::DeliverFrameOnIO( | 494 void VideoTrackAdapter::DeliverFrameOnIO( | 
| 496     const scoped_refptr<media::VideoFrame>& frame, | 495     const scoped_refptr<media::VideoFrame>& frame, | 
| 497     const media::VideoCaptureFormat& format, |  | 
| 498     const base::TimeTicks& estimated_capture_time) { | 496     const base::TimeTicks& estimated_capture_time) { | 
| 499   DCHECK(io_message_loop_->BelongsToCurrentThread()); | 497   DCHECK(io_message_loop_->BelongsToCurrentThread()); | 
| 500   TRACE_EVENT0("video", "VideoTrackAdapter::DeliverFrameOnIO"); | 498   TRACE_EVENT0("video", "VideoTrackAdapter::DeliverFrameOnIO"); | 
| 501   ++frame_counter_; | 499   ++frame_counter_; | 
| 502   for (FrameAdapters::iterator it = adapters_.begin(); | 500   for (const auto& adapter : adapters_) | 
| 503        it != adapters_.end(); ++it) { | 501     adapter->DeliverFrame(frame, estimated_capture_time); | 
| 504     (*it)->DeliverFrame(frame, format, estimated_capture_time); |  | 
| 505   } |  | 
| 506 } | 502 } | 
| 507 | 503 | 
| 508 void VideoTrackAdapter::CheckFramesReceivedOnIO( | 504 void VideoTrackAdapter::CheckFramesReceivedOnIO( | 
| 509     const OnMutedCallback& set_muted_state_callback, | 505     const OnMutedCallback& set_muted_state_callback, | 
| 510     uint64 old_frame_counter_snapshot) { | 506     uint64 old_frame_counter_snapshot) { | 
| 511   DCHECK(io_message_loop_->BelongsToCurrentThread()); | 507   DCHECK(io_message_loop_->BelongsToCurrentThread()); | 
| 512 | 508 | 
| 513   if (!monitoring_frame_rate_) | 509   if (!monitoring_frame_rate_) | 
| 514     return; | 510     return; | 
| 515 | 511 | 
| 516   DVLOG_IF(1, old_frame_counter_snapshot == frame_counter_) | 512   DVLOG_IF(1, old_frame_counter_snapshot == frame_counter_) | 
| 517       << "No frames have passed, setting source as Muted."; | 513       << "No frames have passed, setting source as Muted."; | 
| 518 | 514 | 
| 519   bool muted_state = old_frame_counter_snapshot == frame_counter_; | 515   bool muted_state = old_frame_counter_snapshot == frame_counter_; | 
| 520   if (muted_state_ != muted_state) { | 516   if (muted_state_ != muted_state) { | 
| 521     set_muted_state_callback.Run(muted_state); | 517     set_muted_state_callback.Run(muted_state); | 
| 522     muted_state_ = muted_state; | 518     muted_state_ = muted_state; | 
| 523   } | 519   } | 
| 524 | 520 | 
| 525   io_message_loop_->PostDelayedTask(FROM_HERE, | 521   io_message_loop_->PostDelayedTask(FROM_HERE, | 
| 526       base::Bind(&VideoTrackAdapter::CheckFramesReceivedOnIO, this, | 522       base::Bind(&VideoTrackAdapter::CheckFramesReceivedOnIO, this, | 
| 527           set_muted_state_callback, frame_counter_), | 523           set_muted_state_callback, frame_counter_), | 
| 528       base::TimeDelta::FromSecondsD(kNormalFrameTimeoutInFrameIntervals / | 524       base::TimeDelta::FromSecondsD(kNormalFrameTimeoutInFrameIntervals / | 
| 529                                     source_frame_rate_)); | 525                                     source_frame_rate_)); | 
| 530 } | 526 } | 
| 531 | 527 | 
| 532 }  // namespace content | 528 }  // namespace content | 
| OLD | NEW | 
|---|