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

Side by Side Diff: media/gpu/ipc/client/gpu_jpeg_decode_accelerator_host.cc

Issue 2923933004: [NotForReview] Move GJDAH and GJDA to media/gpu/mojo
Patch Set: . Created 3 years, 6 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
« no previous file with comments | « media/gpu/ipc/client/gpu_jpeg_decode_accelerator_host.h ('k') | media/gpu/ipc/service/BUILD.gn » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "media/gpu/ipc/client/gpu_jpeg_decode_accelerator_host.h"
6
7 #include <stddef.h>
8
9 #include "base/bind.h"
10 #include "base/logging.h"
11 #include "base/macros.h"
12 #include "base/memory/shared_memory_handle.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/synchronization/waitable_event.h"
15 #include "build/build_config.h"
16 #include "gpu/ipc/client/gpu_channel_host.h"
17 #include "ipc/ipc_listener.h"
18 #include "ipc/ipc_message_macros.h"
19 #include "ipc/ipc_message_utils.h"
20 #include "media/gpu/ipc/common/media_messages.h"
21
22 namespace media {
23
24 // Class to receive AcceleratedJpegDecoderHostMsg_DecodeAck IPC message on IO
25 // thread. This does very similar what MessageFilter usually does. It is not
26 // MessageFilter because GpuChannelHost doesn't support AddFilter.
27 class GpuJpegDecodeAcceleratorHost::Receiver : public IPC::Listener {
28 public:
29 Receiver(Client* client,
30 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
31 : client_(client),
32 io_task_runner_(io_task_runner),
33 weak_factory_for_io_(
34 base::MakeUnique<base::WeakPtrFactory<Receiver>>(this)),
35 weak_ptr_for_io_(weak_factory_for_io_->GetWeakPtr()) {
36 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
37 }
38
39 ~Receiver() override {
40 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
41 // If |io_task_runner_| no longer accepts tasks, |weak_factory_for_io_|
42 // will leak. This is acceptable, because that should only happen on
43 // Browser shutdown.
44 io_task_runner_->DeleteSoon(FROM_HERE, weak_factory_for_io_.release());
45 }
46
47 void InvalidateWeakPtrOnIOThread(base::WaitableEvent* event) {
48 DCHECK(io_task_runner_->BelongsToCurrentThread());
49 weak_factory_for_io_->InvalidateWeakPtrs();
50 event->Signal();
51 }
52
53 // IPC::Listener implementation.
54 void OnChannelError() override {
55 DCHECK(io_task_runner_->BelongsToCurrentThread());
56
57 OnDecodeAck(kInvalidBitstreamBufferId, PLATFORM_FAILURE);
58 }
59
60 bool OnMessageReceived(const IPC::Message& msg) override {
61 DCHECK(io_task_runner_->BelongsToCurrentThread());
62
63 bool handled = true;
64 IPC_BEGIN_MESSAGE_MAP(GpuJpegDecodeAcceleratorHost::Receiver, msg)
65 IPC_MESSAGE_HANDLER(AcceleratedJpegDecoderHostMsg_DecodeAck, OnDecodeAck)
66 IPC_MESSAGE_UNHANDLED(handled = false)
67 IPC_END_MESSAGE_MAP()
68 DCHECK(handled);
69 return handled;
70 }
71
72 base::WeakPtr<IPC::Listener> AsWeakPtrForIO() { return weak_ptr_for_io_; }
73
74 private:
75 void OnDecodeAck(int32_t bitstream_buffer_id, Error error) {
76 DCHECK(io_task_runner_->BelongsToCurrentThread());
77
78 if (!client_)
79 return;
80
81 if (error == JpegDecodeAccelerator::NO_ERRORS) {
82 client_->VideoFrameReady(bitstream_buffer_id);
83 } else {
84 // Only NotifyError once.
85 // Client::NotifyError() may trigger deletion of |this| (on another
86 // thread), so calling it needs to be the last thing done on this stack!
87 JpegDecodeAccelerator::Client* client = nullptr;
88 std::swap(client, client_);
89 client->NotifyError(bitstream_buffer_id, error);
90 }
91 }
92
93 Client* client_;
94
95 // GPU IO task runner.
96 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
97
98 SEQUENCE_CHECKER(sequence_checker_);
99
100 // Weak pointers will be invalidated on IO thread.
101 std::unique_ptr<base::WeakPtrFactory<Receiver>> weak_factory_for_io_;
102 base::WeakPtr<Receiver> weak_ptr_for_io_;
103
104 DISALLOW_COPY_AND_ASSIGN(Receiver);
105 };
106
107 GpuJpegDecodeAcceleratorHost::GpuJpegDecodeAcceleratorHost(
108 scoped_refptr<gpu::GpuChannelHost> channel,
109 int32_t route_id,
110 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
111 : channel_(std::move(channel)),
112 decoder_route_id_(route_id),
113 io_task_runner_(io_task_runner) {
114 DCHECK(channel_);
115 DCHECK_NE(decoder_route_id_, MSG_ROUTING_NONE);
116 }
117
118 GpuJpegDecodeAcceleratorHost::~GpuJpegDecodeAcceleratorHost() {
119 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
120 Send(new AcceleratedJpegDecoderMsg_Destroy(decoder_route_id_));
121
122 if (receiver_) {
123 channel_->RemoveRoute(decoder_route_id_);
124
125 // Invalidate weak ptr of |receiver_|. After that, no more messages will be
126 // routed to |receiver_| on IO thread.
127 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
128 base::WaitableEvent::InitialState::NOT_SIGNALED);
129 // Use of Unretained() is safe, because if the task executes, we block
130 // until it is finished by waiting on |event| below.
131 bool task_expected_to_run = io_task_runner_->PostTask(
132 FROM_HERE, base::Bind(&Receiver::InvalidateWeakPtrOnIOThread,
133 base::Unretained(receiver_.get()),
134 base::Unretained(&event)));
135 // If the current call is happening during the browser shutdown, the
136 // |io_task_runner_| may no longer be accepting tasks.
137 if (task_expected_to_run)
138 event.Wait();
139 }
140 }
141
142 bool GpuJpegDecodeAcceleratorHost::Initialize(
143 JpegDecodeAccelerator::Client* client) {
144 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
145
146 bool succeeded = false;
147 // This cannot be on IO thread because the msg is synchronous.
148 Send(new GpuChannelMsg_CreateJpegDecoder(decoder_route_id_, &succeeded));
149
150 if (!succeeded) {
151 DLOG(ERROR) << "Send(GpuChannelMsg_CreateJpegDecoder()) failed";
152 return false;
153 }
154
155 receiver_.reset(new Receiver(client, io_task_runner_));
156
157 return true;
158 }
159
160 void GpuJpegDecodeAcceleratorHost::Decode(
161 const BitstreamBuffer& bitstream_buffer,
162 const scoped_refptr<VideoFrame>& video_frame) {
163 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
164
165 DCHECK(
166 base::SharedMemory::IsHandleValid(video_frame->shared_memory_handle()));
167
168 AcceleratedJpegDecoderMsg_Decode_Params decode_params;
169 decode_params.input_buffer = bitstream_buffer;
170 base::SharedMemoryHandle input_handle =
171 channel_->ShareToGpuProcess(bitstream_buffer.handle());
172 if (!base::SharedMemory::IsHandleValid(input_handle)) {
173 DLOG(ERROR) << "Failed to duplicate handle of BitstreamBuffer";
174 return;
175 }
176 decode_params.input_buffer.set_handle(input_handle);
177 base::SharedMemoryHandle output_handle =
178 channel_->ShareToGpuProcess(video_frame->shared_memory_handle());
179 if (!base::SharedMemory::IsHandleValid(output_handle)) {
180 DLOG(ERROR) << "Failed to duplicate handle of VideoFrame";
181 #if defined(OS_POSIX) && !defined(OS_MACOSX)
182 if (input_handle.OwnershipPassesToIPC()) {
183 input_handle.Close();
184 }
185 #else
186 // TODO(kcwu) fix the handle leak after crbug.com/493414 resolved.
187 #endif
188 return;
189 }
190
191 size_t output_buffer_size = VideoFrame::AllocationSize(
192 video_frame->format(), video_frame->coded_size());
193
194 decode_params.coded_size = video_frame->coded_size();
195 decode_params.output_video_frame_handle = output_handle;
196 decode_params.output_buffer_size =
197 base::checked_cast<uint32_t>(output_buffer_size);
198 Send(new AcceleratedJpegDecoderMsg_Decode(decoder_route_id_, decode_params));
199 }
200
201 bool GpuJpegDecodeAcceleratorHost::IsSupported() {
202 return channel_->gpu_info().jpeg_decode_accelerator_supported;
203 }
204
205 void GpuJpegDecodeAcceleratorHost::Send(IPC::Message* message) {
206 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
207
208 if (!channel_->Send(message)) {
209 DLOG(ERROR) << "Send(" << message->type() << ") failed";
210 }
211 }
212
213 base::WeakPtr<IPC::Listener> GpuJpegDecodeAcceleratorHost::GetReceiver() {
214 return receiver_->AsWeakPtrForIO();
215 }
216
217 } // namespace media
OLDNEW
« no previous file with comments | « media/gpu/ipc/client/gpu_jpeg_decode_accelerator_host.h ('k') | media/gpu/ipc/service/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698