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

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: addressed Owen's comments 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.
dcheng 2016/03/16 17:44:50 How come this isn't a problem for other mojo servi
Luis Héctor Chávez 2016/03/16 19:07:55 Other mojo services are running in the same pid na
kcwu 2016/03/17 08:07:44 Do you know that the pid is just not used yet or w
dcheng 2016/03/24 20:29:14 If the pid isn't used at all, then why do we need
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) {
32 uint32_t kPidBase = 0x3F000000; // arbitrary chosen.
Luis Héctor Chávez 2016/03/16 19:07:55 arbitrarily.
kcwu 2016/03/17 08:07:44 Done.
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.image_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::DeviceType>(input->device_type);
90 result.num_input_buffers = input->num_input_buffers;
91 result.input_pixel_format = input->input_pixel_format;
92 return result;
93 }
94 };
95
96 } // namespace mojo
97
98 namespace chromeos {
99 namespace arc {
100
101 class GpuArcVideoService::AcceleratorStub
102 : public ::arc::VideoAcceleratorService,
103 public ArcVideoAccelerator::Client {
104 public:
105 // |owner| outlives AcceleratorStub.
106 explicit AcceleratorStub(GpuArcVideoService* owner)
107 : owner_(owner), binding_(this) {}
108
109 ~AcceleratorStub() override { DCHECK(thread_checker_.CalledOnValidThread()); }
110
111 bool Connect(std::string token) {
dcheng 2016/03/16 17:44:50 const std::string&
kcwu 2016/03/17 08:07:44 Done.
112 DVLOG(2) << "Connect";
113
114 mojo::ScopedMessagePipeHandle server_pipe =
115 mojo::edk::CreateParentMessagePipe(token);
116 if (!server_pipe.is_valid()) {
117 LOG(ERROR) << "Invalid pipe";
118 return false;
119 }
120
121 client_.Bind(mojo::InterfacePtrInfo<::arc::VideoAcceleratorServiceClient>(
122 std::move(server_pipe), 0u));
123
124 // base::Unretained is safe because we owned |client_|
Luis Héctor Chávez 2016/03/16 19:07:55 nit: we own. Same below.
kcwu 2016/03/17 08:07:44 Done.
125 client_.set_connection_error_handler(
126 base::Bind(&GpuArcVideoService::AcceleratorStub::OnConnectionError,
127 base::Unretained(this)));
128
129 accelerator_.reset(
130 new ArcGpuVideoDecodeAccelerator(base::ThreadTaskRunnerHandle::Get()));
131
132 ::arc::VideoAcceleratorServicePtr service;
133 binding_.Bind(GetProxy(&service));
134 // base::Unretained is safe because we owned |binding_|
135 binding_.set_connection_error_handler(
136 base::Bind(&GpuArcVideoService::AcceleratorStub::OnConnectionError,
137 base::Unretained(this)));
138
139 client_->SetService(std::move(service));
140 return true;
141 }
142
143 void OnConnectionError() {
144 DVLOG(2) << "OnConnectionError";
145 owner_->RemoveClient(this);
146 // |this| is deleted.
147 }
148
149 // ArcVideoAccelerator::Client implementation:
150 void OnError(ArcVideoAccelerator::Error error) override {
151 DVLOG(2) << "OnError " << error;
152 client_->OnError(
153 static_cast<::arc::VideoAcceleratorServiceClient::Error>(error));
154 }
155
156 void OnBufferDone(PortType port,
157 uint32_t index,
158 const BufferMetadata& metadata) override {
159 DVLOG(2) << "OnBufferDone " << port << "," << index;
160 client_->OnBufferDone(static_cast<::arc::PortType>(port), index,
161 ::arc::BufferMetadata::From(metadata));
162 }
163
164 void OnOutputFormatChanged(const VideoFormat& format) override {
165 DVLOG(2) << "OnOutputFormatChanged";
166 client_->OnOutputFormatChanged(::arc::VideoFormat::From(format));
167 }
168
169 // ::arc::VideoAcceleratorService impementation:
170 void Initialize(::arc::ArcVideoAcceleratorConfigPtr config,
171 const InitializeCallback& callback) override {
172 DVLOG(2) << "Initialize";
173 bool result = accelerator_->Initialize(
174 config.To<ArcVideoAccelerator::Config>(), this);
175 callback.Run(result);
176 }
177
178 void BindSharedMemory(::arc::PortType port,
179 uint32_t index,
180 mojo::ScopedHandle ashmem_handle,
181 uint64_t offset,
182 uint64_t length) override {
183 DVLOG(2) << "BindSharedMemoryCallback port=" << port << ", index=" << index
184 << ", offset=" << offset << ", length=" << length;
185 // TODO(kcwu) make sure do we need special care for invalid handle?
186 mojo::edk::ScopedPlatformHandle scoped_platform_handle;
187 MojoResult mojo_result = mojo::edk::PassWrappedPlatformHandle(
188 ashmem_handle.release().value(), &scoped_platform_handle);
189 DCHECK_EQ(mojo_result, MOJO_RESULT_OK);
190
191 int fd = scoped_platform_handle.release().handle;
192 accelerator_->BindSharedMemory(static_cast<PortType>(port), index, fd,
193 static_cast<size_t>(offset),
194 static_cast<size_t>(length));
195 }
196
197 void BindDmabuf(::arc::PortType port,
198 uint32_t index,
199 mojo::ScopedHandle dmabuf_handle) override {
200 DVLOG(2) << "BindDmabuf port=" << port << ", index=" << index;
201 mojo::edk::ScopedPlatformHandle scoped_platform_handle;
202 MojoResult mojo_result = mojo::edk::PassWrappedPlatformHandle(
203 dmabuf_handle.release().value(), &scoped_platform_handle);
204 DCHECK_EQ(mojo_result, MOJO_RESULT_OK);
205
206 int fd = scoped_platform_handle.release().handle;
207 accelerator_->BindDmabuf(static_cast<PortType>(port), index, fd);
dcheng 2016/03/16 17:44:50 Am I missing another CL? Where is this defined? (S
kcwu 2016/03/17 08:07:44 They are in this pending CL https://codereview.chr
208 }
209
210 void UseBuffer(::arc::PortType port,
211 uint32_t index,
212 ::arc::BufferMetadataPtr metadata) override {
213 DVLOG(2) << "UseBuffer port=" << port << ", index=" << index;
214 accelerator_->UseBuffer(static_cast<PortType>(port), index,
215 metadata.To<BufferMetadata>());
216 }
217
218 void SetNumberOfOutputBuffers(uint64_t number) override {
219 DVLOG(2) << "SetNumberOfOutputBuffers number=" << number;
220 accelerator_->SetNumberOfOutputBuffers(static_cast<size_t>(number));
221 }
222
223 void Reset(const ResetCallback& callback) override {
224 DVLOG(2) << "Reset";
225 accelerator_->Reset();
226 callback.Run();
227 }
228
229 private:
230 base::ThreadChecker thread_checker_;
231 GpuArcVideoService* const owner_;
232 scoped_ptr<ArcVideoAccelerator> accelerator_;
233 ::arc::VideoAcceleratorServiceClientPtr client_;
234 mojo::Binding<::arc::VideoAcceleratorService> binding_;
235 };
236
237 GpuArcVideoService::GpuArcVideoService(
238 mojo::InterfaceRequest<::arc::VideoHost> request)
239 : binding_(this, std::move(request)) {}
240
241 GpuArcVideoService::~GpuArcVideoService() {}
242
243 void GpuArcVideoService::OnRequestArcVideoAcceleratorChannel(
244 uint32_t pid,
245 const OnRequestArcVideoAcceleratorChannelCallback& callback) {
246 DVLOG(1) << "OnRequestArcVideoAcceleratorChannelCallback";
247
248 mojo::edk::ScopedPlatformHandle child_handle =
249 mojo::edk::ChildProcessLaunched(RemapChildPid(pid));
250
251 MojoHandle wrapped_handle;
252 MojoResult wrap_result = mojo::edk::CreatePlatformHandleWrapper(
253 std::move(child_handle), &wrapped_handle);
254 if (wrap_result != MOJO_RESULT_OK) {
255 LOG(WARNING) << "Pipe failed to wrap handles. Closing: " << wrap_result;
256 callback.Run(mojo::ScopedHandle(), std::string());
257 return;
258 }
259
260 scoped_ptr<AcceleratorStub> stub(new AcceleratorStub(this));
261
262 std::string token = mojo::edk::GenerateRandomToken();
263 if (!stub->Connect(token)) {
264 callback.Run(mojo::ScopedHandle(), std::string());
265 return;
266 }
267 accelerator_stubs_[stub.get()] = std::move(stub);
268
269 callback.Run(mojo::ScopedHandle(mojo::Handle(wrapped_handle)), token);
270 }
271
272 void GpuArcVideoService::RemoveClient(AcceleratorStub* stub) {
273 accelerator_stubs_.erase(stub);
274 }
275
276 } // namespace arc
277 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698