diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 28893a54a3..12e0c56ceb 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -1069,7 +1069,7 @@ void WebContents::BeginFrameSubscription( const auto view = web_contents()->GetRenderWidgetHostView(); if (view) { scoped_ptr frame_subscriber(new FrameSubscriber( - isolate(), view->GetVisibleViewportSize(), callback)); + isolate(), view, callback)); view->BeginFrameSubscription(frame_subscriber.Pass()); } } diff --git a/atom/browser/api/frame_subscriber.cc b/atom/browser/api/frame_subscriber.cc index b2b049ce8b..c76d5ffc87 100644 --- a/atom/browser/api/frame_subscriber.cc +++ b/atom/browser/api/frame_subscriber.cc @@ -4,19 +4,18 @@ #include "atom/browser/api/frame_subscriber.h" -#include "atom/common/node_includes.h" #include "base/bind.h" -#include "media/base/video_frame.h" -#include "media/base/yuv_convert.h" +#include "atom/common/node_includes.h" +#include "content/public/browser/render_widget_host.h" namespace atom { namespace api { FrameSubscriber::FrameSubscriber(v8::Isolate* isolate, - const gfx::Size& size, + content::RenderWidgetHostView* view, const FrameCaptureCallback& callback) - : isolate_(isolate), size_(size), callback_(callback), weak_factory_(this) { + : isolate_(isolate), view_(view), callback_(callback), weak_factory_(this) { } bool FrameSubscriber::ShouldCaptureFrame( @@ -24,39 +23,39 @@ bool FrameSubscriber::ShouldCaptureFrame( base::TimeTicks present_time, scoped_refptr* storage, DeliverFrameCallback* callback) { - *storage = media::VideoFrame::CreateFrame( - media::PIXEL_FORMAT_YV12, - size_, gfx::Rect(size_), size_, base::TimeDelta()); - *callback = base::Bind(&FrameSubscriber::OnFrameDelivered, - weak_factory_.GetWeakPtr(), *storage); - return true; + const auto host = view_ ? view_->GetRenderWidgetHost() : nullptr; + if (!view_ || !host) + return false; + + const auto size = view_->GetVisibleViewportSize(); + + host->CopyFromBackingStore( + gfx::Rect(size), + size, + base::Bind(&FrameSubscriber::OnFrameDelivered, + weak_factory_.GetWeakPtr(), callback_), + kBGRA_8888_SkColorType); + + return false; } -void FrameSubscriber::OnFrameDelivered( - scoped_refptr frame, base::TimeTicks, bool result) { - if (!result) +void FrameSubscriber::OnFrameDelivered(const FrameCaptureCallback& callback, + const SkBitmap& bitmap, content::ReadbackResponse response) { + if (bitmap.computeSize64() == 0) return; v8::Locker locker(isolate_); v8::HandleScope handle_scope(isolate_); - gfx::Rect rect = frame->visible_rect(); - size_t rgb_arr_size = rect.width() * rect.height() * 4; + size_t rgb_arr_size = bitmap.width() * bitmap.height() * + bitmap.bytesPerPixel(); v8::MaybeLocal buffer = node::Buffer::New(isolate_, rgb_arr_size); if (buffer.IsEmpty()) return; - // Convert a frame of YUV to 32 bit ARGB. - media::ConvertYUVToRGB32(frame->data(media::VideoFrame::kYPlane), - frame->data(media::VideoFrame::kUPlane), - frame->data(media::VideoFrame::kVPlane), - reinterpret_cast( - node::Buffer::Data(buffer.ToLocalChecked())), - rect.width(), rect.height(), - frame->stride(media::VideoFrame::kYPlane), - frame->stride(media::VideoFrame::kUVPlane), - rect.width() * 4, - media::YV12); + bitmap.copyPixelsTo( + reinterpret_cast(node::Buffer::Data(buffer.ToLocalChecked())), + rgb_arr_size); callback_.Run(buffer.ToLocalChecked()); } diff --git a/atom/browser/api/frame_subscriber.h b/atom/browser/api/frame_subscriber.h index 089c4922d7..a803d75dff 100644 --- a/atom/browser/api/frame_subscriber.h +++ b/atom/browser/api/frame_subscriber.h @@ -7,7 +7,10 @@ #include "base/callback.h" #include "base/memory/weak_ptr.h" +#include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/render_widget_host_view_frame_subscriber.h" +#include "content/public/browser/readback_types.h" +#include "third_party/skia/include/core/SkBitmap.h" #include "ui/gfx/geometry/size.h" #include "v8/include/v8.h" @@ -20,7 +23,7 @@ class FrameSubscriber : public content::RenderWidgetHostViewFrameSubscriber { using FrameCaptureCallback = base::Callback)>; FrameSubscriber(v8::Isolate* isolate, - const gfx::Size& size, + content::RenderWidgetHostView* view, const FrameCaptureCallback& callback); bool ShouldCaptureFrame(const gfx::Rect& damage_rect, @@ -29,11 +32,11 @@ class FrameSubscriber : public content::RenderWidgetHostViewFrameSubscriber { DeliverFrameCallback* callback) override; private: - void OnFrameDelivered( - scoped_refptr frame, base::TimeTicks, bool); + void OnFrameDelivered(const FrameCaptureCallback& callback, + const SkBitmap& bitmap, content::ReadbackResponse response); v8::Isolate* isolate_; - gfx::Size size_; + content::RenderWidgetHostView* view_; FrameCaptureCallback callback_; base::WeakPtrFactory weak_factory_;