OLD | NEW |
---|---|
(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 GLSurfaceCapturer::GLSurfaceCapturer(int32 route_id, GpuCommandBufferStub* stub) | |
15 : thread_checker_(), | |
16 route_id_(route_id), | |
17 stub_(stub), | |
18 output_format_(media::VideoFrame::INVALID) { | |
19 DCHECK(thread_checker_.CalledOnValidThread()); | |
20 stub_->AddDestructionObserver(this); | |
21 stub_->channel()->AddRoute(route_id_, this); | |
22 } | |
23 | |
24 GLSurfaceCapturer::~GLSurfaceCapturer() { | |
25 DCHECK(thread_checker_.CalledOnValidThread()); | |
26 if (surface_capturer_) | |
27 surface_capturer_.release()->Destroy(); | |
28 | |
29 stub_->channel()->RemoveRoute(route_id_); | |
30 stub_->RemoveDestructionObserver(this); | |
31 } | |
32 | |
33 bool GLSurfaceCapturer::OnMessageReceived(const IPC::Message& message) { | |
34 bool handled = true; | |
35 IPC_BEGIN_MESSAGE_MAP(GLSurfaceCapturer, message) | |
36 IPC_MESSAGE_HANDLER(SurfaceCapturerMsg_Initialize, OnInitialize) | |
37 IPC_MESSAGE_HANDLER(SurfaceCapturerMsg_TryCapture, OnTryCapture) | |
38 IPC_MESSAGE_HANDLER(SurfaceCapturerMsg_CopyCaptureToVideoFrame, | |
39 OnCopyCaptureToVideoFrame) | |
40 IPC_MESSAGE_HANDLER(SurfaceCapturerMsg_Destroy, OnDestroy) | |
41 IPC_MESSAGE_UNHANDLED(handled = false) | |
42 IPC_END_MESSAGE_MAP() | |
43 return handled; | |
44 } | |
45 | |
46 void GLSurfaceCapturer::NotifyCaptureParameters(const gfx::Size& buffer_size, | |
Cris Neckar
2013/08/23 22:29:39
As discussed over chat you should set reasonable u
sheu
2013/08/26 21:30:52
Done.
Cris Neckar
2013/08/26 22:33:47
Sorry, where is this being checked now?
| |
47 const gfx::Rect& visible_rect) { | |
48 DCHECK(thread_checker_.CalledOnValidThread()); | |
49 output_buffer_size_ = buffer_size; | |
50 output_visible_rect_ = visible_rect; | |
51 Send(new SurfaceCapturerHostMsg_NotifyCaptureParameters( | |
52 route_id_, buffer_size, visible_rect)); | |
53 } | |
54 | |
55 void GLSurfaceCapturer::NotifyCopyCaptureDone( | |
56 const scoped_refptr<media::VideoFrame>& frame) { | |
57 DCHECK(thread_checker_.CalledOnValidThread()); | |
58 FrameIdMap::iterator iter = frame_id_map_.find(frame); | |
59 if (iter == frame_id_map_.end()) { | |
60 DLOG(ERROR) << "NotifyCopyCaptureDone(): invalid frame"; | |
61 NotifyError(SurfaceCapturer::kInvalidArgumentError); | |
62 return; | |
63 } | |
64 Send(new SurfaceCapturerHostMsg_NotifyCopyCaptureDone(route_id_, | |
65 iter->second)); | |
66 frame_id_map_.erase(iter); | |
67 } | |
68 | |
69 void GLSurfaceCapturer::NotifyError(SurfaceCapturer::Error error) { | |
70 DCHECK(thread_checker_.CalledOnValidThread()); | |
71 Send(new SurfaceCapturerHostMsg_NotifyError(route_id_, error)); | |
72 } | |
73 | |
74 void GLSurfaceCapturer::OnWillDestroyStub() { | |
75 DCHECK(thread_checker_.CalledOnValidThread()); | |
76 delete this; | |
77 } | |
78 | |
79 void GLSurfaceCapturer::OnInitialize(media::VideoFrame::Format format) { | |
80 DVLOG(2) << "OnInitialize(): format=" << format; | |
81 DCHECK(thread_checker_.CalledOnValidThread()); | |
82 DCHECK(!surface_capturer_); | |
83 | |
84 // TODO(sheu): actually create a surface capturer. | |
85 | |
86 if (!surface_capturer_) { | |
87 NOTIMPLEMENTED() << "OnInitialize(): GL surface capturing not available"; | |
88 NotifyError(SurfaceCapturer::kPlatformFailureError); | |
89 return; | |
90 } | |
91 | |
92 output_format_ = format; | |
93 surface_capturer_->Initialize(output_format_); | |
94 } | |
95 | |
96 void GLSurfaceCapturer::OnTryCapture() { | |
97 DVLOG(3) << "OnTryCapture()"; | |
98 DCHECK(thread_checker_.CalledOnValidThread()); | |
99 if (!surface_capturer_) | |
100 return; | |
101 surface_capturer_->TryCapture(); | |
102 } | |
103 | |
104 static void DeleteShm(scoped_ptr<base::SharedMemory> shm) { | |
105 // Just let shm fall out of scope. | |
106 } | |
107 | |
108 void GLSurfaceCapturer::OnCopyCaptureToVideoFrame( | |
109 int32 frame_id, | |
110 base::SharedMemoryHandle buffer_shm, | |
111 uint32_t buffer_size) { | |
112 DVLOG(3) << "OnCopyCaptureToVideoFrame(): frame_id=" << frame_id | |
113 << ", buffer_size=" << buffer_size; | |
114 DCHECK(thread_checker_.CalledOnValidThread()); | |
115 if (!surface_capturer_) | |
116 return; | |
117 if (frame_id < 0) { | |
118 DLOG(ERROR) << "OnCopyCaptureToVideoFrame(): invalid frame_id=" << frame_id; | |
119 NotifyError(SurfaceCapturer::kPlatformFailureError); | |
120 return; | |
121 } | |
122 | |
123 scoped_ptr<base::SharedMemory> shm(new base::SharedMemory(buffer_shm, false)); | |
124 if (!shm->Map(buffer_size)) { | |
125 DLOG(ERROR) << "OnCopyCaptureToVideoFrame(): could not map " | |
126 "frame_id=" << frame_id; | |
127 NotifyError(SurfaceCapturer::kPlatformFailureError); | |
128 return; | |
129 } | |
130 scoped_refptr<media::VideoFrame> frame = | |
131 media::VideoFrame::WrapExternalSharedMemory( | |
132 output_format_, | |
133 output_buffer_size_, | |
134 output_visible_rect_, | |
135 output_visible_rect_.size(), | |
136 reinterpret_cast<uint8*>(shm->memory()), | |
137 buffer_size, | |
138 buffer_shm, | |
139 base::TimeDelta(), | |
140 base::Bind(&DeleteShm, base::Passed(&shm))); | |
141 if (!frame) { | |
142 DLOG(ERROR) << "OnCopyCaptureToVideoFrame(): could not create frame for" | |
143 "frame_id=" << frame_id; | |
144 NotifyError(SurfaceCapturer::kPlatformFailureError); | |
145 return; | |
146 } | |
147 frame_id_map_[frame] = frame_id; | |
148 surface_capturer_->CopyCaptureToVideoFrame(frame); | |
149 } | |
150 | |
151 void GLSurfaceCapturer::OnDestroy() { | |
152 DVLOG(2) << "OnDestroy()"; | |
153 DCHECK(thread_checker_.CalledOnValidThread()); | |
154 delete this; | |
155 } | |
156 | |
157 void GLSurfaceCapturer::Send(IPC::Message* message) { | |
158 DCHECK(thread_checker_.CalledOnValidThread()); | |
159 uint32 type = message->type(); | |
160 if (!stub_->channel()->Send(message)) { | |
161 DLOG(ERROR) << "Send(): send failed: message->type()=" << type; | |
162 NotifyError(SurfaceCapturer::kPlatformFailureError); | |
163 } | |
164 } | |
165 | |
166 } // namespace content | |
OLD | NEW |