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/vaapi_jpeg_decode_accelerator.h" | 5 #include "content/common/gpu/media/vaapi_jpeg_decode_accelerator.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <string.h> | 8 #include <string.h> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
14 #include "base/thread_task_runner_handle.h" | 14 #include "base/thread_task_runner_handle.h" |
15 #include "base/trace_event/trace_event.h" | 15 #include "base/trace_event/trace_event.h" |
16 #include "content/common/gpu/gpu_channel.h" | 16 #include "content/common/gpu/gpu_channel.h" |
| 17 #include "content/common/gpu/media/shared_memory_region.h" |
17 #include "content/common/gpu/media/vaapi_picture.h" | 18 #include "content/common/gpu/media/vaapi_picture.h" |
18 #include "media/base/video_frame.h" | 19 #include "media/base/video_frame.h" |
19 #include "media/filters/jpeg_parser.h" | 20 #include "media/filters/jpeg_parser.h" |
20 #include "third_party/libyuv/include/libyuv.h" | 21 #include "third_party/libyuv/include/libyuv.h" |
21 | 22 |
22 namespace content { | 23 namespace content { |
23 | 24 |
24 namespace { | 25 namespace { |
25 // UMA errors that the VaapiJpegDecodeAccelerator class reports. | 26 // UMA errors that the VaapiJpegDecodeAccelerator class reports. |
26 enum VAJDADecoderFailure { | 27 enum VAJDADecoderFailure { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 DVLOG(1) << "Unsupported sampling factor: num_components=" | 70 DVLOG(1) << "Unsupported sampling factor: num_components=" |
70 << frame_header.num_components << ", h=" << std::hex << h | 71 << frame_header.num_components << ", h=" << std::hex << h |
71 << ", v=" << v; | 72 << ", v=" << v; |
72 | 73 |
73 return 0; | 74 return 0; |
74 } | 75 } |
75 | 76 |
76 } // namespace | 77 } // namespace |
77 | 78 |
78 VaapiJpegDecodeAccelerator::DecodeRequest::DecodeRequest( | 79 VaapiJpegDecodeAccelerator::DecodeRequest::DecodeRequest( |
79 const media::BitstreamBuffer& bitstream_buffer, | 80 int32_t bitstream_buffer_id, |
80 scoped_ptr<base::SharedMemory> shm, | 81 scoped_ptr<SharedMemoryRegion> shm, |
81 const scoped_refptr<media::VideoFrame>& video_frame) | 82 const scoped_refptr<media::VideoFrame>& video_frame) |
82 : bitstream_buffer(bitstream_buffer), | 83 : bitstream_buffer_id(bitstream_buffer_id), |
83 shm(std::move(shm)), | 84 shm(std::move(shm)), |
84 video_frame(video_frame) {} | 85 video_frame(video_frame) {} |
85 | 86 |
86 VaapiJpegDecodeAccelerator::DecodeRequest::~DecodeRequest() { | 87 VaapiJpegDecodeAccelerator::DecodeRequest::~DecodeRequest() { |
87 } | 88 } |
88 | 89 |
89 void VaapiJpegDecodeAccelerator::NotifyError(int32_t bitstream_buffer_id, | 90 void VaapiJpegDecodeAccelerator::NotifyError(int32_t bitstream_buffer_id, |
90 Error error) { | 91 Error error) { |
91 DCHECK(task_runner_->BelongsToCurrentThread()); | 92 DCHECK(task_runner_->BelongsToCurrentThread()); |
92 DLOG(ERROR) << "Notifying of error " << error; | 93 DLOG(ERROR) << "Notifying of error " << error; |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 | 220 |
220 void VaapiJpegDecodeAccelerator::DecodeTask( | 221 void VaapiJpegDecodeAccelerator::DecodeTask( |
221 const scoped_ptr<DecodeRequest>& request) { | 222 const scoped_ptr<DecodeRequest>& request) { |
222 DVLOG(3) << __func__; | 223 DVLOG(3) << __func__; |
223 DCHECK(decoder_task_runner_->BelongsToCurrentThread()); | 224 DCHECK(decoder_task_runner_->BelongsToCurrentThread()); |
224 TRACE_EVENT0("jpeg", "DecodeTask"); | 225 TRACE_EVENT0("jpeg", "DecodeTask"); |
225 | 226 |
226 media::JpegParseResult parse_result; | 227 media::JpegParseResult parse_result; |
227 if (!media::ParseJpegPicture( | 228 if (!media::ParseJpegPicture( |
228 reinterpret_cast<const uint8_t*>(request->shm->memory()), | 229 reinterpret_cast<const uint8_t*>(request->shm->memory()), |
229 request->bitstream_buffer.size(), &parse_result)) { | 230 request->shm->size(), &parse_result)) { |
230 DLOG(ERROR) << "ParseJpegPicture failed"; | 231 DLOG(ERROR) << "ParseJpegPicture failed"; |
231 NotifyErrorFromDecoderThread(request->bitstream_buffer.id(), | 232 NotifyErrorFromDecoderThread(request->bitstream_buffer_id, |
232 PARSE_JPEG_FAILED); | 233 PARSE_JPEG_FAILED); |
233 return; | 234 return; |
234 } | 235 } |
235 | 236 |
236 unsigned int new_va_rt_format = | 237 unsigned int new_va_rt_format = |
237 VaSurfaceFormatForJpeg(parse_result.frame_header); | 238 VaSurfaceFormatForJpeg(parse_result.frame_header); |
238 if (!new_va_rt_format) { | 239 if (!new_va_rt_format) { |
239 DLOG(ERROR) << "Unsupported subsampling"; | 240 DLOG(ERROR) << "Unsupported subsampling"; |
240 NotifyErrorFromDecoderThread(request->bitstream_buffer.id(), | 241 NotifyErrorFromDecoderThread(request->bitstream_buffer_id, |
241 UNSUPPORTED_JPEG); | 242 UNSUPPORTED_JPEG); |
242 return; | 243 return; |
243 } | 244 } |
244 | 245 |
245 // Reuse VASurface if size doesn't change. | 246 // Reuse VASurface if size doesn't change. |
246 gfx::Size new_coded_size(parse_result.frame_header.coded_width, | 247 gfx::Size new_coded_size(parse_result.frame_header.coded_width, |
247 parse_result.frame_header.coded_height); | 248 parse_result.frame_header.coded_height); |
248 if (new_coded_size != coded_size_ || va_surface_id_ == VA_INVALID_SURFACE || | 249 if (new_coded_size != coded_size_ || va_surface_id_ == VA_INVALID_SURFACE || |
249 new_va_rt_format != va_rt_format_) { | 250 new_va_rt_format != va_rt_format_) { |
250 vaapi_wrapper_->DestroySurfaces(); | 251 vaapi_wrapper_->DestroySurfaces(); |
251 va_surface_id_ = VA_INVALID_SURFACE; | 252 va_surface_id_ = VA_INVALID_SURFACE; |
252 va_rt_format_ = new_va_rt_format; | 253 va_rt_format_ = new_va_rt_format; |
253 | 254 |
254 std::vector<VASurfaceID> va_surfaces; | 255 std::vector<VASurfaceID> va_surfaces; |
255 if (!vaapi_wrapper_->CreateSurfaces(va_rt_format_, new_coded_size, 1, | 256 if (!vaapi_wrapper_->CreateSurfaces(va_rt_format_, new_coded_size, 1, |
256 &va_surfaces)) { | 257 &va_surfaces)) { |
257 LOG(ERROR) << "Create VA surface failed"; | 258 LOG(ERROR) << "Create VA surface failed"; |
258 NotifyErrorFromDecoderThread(request->bitstream_buffer.id(), | 259 NotifyErrorFromDecoderThread(request->bitstream_buffer_id, |
259 PLATFORM_FAILURE); | 260 PLATFORM_FAILURE); |
260 return; | 261 return; |
261 } | 262 } |
262 va_surface_id_ = va_surfaces[0]; | 263 va_surface_id_ = va_surfaces[0]; |
263 coded_size_ = new_coded_size; | 264 coded_size_ = new_coded_size; |
264 } | 265 } |
265 | 266 |
266 if (!VaapiJpegDecoder::Decode(vaapi_wrapper_.get(), parse_result, | 267 if (!VaapiJpegDecoder::Decode(vaapi_wrapper_.get(), parse_result, |
267 va_surface_id_)) { | 268 va_surface_id_)) { |
268 LOG(ERROR) << "Decode JPEG failed"; | 269 LOG(ERROR) << "Decode JPEG failed"; |
269 NotifyErrorFromDecoderThread(request->bitstream_buffer.id(), | 270 NotifyErrorFromDecoderThread(request->bitstream_buffer_id, |
270 PLATFORM_FAILURE); | 271 PLATFORM_FAILURE); |
271 return; | 272 return; |
272 } | 273 } |
273 | 274 |
274 if (!OutputPicture(va_surface_id_, request->bitstream_buffer.id(), | 275 if (!OutputPicture(va_surface_id_, request->bitstream_buffer_id, |
275 request->video_frame)) { | 276 request->video_frame)) { |
276 LOG(ERROR) << "Output picture failed"; | 277 LOG(ERROR) << "Output picture failed"; |
277 NotifyErrorFromDecoderThread(request->bitstream_buffer.id(), | 278 NotifyErrorFromDecoderThread(request->bitstream_buffer_id, |
278 PLATFORM_FAILURE); | 279 PLATFORM_FAILURE); |
279 return; | 280 return; |
280 } | 281 } |
281 } | 282 } |
282 | 283 |
283 void VaapiJpegDecodeAccelerator::Decode( | 284 void VaapiJpegDecodeAccelerator::Decode( |
284 const media::BitstreamBuffer& bitstream_buffer, | 285 const media::BitstreamBuffer& bitstream_buffer, |
285 const scoped_refptr<media::VideoFrame>& video_frame) { | 286 const scoped_refptr<media::VideoFrame>& video_frame) { |
286 DVLOG(3) << __func__; | 287 DVLOG(3) << __func__; |
287 DCHECK(io_task_runner_->BelongsToCurrentThread()); | 288 DCHECK(io_task_runner_->BelongsToCurrentThread()); |
288 TRACE_EVENT1("jpeg", "Decode", "input_id", bitstream_buffer.id()); | 289 TRACE_EVENT1("jpeg", "Decode", "input_id", bitstream_buffer.id()); |
289 | 290 |
290 DVLOG(4) << "Mapping new input buffer id: " << bitstream_buffer.id() | 291 DVLOG(4) << "Mapping new input buffer id: " << bitstream_buffer.id() |
291 << " size: " << bitstream_buffer.size(); | 292 << " size: " << bitstream_buffer.size(); |
292 | 293 |
| 294 // SharedMemoryRegion will take over the |bitstream_buffer.handle()|. |
| 295 scoped_ptr<SharedMemoryRegion> shm( |
| 296 new SharedMemoryRegion(bitstream_buffer, true)); |
| 297 |
293 if (bitstream_buffer.id() < 0) { | 298 if (bitstream_buffer.id() < 0) { |
294 LOG(ERROR) << "Invalid bitstream_buffer, id: " << bitstream_buffer.id(); | 299 LOG(ERROR) << "Invalid bitstream_buffer, id: " << bitstream_buffer.id(); |
295 if (base::SharedMemory::IsHandleValid(bitstream_buffer.handle())) | |
296 base::SharedMemory::CloseHandle(bitstream_buffer.handle()); | |
297 NotifyErrorFromDecoderThread(bitstream_buffer.id(), INVALID_ARGUMENT); | 300 NotifyErrorFromDecoderThread(bitstream_buffer.id(), INVALID_ARGUMENT); |
298 return; | 301 return; |
299 } | 302 } |
300 | 303 |
301 scoped_ptr<base::SharedMemory> shm( | 304 if (!shm->Map()) { |
302 new base::SharedMemory(bitstream_buffer.handle(), true)); | |
303 | |
304 if (!shm->Map(bitstream_buffer.size())) { | |
305 LOG(ERROR) << "Failed to map input buffer"; | 305 LOG(ERROR) << "Failed to map input buffer"; |
306 NotifyErrorFromDecoderThread(bitstream_buffer.id(), UNREADABLE_INPUT); | 306 NotifyErrorFromDecoderThread(bitstream_buffer.id(), UNREADABLE_INPUT); |
307 return; | 307 return; |
308 } | 308 } |
309 | 309 |
310 scoped_ptr<DecodeRequest> request( | 310 scoped_ptr<DecodeRequest> request( |
311 new DecodeRequest(bitstream_buffer, std::move(shm), video_frame)); | 311 new DecodeRequest(bitstream_buffer.id(), std::move(shm), video_frame)); |
312 | 312 |
313 decoder_task_runner_->PostTask( | 313 decoder_task_runner_->PostTask( |
314 FROM_HERE, base::Bind(&VaapiJpegDecodeAccelerator::DecodeTask, | 314 FROM_HERE, base::Bind(&VaapiJpegDecodeAccelerator::DecodeTask, |
315 base::Unretained(this), base::Passed(&request))); | 315 base::Unretained(this), base::Passed(&request))); |
316 } | 316 } |
317 | 317 |
318 bool VaapiJpegDecodeAccelerator::IsSupported() { | 318 bool VaapiJpegDecodeAccelerator::IsSupported() { |
319 return VaapiWrapper::IsJpegDecodeSupported(); | 319 return VaapiWrapper::IsJpegDecodeSupported(); |
320 } | 320 } |
321 | 321 |
322 } // namespace content | 322 } // namespace content |
OLD | NEW |