Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(32)

Unified Diff: content/common/gpu/media/gl_surface_capturer.cc

Issue 22935009: Add content::SurfaceCapturer (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@screencast_stride
Patch Set: cff149b4 WIP Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/common/gpu/media/gl_surface_capturer.cc
diff --git a/content/common/gpu/media/gl_surface_capturer.cc b/content/common/gpu/media/gl_surface_capturer.cc
new file mode 100644
index 0000000000000000000000000000000000000000..21814fe55699224472db44509c6e89a74a469126
--- /dev/null
+++ b/content/common/gpu/media/gl_surface_capturer.cc
@@ -0,0 +1,151 @@
+// Copyright (c) 2013 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/common/gpu/media/gl_surface_capturer.h"
+
+#include "base/message_loop/message_loop_proxy.h"
+#include "content/common/gpu/gpu_channel.h"
+#include "content/common/gpu/gpu_messages.h"
+#include "ipc/ipc_message_macros.h"
+
+namespace content {
+
+GLSurfaceCapturer::GLSurfaceCapturer(int32 route_id, GpuCommandBufferStub* stub)
+ : weak_this_factory_(this),
+ route_id_(route_id),
+ stub_(stub),
+ output_format_(media::VideoFrame::INVALID) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ stub_->AddDestructionObserver(this);
+ stub_->channel()->AddRoute(route_id_, this);
+}
+
+GLSurfaceCapturer::~GLSurfaceCapturer() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ if (surface_capturer_)
+ surface_capturer_.release()->Destroy();
+
+ stub_->channel()->RemoveRoute(route_id_);
+ stub_->RemoveDestructionObserver(this);
+}
+
+bool GLSurfaceCapturer::OnMessageReceived(const IPC::Message& message) {
+ if (!surface_capturer_)
+ return false;
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(GLSurfaceCapturer, message)
+ IPC_MESSAGE_HANDLER(SurfaceCapturerMsg_Initialize, OnInitialize)
+ IPC_MESSAGE_HANDLER(SurfaceCapturerMsg_Capture, OnCapture)
+ IPC_MESSAGE_HANDLER(SurfaceCapturerMsg_Destroy, OnDestroy)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void GLSurfaceCapturer::NotifyCaptureParameters(const gfx::Size& buffer_size,
+ const gfx::Rect& visible_rect) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ output_buffer_size_ = buffer_size;
+ output_visible_rect_ = visible_rect;
+ Send(new SurfaceCapturerHostMsg_NotifyCaptureParameters(
+ route_id_, buffer_size, visible_rect));
+}
+
+void GLSurfaceCapturer::NotifyError(SurfaceCapturer::Error error) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ Send(new SurfaceCapturerHostMsg_NotifyError(route_id_, error));
+}
+
+void GLSurfaceCapturer::OnWillDestroyStub() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ delete this;
+}
+
+void GLSurfaceCapturer::OnInitialize(media::VideoFrame::Format format) {
+ DVLOG(2) << "OnInitialize(): format=" << format;
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(!surface_capturer_);
+
+ // TODO(sheu): actually create a capturer.
+
+ if (!surface_capturer_) {
+ NOTIMPLEMENTED() << "OnInitialize(): GL surface capturing not available.";
+ NotifyError(SurfaceCapturer::kPlatformFailureError);
+ return;
+ }
+
+ output_format_ = format;
+ surface_capturer_->Initialize(output_format_);
+}
+
+void GLSurfaceCapturer::OnCapture(int32 frame_id,
+ base::SharedMemoryHandle buffer_shm,
+ uint32_t buffer_size) {
+ DVLOG(3) << "OnCapture(): frame_id=" << frame_id
+ << ", buffer_size=" << buffer_size;
+ DCHECK(thread_checker_.CalledOnValidThread());
+ if (!surface_capturer_)
+ return;
+ if (frame_id < 0) {
+ DLOG(ERROR) << "OnCapture(): invalid frame_id=" << frame_id;
+ NotifyError(SurfaceCapturer::kPlatformFailureError);
+ return;
+ }
+
+ scoped_ptr<base::SharedMemory> shm(new base::SharedMemory(buffer_shm, true));
+ if (!shm->Map(buffer_size)) {
+ DLOG(ERROR) << "OnCapture(): could not map frame_id=" << frame_id;
+ NotifyError(SurfaceCapturer::kPlatformFailureError);
+ return;
+ }
+ scoped_refptr<media::VideoFrame> frame =
+ media::VideoFrame::WrapExternalSharedMemory(
+ output_format_,
+ output_buffer_size_,
+ output_visible_rect_,
+ output_visible_rect_.size(),
+ reinterpret_cast<uint8*>(shm->memory()),
+ buffer_size,
+ buffer_shm,
+ base::TimeDelta(),
+ base::Bind(base::IgnoreResult(&base::MessageLoopProxy::PostTask),
+ base::MessageLoopProxy::current(),
+ FROM_HERE,
+ base::Bind(&GLSurfaceCapturer::CaptureFrameFinished,
+ weak_this_factory_.GetWeakPtr(),
+ frame_id,
+ base::Passed(&shm))));
+ if (!frame) {
+ DLOG(ERROR) << "OnCapture(): could not create frame for"
+ "frame_id=" << frame_id;
+ NotifyError(SurfaceCapturer::kPlatformFailureError);
+ return;
+ }
+ surface_capturer_->Capture(frame);
+}
+
+void GLSurfaceCapturer::OnDestroy() {
+ DVLOG(2) << "OnDestroy()";
+ DCHECK(thread_checker_.CalledOnValidThread());
+ delete this;
+}
+
+void GLSurfaceCapturer::CaptureFrameFinished(
+ int32 frame_id,
+ scoped_ptr<base::SharedMemory> shm) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ Send(new SurfaceCapturerHostMsg_NotifyCaptureDone(route_id_, frame_id));
+ // Let shm fall out of scope.
+}
+
+void GLSurfaceCapturer::Send(IPC::Message* message) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ uint32 type = message->type();
+ if (!stub_->channel()->Send(message)) {
+ DLOG(ERROR) << "Send(): sending failed: message->type()=" << type;
+ NotifyError(SurfaceCapturer::kPlatformFailureError);
+ }
+}
+
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698