| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/image_capture_frame_grabber.h" | 5 #include "content/renderer/media/image_capture_frame_grabber.h" |
| 6 | 6 |
| 7 #include "media/base/bind_to_current_loop.h" | 7 #include "media/base/bind_to_current_loop.h" |
| 8 #include "media/base/video_frame.h" | 8 #include "media/base/video_frame.h" |
| 9 #include "media/base/video_util.h" | 9 #include "media/base/video_util.h" |
| 10 #include "skia/ext/platform_canvas.h" | 10 #include "skia/ext/platform_canvas.h" |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 libyuv::ARGBCopyYToAlpha(frame->visible_data(media::VideoFrame::kAPlane), | 99 libyuv::ARGBCopyYToAlpha(frame->visible_data(media::VideoFrame::kAPlane), |
| 100 frame->stride(media::VideoFrame::kAPlane), | 100 frame->stride(media::VideoFrame::kAPlane), |
| 101 static_cast<uint8*>(pixmap.writable_addr()), | 101 static_cast<uint8*>(pixmap.writable_addr()), |
| 102 pixmap.width() * 4, pixmap.width(), | 102 pixmap.width() * 4, pixmap.width(), |
| 103 pixmap.height()); | 103 pixmap.height()); |
| 104 } | 104 } |
| 105 | 105 |
| 106 callback.Run(surface->makeImageSnapshot()); | 106 callback.Run(surface->makeImageSnapshot()); |
| 107 } | 107 } |
| 108 | 108 |
| 109 ImageCaptureFrameGrabber::ImageCaptureFrameGrabber() : weak_factory_(this) {} | 109 ImageCaptureFrameGrabber::ImageCaptureFrameGrabber() |
| 110 : frame_grab_in_progress_(false), weak_factory_(this) {} |
| 110 | 111 |
| 111 ImageCaptureFrameGrabber::~ImageCaptureFrameGrabber() { | 112 ImageCaptureFrameGrabber::~ImageCaptureFrameGrabber() { |
| 112 DCHECK(thread_checker_.CalledOnValidThread()); | 113 DCHECK(thread_checker_.CalledOnValidThread()); |
| 113 } | 114 } |
| 114 | 115 |
| 115 void ImageCaptureFrameGrabber::grabFrame( | 116 void ImageCaptureFrameGrabber::grabFrame( |
| 116 blink::WebMediaStreamTrack* track, | 117 blink::WebMediaStreamTrack* track, |
| 117 WebImageCaptureGrabFrameCallbacks* callbacks) { | 118 WebImageCaptureGrabFrameCallbacks* callbacks) { |
| 118 DCHECK(thread_checker_.CalledOnValidThread()); | 119 DCHECK(thread_checker_.CalledOnValidThread()); |
| 119 DCHECK(!!callbacks); | 120 DCHECK(!!callbacks); |
| 120 | 121 |
| 121 DCHECK(track && !track->isNull() && track->getTrackData()); | 122 DCHECK(track && !track->isNull() && track->getTrackData()); |
| 122 DCHECK_EQ(blink::WebMediaStreamSource::TypeVideo, track->source().getType()); | 123 DCHECK_EQ(blink::WebMediaStreamSource::TypeVideo, track->source().getType()); |
| 123 | 124 |
| 125 if (frame_grab_in_progress_) { |
| 126 // Reject grabFrame()s too close back to back. |
| 127 callbacks->onError(); |
| 128 return; |
| 129 } |
| 130 |
| 124 ScopedWebCallbacks<WebImageCaptureGrabFrameCallbacks> scoped_callbacks = | 131 ScopedWebCallbacks<WebImageCaptureGrabFrameCallbacks> scoped_callbacks = |
| 125 make_scoped_web_callbacks(callbacks, base::Bind(&OnError)); | 132 make_scoped_web_callbacks(callbacks, base::Bind(&OnError)); |
| 126 | 133 |
| 127 // A SingleShotFrameHandler is bound and given to the Track to guarantee that | 134 // A SingleShotFrameHandler is bound and given to the Track to guarantee that |
| 128 // only one VideoFrame is converted and delivered to OnSkImage(), otherwise | 135 // only one VideoFrame is converted and delivered to OnSkImage(), otherwise |
| 129 // SKImages might be sent to resolved |callbacks| while DisconnectFromTrack() | 136 // SKImages might be sent to resolved |callbacks| while DisconnectFromTrack() |
| 130 // is being processed, which might be further held up if UI is busy, see | 137 // is being processed, which might be further held up if UI is busy, see |
| 131 // https://crbug.com/623042. | 138 // https://crbug.com/623042. |
| 139 frame_grab_in_progress_ = true; |
| 132 MediaStreamVideoSink::ConnectToTrack( | 140 MediaStreamVideoSink::ConnectToTrack( |
| 133 *track, base::Bind(&SingleShotFrameHandler::OnVideoFrameOnIOThread, | 141 *track, base::Bind(&SingleShotFrameHandler::OnVideoFrameOnIOThread, |
| 134 make_scoped_refptr(new SingleShotFrameHandler), | 142 make_scoped_refptr(new SingleShotFrameHandler), |
| 135 media::BindToCurrentLoop( | 143 media::BindToCurrentLoop( |
| 136 base::Bind(&ImageCaptureFrameGrabber::OnSkImage, | 144 base::Bind(&ImageCaptureFrameGrabber::OnSkImage, |
| 137 weak_factory_.GetWeakPtr(), | 145 weak_factory_.GetWeakPtr(), |
| 138 base::Passed(&scoped_callbacks)))), | 146 base::Passed(&scoped_callbacks)))), |
| 139 false); | 147 false); |
| 140 } | 148 } |
| 141 | 149 |
| 142 void ImageCaptureFrameGrabber::OnSkImage( | 150 void ImageCaptureFrameGrabber::OnSkImage( |
| 143 ScopedWebCallbacks<blink::WebImageCaptureGrabFrameCallbacks> callbacks, | 151 ScopedWebCallbacks<blink::WebImageCaptureGrabFrameCallbacks> callbacks, |
| 144 sk_sp<SkImage> image) { | 152 sk_sp<SkImage> image) { |
| 145 DCHECK(thread_checker_.CalledOnValidThread()); | 153 DCHECK(thread_checker_.CalledOnValidThread()); |
| 146 | 154 |
| 147 MediaStreamVideoSink::DisconnectFromTrack(); | 155 MediaStreamVideoSink::DisconnectFromTrack(); |
| 156 frame_grab_in_progress_ = false; |
| 148 if (image) | 157 if (image) |
| 149 callbacks.PassCallbacks()->onSuccess(image); | 158 callbacks.PassCallbacks()->onSuccess(image); |
| 150 else | 159 else |
| 151 callbacks.PassCallbacks()->onError(); | 160 callbacks.PassCallbacks()->onError(); |
| 152 } | 161 } |
| 153 | 162 |
| 154 } // namespace content | 163 } // namespace content |
| OLD | NEW |