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

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

Issue 1165943008: MJPEG acceleration for video capture using VAAPI, the GPU host part (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@mjpeg-2-gpu
Patch Set: Created 5 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
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/client/gpu_jpeg_decode_accelerator_host.h"
6
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/memory/weak_ptr.h"
10 #include "base/synchronization/waitable_event.h"
11 #include "content/common/gpu/client/gpu_channel_host.h"
12 #include "content/common/gpu/gpu_messages.h"
13 #include "ipc/ipc_listener.h"
14 #include "ipc/ipc_message_macros.h"
15 #include "ipc/ipc_message_utils.h"
16
17 namespace content {
18
19 // Class to receive AcceleratedJpegDecoderHostMsg_DecodeAck IPC message on IO
20 // thread. This does very similar what MessageFilter usually does. It is not
21 // MessageFilter because GpuChannelHost doesn't support AddFilter.
22 class GpuJpegDecodeAcceleratorHost::Receiver : public IPC::Listener,
23 public base::NonThreadSafe {
24 public:
25 Receiver(Client* client,
26 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
27 : client_(client),
28 io_task_runner_(io_task_runner),
29 weak_factory_for_io_(this) {
30 DCHECK(CalledOnValidThread());
31 }
32
33 ~Receiver() { DCHECK(CalledOnValidThread()); }
34
35 void InvalidateWeakPtr(base::WaitableEvent* event) {
36 DCHECK(io_task_runner_->BelongsToCurrentThread());
37 weak_factory_for_io_.InvalidateWeakPtrs();
38 event->Signal();
39 }
40
41 // IPC::Listener implementation.
42 void OnChannelError() override {
43 DCHECK(io_task_runner_->BelongsToCurrentThread());
44
45 OnDecodeAck(kInvalidBitstreamBufferId, PLATFORM_FAILURE);
46 }
47
48 bool OnMessageReceived(const IPC::Message& msg) override {
49 DCHECK(io_task_runner_->BelongsToCurrentThread());
50
51 bool handled = true;
52 IPC_BEGIN_MESSAGE_MAP(GpuJpegDecodeAcceleratorHost::Receiver, msg)
53 IPC_MESSAGE_HANDLER(AcceleratedJpegDecoderHostMsg_DecodeAck, OnDecodeAck)
54 IPC_MESSAGE_UNHANDLED(handled = false)
55 IPC_END_MESSAGE_MAP()
56 DCHECK(handled);
57 return handled;
58 }
59
60 base::WeakPtr<IPC::Listener> AsWeakPtrForIO() {
61 return weak_factory_for_io_.GetWeakPtr();
62 }
63
64 private:
65 void OnDecodeAck(int32_t bitstream_buffer_id, Error error) {
66 DCHECK(io_task_runner_->BelongsToCurrentThread());
67
68 if (!client_)
69 return;
70
71 if (error == media::JpegDecodeAccelerator::NO_ERROR) {
72 client_->VideoFrameReady(bitstream_buffer_id);
73 } else {
74 // Only NotifyError once.
75 // Client::NotifyError() may trigger deletion of |this| (on another
76 // thread), so calling it needs to be the last thing done on this stack!
77 media::JpegDecodeAccelerator::Client* client = nullptr;
78 std::swap(client, client_);
79 client->NotifyError(bitstream_buffer_id, error);
80 }
81 }
82
83 Client* client_;
84
85 // GPU IO task runner.
86 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
87
88 // Weak pointers will be invalidated on IO thread.
89 base::WeakPtrFactory<Receiver> weak_factory_for_io_;
90
91 DISALLOW_COPY_AND_ASSIGN(Receiver);
92 };
93
94 GpuJpegDecodeAcceleratorHost::GpuJpegDecodeAcceleratorHost(
95 GpuChannelHost* channel,
96 int32 route_id,
97 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
98 : channel_(channel),
99 decoder_route_id_(route_id),
100 io_task_runner_(io_task_runner) {
101 DCHECK(channel_);
102 DCHECK_NE(decoder_route_id_, MSG_ROUTING_NONE);
103 }
104
105 GpuJpegDecodeAcceleratorHost::~GpuJpegDecodeAcceleratorHost() {
106 DCHECK(CalledOnValidThread());
107 Send(new AcceleratedJpegDecoderMsg_Destroy(decoder_route_id_));
108
109 channel_->RemoveRoute(decoder_route_id_);
110
111 // Invalidate weak ptr of |receiver_|. After that, no more messages will be
112 // routed to |receiver_| on IO thread.
113 base::WaitableEvent event(false, false);
114 io_task_runner_->PostTask(
115 FROM_HERE,
116 base::Bind(&Receiver::InvalidateWeakPtr,
117 base::Unretained(receiver_.get()), base::Unretained(&event)));
118 event.Wait();
119 }
120
121 bool GpuJpegDecodeAcceleratorHost::Initialize(
122 media::JpegDecodeAccelerator::Client* client) {
123 DCHECK(CalledOnValidThread());
124
125 bool succeeded = false;
126 // This cannot be on IO thread because the msg is synchronous.
127 Send(new GpuMsg_CreateJpegDecoder(decoder_route_id_, &succeeded));
128
129 if (!succeeded) {
130 DLOG(ERROR) << "Send(GpuMsg_CreateJpegDecoder()) failed";
131 return false;
132 }
133
134 receiver_.reset(new Receiver(client, io_task_runner_));
135
136 return true;
137 }
138
139 void GpuJpegDecodeAcceleratorHost::Decode(
140 const media::BitstreamBuffer& bitstream_buffer,
141 const scoped_refptr<media::VideoFrame>& video_frame) {
142 DCHECK(CalledOnValidThread());
143
144 DCHECK(
145 base::SharedMemory::IsHandleValid(video_frame->shared_memory_handle()));
146
147 base::SharedMemoryHandle input_handle =
148 channel_->ShareToGpuProcess(bitstream_buffer.handle());
149 if (!base::SharedMemory::IsHandleValid(input_handle)) {
150 DLOG(ERROR) << "Failed to duplicate handle of BitstreamBuffer";
151 return;
152 }
153 base::SharedMemoryHandle output_handle =
154 channel_->ShareToGpuProcess(video_frame->shared_memory_handle());
155 if (!base::SharedMemory::IsHandleValid(output_handle)) {
156 DLOG(ERROR) << "Failed to duplicate handle of VideoFrame";
157 if (input_handle.auto_close) {
158 // Defer closing task to the ScopedFD.
159 base::ScopedFD(input_handle.fd);
160 }
161 return;
162 }
163
164 size_t output_buffer_size = media::VideoFrame::AllocationSize(
165 video_frame->format(), video_frame->coded_size());
166
167 AcceleratedJpegDecoderMsg_Decode_Params decode_params;
168 decode_params.coded_size = video_frame->coded_size();
169 decode_params.input_buffer_id = bitstream_buffer.id();
170 decode_params.input_buffer_handle = input_handle;
171 decode_params.input_buffer_size = bitstream_buffer.size();
172 decode_params.output_video_frame_handle = output_handle;
173 decode_params.output_buffer_size = output_buffer_size;
174 Send(new AcceleratedJpegDecoderMsg_Decode(decoder_route_id_, decode_params));
175 }
176
177 void GpuJpegDecodeAcceleratorHost::Send(IPC::Message* message) {
178 DCHECK(CalledOnValidThread());
179
180 if (!channel_->Send(message)) {
181 DLOG(ERROR) << "Send(" << message->type() << ") failed";
182 }
183 }
184
185 base::WeakPtr<IPC::Listener> GpuJpegDecodeAcceleratorHost::GetReceiver() {
186 return receiver_->AsWeakPtrForIO();
187 }
188
189 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698