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

Side by Side Diff: content/common/gpu/media/gpu_arc_video_service.cc

Issue 1451353002: Implement GpuArcVideoService for arc video accelerator (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: use GpuProcessHost instead of GpuChannelHost Created 5 years 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 2015 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 "content/common/gpu/media/gpu_arc_video_service.h"
6
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/logging.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/synchronization/waitable_event.h"
12 #include "base/thread_task_runner_handle.h"
13 #include "content/common/gpu/gpu_channel_manager.h"
14 #include "content/common/gpu/gpu_messages.h"
15 #include "ipc/ipc_listener.h"
16 #include "ipc/ipc_message_macros.h"
17 #include "ipc/ipc_sync_channel.h"
18
19 // HACK remove this before commit
20 namespace media {
21 arc::ArcVideoAccelerator::Client::~Client() {}
22 }
23
24 namespace content {
25
26 // AcceleratorStub's all methods are running on arc thread.
27 class GpuArcVideoService::AcceleratorStub
28 : public IPC::Listener,
29 public IPC::Sender,
30 public media::arc::ArcVideoAccelerator::Client,
31 public base::NonThreadSafe {
32 public:
33 // |owner| outlives AcceleratorStub.
34 AcceleratorStub(GpuArcVideoService* owner)
35 : owner_(owner),
36 #if 0
37 accelerator_(new ArcVideoAcceleratorImp()),
38 #endif
39 arc_task_runner_(base::ThreadTaskRunnerHandle::Get()) {
40 }
41
42 ~AcceleratorStub() override {
43 DCHECK(CalledOnValidThread());
44 accelerator_.reset();
45 channel_->Close();
46 }
47
48 IPC::ChannelHandle CreateChannel(
49 base::WaitableEvent* shutdown_event,
50 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner) {
51 IPC::ChannelHandle handle;
52 channel_ = IPC::SyncChannel::Create(handle, IPC::Channel::MODE_SERVER, this,
53 io_task_runner, false, shutdown_event);
54 #if defined(OS_POSIX)
55 base::ScopedFD client_fd = channel_->TakeClientFileDescriptor();
56 DCHECK(client_fd.is_valid());
57 handle.socket = base::FileDescriptor(client_fd.Pass());
58 #endif
59 return handle;
60 }
61
62 // IPC::Sender implementation:
63 bool Send(IPC::Message* msg) override {
64 DCHECK(msg);
65 return channel_->Send(msg);
66 }
67
68 // IPC::Listener implementation:
69 void OnChannelError() override {
70 DCHECK(CalledOnValidThread());
71 // RemoveClientOnArcThread will delete |this|.
72 owner_->RemoveClientOnArcThread(this);
73 }
74
75 // ArcVideoAccelerator::Client implementation:
76 void onError(media::arc::ArcVideoAccelerator::Error error) override {
77 DCHECK(CalledOnValidThread());
78 channel_->Send(new ArcAcceleratorHostMsg_Error(error));
79 }
80
81 void onBufferDone(media::arc::PortType port,
82 uint32_t index,
83 const media::arc::BufferMetadata& metadata) override {
84 DCHECK(CalledOnValidThread());
85 channel_->Send(new ArcAcceleratorHostMsg_BufferDone(port, index, metadata));
86 }
87
88 void onOutputFormatChanged(const media::arc::VideoFormat& format) override {
89 DCHECK(CalledOnValidThread());
90 channel_->Send(new ArcAcceleratorHostMsg_OutputFormatChanged(format));
91 }
92
93 // IPC::Listener implementation:
94 bool OnMessageReceived(const IPC::Message& msg) override {
95 DCHECK(CalledOnValidThread());
96
97 IPC_BEGIN_MESSAGE_MAP(AcceleratorStub, msg)
98 IPC_MESSAGE_HANDLER(ArcAcceleratorMsg_Initialize, OnInitialize)
99 IPC_MESSAGE_HANDLER(ArcAcceleratorMsg_BindSharedBuffer,
100 OnBindSharedBuffer)
101 IPC_MESSAGE_HANDLER(ArcAcceleratorMsg_BindGraphicBuffer,
102 OnBindGraphicBuffer)
103 IPC_MESSAGE_HANDLER(ArcAcceleratorMsg_UseBuffer, OnUseBuffer)
104 IPC_MESSAGE_HANDLER(ArcAcceleratorMsg_SetBufferCount, OnSetBufferCount)
105 IPC_MESSAGE_HANDLER(ArcAcceleratorMsg_Reset, OnReset)
106 IPC_MESSAGE_HANDLER(ArcAcceleratorMsg_SetBufferFormat, OnSetBufferFormat)
107 IPC_MESSAGE_UNHANDLED(return false;)
108 IPC_END_MESSAGE_MAP()
109 return true;
110 }
111
112 void OnInitialize(media::arc::DeviceType device_type, uint32_t* result) {
113 *result = accelerator_->initialize(device_type, this);
114 }
115
116 void OnBindSharedBuffer(media::arc::PortType port,
117 uint32_t index,
118 base::FileDescriptor ashmem_fd,
119 size_t offset,
120 size_t length,
121 uint32_t* result) {
122 *result = accelerator_->bindSharedBuffer(port, index, ashmem_fd.fd, offset,
123 length);
124 }
125
126 void OnBindGraphicBuffer(media::arc::PortType port,
127 uint32_t index,
128 base::FileDescriptor dmabuf_fd,
129 uint32_t* result) {
130 *result = accelerator_->bindGraphicBuffer(port, index, dmabuf_fd.fd);
131 }
132
133 void OnUseBuffer(media::arc::PortType port,
134 uint32_t index,
135 const media::arc::BufferMetadata& metadata) {
136 accelerator_->useBuffer(port, index, metadata);
137 }
138
139 void OnSetBufferCount(media::arc::PortType port,
140 size_t in_count,
141 size_t* out_count,
142 uint32_t* result) {
143 size_t count = in_count;
144 *result = accelerator_->setBufferCount(port, &count);
145 *out_count = count;
146 }
147
148 void OnReset() { accelerator_->reset(); }
149
150 void OnSetBufferFormat(media::arc::PortType port,
151 media::arc::BufferFormat format,
152 uint32_t* result) {
153 *result = accelerator_->setBufferFormat(port, format);
154 }
155
156 private:
157 GpuArcVideoService* owner_;
158 scoped_ptr<media::arc::ArcVideoAccelerator> accelerator_;
159 scoped_ptr<IPC::SyncChannel> channel_;
160 const scoped_refptr<base::SingleThreadTaskRunner> arc_task_runner_;
161 };
162
163 GpuArcVideoService::GpuArcVideoService(
164 GpuChannelManager* gpu_channel_manager,
165 base::WaitableEvent* shutdown_event,
166 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
167 : gpu_channel_manager_(gpu_channel_manager),
168 shutdown_event_(shutdown_event),
169 io_task_runner_(io_task_runner),
170 task_runner_(base::ThreadTaskRunnerHandle::Get()),
171 arc_video_accelerator_thread_("ArcVideoAcceleratorThread") {}
172
173 GpuArcVideoService::~GpuArcVideoService() {
174 DCHECK(CalledOnValidThread());
175
176 if (!arc_video_accelerator_thread_.IsRunning())
177 return;
178
179 base::WaitableEvent done(false, false);
180 arc_task_runner_->PostTask(
181 FROM_HERE, base::Bind(&GpuArcVideoService::RemoveAllClientsOnArcThread,
182 base::Unretained(this), base::Unretained(&done)));
183 done.Wait();
184
185 arc_video_accelerator_thread_.Stop();
186 }
187
188 void GpuArcVideoService::Initialize() {
189 DCHECK(CalledOnValidThread());
190
191 arc_video_accelerator_thread_.Start();
192 arc_task_runner_ = arc_video_accelerator_thread_.task_runner();
193 }
194
195 void GpuArcVideoService::CreateChannel() {
196 DCHECK(CalledOnValidThread());
197 DCHECK(arc_task_runner_);
198
199 // It's safe to Unretained |this| because the thread is owned by |this|.
200 arc_task_runner_->PostTask(
201 FROM_HERE, base::Bind(&GpuArcVideoService::CreateClientOnArcThread,
202 base::Unretained(this)));
203 }
204
205 void GpuArcVideoService::CreateClientOnArcThread() {
206 DCHECK(arc_task_runner_->BelongsToCurrentThread());
207 scoped_ptr<AcceleratorStub> stub(new AcceleratorStub(this));
208 accelerator_stubs_[stub.get()] = stub.Pass();
209
210 IPC::ChannelHandle handle =
211 stub->CreateChannel(shutdown_event_, io_task_runner_);
212 gpu_channel_manager_->Send(
213 new GpuHostMsg_ArcAcceleratorChannelCreated(handle));
214 }
215
216 void GpuArcVideoService::RemoveClientOnArcThread(AcceleratorStub* stub) {
217 DCHECK(arc_task_runner_->BelongsToCurrentThread());
218 accelerator_stubs_.erase(stub);
219 }
220
221 void GpuArcVideoService::RemoveAllClientsOnArcThread(
Owen Lin 2015/12/07 09:05:23 Can we just depends on OnChannelError() to remove
kcwu 2015/12/10 10:17:37 If doing so, the client inside arc instance must b
222 base::WaitableEvent* done) {
223 DCHECK(arc_task_runner_->BelongsToCurrentThread());
224 accelerator_stubs_.clear();
225 done->Signal();
226 }
227
228 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698