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

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: a1372c98 Rebase for commit. 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
« no previous file with comments | « content/common/gpu/media/gl_surface_capturer.h ('k') | content/common/gpu/surface_capturer.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..a92848baa21fdc8d3173a9c8f13fc67adda3eed7
--- /dev/null
+++ b/content/common/gpu/media/gl_surface_capturer.cc
@@ -0,0 +1,186 @@
+// 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 {
+
+namespace {
+
+enum {
+ kMaxCaptureSize = 4096,
+};
+
+} // anonymous namespace
+
+GLSurfaceCapturer::GLSurfaceCapturer(int32 route_id, GpuCommandBufferStub* stub)
+ : thread_checker_(),
+ 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) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(GLSurfaceCapturer, message)
+ IPC_MESSAGE_HANDLER(SurfaceCapturerMsg_Initialize, OnInitialize)
+ IPC_MESSAGE_HANDLER(SurfaceCapturerMsg_TryCapture, OnTryCapture)
+ IPC_MESSAGE_HANDLER(SurfaceCapturerMsg_CopyCaptureToVideoFrame,
+ OnCopyCaptureToVideoFrame)
+ 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());
+ if (buffer_size.width() < 1 || buffer_size.width() > kMaxCaptureSize ||
+ buffer_size.height() < 1 || buffer_size.height() > kMaxCaptureSize ||
+ visible_rect.x() < 0 || visible_rect.x() > kMaxCaptureSize - 1 ||
+ visible_rect.y() < 0 || visible_rect.y() > kMaxCaptureSize - 1 ||
+ visible_rect.width() < 1 || visible_rect.width() > kMaxCaptureSize ||
+ visible_rect.height() < 1 || visible_rect.height() > kMaxCaptureSize) {
+ DLOG(ERROR) << "NotifyCaptureParameters(): parameters out of bounds: "
+ "buffer_size=" << buffer_size.ToString()
+ << ", visible_rect=" << visible_rect.ToString();
+ NotifyError(SurfaceCapturer::kInvalidArgumentError);
+ return;
+ }
+ output_buffer_size_ = buffer_size;
+ output_visible_rect_ = visible_rect;
+ Send(new SurfaceCapturerHostMsg_NotifyCaptureParameters(
+ route_id_, buffer_size, visible_rect));
+}
+
+void GLSurfaceCapturer::NotifyCopyCaptureDone(
+ const scoped_refptr<media::VideoFrame>& frame) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ FrameIdMap::iterator iter = frame_id_map_.find(frame);
+ if (iter == frame_id_map_.end()) {
+ DLOG(ERROR) << "NotifyCopyCaptureDone(): invalid frame";
+ NotifyError(SurfaceCapturer::kInvalidArgumentError);
+ return;
+ }
+ Send(new SurfaceCapturerHostMsg_NotifyCopyCaptureDone(route_id_,
+ iter->second));
+ frame_id_map_.erase(iter);
+}
+
+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 surface 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::OnTryCapture() {
+ DVLOG(3) << "OnTryCapture()";
+ DCHECK(thread_checker_.CalledOnValidThread());
+ if (!surface_capturer_)
+ return;
+ surface_capturer_->TryCapture();
+}
+
+static void DeleteShm(scoped_ptr<base::SharedMemory> shm) {
+ // Just let shm fall out of scope.
+}
+
+void GLSurfaceCapturer::OnCopyCaptureToVideoFrame(
+ int32 frame_id,
+ base::SharedMemoryHandle buffer_shm,
+ uint32_t buffer_size) {
+ DVLOG(3) << "OnCopyCaptureToVideoFrame(): frame_id=" << frame_id
+ << ", buffer_size=" << buffer_size;
+ DCHECK(thread_checker_.CalledOnValidThread());
+ if (!surface_capturer_)
+ return;
+ if (frame_id < 0) {
+ DLOG(ERROR) << "OnCopyCaptureToVideoFrame(): invalid frame_id=" << frame_id;
+ NotifyError(SurfaceCapturer::kPlatformFailureError);
+ return;
+ }
+
+ scoped_ptr<base::SharedMemory> shm(new base::SharedMemory(buffer_shm, false));
+ if (!shm->Map(buffer_size)) {
+ DLOG(ERROR) << "OnCopyCaptureToVideoFrame(): 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(&DeleteShm, base::Passed(&shm)));
+ if (!frame) {
+ DLOG(ERROR) << "OnCopyCaptureToVideoFrame(): could not create frame for"
+ "frame_id=" << frame_id;
+ NotifyError(SurfaceCapturer::kPlatformFailureError);
+ return;
+ }
+ frame_id_map_[frame] = frame_id;
+ surface_capturer_->CopyCaptureToVideoFrame(frame);
+}
+
+void GLSurfaceCapturer::OnDestroy() {
+ DVLOG(2) << "OnDestroy()";
+ DCHECK(thread_checker_.CalledOnValidThread());
+ delete this;
+}
+
+void GLSurfaceCapturer::Send(IPC::Message* message) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ uint32 type = message->type();
+ if (!stub_->channel()->Send(message)) {
+ DLOG(ERROR) << "Send(): send failed: message->type()=" << type;
+ NotifyError(SurfaceCapturer::kPlatformFailureError);
+ }
+}
+
+} // namespace content
« no previous file with comments | « content/common/gpu/media/gl_surface_capturer.h ('k') | content/common/gpu/surface_capturer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698