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