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

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

Issue 1656433002: Sample code: IPC Transport object for GPU Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: GpuMemoryBufferService + Transport object. TODO: Eliminate ChildThreadImpl dependency Created 4 years, 10 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
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 "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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698