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

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

Issue 1016773002: MJPEG acceleration for video capture using VAAPI (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: reuse VASurface Created 5 years, 7 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/message_loop/message_loop.h"
10 #include "content/common/gpu/client/gpu_channel_host.h"
11 #include "content/common/gpu/gpu_messages.h"
12 #include "ipc/ipc_message_macros.h"
13 #include "ipc/ipc_message_utils.h"
14
15 using media::JpegDecodeAccelerator;
16 namespace content {
17
18 GpuJpegDecodeAcceleratorHost::GpuJpegDecodeAcceleratorHost(
19 GpuChannelHost* channel,
20 int32 route_id,
21 const scoped_refptr<base::MessageLoopProxy>& io_message_loop)
22 : channel_(channel),
23 channel_disconnected_(true, false),
24 client_(NULL),
25 decoder_route_id_(route_id),
26 io_message_loop_(io_message_loop),
27 weak_this_factory_(this) {
28 DCHECK(channel_);
29 }
30
31 GpuJpegDecodeAcceleratorHost::~GpuJpegDecodeAcceleratorHost() {
32 }
33
34 bool GpuJpegDecodeAcceleratorHost::OnMessageReceived(const IPC::Message& msg) {
35 DCHECK(io_message_loop_->BelongsToCurrentThread());
36 bool handled = true;
37 IPC_BEGIN_MESSAGE_MAP(GpuJpegDecodeAcceleratorHost, msg)
38 IPC_MESSAGE_HANDLER(AcceleratedJpegDecoderHostMsg_VideoFrameReady,
39 OnVideoFrameReady)
40 IPC_MESSAGE_HANDLER(AcceleratedJpegDecoderHostMsg_NotifyError,
41 OnNotifyError)
42 IPC_MESSAGE_UNHANDLED(handled = false)
43 IPC_END_MESSAGE_MAP()
44 DCHECK(handled);
45 // See OnNotifyError for why |this| mustn't be used after OnNotifyError might
46 // have been called above.
47 return handled;
48 }
49
50 void GpuJpegDecodeAcceleratorHost::OnChannelError() {
51 DVLOG(3) << __func__;
52 DCHECK(io_message_loop_->BelongsToCurrentThread());
53 DisconnectChannelOnIOThread();
54 OnNotifyError(kInvalidBitstreamBufferId, PLATFORM_FAILURE);
55 }
56
57 bool GpuJpegDecodeAcceleratorHost::Initialize(
58 media::JpegDecodeAccelerator::Client* client) {
59 DCHECK(CalledOnValidThread());
60
61 bool succeeded = false;
62 // This cannot be on IO thread because the msg is synchronous.
63 Send(new GpuMsg_CreateJpegDecoder(decoder_route_id_, &succeeded));
64
65 if (!succeeded) {
66 DLOG(ERROR) << "Send(GpuMsg_CreateJpegDecoder()) failed";
67 channel_->RemoveRoute(decoder_route_id_);
68 return false;
69 }
70 client_ = client;
71
72 return true;
73 }
74
75 void GpuJpegDecodeAcceleratorHost::Decode(
76 const media::BitstreamBuffer& bitstream_buffer,
77 const scoped_refptr<media::VideoFrame>& video_frame) {
78 DCHECK(CalledOnValidThread());
79 GpuChannelHost* channel;
80 {
81 base::AutoLock lock(channel_lock_);
wuchengli 2015/05/06 07:59:18 As discussed, dealing with synchronization in GpuJ
kcwu 2015/05/08 14:42:42 Done. Looks good after using jpeg thread.
82 channel = channel_;
83 }
84 if (!channel)
85 return;
86
87 base::SharedMemoryHandle input_handle =
88 channel->ShareToGpuProcess(bitstream_buffer.handle());
89 if (!base::SharedMemory::IsHandleValid(input_handle)) {
90 LOG(ERROR) << "Failed to duplicate buffer handle of BitstreamBuffer";
91 PostNotifyError(bitstream_buffer.id(), INVALID_ARGUMENT);
92 return;
93 }
94
95 if (!base::SharedMemory::IsHandleValid(video_frame->shared_memory_handle())) {
96 LOG(ERROR)
97 << "Decode(): cannot output to frame not backed by shared memory";
98 PostNotifyError(bitstream_buffer.id(), INVALID_ARGUMENT);
99 return;
100 }
101
102 base::SharedMemoryHandle output_handle =
103 channel->ShareToGpuProcess(video_frame->shared_memory_handle());
104 if (!base::SharedMemory::IsHandleValid(output_handle)) {
105 LOG(ERROR) << "Decode(): failed to duplicate buffer handle of VideoFrame";
106 PostNotifyError(bitstream_buffer.id(), PLATFORM_FAILURE);
107 return;
108 }
109
110 size_t output_buffer_size = media::VideoFrame::AllocationSize(
111 video_frame->format(), video_frame->coded_size());
112
113 AcceleratedJpegDecoderMsg_Decode_Params decode_params;
114 decode_params.coded_size = video_frame->coded_size();
115 decode_params.input_buffer_id = bitstream_buffer.id();
116 decode_params.input_buffer_handle = input_handle;
117 decode_params.input_buffer_size = bitstream_buffer.size();
118 decode_params.output_video_frame_handle = output_handle;
119 decode_params.output_buffer_size = output_buffer_size;
120 Send(new AcceleratedJpegDecoderMsg_Decode(decoder_route_id_, decode_params));
121 }
122
123 void GpuJpegDecodeAcceleratorHost::DisconnectChannelOnIOThread() {
124 DCHECK(io_message_loop_->BelongsToCurrentThread());
125 base::AutoLock lock(channel_lock_);
126 if (channel_) {
127 if (decoder_route_id_ != MSG_ROUTING_NONE)
128 channel_->RemoveRoute(decoder_route_id_);
129 channel_ = NULL;
130 }
131 weak_this_factory_.InvalidateWeakPtrs();
132 channel_disconnected_.Signal();
133 }
134
135 void GpuJpegDecodeAcceleratorHost::Destroy() {
136 DCHECK(CalledOnValidThread());
137 Send(new AcceleratedJpegDecoderMsg_Destroy(decoder_route_id_));
138
139 io_message_loop_->PostTask(
140 FROM_HERE,
141 base::Bind(&GpuJpegDecodeAcceleratorHost::DisconnectChannelOnIOThread,
142 weak_this_factory_.GetWeakPtr()));
143 channel_disconnected_.Wait();
144 delete this;
145 }
146
147 void GpuJpegDecodeAcceleratorHost::PostNotifyError(int32_t bitstream_buffer_id,
148 Error error) {
149 DCHECK(CalledOnValidThread());
150 io_message_loop_->PostTask(
151 FROM_HERE,
152 base::Bind(&GpuJpegDecodeAcceleratorHost::OnNotifyError,
153 weak_this_factory_.GetWeakPtr(), bitstream_buffer_id, error));
154 }
155
156 void GpuJpegDecodeAcceleratorHost::Send(IPC::Message* message) {
157 DVLOG(3) << __func__;
158 DCHECK(CalledOnValidThread());
159
160 base::AutoLock lock(channel_lock_);
161 if (!channel_)
162 return;
163 if (!channel_->Send(message)) {
164 DLOG(ERROR) << "Send(" << message->type() << ") failed";
165 }
166 }
167
168 void GpuJpegDecodeAcceleratorHost::OnVideoFrameReady(
169 int32_t bitstream_buffer_id) {
170 DCHECK(io_message_loop_->BelongsToCurrentThread());
171 DCHECK(client_);
172 client_->VideoFrameReady(bitstream_buffer_id);
173 }
174
175 void GpuJpegDecodeAcceleratorHost::OnNotifyError(int32_t bitstream_buffer_id,
176 Error error) {
177 DVLOG(2) << __func__ << ": error=" << error
178 << ", bitstream_buffer_id=" << bitstream_buffer_id;
179 DCHECK(io_message_loop_->BelongsToCurrentThread());
180 if (!client_)
181 return;
182 weak_this_factory_.InvalidateWeakPtrs();
183
184 client_->NotifyError(bitstream_buffer_id,
185 static_cast<media::JpegDecodeAccelerator::Error>(error));
186 client_ = nullptr;
187 }
188
189 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698