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

Side by Side Diff: chrome/gpu/gpu_arc_video_service.cc

Issue 1641353003: GpuArcVideoService (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@arc-4-owen-ArcGpuVideoDecodeAccelerator
Patch Set: modify content gui client hook Created 4 years, 9 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
(Empty)
1 // Copyright 2016 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.
4
5 #include "chrome/gpu/gpu_arc_video_service.h"
6
7 #include <fcntl.h>
8
9 #include <utility>
10
11 #include "base/bind.h"
12 #include "base/logging.h"
13 #include "base/thread_task_runner_handle.h"
14 #include "chrome/gpu/arc_gpu_video_decode_accelerator.h"
15 #include "chrome/gpu/arc_video_accelerator.h"
16 #include "components/arc/common/video_accelerator.mojom.h"
17 #include "mojo/edk/embedder/embedder.h"
18 #include "mojo/public/cpp/bindings/binding.h"
19 #include "mojo/public/cpp/bindings/type_converter.h"
20
21 namespace {
22
23 // Child process may be created in the different namespace, thus we don't have
24 // its real PID. Since Mojo in POSIX only uses the value as identifier for the
25 // routing table, we can give it fake value as long as it is unique.
26 // Chrome OS uses default pid_max of 32k, so we can safely shift the pid range
27 // by kPidBase and don't conflict with legitimate process.
28 //
29 // This assumes all video accelerator clients are from the same namespace and
30 // the max pid of the said namespace is kPidMask.
31 base::ProcessHandle RemapChildPid(uint32_t pid) {
Luis Héctor Chávez 2016/03/24 17:24:20 Can you move this somewhere in components/arc and
kcwu 2016/03/28 13:17:35 Done.
32 uint32_t kPidBase = 0x3F000000; // arbitrarily chosen.
33 uint32_t kPidMask = 0x7fff; // the default, 32k.
34 return kPidBase + (pid & kPidMask);
35 }
36
37 } // namespace
38
39 namespace mojo {
40
41 template <>
42 struct TypeConverter<arc::BufferMetadataPtr, chromeos::arc::BufferMetadata> {
43 static arc::BufferMetadataPtr Convert(
44 const chromeos::arc::BufferMetadata& input) {
45 arc::BufferMetadataPtr result = arc::BufferMetadata::New();
46 result->timestamp = input.timestamp;
47 result->flags = input.flags;
48 result->bytes_used = input.bytes_used;
49 return result;
50 }
51 };
52
53 template <>
54 struct TypeConverter<chromeos::arc::BufferMetadata, arc::BufferMetadataPtr> {
55 static chromeos::arc::BufferMetadata Convert(
56 const arc::BufferMetadataPtr& input) {
57 chromeos::arc::BufferMetadata result;
58 result.timestamp = input->timestamp;
59 result.flags = input->flags;
60 result.bytes_used = input->bytes_used;
61 return result;
62 }
63 };
64
65 template <>
66 struct TypeConverter<arc::VideoFormatPtr, chromeos::arc::VideoFormat> {
67 static arc::VideoFormatPtr Convert(const chromeos::arc::VideoFormat& input) {
68 arc::VideoFormatPtr result = arc::VideoFormat::New();
69 result->pixel_format = input.pixel_format;
70 result->buffer_size = input.buffer_size;
71 result->min_num_buffers = input.min_num_buffers;
72 result->coded_width = input.coded_width;
73 result->coded_height = input.coded_height;
74 result->crop_left = input.crop_left;
75 result->crop_width = input.crop_width;
76 result->crop_top = input.crop_top;
77 result->crop_height = input.crop_height;
78 return result;
79 }
80 };
81
82 template <>
83 struct TypeConverter<chromeos::arc::ArcVideoAccelerator::Config,
84 arc::ArcVideoAcceleratorConfigPtr> {
85 static chromeos::arc::ArcVideoAccelerator::Config Convert(
86 const arc::ArcVideoAcceleratorConfigPtr& input) {
87 chromeos::arc::ArcVideoAccelerator::Config result;
88 result.device_type =
89 static_cast<chromeos::arc::ArcVideoAccelerator::Config::DeviceType>(
90 input->device_type);
91 result.num_input_buffers = input->num_input_buffers;
92 result.input_pixel_format = input->input_pixel_format;
93 return result;
94 }
95 };
96
97 } // namespace mojo
98
99 namespace chromeos {
100 namespace arc {
101
102 class GpuArcVideoService::AcceleratorStub
103 : public ::arc::VideoAcceleratorService,
104 public ArcVideoAccelerator::Client {
105 public:
106 // |owner| outlives AcceleratorStub.
107 explicit AcceleratorStub(GpuArcVideoService* owner)
108 : owner_(owner), binding_(this) {}
109
110 ~AcceleratorStub() override { DCHECK(thread_checker_.CalledOnValidThread()); }
111
112 bool Connect(const gpu::GpuPreferences& gpu_preferences,
113 const std::string& token) {
114 DVLOG(2) << "Connect";
115
116 mojo::ScopedMessagePipeHandle server_pipe =
117 mojo::edk::CreateParentMessagePipe(token);
118 if (!server_pipe.is_valid()) {
119 LOG(ERROR) << "Invalid pipe";
120 return false;
121 }
122
123 client_.Bind(mojo::InterfacePtrInfo<::arc::VideoAcceleratorServiceClient>(
124 std::move(server_pipe), 0u));
125
126 // base::Unretained is safe because we own |client_|
127 client_.set_connection_error_handler(
128 base::Bind(&GpuArcVideoService::AcceleratorStub::OnConnectionError,
129 base::Unretained(this)));
130
131 accelerator_.reset(new ArcGpuVideoDecodeAccelerator(gpu_preferences));
132
133 ::arc::VideoAcceleratorServicePtr service;
134 binding_.Bind(GetProxy(&service));
135 // base::Unretained is safe because we own |binding_|
136 binding_.set_connection_error_handler(
137 base::Bind(&GpuArcVideoService::AcceleratorStub::OnConnectionError,
138 base::Unretained(this)));
139
140 client_->Init(std::move(service));
141 return true;
142 }
143
144 void OnConnectionError() {
145 DVLOG(2) << "OnConnectionError";
146 owner_->RemoveClient(this);
147 // |this| is deleted.
148 }
149
150 // ArcVideoAccelerator::Client implementation:
151 void OnError(ArcVideoAccelerator::Error error) override {
152 DVLOG(2) << "OnError " << error;
153 client_->OnError(
154 static_cast<::arc::VideoAcceleratorServiceClient::Error>(error));
155 }
156
157 void OnBufferDone(PortType port,
158 uint32_t index,
159 const BufferMetadata& metadata) override {
160 DVLOG(2) << "OnBufferDone " << port << "," << index;
161 client_->OnBufferDone(static_cast<::arc::PortType>(port), index,
162 ::arc::BufferMetadata::From(metadata));
163 }
164
165 void OnResetDone() override {
166 DVLOG(2) << "OnResetDone";
167 client_->OnResetDone();
168 }
169
170 void OnOutputFormatChanged(const VideoFormat& format) override {
171 DVLOG(2) << "OnOutputFormatChanged";
172 client_->OnOutputFormatChanged(::arc::VideoFormat::From(format));
173 }
174
175 // ::arc::VideoAcceleratorService impementation:
176 void Initialize(::arc::ArcVideoAcceleratorConfigPtr config,
177 const InitializeCallback& callback) override {
178 DVLOG(2) << "Initialize";
179 bool result = accelerator_->Initialize(
180 config.To<ArcVideoAccelerator::Config>(), this);
181 callback.Run(result);
182 }
183
184 void BindSharedMemory(::arc::PortType port,
185 uint32_t index,
186 mojo::ScopedHandle ashmem_handle,
187 uint64_t offset,
188 uint64_t length) override {
189 DVLOG(2) << "BindSharedMemoryCallback port=" << port << ", index=" << index
190 << ", offset=" << offset << ", length=" << length;
191 // TODO(kcwu) make sure do we need special care for invalid handle?
192 mojo::edk::ScopedPlatformHandle scoped_platform_handle;
193 MojoResult mojo_result = mojo::edk::PassWrappedPlatformHandle(
194 ashmem_handle.release().value(), &scoped_platform_handle);
dcheng 2016/03/24 20:29:14 Mojo folks: can we make this API a little more str
195 DCHECK_EQ(mojo_result, MOJO_RESULT_OK);
196
197 int fd = scoped_platform_handle.release().handle;
198 accelerator_->BindSharedMemory(static_cast<PortType>(port), index, fd,
199 static_cast<size_t>(offset),
dcheng 2016/03/24 20:29:14 These static casts make me nervous, is there some
Luis Héctor Chávez 2016/03/24 23:16:53 No, and in fact for x86_64 devices it is guarantee
dcheng 2016/03/30 16:52:36 If that's the case, why not just make the argument
200 static_cast<size_t>(length));
201 }
202
203 void BindDmabuf(::arc::PortType port,
204 uint32_t index,
205 mojo::ScopedHandle dmabuf_handle) override {
206 DVLOG(2) << "BindDmabuf port=" << port << ", index=" << index;
207 mojo::edk::ScopedPlatformHandle scoped_platform_handle;
208 MojoResult mojo_result = mojo::edk::PassWrappedPlatformHandle(
209 dmabuf_handle.release().value(), &scoped_platform_handle);
210 DCHECK_EQ(mojo_result, MOJO_RESULT_OK);
211
212 int fd = scoped_platform_handle.release().handle;
213 accelerator_->BindDmabuf(static_cast<PortType>(port), index, fd);
214 }
215
216 void UseBuffer(::arc::PortType port,
217 uint32_t index,
218 ::arc::BufferMetadataPtr metadata) override {
219 DVLOG(2) << "UseBuffer port=" << port << ", index=" << index;
220 accelerator_->UseBuffer(static_cast<PortType>(port), index,
221 metadata.To<BufferMetadata>());
222 }
223
224 void SetNumberOfOutputBuffers(uint64_t number) override {
225 DVLOG(2) << "SetNumberOfOutputBuffers number=" << number;
226 accelerator_->SetNumberOfOutputBuffers(static_cast<size_t>(number));
227 }
228
229 void Reset() override { accelerator_->Reset(); }
230
231 private:
232 base::ThreadChecker thread_checker_;
233 GpuArcVideoService* const owner_;
234 scoped_ptr<ArcVideoAccelerator> accelerator_;
235 ::arc::VideoAcceleratorServiceClientPtr client_;
236 mojo::Binding<::arc::VideoAcceleratorService> binding_;
237 };
238
239 GpuArcVideoService::GpuArcVideoService(
240 mojo::InterfaceRequest<::arc::VideoHost> request,
241 const gpu::GpuPreferences& gpu_preferences)
242 : binding_(this, std::move(request)), gpu_preferences_(gpu_preferences) {}
243
244 GpuArcVideoService::~GpuArcVideoService() {}
245
246 void GpuArcVideoService::OnRequestArcVideoAcceleratorChannel(
247 uint32_t pid,
248 const OnRequestArcVideoAcceleratorChannelCallback& callback) {
249 DVLOG(1) << "OnRequestArcVideoAcceleratorChannelCallback";
250
251 mojo::edk::ScopedPlatformHandle child_handle =
252 mojo::edk::ChildProcessLaunched(RemapChildPid(pid));
253
254 MojoHandle wrapped_handle;
255 MojoResult wrap_result = mojo::edk::CreatePlatformHandleWrapper(
256 std::move(child_handle), &wrapped_handle);
257 if (wrap_result != MOJO_RESULT_OK) {
258 LOG(WARNING) << "Pipe failed to wrap handles. Closing: " << wrap_result;
259 callback.Run(mojo::ScopedHandle(), std::string());
260 return;
261 }
262
263 scoped_ptr<AcceleratorStub> stub(new AcceleratorStub(this));
264
265 std::string token = mojo::edk::GenerateRandomToken();
266 if (!stub->Connect(gpu_preferences_, token)) {
267 callback.Run(mojo::ScopedHandle(), std::string());
268 return;
269 }
270 accelerator_stubs_[stub.get()] = std::move(stub);
Luis Héctor Chávez 2016/03/24 17:24:20 nit: accelerator_stubs_.insert(std::make_pair(stub
kcwu 2016/03/28 13:17:34 Done.
271
272 callback.Run(mojo::ScopedHandle(mojo::Handle(wrapped_handle)), token);
273 }
274
275 void GpuArcVideoService::RemoveClient(AcceleratorStub* stub) {
276 accelerator_stubs_.erase(stub);
277 }
278
279 } // namespace arc
280 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698