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 21 matching lines...) Expand all Loading... |
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 const blink::WebSize& size = canvas_handler_->GetSourceSize(); | 41 const blink::WebSize& size = canvas_handler_->GetSourceSize(); |
42 const media::VideoCaptureFormat format(gfx::Size(size.width, size.height), | |
43 frame_rate_, | |
44 media::PIXEL_FORMAT_I420); | |
45 media::VideoCaptureFormats formats; | 42 media::VideoCaptureFormats formats; |
46 formats.push_back(format); | 43 formats.push_back( |
| 44 media::VideoCaptureFormat(gfx::Size(size.width, size.height), |
| 45 frame_rate_, media::PIXEL_FORMAT_I420)); |
| 46 formats.push_back( |
| 47 media::VideoCaptureFormat(gfx::Size(size.width, size.height), |
| 48 frame_rate_, media::PIXEL_FORMAT_YV12A)); |
47 callback.Run(formats); | 49 callback.Run(formats); |
48 } | 50 } |
49 void StartCapture(const media::VideoCaptureParams& params, | 51 void StartCapture(const media::VideoCaptureParams& params, |
50 const VideoCaptureDeliverFrameCB& frame_callback, | 52 const VideoCaptureDeliverFrameCB& frame_callback, |
51 const RunningCallback& running_callback) override { | 53 const RunningCallback& running_callback) override { |
52 canvas_handler_->StartVideoCapture(params, frame_callback, | 54 canvas_handler_->StartVideoCapture(params, frame_callback, |
53 running_callback); | 55 running_callback); |
54 } | 56 } |
55 void StopCapture() override { | 57 void StopCapture() override { |
56 canvas_handler_->StopVideoCapture(); | 58 canvas_handler_->StopVideoCapture(); |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 | 161 |
160 void CanvasCaptureHandler::StopVideoCapture() { | 162 void CanvasCaptureHandler::StopVideoCapture() { |
161 DVLOG(3) << __FUNCTION__; | 163 DVLOG(3) << __FUNCTION__; |
162 DCHECK(thread_checker_.CalledOnValidThread()); | 164 DCHECK(thread_checker_.CalledOnValidThread()); |
163 ask_for_new_frame_ = false; | 165 ask_for_new_frame_ = false; |
164 io_task_runner_->DeleteSoon(FROM_HERE, delegate_.release()); | 166 io_task_runner_->DeleteSoon(FROM_HERE, delegate_.release()); |
165 } | 167 } |
166 | 168 |
167 void CanvasCaptureHandler::CreateNewFrame(const SkImage* image) { | 169 void CanvasCaptureHandler::CreateNewFrame(const SkImage* image) { |
168 DCHECK(thread_checker_.CalledOnValidThread()); | 170 DCHECK(thread_checker_.CalledOnValidThread()); |
| 171 DCHECK(image); |
169 | 172 |
170 DCHECK(image); | |
171 const gfx::Size size(image->width(), image->height()); | 173 const gfx::Size size(image->width(), image->height()); |
172 if (size != last_size) { | 174 if (size != last_size) { |
173 temp_data_.resize( | 175 temp_data_.resize( |
174 media::VideoFrame::AllocationSize(media::PIXEL_FORMAT_ARGB, size)); | 176 media::VideoFrame::AllocationSize(media::PIXEL_FORMAT_ARGB, size)); |
175 row_bytes_ = | 177 row_bytes_ = |
176 media::VideoFrame::RowBytes(0, media::PIXEL_FORMAT_ARGB, size.width()); | 178 media::VideoFrame::RowBytes(0, media::PIXEL_FORMAT_ARGB, size.width()); |
177 image_info_ = | 179 image_info_ = |
178 SkImageInfo::Make(size.width(), size.height(), kBGRA_8888_SkColorType, | 180 SkImageInfo::Make(size.width(), size.height(), kBGRA_8888_SkColorType, |
179 kPremul_SkAlphaType); | 181 kUnpremul_SkAlphaType); |
180 last_size = size; | 182 last_size = size; |
181 } | 183 } |
182 | 184 |
183 image->readPixels(image_info_, &temp_data_[0], row_bytes_, 0, 0); | 185 if(!image->readPixels(image_info_, &temp_data_[0], row_bytes_, 0, 0)) { |
184 scoped_refptr<media::VideoFrame> video_frame = | 186 DLOG(ERROR) << "Couldn't read SkImage pixels"; |
185 frame_pool_.CreateFrame(media::PIXEL_FORMAT_I420, size, gfx::Rect(size), | 187 return; |
186 size, base::TimeTicks::Now() - base::TimeTicks()); | 188 } |
| 189 |
| 190 const bool isOpaque = image->isOpaque(); |
| 191 scoped_refptr<media::VideoFrame> video_frame = frame_pool_.CreateFrame( |
| 192 isOpaque ? media::PIXEL_FORMAT_I420 : media::PIXEL_FORMAT_YV12A, size, |
| 193 gfx::Rect(size), size, base::TimeTicks::Now() - base::TimeTicks()); |
187 DCHECK(video_frame); | 194 DCHECK(video_frame); |
188 | 195 |
| 196 // TODO(emircan): Use https://code.google.com/p/libyuv/issues/detail?id=572 |
| 197 // when it becomes available. |
189 libyuv::ARGBToI420(temp_data_.data(), row_bytes_, | 198 libyuv::ARGBToI420(temp_data_.data(), row_bytes_, |
190 video_frame->data(media::VideoFrame::kYPlane), | 199 video_frame->data(media::VideoFrame::kYPlane), |
191 video_frame->stride(media::VideoFrame::kYPlane), | 200 video_frame->stride(media::VideoFrame::kYPlane), |
192 video_frame->data(media::VideoFrame::kUPlane), | 201 video_frame->data(media::VideoFrame::kUPlane), |
193 video_frame->stride(media::VideoFrame::kUPlane), | 202 video_frame->stride(media::VideoFrame::kUPlane), |
194 video_frame->data(media::VideoFrame::kVPlane), | 203 video_frame->data(media::VideoFrame::kVPlane), |
195 video_frame->stride(media::VideoFrame::kVPlane), | 204 video_frame->stride(media::VideoFrame::kVPlane), |
196 size.width(), size.height()); | 205 size.width(), size.height()); |
| 206 if (!isOpaque) { |
| 207 for (int p = 0; p < size.GetArea(); ++p) |
| 208 video_frame->data(media::VideoFrame::kAPlane)[p] = temp_data_[p * 4 + 3]; |
| 209 } |
| 210 |
197 io_task_runner_->PostTask( | 211 io_task_runner_->PostTask( |
198 FROM_HERE, | 212 FROM_HERE, |
199 base::Bind(&CanvasCaptureHandler::CanvasCaptureHandlerDelegate:: | 213 base::Bind(&CanvasCaptureHandler::CanvasCaptureHandlerDelegate:: |
200 SendNewFrameOnIOThread, | 214 SendNewFrameOnIOThread, |
201 delegate_->GetWeakPtrForIOThread(), video_frame, | 215 delegate_->GetWeakPtrForIOThread(), video_frame, |
202 base::TimeTicks())); | 216 base::TimeTicks())); |
203 } | 217 } |
204 | 218 |
205 void CanvasCaptureHandler::AddVideoCapturerSourceToVideoTrack( | 219 void CanvasCaptureHandler::AddVideoCapturerSourceToVideoTrack( |
206 scoped_ptr<media::VideoCapturerSource> source, | 220 scoped_ptr<media::VideoCapturerSource> source, |
(...skipping 11 matching lines...) Expand all Loading... |
218 | 232 |
219 web_track->initialize(webkit_source); | 233 web_track->initialize(webkit_source); |
220 blink::WebMediaConstraints constraints; | 234 blink::WebMediaConstraints constraints; |
221 constraints.initialize(); | 235 constraints.initialize(); |
222 web_track->setExtraData(new MediaStreamVideoTrack( | 236 web_track->setExtraData(new MediaStreamVideoTrack( |
223 media_stream_source.release(), constraints, | 237 media_stream_source.release(), constraints, |
224 MediaStreamVideoSource::ConstraintsCallback(), true)); | 238 MediaStreamVideoSource::ConstraintsCallback(), true)); |
225 } | 239 } |
226 | 240 |
227 } // namespace content | 241 } // namespace content |
OLD | NEW |