Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 |
| OLD | NEW |