OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/common/gpu/media/gpu_jpeg_decode_accelerator.h" | 5 #include "content/common/gpu/media/gpu_jpeg_decode_accelerator.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 23 matching lines...) Expand all Loading... |
34 | 34 |
35 namespace { | 35 namespace { |
36 | 36 |
37 void DecodeFinished(scoped_ptr<base::SharedMemory> shm) { | 37 void DecodeFinished(scoped_ptr<base::SharedMemory> shm) { |
38 // Do nothing. Because VideoFrame is backed by |shm|, the purpose of this | 38 // Do nothing. Because VideoFrame is backed by |shm|, the purpose of this |
39 // function is to just keep reference of |shm| to make sure it lives util | 39 // function is to just keep reference of |shm| to make sure it lives util |
40 // decode finishes. | 40 // decode finishes. |
41 } | 41 } |
42 | 42 |
43 bool VerifyDecodeParams(const AcceleratedJpegDecoderMsg_Decode_Params& params) { | 43 bool VerifyDecodeParams(const AcceleratedJpegDecoderMsg_Decode_Params& params) { |
44 if (params.input_buffer_id < 0) { | |
45 LOG(ERROR) << "BitstreamBuffer id " << params.input_buffer_id | |
46 << " out of range"; | |
47 return false; | |
48 } | |
49 | |
50 const int kJpegMaxDimension = UINT16_MAX; | 44 const int kJpegMaxDimension = UINT16_MAX; |
51 if (params.coded_size.IsEmpty() || | 45 if (params.coded_size.IsEmpty() || |
52 params.coded_size.width() > kJpegMaxDimension || | 46 params.coded_size.width() > kJpegMaxDimension || |
53 params.coded_size.height() > kJpegMaxDimension) { | 47 params.coded_size.height() > kJpegMaxDimension) { |
54 LOG(ERROR) << "invalid coded_size " << params.coded_size.ToString(); | 48 LOG(ERROR) << "invalid coded_size " << params.coded_size.ToString(); |
55 return false; | 49 return false; |
56 } | 50 } |
57 | 51 |
58 if (!base::SharedMemory::IsHandleValid(params.input_buffer_handle)) { | |
59 LOG(ERROR) << "invalid input_buffer_handle"; | |
60 return false; | |
61 } | |
62 | |
63 if (!base::SharedMemory::IsHandleValid(params.output_video_frame_handle)) { | 52 if (!base::SharedMemory::IsHandleValid(params.output_video_frame_handle)) { |
64 LOG(ERROR) << "invalid output_video_frame_handle"; | 53 LOG(ERROR) << "invalid output_video_frame_handle"; |
65 return false; | 54 return false; |
66 } | 55 } |
67 | 56 |
68 if (params.output_buffer_size < | 57 if (params.output_buffer_size < |
69 media::VideoFrame::AllocationSize(media::PIXEL_FORMAT_I420, | 58 media::VideoFrame::AllocationSize(media::PIXEL_FORMAT_I420, |
70 params.coded_size)) { | 59 params.coded_size)) { |
71 LOG(ERROR) << "output_buffer_size is too small: " | 60 LOG(ERROR) << "output_buffer_size is too small: " |
72 << params.output_buffer_size; | 61 << params.output_buffer_size; |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 | 190 |
202 void OnDecodeOnIOThread( | 191 void OnDecodeOnIOThread( |
203 const int32_t* route_id, | 192 const int32_t* route_id, |
204 const AcceleratedJpegDecoderMsg_Decode_Params& params) { | 193 const AcceleratedJpegDecoderMsg_Decode_Params& params) { |
205 DCHECK(io_task_runner_->BelongsToCurrentThread()); | 194 DCHECK(io_task_runner_->BelongsToCurrentThread()); |
206 DCHECK(route_id); | 195 DCHECK(route_id); |
207 TRACE_EVENT0("jpeg", "GpuJpegDecodeAccelerator::MessageFilter::OnDecode"); | 196 TRACE_EVENT0("jpeg", "GpuJpegDecodeAccelerator::MessageFilter::OnDecode"); |
208 | 197 |
209 if (!VerifyDecodeParams(params)) { | 198 if (!VerifyDecodeParams(params)) { |
210 NotifyDecodeStatusOnIOThread( | 199 NotifyDecodeStatusOnIOThread( |
211 *route_id, params.input_buffer_id, | 200 *route_id, params.input_buffer.id(), |
212 media::JpegDecodeAccelerator::INVALID_ARGUMENT); | 201 media::JpegDecodeAccelerator::INVALID_ARGUMENT); |
213 if (base::SharedMemory::IsHandleValid(params.input_buffer_handle)) | |
214 base::SharedMemory::CloseHandle(params.input_buffer_handle); | |
215 if (base::SharedMemory::IsHandleValid(params.output_video_frame_handle)) | 202 if (base::SharedMemory::IsHandleValid(params.output_video_frame_handle)) |
216 base::SharedMemory::CloseHandle(params.output_video_frame_handle); | 203 base::SharedMemory::CloseHandle(params.output_video_frame_handle); |
217 return; | 204 return; |
218 } | 205 } |
219 | 206 |
220 // For handles in |params|, from now on, |params.output_video_frame_handle| | 207 // For handles in |params|, from now on, |params.output_video_frame_handle| |
221 // is taken cared by scoper. |params.input_buffer_handle| need to be closed | 208 // is taken cared by scoper. |params.input_buffer.handle()| need to be |
222 // manually for early exits. | 209 // closed manually for early exits. |
223 scoped_ptr<base::SharedMemory> output_shm( | 210 scoped_ptr<base::SharedMemory> output_shm( |
224 new base::SharedMemory(params.output_video_frame_handle, false)); | 211 new base::SharedMemory(params.output_video_frame_handle, false)); |
225 if (!output_shm->Map(params.output_buffer_size)) { | 212 if (!output_shm->Map(params.output_buffer_size)) { |
226 LOG(ERROR) << "Could not map output shared memory for input buffer id " | 213 LOG(ERROR) << "Could not map output shared memory for input buffer id " |
227 << params.input_buffer_id; | 214 << params.input_buffer.id(); |
228 NotifyDecodeStatusOnIOThread( | 215 NotifyDecodeStatusOnIOThread( |
229 *route_id, params.input_buffer_id, | 216 *route_id, params.input_buffer.id(), |
230 media::JpegDecodeAccelerator::PLATFORM_FAILURE); | 217 media::JpegDecodeAccelerator::PLATFORM_FAILURE); |
231 base::SharedMemory::CloseHandle(params.input_buffer_handle); | 218 base::SharedMemory::CloseHandle(params.input_buffer.handle()); |
232 return; | 219 return; |
233 } | 220 } |
234 | 221 |
235 media::BitstreamBuffer input_buffer(params.input_buffer_id, | |
236 params.input_buffer_handle, | |
237 params.input_buffer_size); | |
238 | |
239 uint8_t* shm_memory = static_cast<uint8_t*>(output_shm->memory()); | 222 uint8_t* shm_memory = static_cast<uint8_t*>(output_shm->memory()); |
240 scoped_refptr<media::VideoFrame> frame = | 223 scoped_refptr<media::VideoFrame> frame = |
241 media::VideoFrame::WrapExternalSharedMemory( | 224 media::VideoFrame::WrapExternalSharedMemory( |
242 media::PIXEL_FORMAT_I420, // format | 225 media::PIXEL_FORMAT_I420, // format |
243 params.coded_size, // coded_size | 226 params.coded_size, // coded_size |
244 gfx::Rect(params.coded_size), // visible_rect | 227 gfx::Rect(params.coded_size), // visible_rect |
245 params.coded_size, // natural_size | 228 params.coded_size, // natural_size |
246 shm_memory, // data | 229 shm_memory, // data |
247 params.output_buffer_size, // data_size | 230 params.output_buffer_size, // data_size |
248 params.output_video_frame_handle, // handle | 231 params.output_video_frame_handle, // handle |
249 0, // data_offset | 232 0, // data_offset |
250 base::TimeDelta()); // timestamp | 233 base::TimeDelta()); // timestamp |
251 if (!frame.get()) { | 234 if (!frame.get()) { |
252 LOG(ERROR) << "Could not create VideoFrame for input buffer id " | 235 LOG(ERROR) << "Could not create VideoFrame for input buffer id " |
253 << params.input_buffer_id; | 236 << params.input_buffer.id(); |
254 NotifyDecodeStatusOnIOThread( | 237 NotifyDecodeStatusOnIOThread( |
255 *route_id, params.input_buffer_id, | 238 *route_id, params.input_buffer.id(), |
256 media::JpegDecodeAccelerator::PLATFORM_FAILURE); | 239 media::JpegDecodeAccelerator::PLATFORM_FAILURE); |
257 base::SharedMemory::CloseHandle(params.input_buffer_handle); | 240 base::SharedMemory::CloseHandle(params.input_buffer.handle()); |
258 return; | 241 return; |
259 } | 242 } |
260 frame->AddDestructionObserver( | 243 frame->AddDestructionObserver( |
261 base::Bind(DecodeFinished, base::Passed(&output_shm))); | 244 base::Bind(DecodeFinished, base::Passed(&output_shm))); |
262 | 245 |
263 DCHECK_GT(client_map_.count(*route_id), 0u); | 246 DCHECK_GT(client_map_.count(*route_id), 0u); |
264 Client* client = client_map_[*route_id]; | 247 Client* client = client_map_[*route_id]; |
265 client->Decode(input_buffer, frame); | 248 client->Decode(params.input_buffer, frame); |
266 } | 249 } |
267 | 250 |
268 protected: | 251 protected: |
269 ~MessageFilter() override { | 252 ~MessageFilter() override { |
270 if (client_map_.empty()) | 253 if (client_map_.empty()) |
271 return; | 254 return; |
272 | 255 |
273 if (child_task_runner_->BelongsToCurrentThread()) { | 256 if (child_task_runner_->BelongsToCurrentThread()) { |
274 STLDeleteValues(&client_map_); | 257 STLDeleteValues(&client_map_); |
275 } else { | 258 } else { |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
432 for (const auto& create_jda_function : create_jda_fps) { | 415 for (const auto& create_jda_function : create_jda_fps) { |
433 scoped_ptr<media::JpegDecodeAccelerator> accelerator = | 416 scoped_ptr<media::JpegDecodeAccelerator> accelerator = |
434 (*create_jda_function)(base::ThreadTaskRunnerHandle::Get()); | 417 (*create_jda_function)(base::ThreadTaskRunnerHandle::Get()); |
435 if (accelerator && accelerator->IsSupported()) | 418 if (accelerator && accelerator->IsSupported()) |
436 return true; | 419 return true; |
437 } | 420 } |
438 return false; | 421 return false; |
439 } | 422 } |
440 | 423 |
441 } // namespace content | 424 } // namespace content |
OLD | NEW |