| 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 "base/thread_task_runner_handle.h" |
| 10 #include "build/build_config.h" | 11 #include "build/build_config.h" |
| 11 #include "content/common/gpu/client/gpu_channel_host.h" | 12 #include "content/common/gpu/client/gpu_channel_host.h" |
| 12 #include "content/common/gpu/gpu_messages.h" | 13 #include "content/common/gpu/client/ipc/chrome/chrome_command_buffer_ipc_transpo
rt.h" |
| 13 #include "content/common/view_messages.h" | 14 #include "content/common/gpu/video_decode_params.h" |
| 14 #include "ipc/ipc_message_macros.h" | |
| 15 #include "ipc/ipc_message_utils.h" | |
| 16 | 15 |
| 17 #if defined(OS_WIN) | 16 #if defined(OS_WIN) |
| 18 #include "content/public/common/sandbox_init.h" | 17 #include "content/public/common/sandbox_init.h" |
| 19 #endif // OS_WIN | 18 #endif // OS_WIN |
| 20 | 19 |
| 21 using media::VideoDecodeAccelerator; | 20 using media::VideoDecodeAccelerator; |
| 21 |
| 22 namespace content { | 22 namespace content { |
| 23 | 23 |
| 24 GpuVideoDecodeAcceleratorHost::GpuVideoDecodeAcceleratorHost( | 24 GpuVideoDecodeAcceleratorHost::GpuVideoDecodeAcceleratorHost( |
| 25 GpuChannelHost* channel, | 25 GpuChannelHost* channel, |
| 26 scoped_ptr<GpuVideoDecodeAcceleratorHostIPCTransport> transport, |
| 26 CommandBufferProxyImpl* impl) | 27 CommandBufferProxyImpl* impl) |
| 27 : channel_(channel), | 28 : channel_(channel), |
| 28 decoder_route_id_(MSG_ROUTING_NONE), | 29 transport_(std::move(transport)), |
| 29 client_(NULL), | 30 client_(nullptr), |
| 30 impl_(impl), | 31 impl_(impl), |
| 31 weak_this_factory_(this) { | 32 weak_this_factory_(this) { |
| 32 DCHECK(channel_); | |
| 33 DCHECK(impl_); | 33 DCHECK(impl_); |
| 34 impl_->AddDeletionObserver(this); | 34 impl_->AddDeletionObserver(this); |
| 35 transport_->SetClient(this); |
| 35 } | 36 } |
| 36 | 37 |
| 37 GpuVideoDecodeAcceleratorHost::~GpuVideoDecodeAcceleratorHost() { | 38 GpuVideoDecodeAcceleratorHost::~GpuVideoDecodeAcceleratorHost() { |
| 38 DCHECK(CalledOnValidThread()); | 39 DCHECK(CalledOnValidThread()); |
| 39 | 40 transport_.reset(); |
| 40 if (channel_ && decoder_route_id_ != MSG_ROUTING_NONE) | |
| 41 channel_->RemoveRoute(decoder_route_id_); | |
| 42 if (impl_) | 41 if (impl_) |
| 43 impl_->RemoveDeletionObserver(this); | 42 impl_->RemoveDeletionObserver(this); |
| 44 } | 43 } |
| 45 | 44 |
| 46 bool GpuVideoDecodeAcceleratorHost::OnMessageReceived(const IPC::Message& msg) { | 45 bool GpuVideoDecodeAcceleratorHost::Initialize( |
| 47 DCHECK(CalledOnValidThread()); | 46 const Config& config, |
| 48 bool handled = true; | 47 media::VideoDecodeAccelerator::Client* client) { |
| 49 IPC_BEGIN_MESSAGE_MAP(GpuVideoDecodeAcceleratorHost, msg) | |
| 50 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_CdmAttached, | |
| 51 OnCdmAttached) | |
| 52 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_BitstreamBufferProcessed, | |
| 53 OnBitstreamBufferProcessed) | |
| 54 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ProvidePictureBuffers, | |
| 55 OnProvidePictureBuffer) | |
| 56 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_PictureReady, | |
| 57 OnPictureReady) | |
| 58 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_FlushDone, | |
| 59 OnFlushDone) | |
| 60 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ResetDone, | |
| 61 OnResetDone) | |
| 62 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ErrorNotification, | |
| 63 OnNotifyError) | |
| 64 IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_DismissPictureBuffer, | |
| 65 OnDismissPictureBuffer) | |
| 66 IPC_MESSAGE_UNHANDLED(handled = false) | |
| 67 IPC_END_MESSAGE_MAP() | |
| 68 DCHECK(handled); | |
| 69 // See OnNotifyError for why |this| mustn't be used after OnNotifyError might | |
| 70 // have been called above. | |
| 71 return handled; | |
| 72 } | |
| 73 | |
| 74 void GpuVideoDecodeAcceleratorHost::OnChannelError() { | |
| 75 DCHECK(CalledOnValidThread()); | |
| 76 if (channel_) { | |
| 77 if (decoder_route_id_ != MSG_ROUTING_NONE) | |
| 78 channel_->RemoveRoute(decoder_route_id_); | |
| 79 channel_ = NULL; | |
| 80 } | |
| 81 DLOG(ERROR) << "OnChannelError()"; | |
| 82 PostNotifyError(PLATFORM_FAILURE); | |
| 83 } | |
| 84 | |
| 85 bool GpuVideoDecodeAcceleratorHost::Initialize(const Config& config, | |
| 86 Client* client) { | |
| 87 DCHECK(CalledOnValidThread()); | 48 DCHECK(CalledOnValidThread()); |
| 88 client_ = client; | 49 client_ = client; |
| 89 | 50 |
| 90 if (!impl_) | 51 if (!impl_) |
| 91 return false; | 52 return false; |
| 92 | 53 |
| 93 int32_t route_id = channel_->GenerateRouteID(); | |
| 94 channel_->AddRoute(route_id, weak_this_factory_.GetWeakPtr()); | |
| 95 | |
| 96 bool succeeded = false; | 54 bool succeeded = false; |
| 97 Send(new GpuCommandBufferMsg_CreateVideoDecoder(impl_->route_id(), config, | 55 impl_->transport()->CreateVideoDecoder(transport_.get(), config, &succeeded); |
| 98 route_id, &succeeded)); | |
| 99 | |
| 100 if (!succeeded) { | 56 if (!succeeded) { |
| 101 DLOG(ERROR) << "Send(GpuCommandBufferMsg_CreateVideoDecoder()) failed"; | 57 DLOG(ERROR) << "CreateVideoDecoder() failed"; |
| 102 PostNotifyError(PLATFORM_FAILURE); | 58 PostNotifyError(PLATFORM_FAILURE); |
| 103 channel_->RemoveRoute(route_id); | |
| 104 return false; | 59 return false; |
| 105 } | 60 } |
| 106 decoder_route_id_ = route_id; | |
| 107 return true; | 61 return true; |
| 108 } | 62 } |
| 109 | 63 |
| 110 void GpuVideoDecodeAcceleratorHost::SetCdm(int cdm_id) { | 64 void GpuVideoDecodeAcceleratorHost::SetCdm(int cdm_id) { |
| 111 DCHECK(CalledOnValidThread()); | 65 DCHECK(CalledOnValidThread()); |
| 112 if (!channel_) | 66 transport_->SetCdm(cdm_id); |
| 113 return; | |
| 114 Send(new AcceleratedVideoDecoderMsg_SetCdm(decoder_route_id_, cdm_id)); | |
| 115 } | 67 } |
| 116 | 68 |
| 117 void GpuVideoDecodeAcceleratorHost::Decode( | 69 void GpuVideoDecodeAcceleratorHost::Decode( |
| 118 const media::BitstreamBuffer& bitstream_buffer) { | 70 const media::BitstreamBuffer& bitstream_buffer) { |
| 119 DCHECK(CalledOnValidThread()); | 71 DCHECK(CalledOnValidThread()); |
| 120 if (!channel_) | |
| 121 return; | |
| 122 | 72 |
| 123 base::SharedMemoryHandle handle = channel_->ShareToGpuProcess( | 73 base::SharedMemoryHandle handle = channel_->ShareToGpuProcess( |
| 124 bitstream_buffer.handle()); | 74 bitstream_buffer.handle()); |
| 125 if (!base::SharedMemory::IsHandleValid(handle)) { | 75 if (!base::SharedMemory::IsHandleValid(handle)) { |
| 126 NOTREACHED() << "Failed to duplicate buffer handler"; | 76 NOTREACHED() << "Failed to duplicate buffer handler"; |
| 127 return; | 77 return; |
| 128 } | 78 } |
| 129 | 79 |
| 130 AcceleratedVideoDecoderMsg_Decode_Params params; | 80 VideoDecodeParams params; |
| 131 params.bitstream_buffer_id = bitstream_buffer.id(); | 81 params.bitstream_buffer_id = bitstream_buffer.id(); |
| 132 params.buffer_handle = handle; | 82 params.buffer_handle = handle; |
| 133 params.size = bitstream_buffer.size(); | 83 params.size = bitstream_buffer.size(); |
| 134 params.presentation_timestamp = bitstream_buffer.presentation_timestamp(); | 84 params.presentation_timestamp = bitstream_buffer.presentation_timestamp(); |
| 135 params.key_id = bitstream_buffer.key_id(); | 85 params.key_id = bitstream_buffer.key_id(); |
| 136 params.iv = bitstream_buffer.iv(); | 86 params.iv = bitstream_buffer.iv(); |
| 137 params.subsamples = bitstream_buffer.subsamples(); | 87 params.subsamples = bitstream_buffer.subsamples(); |
| 138 | 88 |
| 139 Send(new AcceleratedVideoDecoderMsg_Decode(decoder_route_id_, params)); | 89 transport_->Decode(params); |
| 140 } | 90 } |
| 141 | 91 |
| 142 void GpuVideoDecodeAcceleratorHost::AssignPictureBuffers( | 92 void GpuVideoDecodeAcceleratorHost::AssignPictureBuffers( |
| 143 const std::vector<media::PictureBuffer>& buffers) { | 93 const std::vector<media::PictureBuffer>& buffers) { |
| 144 DCHECK(CalledOnValidThread()); | 94 DCHECK(CalledOnValidThread()); |
| 145 if (!channel_) | 95 if (!channel_) |
| 146 return; | 96 return; |
| 147 // Rearrange data for IPC command. | 97 // Rearrange data for IPC command. |
| 148 std::vector<int32_t> buffer_ids; | 98 std::vector<int32_t> buffer_ids; |
| 149 std::vector<uint32_t> texture_ids; | 99 std::vector<uint32_t> texture_ids; |
| 150 for (uint32_t i = 0; i < buffers.size(); i++) { | 100 for (uint32_t i = 0; i < buffers.size(); i++) { |
| 151 const media::PictureBuffer& buffer = buffers[i]; | 101 const media::PictureBuffer& buffer = buffers[i]; |
| 152 if (buffer.size() != picture_buffer_dimensions_) { | 102 if (buffer.size() != picture_buffer_dimensions_) { |
| 153 DLOG(ERROR) << "buffer.size() invalid: expected " | 103 DLOG(ERROR) << "buffer.size() invalid: expected " |
| 154 << picture_buffer_dimensions_.ToString() | 104 << picture_buffer_dimensions_.ToString() |
| 155 << ", got " << buffer.size().ToString(); | 105 << ", got " << buffer.size().ToString(); |
| 156 PostNotifyError(INVALID_ARGUMENT); | 106 PostNotifyError(INVALID_ARGUMENT); |
| 157 return; | 107 return; |
| 158 } | 108 } |
| 159 texture_ids.push_back(buffer.texture_id()); | 109 texture_ids.push_back(buffer.texture_id()); |
| 160 buffer_ids.push_back(buffer.id()); | 110 buffer_ids.push_back(buffer.id()); |
| 161 } | 111 } |
| 162 Send(new AcceleratedVideoDecoderMsg_AssignPictureBuffers( | 112 transport_->AssignPictureBuffers(buffer_ids, texture_ids); |
| 163 decoder_route_id_, buffer_ids, texture_ids)); | |
| 164 } | 113 } |
| 165 | 114 |
| 166 void GpuVideoDecodeAcceleratorHost::ReusePictureBuffer( | 115 void GpuVideoDecodeAcceleratorHost::ReusePictureBuffer( |
| 167 int32_t picture_buffer_id) { | 116 int32_t picture_buffer_id) { |
| 168 DCHECK(CalledOnValidThread()); | 117 DCHECK(CalledOnValidThread()); |
| 169 if (!channel_) | 118 if (!channel_) |
| 170 return; | 119 return; |
| 171 Send(new AcceleratedVideoDecoderMsg_ReusePictureBuffer( | 120 transport_->ReusePictureBuffer(picture_buffer_id); |
| 172 decoder_route_id_, picture_buffer_id)); | |
| 173 } | 121 } |
| 174 | 122 |
| 175 void GpuVideoDecodeAcceleratorHost::Flush() { | 123 void GpuVideoDecodeAcceleratorHost::Flush() { |
| 176 DCHECK(CalledOnValidThread()); | 124 DCHECK(CalledOnValidThread()); |
| 177 if (!channel_) | 125 if (!channel_) |
| 178 return; | 126 return; |
| 179 Send(new AcceleratedVideoDecoderMsg_Flush(decoder_route_id_)); | 127 transport_->Flush(); |
| 180 } | 128 } |
| 181 | 129 |
| 182 void GpuVideoDecodeAcceleratorHost::Reset() { | 130 void GpuVideoDecodeAcceleratorHost::Reset() { |
| 183 DCHECK(CalledOnValidThread()); | 131 DCHECK(CalledOnValidThread()); |
| 184 if (!channel_) | 132 if (!channel_) |
| 185 return; | 133 return; |
| 186 Send(new AcceleratedVideoDecoderMsg_Reset(decoder_route_id_)); | 134 transport_->Reset(); |
| 187 } | 135 } |
| 188 | 136 |
| 189 void GpuVideoDecodeAcceleratorHost::Destroy() { | 137 void GpuVideoDecodeAcceleratorHost::Destroy() { |
| 190 DCHECK(CalledOnValidThread()); | 138 DCHECK(CalledOnValidThread()); |
| 191 if (channel_) | 139 if (channel_) |
| 192 Send(new AcceleratedVideoDecoderMsg_Destroy(decoder_route_id_)); | 140 transport_->Destroy(); |
| 193 client_ = NULL; | 141 client_ = nullptr; |
| 194 delete this; | 142 delete this; |
| 195 } | 143 } |
| 196 | 144 |
| 197 void GpuVideoDecodeAcceleratorHost::OnWillDeleteImpl() { | 145 void GpuVideoDecodeAcceleratorHost::OnWillDeleteImpl() { |
| 198 DCHECK(CalledOnValidThread()); | 146 DCHECK(CalledOnValidThread()); |
| 199 impl_ = NULL; | 147 impl_ = nullptr; |
| 200 | |
| 201 // The CommandBufferProxyImpl is going away; error out this VDA. | |
| 202 OnChannelError(); | |
| 203 } | 148 } |
| 204 | 149 |
| 205 void GpuVideoDecodeAcceleratorHost::PostNotifyError(Error error) { | 150 void GpuVideoDecodeAcceleratorHost::PostNotifyError(Error error) { |
| 206 DCHECK(CalledOnValidThread()); | 151 DCHECK(CalledOnValidThread()); |
| 207 DVLOG(2) << "PostNotifyError(): error=" << error; | 152 DVLOG(2) << "PostNotifyError(): error=" << error; |
| 208 base::ThreadTaskRunnerHandle::Get()->PostTask( | 153 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 209 FROM_HERE, base::Bind(&GpuVideoDecodeAcceleratorHost::OnNotifyError, | 154 FROM_HERE, base::Bind(&GpuVideoDecodeAcceleratorHost::OnNotifyError, |
| 210 weak_this_factory_.GetWeakPtr(), error)); | 155 weak_this_factory_.GetWeakPtr(), error)); |
| 211 } | 156 } |
| 212 | 157 |
| 213 void GpuVideoDecodeAcceleratorHost::Send(IPC::Message* message) { | |
| 214 DCHECK(CalledOnValidThread()); | |
| 215 uint32_t message_type = message->type(); | |
| 216 if (!channel_->Send(message)) { | |
| 217 DLOG(ERROR) << "Send(" << message_type << ") failed"; | |
| 218 PostNotifyError(PLATFORM_FAILURE); | |
| 219 } | |
| 220 } | |
| 221 | |
| 222 void GpuVideoDecodeAcceleratorHost::OnCdmAttached(bool success) { | 158 void GpuVideoDecodeAcceleratorHost::OnCdmAttached(bool success) { |
| 223 DCHECK(CalledOnValidThread()); | 159 DCHECK(CalledOnValidThread()); |
| 224 if (client_) | 160 if (client_) |
| 225 client_->NotifyCdmAttached(success); | 161 client_->NotifyCdmAttached(success); |
| 226 } | 162 } |
| 227 | 163 |
| 228 void GpuVideoDecodeAcceleratorHost::OnBitstreamBufferProcessed( | 164 void GpuVideoDecodeAcceleratorHost::OnBitstreamBufferProcessed( |
| 229 int32_t bitstream_buffer_id) { | 165 int32_t bitstream_buffer_id) { |
| 230 DCHECK(CalledOnValidThread()); | 166 DCHECK(CalledOnValidThread()); |
| 231 if (client_) | 167 if (client_) |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 } | 213 } |
| 278 | 214 |
| 279 void GpuVideoDecodeAcceleratorHost::OnNotifyError(uint32_t error) { | 215 void GpuVideoDecodeAcceleratorHost::OnNotifyError(uint32_t error) { |
| 280 DCHECK(CalledOnValidThread()); | 216 DCHECK(CalledOnValidThread()); |
| 281 if (!client_) | 217 if (!client_) |
| 282 return; | 218 return; |
| 283 weak_this_factory_.InvalidateWeakPtrs(); | 219 weak_this_factory_.InvalidateWeakPtrs(); |
| 284 | 220 |
| 285 // Client::NotifyError() may Destroy() |this|, so calling it needs to be the | 221 // Client::NotifyError() may Destroy() |this|, so calling it needs to be the |
| 286 // last thing done on this stack! | 222 // last thing done on this stack! |
| 287 media::VideoDecodeAccelerator::Client* client = NULL; | 223 media::VideoDecodeAccelerator::Client* client = nullptr; |
| 288 std::swap(client, client_); | 224 std::swap(client, client_); |
| 289 client->NotifyError(static_cast<media::VideoDecodeAccelerator::Error>(error)); | 225 client->NotifyError(static_cast<media::VideoDecodeAccelerator::Error>(error)); |
| 290 } | 226 } |
| 291 | 227 |
| 292 } // namespace content | 228 } // namespace content |
| OLD | NEW |