Add ICU message format support
[chromium-blink-merge.git] / content / common / gpu / client / gpu_video_decode_accelerator_host.cc
blob3e616a8620f1c5b7f5db47c10a0dbcf939895656
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 CommandBufferProxyImpl* impl)
26 : channel_(channel),
27 decoder_route_id_(MSG_ROUTING_NONE),
28 client_(NULL),
29 impl_(impl),
30 weak_this_factory_(this) {
31 DCHECK(channel_);
32 DCHECK(impl_);
33 impl_->AddDeletionObserver(this);
36 GpuVideoDecodeAcceleratorHost::~GpuVideoDecodeAcceleratorHost() {
37 DCHECK(CalledOnValidThread());
39 if (channel_ && decoder_route_id_ != MSG_ROUTING_NONE)
40 channel_->RemoveRoute(decoder_route_id_);
41 if (impl_)
42 impl_->RemoveDeletionObserver(this);
45 bool GpuVideoDecodeAcceleratorHost::OnMessageReceived(const IPC::Message& msg) {
46 DCHECK(CalledOnValidThread());
47 bool handled = true;
48 IPC_BEGIN_MESSAGE_MAP(GpuVideoDecodeAcceleratorHost, msg)
49 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_BitstreamBufferProcessed,
50 OnBitstreamBufferProcessed)
51 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ProvidePictureBuffers,
52 OnProvidePictureBuffer)
53 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_PictureReady,
54 OnPictureReady)
55 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_FlushDone,
56 OnFlushDone)
57 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ResetDone,
58 OnResetDone)
59 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ErrorNotification,
60 OnNotifyError)
61 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_DismissPictureBuffer,
62 OnDismissPictureBuffer)
63 IPC_MESSAGE_UNHANDLED(handled = false)
64 IPC_END_MESSAGE_MAP()
65 DCHECK(handled);
66 // See OnNotifyError for why |this| mustn't be used after OnNotifyError might
67 // have been called above.
68 return handled;
71 void GpuVideoDecodeAcceleratorHost::OnChannelError() {
72 DCHECK(CalledOnValidThread());
73 if (channel_) {
74 if (decoder_route_id_ != MSG_ROUTING_NONE)
75 channel_->RemoveRoute(decoder_route_id_);
76 channel_ = NULL;
78 DLOG(ERROR) << "OnChannelError()";
79 PostNotifyError(PLATFORM_FAILURE);
82 bool GpuVideoDecodeAcceleratorHost::Initialize(media::VideoCodecProfile profile,
83 Client* client) {
84 DCHECK(CalledOnValidThread());
85 client_ = client;
87 if (!impl_)
88 return false;
90 int32 route_id = channel_->GenerateRouteID();
91 channel_->AddRoute(route_id, weak_this_factory_.GetWeakPtr());
93 bool succeeded = false;
94 Send(new GpuCommandBufferMsg_CreateVideoDecoder(impl_->route_id(), profile,
95 route_id, &succeeded));
97 if (!succeeded) {
98 DLOG(ERROR) << "Send(GpuCommandBufferMsg_CreateVideoDecoder()) failed";
99 PostNotifyError(PLATFORM_FAILURE);
100 channel_->RemoveRoute(route_id);
101 return false;
103 decoder_route_id_ = route_id;
104 return true;
107 void GpuVideoDecodeAcceleratorHost::Decode(
108 const media::BitstreamBuffer& bitstream_buffer) {
109 DCHECK(CalledOnValidThread());
110 if (!channel_)
111 return;
113 base::SharedMemoryHandle handle = channel_->ShareToGpuProcess(
114 bitstream_buffer.handle());
115 if (!base::SharedMemory::IsHandleValid(handle)) {
116 NOTREACHED() << "Failed to duplicate buffer handler";
117 return;
120 Send(new AcceleratedVideoDecoderMsg_Decode(
121 decoder_route_id_, handle, bitstream_buffer.id(),
122 bitstream_buffer.size()));
125 void GpuVideoDecodeAcceleratorHost::AssignPictureBuffers(
126 const std::vector<media::PictureBuffer>& buffers) {
127 DCHECK(CalledOnValidThread());
128 if (!channel_)
129 return;
130 // Rearrange data for IPC command.
131 std::vector<int32> buffer_ids;
132 std::vector<uint32> texture_ids;
133 for (uint32 i = 0; i < buffers.size(); i++) {
134 const media::PictureBuffer& buffer = buffers[i];
135 if (buffer.size() != picture_buffer_dimensions_) {
136 DLOG(ERROR) << "buffer.size() invalid: expected "
137 << picture_buffer_dimensions_.ToString()
138 << ", got " << buffer.size().ToString();
139 PostNotifyError(INVALID_ARGUMENT);
140 return;
142 texture_ids.push_back(buffer.texture_id());
143 buffer_ids.push_back(buffer.id());
145 Send(new AcceleratedVideoDecoderMsg_AssignPictureBuffers(
146 decoder_route_id_, buffer_ids, texture_ids));
149 void GpuVideoDecodeAcceleratorHost::ReusePictureBuffer(
150 int32 picture_buffer_id) {
151 DCHECK(CalledOnValidThread());
152 if (!channel_)
153 return;
154 Send(new AcceleratedVideoDecoderMsg_ReusePictureBuffer(
155 decoder_route_id_, picture_buffer_id));
158 void GpuVideoDecodeAcceleratorHost::Flush() {
159 DCHECK(CalledOnValidThread());
160 if (!channel_)
161 return;
162 Send(new AcceleratedVideoDecoderMsg_Flush(decoder_route_id_));
165 void GpuVideoDecodeAcceleratorHost::Reset() {
166 DCHECK(CalledOnValidThread());
167 if (!channel_)
168 return;
169 Send(new AcceleratedVideoDecoderMsg_Reset(decoder_route_id_));
172 void GpuVideoDecodeAcceleratorHost::Destroy() {
173 DCHECK(CalledOnValidThread());
174 if (channel_)
175 Send(new AcceleratedVideoDecoderMsg_Destroy(decoder_route_id_));
176 client_ = NULL;
177 delete this;
180 void GpuVideoDecodeAcceleratorHost::OnWillDeleteImpl() {
181 DCHECK(CalledOnValidThread());
182 impl_ = NULL;
184 // The CommandBufferProxyImpl is going away; error out this VDA.
185 OnChannelError();
188 void GpuVideoDecodeAcceleratorHost::PostNotifyError(Error error) {
189 DCHECK(CalledOnValidThread());
190 DVLOG(2) << "PostNotifyError(): error=" << error;
191 base::ThreadTaskRunnerHandle::Get()->PostTask(
192 FROM_HERE, base::Bind(&GpuVideoDecodeAcceleratorHost::OnNotifyError,
193 weak_this_factory_.GetWeakPtr(), error));
196 void GpuVideoDecodeAcceleratorHost::Send(IPC::Message* message) {
197 DCHECK(CalledOnValidThread());
198 uint32 message_type = message->type();
199 if (!channel_->Send(message)) {
200 DLOG(ERROR) << "Send(" << message_type << ") failed";
201 PostNotifyError(PLATFORM_FAILURE);
205 void GpuVideoDecodeAcceleratorHost::OnBitstreamBufferProcessed(
206 int32 bitstream_buffer_id) {
207 DCHECK(CalledOnValidThread());
208 if (client_)
209 client_->NotifyEndOfBitstreamBuffer(bitstream_buffer_id);
212 void GpuVideoDecodeAcceleratorHost::OnProvidePictureBuffer(
213 uint32 num_requested_buffers,
214 const gfx::Size& dimensions,
215 uint32 texture_target) {
216 DCHECK(CalledOnValidThread());
217 picture_buffer_dimensions_ = dimensions;
218 if (client_) {
219 client_->ProvidePictureBuffers(
220 num_requested_buffers, dimensions, texture_target);
224 void GpuVideoDecodeAcceleratorHost::OnDismissPictureBuffer(
225 int32 picture_buffer_id) {
226 DCHECK(CalledOnValidThread());
227 if (client_)
228 client_->DismissPictureBuffer(picture_buffer_id);
231 void GpuVideoDecodeAcceleratorHost::OnPictureReady(
232 int32 picture_buffer_id,
233 int32 bitstream_buffer_id,
234 const gfx::Rect& visible_rect,
235 bool allow_overlay) {
236 DCHECK(CalledOnValidThread());
237 if (!client_)
238 return;
239 media::Picture picture(picture_buffer_id, bitstream_buffer_id, visible_rect,
240 allow_overlay);
241 client_->PictureReady(picture);
244 void GpuVideoDecodeAcceleratorHost::OnFlushDone() {
245 DCHECK(CalledOnValidThread());
246 if (client_)
247 client_->NotifyFlushDone();
250 void GpuVideoDecodeAcceleratorHost::OnResetDone() {
251 DCHECK(CalledOnValidThread());
252 if (client_)
253 client_->NotifyResetDone();
256 void GpuVideoDecodeAcceleratorHost::OnNotifyError(uint32 error) {
257 DCHECK(CalledOnValidThread());
258 if (!client_)
259 return;
260 weak_this_factory_.InvalidateWeakPtrs();
262 // Client::NotifyError() may Destroy() |this|, so calling it needs to be the
263 // last thing done on this stack!
264 media::VideoDecodeAccelerator::Client* client = NULL;
265 std::swap(client, client_);
266 client->NotifyError(static_cast<media::VideoDecodeAccelerator::Error>(error));
269 } // namespace content