Respond with QuotaExceededError when IndexedDB has no disk space on open.
[chromium-blink-merge.git] / content / common / gpu / client / gpu_video_decode_accelerator_host.cc
blobfcf36bf4eb3a7521b73ef79a7e2af56e6ae8f2c5
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
3 // found in the LICENSE file.
5 #include "content/common/gpu/client/gpu_video_decode_accelerator_host.h"
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/message_loop/message_loop.h"
10 #include "content/common/gpu/client/gpu_channel_host.h"
11 #include "content/common/gpu/gpu_messages.h"
12 #include "content/common/view_messages.h"
13 #include "ipc/ipc_message_macros.h"
14 #include "ipc/ipc_message_utils.h"
16 #if defined(OS_WIN)
17 #include "content/public/common/sandbox_init.h"
18 #endif // OS_WIN
20 using media::VideoDecodeAccelerator;
21 namespace content {
23 GpuVideoDecodeAcceleratorHost::GpuVideoDecodeAcceleratorHost(
24 GpuChannelHost* channel,
25 int32 decoder_route_id,
26 VideoDecodeAccelerator::Client* client,
27 CommandBufferProxyImpl* impl)
28 : channel_(channel),
29 decoder_route_id_(decoder_route_id),
30 client_(client),
31 impl_(impl) {
32 DCHECK(channel_);
33 DCHECK(client_);
34 channel_->AddRoute(decoder_route_id, base::AsWeakPtr(this));
35 impl_->AddDeletionObserver(this);
38 void GpuVideoDecodeAcceleratorHost::OnChannelError() {
39 DLOG(ERROR) << "GpuVideoDecodeAcceleratorHost::OnChannelError()";
40 if (channel_) {
41 channel_->RemoveRoute(decoder_route_id_);
42 channel_ = NULL;
44 // See OnErrorNotification for why this needs to be the last thing in this
45 // function.
46 OnErrorNotification(PLATFORM_FAILURE);
49 bool GpuVideoDecodeAcceleratorHost::OnMessageReceived(const IPC::Message& msg) {
50 DCHECK(CalledOnValidThread());
51 bool handled = true;
52 IPC_BEGIN_MESSAGE_MAP(GpuVideoDecodeAcceleratorHost, msg)
53 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_BitstreamBufferProcessed,
54 OnBitstreamBufferProcessed)
55 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ProvidePictureBuffers,
56 OnProvidePictureBuffer)
57 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_PictureReady,
58 OnPictureReady)
59 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_FlushDone,
60 OnFlushDone)
61 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ResetDone,
62 OnResetDone)
63 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ErrorNotification,
64 OnErrorNotification)
65 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_DismissPictureBuffer,
66 OnDismissPictureBuffer)
67 IPC_MESSAGE_UNHANDLED(handled = false)
68 IPC_END_MESSAGE_MAP()
69 DCHECK(handled);
70 // See OnErrorNotification for why |this| mustn't be used after
71 // OnErrorNotification might have been called above.
72 return handled;
75 bool GpuVideoDecodeAcceleratorHost::Initialize(
76 media::VideoCodecProfile profile) {
77 NOTREACHED();
78 return true;
81 void GpuVideoDecodeAcceleratorHost::Decode(
82 const media::BitstreamBuffer& bitstream_buffer) {
83 DCHECK(CalledOnValidThread());
84 // Can happen if a decode task was posted before an error was delivered.
85 if (!channel_)
86 return;
88 base::SharedMemoryHandle handle = channel_->ShareToGpuProcess(
89 bitstream_buffer.handle());
90 if (!base::SharedMemory::IsHandleValid(handle)) {
91 NOTREACHED() << "Failed to duplicate buffer handler";
92 return;
95 Send(new AcceleratedVideoDecoderMsg_Decode(
96 decoder_route_id_, handle, bitstream_buffer.id(),
97 bitstream_buffer.size()));
100 void GpuVideoDecodeAcceleratorHost::AssignPictureBuffers(
101 const std::vector<media::PictureBuffer>& buffers) {
102 DCHECK(CalledOnValidThread());
103 // Rearrange data for IPC command.
104 std::vector<int32> buffer_ids;
105 std::vector<uint32> texture_ids;
106 std::vector<gfx::Size> sizes;
107 for (uint32 i = 0; i < buffers.size(); i++) {
108 const media::PictureBuffer& buffer = buffers[i];
109 texture_ids.push_back(buffer.texture_id());
110 buffer_ids.push_back(buffer.id());
111 sizes.push_back(buffer.size());
113 Send(new AcceleratedVideoDecoderMsg_AssignPictureBuffers(
114 decoder_route_id_, buffer_ids, texture_ids, sizes));
117 void GpuVideoDecodeAcceleratorHost::ReusePictureBuffer(
118 int32 picture_buffer_id) {
119 DCHECK(CalledOnValidThread());
120 Send(new AcceleratedVideoDecoderMsg_ReusePictureBuffer(
121 decoder_route_id_, picture_buffer_id));
124 void GpuVideoDecodeAcceleratorHost::Flush() {
125 DCHECK(CalledOnValidThread());
126 Send(new AcceleratedVideoDecoderMsg_Flush(decoder_route_id_));
129 void GpuVideoDecodeAcceleratorHost::Reset() {
130 DCHECK(CalledOnValidThread());
131 Send(new AcceleratedVideoDecoderMsg_Reset(decoder_route_id_));
134 void GpuVideoDecodeAcceleratorHost::Destroy() {
135 DCHECK(CalledOnValidThread());
136 client_ = NULL;
137 Send(new AcceleratedVideoDecoderMsg_Destroy(decoder_route_id_));
138 delete this;
141 void GpuVideoDecodeAcceleratorHost::OnWillDeleteImpl() {
142 impl_ = NULL;
144 // The CommandBufferProxyImpl is going away; error out this VDA.
145 OnChannelError();
148 GpuVideoDecodeAcceleratorHost::~GpuVideoDecodeAcceleratorHost() {
149 DCHECK(CalledOnValidThread());
150 DCHECK(!client_) << "destructor called without Destroy being called!";
152 if (channel_)
153 channel_->RemoveRoute(decoder_route_id_);
154 if (impl_)
155 impl_->RemoveDeletionObserver(this);
158 void GpuVideoDecodeAcceleratorHost::Send(IPC::Message* message) {
159 // After OnChannelError is called, the client should no longer send
160 // messages to the gpu channel through this object. But queued posted tasks
161 // can still be draining, so we're forgiving and simply ignore them.
162 bool error = false;
163 uint32 message_type = message->type();
164 if (!channel_) {
165 delete message;
166 DLOG(ERROR) << "Send(" << message_type << ") after error ignored";
167 error = true;
168 } else if (!channel_->Send(message)) {
169 DLOG(ERROR) << "Send(" << message_type << ") failed";
170 error = true;
172 // See OnErrorNotification for why this needs to be the last thing in this
173 // function.
174 if (error)
175 OnErrorNotification(PLATFORM_FAILURE);
178 void GpuVideoDecodeAcceleratorHost::OnBitstreamBufferProcessed(
179 int32 bitstream_buffer_id) {
180 DCHECK(CalledOnValidThread());
181 if (client_)
182 client_->NotifyEndOfBitstreamBuffer(bitstream_buffer_id);
185 void GpuVideoDecodeAcceleratorHost::OnProvidePictureBuffer(
186 uint32 num_requested_buffers,
187 const gfx::Size& buffer_size,
188 uint32 texture_target) {
189 DCHECK(CalledOnValidThread());
190 if (client_) {
191 client_->ProvidePictureBuffers(
192 num_requested_buffers, buffer_size, texture_target);
196 void GpuVideoDecodeAcceleratorHost::OnDismissPictureBuffer(
197 int32 picture_buffer_id) {
198 DCHECK(CalledOnValidThread());
199 if (client_)
200 client_->DismissPictureBuffer(picture_buffer_id);
203 void GpuVideoDecodeAcceleratorHost::OnPictureReady(
204 int32 picture_buffer_id, int32 bitstream_buffer_id) {
205 DCHECK(CalledOnValidThread());
206 if (!client_)
207 return;
208 media::Picture picture(picture_buffer_id, bitstream_buffer_id);
209 client_->PictureReady(picture);
212 void GpuVideoDecodeAcceleratorHost::OnFlushDone() {
213 DCHECK(CalledOnValidThread());
214 if (client_)
215 client_->NotifyFlushDone();
218 void GpuVideoDecodeAcceleratorHost::OnResetDone() {
219 DCHECK(CalledOnValidThread());
220 if (client_)
221 client_->NotifyResetDone();
224 void GpuVideoDecodeAcceleratorHost::OnErrorNotification(uint32 error) {
225 DCHECK(CalledOnValidThread());
226 if (!client_)
227 return;
229 // Client::NotifyError() may Destroy() |this|, so calling it needs to be the
230 // last thing done on this stack!
231 media::VideoDecodeAccelerator::Client* client = NULL;
232 std::swap(client, client_);
233 client->NotifyError(
234 static_cast<media::VideoDecodeAccelerator::Error>(error));
237 } // namespace content