| 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/canvas_capture_handler.h" | 5 #include "content/renderer/media/canvas_capture_handler.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/base64.h" | 9 #include "base/base64.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 double frame_rate) | 31 double frame_rate) |
| 32 : frame_rate_(frame_rate), | 32 : frame_rate_(frame_rate), |
| 33 canvas_handler_(canvas_handler) {} | 33 canvas_handler_(canvas_handler) {} |
| 34 | 34 |
| 35 protected: | 35 protected: |
| 36 void GetCurrentSupportedFormats( | 36 void GetCurrentSupportedFormats( |
| 37 int max_requested_width, | 37 int max_requested_width, |
| 38 int max_requested_height, | 38 int max_requested_height, |
| 39 double max_requested_frame_rate, | 39 double max_requested_frame_rate, |
| 40 const VideoCaptureDeviceFormatsCB& callback) override { | 40 const VideoCaptureDeviceFormatsCB& callback) override { |
| 41 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
| 41 const blink::WebSize& size = canvas_handler_->GetSourceSize(); | 42 const blink::WebSize& size = canvas_handler_->GetSourceSize(); |
| 42 media::VideoCaptureFormats formats; | 43 media::VideoCaptureFormats formats; |
| 43 formats.push_back( | 44 formats.push_back( |
| 44 media::VideoCaptureFormat(gfx::Size(size.width, size.height), | 45 media::VideoCaptureFormat(gfx::Size(size.width, size.height), |
| 45 frame_rate_, media::PIXEL_FORMAT_I420)); | 46 frame_rate_, media::PIXEL_FORMAT_I420)); |
| 46 formats.push_back( | 47 formats.push_back( |
| 47 media::VideoCaptureFormat(gfx::Size(size.width, size.height), | 48 media::VideoCaptureFormat(gfx::Size(size.width, size.height), |
| 48 frame_rate_, media::PIXEL_FORMAT_YV12A)); | 49 frame_rate_, media::PIXEL_FORMAT_YV12A)); |
| 49 callback.Run(formats); | 50 callback.Run(formats); |
| 50 } | 51 } |
| 51 void StartCapture(const media::VideoCaptureParams& params, | 52 void StartCapture(const media::VideoCaptureParams& params, |
| 52 const VideoCaptureDeliverFrameCB& frame_callback, | 53 const VideoCaptureDeliverFrameCB& frame_callback, |
| 53 const RunningCallback& running_callback) override { | 54 const RunningCallback& running_callback) override { |
| 55 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
| 54 canvas_handler_->StartVideoCapture(params, frame_callback, | 56 canvas_handler_->StartVideoCapture(params, frame_callback, |
| 55 running_callback); | 57 running_callback); |
| 56 } | 58 } |
| 57 void StopCapture() override { | 59 void StopCapture() override { |
| 60 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
| 58 canvas_handler_->StopVideoCapture(); | 61 canvas_handler_->StopVideoCapture(); |
| 59 } | 62 } |
| 60 | 63 |
| 61 private: | 64 private: |
| 62 double frame_rate_; | 65 double frame_rate_; |
| 66 // Bound to Main Render thread. |
| 67 base::ThreadChecker main_render_thread_checker_; |
| 63 // CanvasCaptureHandler is owned by CanvasDrawListener in blink and | 68 // CanvasCaptureHandler is owned by CanvasDrawListener in blink and |
| 64 // guaranteed to be alive during the lifetime of this class. | 69 // guaranteed to be alive during the lifetime of this class. |
| 65 base::WeakPtr<CanvasCaptureHandler> canvas_handler_; | 70 base::WeakPtr<CanvasCaptureHandler> canvas_handler_; |
| 66 }; | 71 }; |
| 67 | 72 |
| 68 class CanvasCaptureHandler::CanvasCaptureHandlerDelegate { | 73 class CanvasCaptureHandler::CanvasCaptureHandlerDelegate { |
| 69 public: | 74 public: |
| 70 explicit CanvasCaptureHandlerDelegate( | 75 explicit CanvasCaptureHandlerDelegate( |
| 71 media::VideoCapturerSource::VideoCaptureDeliverFrameCB new_frame_callback) | 76 media::VideoCapturerSource::VideoCaptureDeliverFrameCB new_frame_callback) |
| 72 : new_frame_callback_(new_frame_callback), | 77 : new_frame_callback_(new_frame_callback), |
| 73 weak_ptr_factory_(this) { | 78 weak_ptr_factory_(this) { |
| 74 thread_checker_.DetachFromThread(); | 79 io_thread_checker_.DetachFromThread(); |
| 75 } | 80 } |
| 76 ~CanvasCaptureHandlerDelegate() { | 81 ~CanvasCaptureHandlerDelegate() { |
| 77 DCHECK(thread_checker_.CalledOnValidThread()); | 82 DCHECK(io_thread_checker_.CalledOnValidThread()); |
| 78 } | 83 } |
| 79 | 84 |
| 80 void SendNewFrameOnIOThread( | 85 void SendNewFrameOnIOThread( |
| 81 const scoped_refptr<media::VideoFrame>& video_frame, | 86 const scoped_refptr<media::VideoFrame>& video_frame, |
| 82 const base::TimeTicks& current_time) { | 87 const base::TimeTicks& current_time) { |
| 83 DCHECK(thread_checker_.CalledOnValidThread()); | 88 DCHECK(io_thread_checker_.CalledOnValidThread()); |
| 84 new_frame_callback_.Run(video_frame, current_time); | 89 new_frame_callback_.Run(video_frame, current_time); |
| 85 } | 90 } |
| 86 | 91 |
| 87 base::WeakPtr<CanvasCaptureHandlerDelegate> GetWeakPtrForIOThread() { | 92 base::WeakPtr<CanvasCaptureHandlerDelegate> GetWeakPtrForIOThread() { |
| 88 return weak_ptr_factory_.GetWeakPtr(); | 93 return weak_ptr_factory_.GetWeakPtr(); |
| 89 } | 94 } |
| 90 | 95 |
| 91 private: | 96 private: |
| 92 const media::VideoCapturerSource::VideoCaptureDeliverFrameCB | 97 const media::VideoCapturerSource::VideoCaptureDeliverFrameCB |
| 93 new_frame_callback_; | 98 new_frame_callback_; |
| 94 base::ThreadChecker thread_checker_; | 99 // Bound to IO thread. |
| 100 base::ThreadChecker io_thread_checker_; |
| 95 base::WeakPtrFactory<CanvasCaptureHandlerDelegate> weak_ptr_factory_; | 101 base::WeakPtrFactory<CanvasCaptureHandlerDelegate> weak_ptr_factory_; |
| 96 | 102 |
| 97 DISALLOW_COPY_AND_ASSIGN(CanvasCaptureHandlerDelegate); | 103 DISALLOW_COPY_AND_ASSIGN(CanvasCaptureHandlerDelegate); |
| 98 }; | 104 }; |
| 99 | 105 |
| 100 CanvasCaptureHandler::CanvasCaptureHandler( | 106 CanvasCaptureHandler::CanvasCaptureHandler( |
| 101 const blink::WebSize& size, | 107 const blink::WebSize& size, |
| 102 double frame_rate, | 108 double frame_rate, |
| 103 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner, | 109 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner, |
| 104 blink::WebMediaStreamTrack* track) | 110 blink::WebMediaStreamTrack* track) |
| 105 : ask_for_new_frame_(false), | 111 : ask_for_new_frame_(false), |
| 106 size_(size), | 112 size_(size), |
| 107 io_task_runner_(io_task_runner), | 113 io_task_runner_(io_task_runner), |
| 108 weak_ptr_factory_(this) { | 114 weak_ptr_factory_(this) { |
| 109 scoped_ptr<media::VideoCapturerSource> video_source( | 115 scoped_ptr<media::VideoCapturerSource> video_source( |
| 110 new CanvasCaptureHandler::VideoCapturerSource( | 116 new CanvasCaptureHandler::VideoCapturerSource( |
| 111 weak_ptr_factory_.GetWeakPtr(), frame_rate)); | 117 weak_ptr_factory_.GetWeakPtr(), frame_rate)); |
| 112 AddVideoCapturerSourceToVideoTrack(std::move(video_source), track); | 118 AddVideoCapturerSourceToVideoTrack(std::move(video_source), track); |
| 113 } | 119 } |
| 114 | 120 |
| 115 CanvasCaptureHandler::~CanvasCaptureHandler() { | 121 CanvasCaptureHandler::~CanvasCaptureHandler() { |
| 116 DVLOG(3) << __FUNCTION__; | 122 DVLOG(3) << __FUNCTION__; |
| 117 DCHECK(thread_checker_.CalledOnValidThread()); | 123 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
| 118 io_task_runner_->DeleteSoon(FROM_HERE, delegate_.release()); | 124 io_task_runner_->DeleteSoon(FROM_HERE, delegate_.release()); |
| 119 } | 125 } |
| 120 | 126 |
| 121 // static | 127 // static |
| 122 CanvasCaptureHandler* CanvasCaptureHandler::CreateCanvasCaptureHandler( | 128 CanvasCaptureHandler* CanvasCaptureHandler::CreateCanvasCaptureHandler( |
| 123 const blink::WebSize& size, | 129 const blink::WebSize& size, |
| 124 double frame_rate, | 130 double frame_rate, |
| 125 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner, | 131 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner, |
| 126 blink::WebMediaStreamTrack* track) { | 132 blink::WebMediaStreamTrack* track) { |
| 127 // Save histogram data so we can see how much CanvasCapture is used. | 133 // Save histogram data so we can see how much CanvasCapture is used. |
| 128 // The histogram counts the number of calls to the JS API. | 134 // The histogram counts the number of calls to the JS API. |
| 129 UpdateWebRTCMethodCount(WEBKIT_CANVAS_CAPTURE_STREAM); | 135 UpdateWebRTCMethodCount(WEBKIT_CANVAS_CAPTURE_STREAM); |
| 130 | 136 |
| 131 return new CanvasCaptureHandler(size, frame_rate, io_task_runner, track); | 137 return new CanvasCaptureHandler(size, frame_rate, io_task_runner, track); |
| 132 } | 138 } |
| 133 | 139 |
| 134 void CanvasCaptureHandler::sendNewFrame(const SkImage* image) { | 140 void CanvasCaptureHandler::sendNewFrame(const SkImage* image) { |
| 135 DCHECK(thread_checker_.CalledOnValidThread()); | 141 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
| 136 CreateNewFrame(image); | 142 CreateNewFrame(image); |
| 137 } | 143 } |
| 138 | 144 |
| 139 bool CanvasCaptureHandler::needsNewFrame() const { | 145 bool CanvasCaptureHandler::needsNewFrame() const { |
| 140 DCHECK(thread_checker_.CalledOnValidThread()); | 146 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
| 141 return ask_for_new_frame_; | 147 return ask_for_new_frame_; |
| 142 } | 148 } |
| 143 | 149 |
| 144 void CanvasCaptureHandler::StartVideoCapture( | 150 void CanvasCaptureHandler::StartVideoCapture( |
| 145 const media::VideoCaptureParams& params, | 151 const media::VideoCaptureParams& params, |
| 146 const media::VideoCapturerSource::VideoCaptureDeliverFrameCB& | 152 const media::VideoCapturerSource::VideoCaptureDeliverFrameCB& |
| 147 new_frame_callback, | 153 new_frame_callback, |
| 148 const media::VideoCapturerSource::RunningCallback& running_callback) { | 154 const media::VideoCapturerSource::RunningCallback& running_callback) { |
| 149 DVLOG(3) << __FUNCTION__ << " requested " | 155 DVLOG(3) << __FUNCTION__ << " requested " |
| 150 << media::VideoCaptureFormat::ToString(params.requested_format); | 156 << media::VideoCaptureFormat::ToString(params.requested_format); |
| 157 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
| 151 DCHECK(params.requested_format.IsValid()); | 158 DCHECK(params.requested_format.IsValid()); |
| 152 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 153 | 159 |
| 154 // TODO(emircan): Accomodate to the given frame rate constraints here. | 160 // TODO(emircan): Accomodate to the given frame rate constraints here. |
| 155 capture_format_ = params.requested_format; | 161 capture_format_ = params.requested_format; |
| 156 delegate_.reset(new CanvasCaptureHandlerDelegate(new_frame_callback)); | 162 delegate_.reset(new CanvasCaptureHandlerDelegate(new_frame_callback)); |
| 157 DCHECK(delegate_); | 163 DCHECK(delegate_); |
| 158 ask_for_new_frame_ = true; | 164 ask_for_new_frame_ = true; |
| 159 running_callback.Run(true); | 165 running_callback.Run(true); |
| 160 } | 166 } |
| 161 | 167 |
| 162 void CanvasCaptureHandler::StopVideoCapture() { | 168 void CanvasCaptureHandler::StopVideoCapture() { |
| 163 DVLOG(3) << __FUNCTION__; | 169 DVLOG(3) << __FUNCTION__; |
| 164 DCHECK(thread_checker_.CalledOnValidThread()); | 170 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
| 165 ask_for_new_frame_ = false; | 171 ask_for_new_frame_ = false; |
| 166 io_task_runner_->DeleteSoon(FROM_HERE, delegate_.release()); | 172 io_task_runner_->DeleteSoon(FROM_HERE, delegate_.release()); |
| 167 } | 173 } |
| 168 | 174 |
| 169 void CanvasCaptureHandler::CreateNewFrame(const SkImage* image) { | 175 void CanvasCaptureHandler::CreateNewFrame(const SkImage* image) { |
| 170 DCHECK(thread_checker_.CalledOnValidThread()); | 176 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
| 171 DCHECK(image); | 177 DCHECK(image); |
| 172 | 178 |
| 173 const gfx::Size size(image->width(), image->height()); | 179 const gfx::Size size(image->width(), image->height()); |
| 174 if (size != last_size) { | 180 if (size != last_size) { |
| 175 temp_data_.resize( | 181 temp_data_.resize( |
| 176 media::VideoFrame::AllocationSize(media::PIXEL_FORMAT_ARGB, size)); | 182 media::VideoFrame::AllocationSize(media::PIXEL_FORMAT_ARGB, size)); |
| 177 row_bytes_ = | 183 row_bytes_ = |
| 178 media::VideoFrame::RowBytes(0, media::PIXEL_FORMAT_ARGB, size.width()); | 184 media::VideoFrame::RowBytes(0, media::PIXEL_FORMAT_ARGB, size.width()); |
| 179 image_info_ = | 185 image_info_ = |
| 180 SkImageInfo::Make(size.width(), size.height(), kBGRA_8888_SkColorType, | 186 SkImageInfo::Make(size.width(), size.height(), kBGRA_8888_SkColorType, |
| (...skipping 25 matching lines...) Expand all Loading... |
| 206 if (!isOpaque) { | 212 if (!isOpaque) { |
| 207 for (int p = 0; p < size.GetArea(); ++p) | 213 for (int p = 0; p < size.GetArea(); ++p) |
| 208 video_frame->data(media::VideoFrame::kAPlane)[p] = temp_data_[p * 4 + 3]; | 214 video_frame->data(media::VideoFrame::kAPlane)[p] = temp_data_[p * 4 + 3]; |
| 209 } | 215 } |
| 210 | 216 |
| 211 io_task_runner_->PostTask( | 217 io_task_runner_->PostTask( |
| 212 FROM_HERE, | 218 FROM_HERE, |
| 213 base::Bind(&CanvasCaptureHandler::CanvasCaptureHandlerDelegate:: | 219 base::Bind(&CanvasCaptureHandler::CanvasCaptureHandlerDelegate:: |
| 214 SendNewFrameOnIOThread, | 220 SendNewFrameOnIOThread, |
| 215 delegate_->GetWeakPtrForIOThread(), video_frame, | 221 delegate_->GetWeakPtrForIOThread(), video_frame, |
| 216 base::TimeTicks())); | 222 base::TimeTicks::Now())); |
| 217 } | 223 } |
| 218 | 224 |
| 219 void CanvasCaptureHandler::AddVideoCapturerSourceToVideoTrack( | 225 void CanvasCaptureHandler::AddVideoCapturerSourceToVideoTrack( |
| 220 scoped_ptr<media::VideoCapturerSource> source, | 226 scoped_ptr<media::VideoCapturerSource> source, |
| 221 blink::WebMediaStreamTrack* web_track) { | 227 blink::WebMediaStreamTrack* web_track) { |
| 222 std::string str_track_id; | 228 std::string str_track_id; |
| 223 base::Base64Encode(base::RandBytesAsString(64), &str_track_id); | 229 base::Base64Encode(base::RandBytesAsString(64), &str_track_id); |
| 224 const blink::WebString track_id = base::UTF8ToUTF16(str_track_id); | 230 const blink::WebString track_id = base::UTF8ToUTF16(str_track_id); |
| 225 blink::WebMediaStreamSource webkit_source; | 231 blink::WebMediaStreamSource webkit_source; |
| 226 scoped_ptr<MediaStreamVideoSource> media_stream_source( | 232 scoped_ptr<MediaStreamVideoSource> media_stream_source( |
| 227 new MediaStreamVideoCapturerSource( | 233 new MediaStreamVideoCapturerSource( |
| 228 MediaStreamSource::SourceStoppedCallback(), std::move(source))); | 234 MediaStreamSource::SourceStoppedCallback(), std::move(source))); |
| 229 webkit_source.initialize(track_id, blink::WebMediaStreamSource::TypeVideo, | 235 webkit_source.initialize(track_id, blink::WebMediaStreamSource::TypeVideo, |
| 230 track_id, false, true); | 236 track_id, false, true); |
| 231 webkit_source.setExtraData(media_stream_source.get()); | 237 webkit_source.setExtraData(media_stream_source.get()); |
| 232 | 238 |
| 233 web_track->initialize(webkit_source); | 239 web_track->initialize(webkit_source); |
| 234 blink::WebMediaConstraints constraints; | 240 blink::WebMediaConstraints constraints; |
| 235 constraints.initialize(); | 241 constraints.initialize(); |
| 236 web_track->setExtraData(new MediaStreamVideoTrack( | 242 web_track->setExtraData(new MediaStreamVideoTrack( |
| 237 media_stream_source.release(), constraints, | 243 media_stream_source.release(), constraints, |
| 238 MediaStreamVideoSource::ConstraintsCallback(), true)); | 244 MediaStreamVideoSource::ConstraintsCallback(), true)); |
| 239 } | 245 } |
| 240 | 246 |
| 241 } // namespace content | 247 } // namespace content |
| OLD | NEW |