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

Side by Side 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: eb01d94a Comment fixes. Created 7 years, 3 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 unified diff | 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/common/gpu/media/gl_surface_capturer.h"
6
7 #include "base/message_loop/message_loop_proxy.h"
8 #include "content/common/gpu/gpu_channel.h"
9 #include "content/common/gpu/gpu_messages.h"
10 #include "ipc/ipc_message_macros.h"
11
12 namespace content {
13
14 namespace {
15
16 enum {
17 kMaxCaptureSize = 4096,
18 };
19
20 } // anonymous namespace
21
22 GLSurfaceCapturer::GLSurfaceCapturer(int32 route_id, GpuCommandBufferStub* stub)
23 : thread_checker_(),
24 route_id_(route_id),
25 stub_(stub),
26 output_format_(media::VideoFrame::INVALID) {
27 DCHECK(thread_checker_.CalledOnValidThread());
28 stub_->AddDestructionObserver(this);
29 stub_->channel()->AddRoute(route_id_, this);
30 }
31
32 GLSurfaceCapturer::~GLSurfaceCapturer() {
33 DCHECK(thread_checker_.CalledOnValidThread());
34 if (surface_capturer_)
35 surface_capturer_.release()->Destroy();
36
37 stub_->channel()->RemoveRoute(route_id_);
38 stub_->RemoveDestructionObserver(this);
39 }
40
41 bool GLSurfaceCapturer::OnMessageReceived(const IPC::Message& message) {
42 bool handled = true;
43 IPC_BEGIN_MESSAGE_MAP(GLSurfaceCapturer, message)
44 IPC_MESSAGE_HANDLER(SurfaceCapturerMsg_Initialize, OnInitialize)
45 IPC_MESSAGE_HANDLER(SurfaceCapturerMsg_TryCapture, OnTryCapture)
46 IPC_MESSAGE_HANDLER(SurfaceCapturerMsg_CopyCaptureToVideoFrame,
47 OnCopyCaptureToVideoFrame)
48 IPC_MESSAGE_HANDLER(SurfaceCapturerMsg_Destroy, OnDestroy)
49 IPC_MESSAGE_UNHANDLED(handled = false)
50 IPC_END_MESSAGE_MAP()
51 return handled;
52 }
53
54 void GLSurfaceCapturer::NotifyCaptureParameters(const gfx::Size& buffer_size,
55 const gfx::Rect& visible_rect) {
56 DCHECK(thread_checker_.CalledOnValidThread());
57 if (buffer_size.width() > kMaxCaptureSize ||
Cris Neckar 2013/08/26 22:40:03 Aren't these signed ints underneath. Negatives wou
sheu 2013/08/27 01:20:03 Done.
58 buffer_size.height() > kMaxCaptureSize ||
59 visible_rect.x() > kMaxCaptureSize ||
60 visible_rect.y() > kMaxCaptureSize ||
61 visible_rect.width() > kMaxCaptureSize ||
62 visible_rect.height() > kMaxCaptureSize) {
63 DLOG(ERROR) << "NotifyCaptureParameters(): parameters out of bounds: "
64 "buffer_size=" << buffer_size.ToString()
65 << ", visible_rect=" << visible_rect.ToString();
66 NotifyError(SurfaceCapturer::kInvalidArgumentError);
67 return;
68 }
69 output_buffer_size_ = buffer_size;
70 output_visible_rect_ = visible_rect;
71 Send(new SurfaceCapturerHostMsg_NotifyCaptureParameters(
72 route_id_, buffer_size, visible_rect));
73 }
74
75 void GLSurfaceCapturer::NotifyCopyCaptureDone(
76 const scoped_refptr<media::VideoFrame>& frame) {
77 DCHECK(thread_checker_.CalledOnValidThread());
78 FrameIdMap::iterator iter = frame_id_map_.find(frame);
79 if (iter == frame_id_map_.end()) {
80 DLOG(ERROR) << "NotifyCopyCaptureDone(): invalid frame";
81 NotifyError(SurfaceCapturer::kInvalidArgumentError);
82 return;
83 }
84 Send(new SurfaceCapturerHostMsg_NotifyCopyCaptureDone(route_id_,
85 iter->second));
86 frame_id_map_.erase(iter);
87 }
88
89 void GLSurfaceCapturer::NotifyError(SurfaceCapturer::Error error) {
90 DCHECK(thread_checker_.CalledOnValidThread());
91 Send(new SurfaceCapturerHostMsg_NotifyError(route_id_, error));
92 }
93
94 void GLSurfaceCapturer::OnWillDestroyStub() {
95 DCHECK(thread_checker_.CalledOnValidThread());
96 delete this;
97 }
98
99 void GLSurfaceCapturer::OnInitialize(media::VideoFrame::Format format) {
100 DVLOG(2) << "OnInitialize(): format=" << format;
101 DCHECK(thread_checker_.CalledOnValidThread());
102 DCHECK(!surface_capturer_);
103
104 // TODO(sheu): actually create a surface capturer.
105
106 if (!surface_capturer_) {
107 NOTIMPLEMENTED() << "OnInitialize(): GL surface capturing not available";
108 NotifyError(SurfaceCapturer::kPlatformFailureError);
109 return;
110 }
111
112 output_format_ = format;
113 surface_capturer_->Initialize(output_format_);
114 }
115
116 void GLSurfaceCapturer::OnTryCapture() {
117 DVLOG(3) << "OnTryCapture()";
118 DCHECK(thread_checker_.CalledOnValidThread());
119 if (!surface_capturer_)
120 return;
121 surface_capturer_->TryCapture();
122 }
123
124 static void DeleteShm(scoped_ptr<base::SharedMemory> shm) {
125 // Just let shm fall out of scope.
126 }
127
128 void GLSurfaceCapturer::OnCopyCaptureToVideoFrame(
129 int32 frame_id,
130 base::SharedMemoryHandle buffer_shm,
131 uint32_t buffer_size) {
132 DVLOG(3) << "OnCopyCaptureToVideoFrame(): frame_id=" << frame_id
133 << ", buffer_size=" << buffer_size;
134 DCHECK(thread_checker_.CalledOnValidThread());
135 if (!surface_capturer_)
136 return;
137 if (frame_id < 0) {
138 DLOG(ERROR) << "OnCopyCaptureToVideoFrame(): invalid frame_id=" << frame_id;
139 NotifyError(SurfaceCapturer::kPlatformFailureError);
140 return;
141 }
142
143 scoped_ptr<base::SharedMemory> shm(new base::SharedMemory(buffer_shm, false));
144 if (!shm->Map(buffer_size)) {
145 DLOG(ERROR) << "OnCopyCaptureToVideoFrame(): could not map "
146 "frame_id=" << frame_id;
147 NotifyError(SurfaceCapturer::kPlatformFailureError);
148 return;
149 }
150 scoped_refptr<media::VideoFrame> frame =
151 media::VideoFrame::WrapExternalSharedMemory(
152 output_format_,
153 output_buffer_size_,
154 output_visible_rect_,
155 output_visible_rect_.size(),
156 reinterpret_cast<uint8*>(shm->memory()),
157 buffer_size,
158 buffer_shm,
159 base::TimeDelta(),
160 base::Bind(&DeleteShm, base::Passed(&shm)));
161 if (!frame) {
162 DLOG(ERROR) << "OnCopyCaptureToVideoFrame(): could not create frame for"
163 "frame_id=" << frame_id;
164 NotifyError(SurfaceCapturer::kPlatformFailureError);
165 return;
166 }
167 frame_id_map_[frame] = frame_id;
168 surface_capturer_->CopyCaptureToVideoFrame(frame);
169 }
170
171 void GLSurfaceCapturer::OnDestroy() {
172 DVLOG(2) << "OnDestroy()";
173 DCHECK(thread_checker_.CalledOnValidThread());
174 delete this;
175 }
176
177 void GLSurfaceCapturer::Send(IPC::Message* message) {
178 DCHECK(thread_checker_.CalledOnValidThread());
179 uint32 type = message->type();
180 if (!stub_->channel()->Send(message)) {
181 DLOG(ERROR) << "Send(): send failed: message->type()=" << type;
182 NotifyError(SurfaceCapturer::kPlatformFailureError);
183 }
184 }
185
186 } // namespace content
OLDNEW
« 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