| Index: content/renderer/media/image_capture_frame_grabber.cc
|
| diff --git a/content/renderer/media/image_capture_frame_grabber.cc b/content/renderer/media/image_capture_frame_grabber.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..901758efbecbbd72a3cc7762ebbe685c744000bd
|
| --- /dev/null
|
| +++ b/content/renderer/media/image_capture_frame_grabber.cc
|
| @@ -0,0 +1,97 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "content/renderer/media/image_capture_frame_grabber.h"
|
| +
|
| +#include "media/base/bind_to_current_loop.h"
|
| +#include "media/base/video_frame.h"
|
| +#include "media/base/video_util.h"
|
| +#include "third_party/WebKit/public/platform/WebCallbacks.h"
|
| +#include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
|
| +#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
|
| +#include "third_party/libyuv/include/libyuv.h"
|
| +#include "third_party/skia/include/core/SkBitmap.h"
|
| +
|
| +namespace content {
|
| +
|
| +using blink::WebImageCaptureGrabFrameCallbacks;
|
| +
|
| +namespace {
|
| +
|
| +void OnError(std::unique_ptr<WebImageCaptureGrabFrameCallbacks> callbacks) {
|
| + callbacks->onError();
|
| +}
|
| +
|
| +void OnVideoFrame(const ImageCaptureFrameGrabber::SkBitmapDeliverCB& callback,
|
| + const scoped_refptr<media::VideoFrame>& video_frame,
|
| + base::TimeTicks /* current_time */) {
|
| + DCHECK(video_frame->format() == media::PIXEL_FORMAT_YV12 ||
|
| + video_frame->format() == media::PIXEL_FORMAT_I420 ||
|
| + video_frame->format() == media::PIXEL_FORMAT_YV12A);
|
| +
|
| + scoped_refptr<media::VideoFrame> frame = video_frame;
|
| + // Drop alpha channel since it's not supported in libyuv conversion to RGBA.
|
| + if (frame->format() == media::PIXEL_FORMAT_YV12A)
|
| + frame = media::WrapAsI420VideoFrame(video_frame);
|
| +
|
| + std::unique_ptr<SkBitmap> bitmap(new SkBitmap());
|
| + bitmap->allocN32Pixels(frame->visible_rect().width(),
|
| + frame->visible_rect().height(),
|
| + true /* isOpaque */);
|
| +
|
| + libyuv::I420ToARGB(frame->visible_data(media::VideoFrame::kYPlane),
|
| + frame->stride(media::VideoFrame::kYPlane),
|
| + frame->visible_data(media::VideoFrame::kUPlane),
|
| + frame->stride(media::VideoFrame::kUPlane),
|
| + frame->visible_data(media::VideoFrame::kVPlane),
|
| + frame->stride(media::VideoFrame::kVPlane),
|
| + static_cast<uint8*>(bitmap->getPixels()),
|
| + bitmap->width() * 4, bitmap->width(), bitmap->height());
|
| +
|
| + callback.Run(std::move(bitmap));
|
| +}
|
| +
|
| +} // anonymous namespace
|
| +
|
| +ImageCaptureFrameGrabber::ImageCaptureFrameGrabber() : weak_factory_(this) {}
|
| +
|
| +ImageCaptureFrameGrabber::~ImageCaptureFrameGrabber() {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| +}
|
| +
|
| +void ImageCaptureFrameGrabber::grabFrame(
|
| + blink::WebMediaStreamTrack* track,
|
| + WebImageCaptureGrabFrameCallbacks* callbacks) {
|
| + DVLOG(1) << __FUNCTION__;
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| + DCHECK(!!callbacks);
|
| +
|
| + DCHECK(track && !track->isNull() && track->getExtraData());
|
| + DCHECK_EQ(blink::WebMediaStreamSource::TypeVideo, track->source().getType());
|
| +
|
| + ScopedWebCallbacks<WebImageCaptureGrabFrameCallbacks> scoped_callbacks =
|
| + make_scoped_web_callbacks(callbacks, base::Bind(&OnError));
|
| +
|
| + // ConnectToTrack() must happen on render's Main Thread, whereas VideoFrames
|
| + // are delivered on a background thread though, so we Bind the callback to our
|
| + // current thread.
|
| + MediaStreamVideoSink::ConnectToTrack(
|
| + *track,
|
| + base::Bind(&OnVideoFrame, media::BindToCurrentLoop(base::Bind(
|
| + &ImageCaptureFrameGrabber::OnSkBitmap,
|
| + weak_factory_.GetWeakPtr(),
|
| + base::Passed(&scoped_callbacks)))));
|
| +}
|
| +
|
| +void ImageCaptureFrameGrabber::OnSkBitmap(
|
| + ScopedWebCallbacks<WebImageCaptureGrabFrameCallbacks> callbacks,
|
| + std::unique_ptr<SkBitmap> bitmap) {
|
| + DVLOG(1) << __FUNCTION__;
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| +
|
| + MediaStreamVideoSink::DisconnectFromTrack();
|
| + callbacks.PassCallbacks()->onSuccess(std::move(bitmap));
|
| +}
|
| +
|
| +} // namespace content
|
|
|