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

Side by Side Diff: content/common/gpu/client/gpu_video_decode_accelerator_host.cc

Issue 185403020: Make VEA client of command buffer; move sync. IPC to VDA/VEA::Initialize() (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: f2a9ccb5 Rebase, posciak@ comments. Created 6 years, 9 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/common/gpu/client/gpu_video_decode_accelerator_host.h" 5 #include "content/common/gpu/client/gpu_video_decode_accelerator_host.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
10 #include "content/common/gpu/client/gpu_channel_host.h" 10 #include "content/common/gpu/client/gpu_channel_host.h"
11 #include "content/common/gpu/gpu_messages.h" 11 #include "content/common/gpu/gpu_messages.h"
12 #include "content/common/view_messages.h" 12 #include "content/common/view_messages.h"
13 #include "ipc/ipc_message_macros.h" 13 #include "ipc/ipc_message_macros.h"
14 #include "ipc/ipc_message_utils.h" 14 #include "ipc/ipc_message_utils.h"
15 15
16 #if defined(OS_WIN) 16 #if defined(OS_WIN)
17 #include "content/public/common/sandbox_init.h" 17 #include "content/public/common/sandbox_init.h"
18 #endif // OS_WIN 18 #endif // OS_WIN
19 19
20 #define NOTIFY_ERROR(error) \
21 PostNotifyError(error); \
22 DLOG(ERROR)
23
20 using media::VideoDecodeAccelerator; 24 using media::VideoDecodeAccelerator;
21 namespace content { 25 namespace content {
22 26
23 GpuVideoDecodeAcceleratorHost::GpuVideoDecodeAcceleratorHost( 27 GpuVideoDecodeAcceleratorHost::GpuVideoDecodeAcceleratorHost(
24 GpuChannelHost* channel, 28 GpuChannelHost* channel,
25 int32 decoder_route_id,
26 CommandBufferProxyImpl* impl) 29 CommandBufferProxyImpl* impl)
27 : channel_(channel), 30 : channel_(channel),
28 decoder_route_id_(decoder_route_id), 31 decoder_route_id_(-1),
29 client_(NULL), 32 client_(NULL),
30 impl_(impl) { 33 impl_(impl),
34 weak_this_factory_(this) {
31 DCHECK(channel_); 35 DCHECK(channel_);
32 channel_->AddRoute(decoder_route_id, base::AsWeakPtr(this)); 36 DCHECK(impl_);
33 impl_->AddDeletionObserver(this); 37 impl_->AddDeletionObserver(this);
34 } 38 }
35 39
36 void GpuVideoDecodeAcceleratorHost::OnChannelError() { 40 GpuVideoDecodeAcceleratorHost::~GpuVideoDecodeAcceleratorHost() {
37 DLOG(ERROR) << "GpuVideoDecodeAcceleratorHost::OnChannelError()"; 41 DCHECK(CalledOnValidThread());
38 if (channel_) { 42
43 if (channel_)
39 channel_->RemoveRoute(decoder_route_id_); 44 channel_->RemoveRoute(decoder_route_id_);
40 channel_ = NULL; 45 if (impl_)
41 } 46 impl_->RemoveDeletionObserver(this);
42 // See OnErrorNotification for why this needs to be the last thing in this
43 // function.
44 OnErrorNotification(PLATFORM_FAILURE);
45 } 47 }
46 48
47 bool GpuVideoDecodeAcceleratorHost::OnMessageReceived(const IPC::Message& msg) { 49 bool GpuVideoDecodeAcceleratorHost::OnMessageReceived(const IPC::Message& msg) {
48 DCHECK(CalledOnValidThread()); 50 DCHECK(CalledOnValidThread());
49 bool handled = true; 51 bool handled = true;
50 IPC_BEGIN_MESSAGE_MAP(GpuVideoDecodeAcceleratorHost, msg) 52 IPC_BEGIN_MESSAGE_MAP(GpuVideoDecodeAcceleratorHost, msg)
51 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_BitstreamBufferProcessed, 53 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_BitstreamBufferProcessed,
52 OnBitstreamBufferProcessed) 54 OnBitstreamBufferProcessed)
53 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ProvidePictureBuffers, 55 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ProvidePictureBuffers,
54 OnProvidePictureBuffer) 56 OnProvidePictureBuffer)
55 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_PictureReady, 57 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_PictureReady,
56 OnPictureReady) 58 OnPictureReady)
57 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_FlushDone, 59 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_FlushDone,
58 OnFlushDone) 60 OnFlushDone)
59 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ResetDone, 61 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ResetDone,
60 OnResetDone) 62 OnResetDone)
61 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ErrorNotification, 63 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ErrorNotification,
62 OnErrorNotification) 64 OnNotifyError)
63 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_DismissPictureBuffer, 65 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_DismissPictureBuffer,
64 OnDismissPictureBuffer) 66 OnDismissPictureBuffer)
65 IPC_MESSAGE_UNHANDLED(handled = false) 67 IPC_MESSAGE_UNHANDLED(handled = false)
66 IPC_END_MESSAGE_MAP() 68 IPC_END_MESSAGE_MAP()
67 DCHECK(handled); 69 DCHECK(handled);
68 // See OnErrorNotification for why |this| mustn't be used after 70 // See OnNotifyError for why |this| mustn't be used after OnNotifyError might
69 // OnErrorNotification might have been called above. 71 // have been called above.
70 return handled; 72 return handled;
71 } 73 }
72 74
75 void GpuVideoDecodeAcceleratorHost::OnChannelError() {
76 DCHECK(CalledOnValidThread());
77 if (channel_) {
78 channel_->RemoveRoute(decoder_route_id_);
79 channel_ = NULL;
80 weak_this_factory_.InvalidateWeakPtrs();
81 }
82 NOTIFY_ERROR(PLATFORM_FAILURE) << "OnChannelError()";
Ami GONE FROM CHROMIUM 2014/03/17 03:17:54 This will be a no-op since the posted error notifi
sheu 2014/03/18 22:38:35 I suppose. Making this a DLOG(ERROR) instead.
83 }
84
73 bool GpuVideoDecodeAcceleratorHost::Initialize(media::VideoCodecProfile profile, 85 bool GpuVideoDecodeAcceleratorHost::Initialize(media::VideoCodecProfile profile,
74 Client* client) { 86 Client* client) {
87 DCHECK(CalledOnValidThread());
75 client_ = client; 88 client_ = client;
89
90 if (!impl_)
91 return false;
92 Send(new GpuCommandBufferMsg_CreateVideoDecoder(
93 impl_->GetRouteID(), profile, &decoder_route_id_));
94 if (decoder_route_id_ < 0) {
95 NOTIFY_ERROR(PLATFORM_FAILURE)
96 << "Send(GpuCommandBufferMsg_CreateVideoDecoder()) failed";
97 return false;
98 }
99
100 channel_->AddRoute(decoder_route_id_, weak_this_factory_.GetWeakPtr());
76 return true; 101 return true;
77 } 102 }
78 103
79 void GpuVideoDecodeAcceleratorHost::Decode( 104 void GpuVideoDecodeAcceleratorHost::Decode(
80 const media::BitstreamBuffer& bitstream_buffer) { 105 const media::BitstreamBuffer& bitstream_buffer) {
81 DCHECK(CalledOnValidThread()); 106 DCHECK(CalledOnValidThread());
82 // Can happen if a decode task was posted before an error was delivered.
83 if (!channel_) 107 if (!channel_)
84 return; 108 return;
85 109
86 base::SharedMemoryHandle handle = channel_->ShareToGpuProcess( 110 base::SharedMemoryHandle handle = channel_->ShareToGpuProcess(
87 bitstream_buffer.handle()); 111 bitstream_buffer.handle());
88 if (!base::SharedMemory::IsHandleValid(handle)) { 112 if (!base::SharedMemory::IsHandleValid(handle)) {
89 NOTREACHED() << "Failed to duplicate buffer handler"; 113 NOTREACHED() << "Failed to duplicate buffer handler";
90 return; 114 return;
91 } 115 }
92 116
93 Send(new AcceleratedVideoDecoderMsg_Decode( 117 Send(new AcceleratedVideoDecoderMsg_Decode(
94 decoder_route_id_, handle, bitstream_buffer.id(), 118 decoder_route_id_, handle, bitstream_buffer.id(),
95 bitstream_buffer.size())); 119 bitstream_buffer.size()));
96 } 120 }
97 121
98 void GpuVideoDecodeAcceleratorHost::AssignPictureBuffers( 122 void GpuVideoDecodeAcceleratorHost::AssignPictureBuffers(
99 const std::vector<media::PictureBuffer>& buffers) { 123 const std::vector<media::PictureBuffer>& buffers) {
100 DCHECK(CalledOnValidThread()); 124 DCHECK(CalledOnValidThread());
125 if (!channel_)
126 return;
101 // Rearrange data for IPC command. 127 // Rearrange data for IPC command.
102 std::vector<int32> buffer_ids; 128 std::vector<int32> buffer_ids;
103 std::vector<uint32> texture_ids; 129 std::vector<uint32> texture_ids;
104 for (uint32 i = 0; i < buffers.size(); i++) { 130 for (uint32 i = 0; i < buffers.size(); i++) {
105 const media::PictureBuffer& buffer = buffers[i]; 131 const media::PictureBuffer& buffer = buffers[i];
106 if (buffer.size() != picture_buffer_dimensions_) { 132 if (buffer.size() != picture_buffer_dimensions_) {
107 OnErrorNotification(INVALID_ARGUMENT); 133 NOTIFY_ERROR(INVALID_ARGUMENT) << "buffer.size() invalid: expected "
134 << picture_buffer_dimensions_.ToString()
135 << ", got " << buffer.size().ToString();
108 return; 136 return;
109 } 137 }
110 texture_ids.push_back(buffer.texture_id()); 138 texture_ids.push_back(buffer.texture_id());
111 buffer_ids.push_back(buffer.id()); 139 buffer_ids.push_back(buffer.id());
112 } 140 }
113 Send(new AcceleratedVideoDecoderMsg_AssignPictureBuffers( 141 Send(new AcceleratedVideoDecoderMsg_AssignPictureBuffers(
114 decoder_route_id_, buffer_ids, texture_ids)); 142 decoder_route_id_, buffer_ids, texture_ids));
115 } 143 }
116 144
117 void GpuVideoDecodeAcceleratorHost::ReusePictureBuffer( 145 void GpuVideoDecodeAcceleratorHost::ReusePictureBuffer(
118 int32 picture_buffer_id) { 146 int32 picture_buffer_id) {
119 DCHECK(CalledOnValidThread()); 147 DCHECK(CalledOnValidThread());
148 if (!channel_)
149 return;
120 Send(new AcceleratedVideoDecoderMsg_ReusePictureBuffer( 150 Send(new AcceleratedVideoDecoderMsg_ReusePictureBuffer(
121 decoder_route_id_, picture_buffer_id)); 151 decoder_route_id_, picture_buffer_id));
122 } 152 }
123 153
124 void GpuVideoDecodeAcceleratorHost::Flush() { 154 void GpuVideoDecodeAcceleratorHost::Flush() {
125 DCHECK(CalledOnValidThread()); 155 DCHECK(CalledOnValidThread());
156 if (!channel_)
157 return;
126 Send(new AcceleratedVideoDecoderMsg_Flush(decoder_route_id_)); 158 Send(new AcceleratedVideoDecoderMsg_Flush(decoder_route_id_));
127 } 159 }
128 160
129 void GpuVideoDecodeAcceleratorHost::Reset() { 161 void GpuVideoDecodeAcceleratorHost::Reset() {
130 DCHECK(CalledOnValidThread()); 162 DCHECK(CalledOnValidThread());
163 if (!channel_)
164 return;
131 Send(new AcceleratedVideoDecoderMsg_Reset(decoder_route_id_)); 165 Send(new AcceleratedVideoDecoderMsg_Reset(decoder_route_id_));
132 } 166 }
133 167
134 void GpuVideoDecodeAcceleratorHost::Destroy() { 168 void GpuVideoDecodeAcceleratorHost::Destroy() {
135 DCHECK(CalledOnValidThread()); 169 DCHECK(CalledOnValidThread());
170 if (channel_)
171 Send(new AcceleratedVideoDecoderMsg_Destroy(decoder_route_id_));
136 client_ = NULL; 172 client_ = NULL;
137 Send(new AcceleratedVideoDecoderMsg_Destroy(decoder_route_id_));
138 delete this; 173 delete this;
139 } 174 }
140 175
141 void GpuVideoDecodeAcceleratorHost::OnWillDeleteImpl() { 176 void GpuVideoDecodeAcceleratorHost::OnWillDeleteImpl() {
177 DCHECK(CalledOnValidThread());
142 impl_ = NULL; 178 impl_ = NULL;
143 179
144 // The CommandBufferProxyImpl is going away; error out this VDA. 180 // The CommandBufferProxyImpl is going away; error out this VDA.
145 OnChannelError(); 181 OnChannelError();
146 } 182 }
147 183
148 GpuVideoDecodeAcceleratorHost::~GpuVideoDecodeAcceleratorHost() { 184 void GpuVideoDecodeAcceleratorHost::PostNotifyError(Error error) {
149 DCHECK(CalledOnValidThread()); 185 DCHECK(CalledOnValidThread());
150 186 DVLOG(2) << "PostNotifyError(): error=" << error;
151 if (channel_) 187 base::MessageLoopProxy::current()->PostTask(
152 channel_->RemoveRoute(decoder_route_id_); 188 FROM_HERE,
153 if (impl_) 189 base::Bind(&GpuVideoDecodeAcceleratorHost::OnNotifyError,
154 impl_->RemoveDeletionObserver(this); 190 weak_this_factory_.GetWeakPtr(),
191 error));
155 } 192 }
156 193
157 void GpuVideoDecodeAcceleratorHost::Send(IPC::Message* message) { 194 void GpuVideoDecodeAcceleratorHost::Send(IPC::Message* message) {
195 DCHECK(CalledOnValidThread());
158 // After OnChannelError is called, the client should no longer send 196 // After OnChannelError is called, the client should no longer send
159 // messages to the gpu channel through this object. But queued posted tasks 197 // messages to the gpu channel through this object. But queued posted tasks
160 // can still be draining, so we're forgiving and simply ignore them. 198 // can still be draining, so we're forgiving and simply ignore them.
Ami GONE FROM CHROMIUM 2014/03/17 03:17:54 Ditto comments from GVEAH.
161 bool error = false;
162 uint32 message_type = message->type(); 199 uint32 message_type = message->type();
163 if (!channel_) { 200 if (!channel_->Send(message))
164 delete message; 201 NOTIFY_ERROR(PLATFORM_FAILURE) << "Send(" << message_type << ") failed";
165 DLOG(ERROR) << "Send(" << message_type << ") after error ignored";
166 error = true;
167 } else if (!channel_->Send(message)) {
168 DLOG(ERROR) << "Send(" << message_type << ") failed";
169 error = true;
170 }
171 // See OnErrorNotification for why this needs to be the last thing in this
172 // function.
173 if (error)
174 OnErrorNotification(PLATFORM_FAILURE);
175 } 202 }
176 203
177 void GpuVideoDecodeAcceleratorHost::OnBitstreamBufferProcessed( 204 void GpuVideoDecodeAcceleratorHost::OnBitstreamBufferProcessed(
178 int32 bitstream_buffer_id) { 205 int32 bitstream_buffer_id) {
179 DCHECK(CalledOnValidThread()); 206 DCHECK(CalledOnValidThread());
180 if (client_) 207 if (client_)
181 client_->NotifyEndOfBitstreamBuffer(bitstream_buffer_id); 208 client_->NotifyEndOfBitstreamBuffer(bitstream_buffer_id);
182 } 209 }
183 210
184 void GpuVideoDecodeAcceleratorHost::OnProvidePictureBuffer( 211 void GpuVideoDecodeAcceleratorHost::OnProvidePictureBuffer(
(...skipping 29 matching lines...) Expand all
214 if (client_) 241 if (client_)
215 client_->NotifyFlushDone(); 242 client_->NotifyFlushDone();
216 } 243 }
217 244
218 void GpuVideoDecodeAcceleratorHost::OnResetDone() { 245 void GpuVideoDecodeAcceleratorHost::OnResetDone() {
219 DCHECK(CalledOnValidThread()); 246 DCHECK(CalledOnValidThread());
220 if (client_) 247 if (client_)
221 client_->NotifyResetDone(); 248 client_->NotifyResetDone();
222 } 249 }
223 250
224 void GpuVideoDecodeAcceleratorHost::OnErrorNotification(uint32 error) { 251 void GpuVideoDecodeAcceleratorHost::OnNotifyError(uint32 error) {
225 DCHECK(CalledOnValidThread()); 252 DCHECK(CalledOnValidThread());
226 if (!client_) 253 if (!client_)
227 return; 254 return;
228 255
229 // Client::NotifyError() may Destroy() |this|, so calling it needs to be the 256 // Client::NotifyError() may Destroy() |this|, so calling it needs to be the
230 // last thing done on this stack! 257 // last thing done on this stack!
231 media::VideoDecodeAccelerator::Client* client = NULL; 258 media::VideoDecodeAccelerator::Client* client = NULL;
232 std::swap(client, client_); 259 std::swap(client, client_);
233 client->NotifyError( 260 client->NotifyError(static_cast<media::VideoDecodeAccelerator::Error>(error));
234 static_cast<media::VideoDecodeAccelerator::Error>(error));
235 } 261 }
236 262
237 } // namespace content 263 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698