Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "chrome/gpu/arc_gpu_video_decode_accelerator.h" | 5 #include "chrome/gpu/arc_gpu_video_decode_accelerator.h" |
| 6 | 6 |
| 7 #include "base/callback_helpers.h" | 7 #include "base/callback_helpers.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/run_loop.h" | 9 #include "base/run_loop.h" |
| 10 #include "content/public/gpu/gpu_video_decode_accelerator_factory.h" | 10 #include "content/public/gpu/gpu_video_decode_accelerator_factory.h" |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 26 | 26 |
| 27 ArcGpuVideoDecodeAccelerator::InputBufferInfo::InputBufferInfo( | 27 ArcGpuVideoDecodeAccelerator::InputBufferInfo::InputBufferInfo( |
| 28 InputBufferInfo&& other) | 28 InputBufferInfo&& other) |
| 29 : handle(std::move(other.handle)), | 29 : handle(std::move(other.handle)), |
| 30 offset(other.offset), | 30 offset(other.offset), |
| 31 length(other.length) {} | 31 length(other.length) {} |
| 32 | 32 |
| 33 ArcGpuVideoDecodeAccelerator::InputBufferInfo::~InputBufferInfo() {} | 33 ArcGpuVideoDecodeAccelerator::InputBufferInfo::~InputBufferInfo() {} |
| 34 | 34 |
| 35 ArcGpuVideoDecodeAccelerator::ArcGpuVideoDecodeAccelerator() | 35 ArcGpuVideoDecodeAccelerator::ArcGpuVideoDecodeAccelerator() |
| 36 : pending_eos_output_buffer_(false), | 36 : arc_client_(nullptr), |
| 37 arc_client_(nullptr), | |
| 38 next_bitstream_buffer_id_(0), | 37 next_bitstream_buffer_id_(0), |
| 39 output_buffer_size_(0) {} | 38 output_buffer_size_(0) {} |
| 40 | 39 |
| 41 ArcGpuVideoDecodeAccelerator::~ArcGpuVideoDecodeAccelerator() {} | 40 ArcGpuVideoDecodeAccelerator::~ArcGpuVideoDecodeAccelerator() {} |
| 42 | 41 |
| 43 namespace { | 42 namespace { |
| 44 | 43 |
| 45 // An arbitrary chosen limit of the number of buffers. The number of | 44 // An arbitrary chosen limit of the number of buffers. The number of |
| 46 // buffers used is requested from the untrusted client side. | 45 // buffers used is requested from the untrusted client side. |
| 47 const size_t kMaxBufferCount = 128; | 46 const size_t kMaxBufferCount = 128; |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 201 int dup_fd = HANDLE_EINTR(dup(input_info->handle.get())); | 200 int dup_fd = HANDLE_EINTR(dup(input_info->handle.get())); |
| 202 if (dup_fd < 0) { | 201 if (dup_fd < 0) { |
| 203 DLOG(ERROR) << "dup() failed."; | 202 DLOG(ERROR) << "dup() failed."; |
| 204 arc_client_->OnError(PLATFORM_FAILURE); | 203 arc_client_->OnError(PLATFORM_FAILURE); |
| 205 return; | 204 return; |
| 206 } | 205 } |
| 207 CreateInputRecord(bitstream_buffer_id, index, metadata.timestamp); | 206 CreateInputRecord(bitstream_buffer_id, index, metadata.timestamp); |
| 208 vda_->Decode(media::BitstreamBuffer( | 207 vda_->Decode(media::BitstreamBuffer( |
| 209 bitstream_buffer_id, base::SharedMemoryHandle(dup_fd, true), | 208 bitstream_buffer_id, base::SharedMemoryHandle(dup_fd, true), |
| 210 metadata.bytes_used, input_info->offset)); | 209 metadata.bytes_used, input_info->offset)); |
| 211 if (metadata.flags & BUFFER_FLAG_EOS) { | 210 break; |
| 212 vda_->Flush(); | 211 } |
| 212 case PORT_OUTPUT: { | |
| 213 // is_valid() is true for the first time the buffer is passed to the VDA. | |
| 214 // In that case, VDA needs to import the buffer first. | |
| 215 if (buffers_pending_import_[index].is_valid()) { | |
| 216 gfx::GpuMemoryBufferHandle handle; | |
| 217 #if defined(USE_OZONE) | |
| 218 handle.native_pixmap_handle.fd = base::FileDescriptor( | |
| 219 buffers_pending_import_[index].release(), true); | |
| 220 #endif | |
| 221 vda_->ImportBufferForPicture( | |
| 222 index, std::vector<gfx::GpuMemoryBufferHandle>{handle}); | |
|
dcheng
2016/05/10 23:00:11
Also, just write {handle} here (no std::vector<gfx
Owen Lin
2016/05/11 01:49:57
Done. Thanks.
| |
| 223 } else { | |
| 224 vda_->ReusePictureBuffer(index); | |
| 213 } | 225 } |
| 214 break; | 226 break; |
| 215 } | 227 } |
| 216 case PORT_OUTPUT: { | |
| 217 SendEosIfNeededOrReusePicture(index); | |
| 218 break; | |
| 219 } | |
| 220 default: | 228 default: |
| 221 NOTREACHED(); | 229 NOTREACHED(); |
| 222 } | 230 } |
| 223 } | 231 } |
| 224 | 232 |
| 225 void ArcGpuVideoDecodeAccelerator::Reset() { | 233 void ArcGpuVideoDecodeAccelerator::Reset() { |
| 226 DCHECK(thread_checker_.CalledOnValidThread()); | 234 DCHECK(thread_checker_.CalledOnValidThread()); |
| 227 if (!vda_) { | 235 if (!vda_) { |
| 228 DLOG(ERROR) << "VDA not initialized"; | 236 DLOG(ERROR) << "VDA not initialized"; |
| 229 return; | 237 return; |
| 230 } | 238 } |
| 231 vda_->Reset(); | 239 vda_->Reset(); |
| 232 } | 240 } |
| 233 | 241 |
| 242 void ArcGpuVideoDecodeAccelerator::Flush() { | |
| 243 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 244 if (!vda_) { | |
| 245 DLOG(ERROR) << "VDA not initialized"; | |
| 246 return; | |
| 247 } | |
| 248 vda_->Flush(); | |
| 249 } | |
| 250 | |
| 234 void ArcGpuVideoDecodeAccelerator::ProvidePictureBuffers( | 251 void ArcGpuVideoDecodeAccelerator::ProvidePictureBuffers( |
| 235 uint32_t requested_num_of_buffers, | 252 uint32_t requested_num_of_buffers, |
| 236 uint32_t textures_per_buffer, | 253 uint32_t textures_per_buffer, |
| 237 const gfx::Size& dimensions, | 254 const gfx::Size& dimensions, |
| 238 uint32_t texture_target) { | 255 uint32_t texture_target) { |
| 239 DVLOG(5) << "ProvidePictureBuffers(" | 256 DVLOG(5) << "ProvidePictureBuffers(" |
| 240 << "requested_num_of_buffers=" << requested_num_of_buffers | 257 << "requested_num_of_buffers=" << requested_num_of_buffers |
| 241 << ", dimensions=" << dimensions.ToString() << ")"; | 258 << ", dimensions=" << dimensions.ToString() << ")"; |
| 242 DCHECK(thread_checker_.CalledOnValidThread()); | 259 DCHECK(thread_checker_.CalledOnValidThread()); |
| 243 coded_size_ = dimensions; | 260 coded_size_ = dimensions; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 276 void ArcGpuVideoDecodeAccelerator::DismissPictureBuffer( | 293 void ArcGpuVideoDecodeAccelerator::DismissPictureBuffer( |
| 277 int32_t picture_buffer) { | 294 int32_t picture_buffer) { |
| 278 // no-op | 295 // no-op |
| 279 } | 296 } |
| 280 | 297 |
| 281 void ArcGpuVideoDecodeAccelerator::PictureReady(const media::Picture& picture) { | 298 void ArcGpuVideoDecodeAccelerator::PictureReady(const media::Picture& picture) { |
| 282 DVLOG(5) << "PictureReady(picture_buffer_id=" << picture.picture_buffer_id() | 299 DVLOG(5) << "PictureReady(picture_buffer_id=" << picture.picture_buffer_id() |
| 283 << ", bitstream_buffer_id=" << picture.bitstream_buffer_id(); | 300 << ", bitstream_buffer_id=" << picture.bitstream_buffer_id(); |
| 284 DCHECK(thread_checker_.CalledOnValidThread()); | 301 DCHECK(thread_checker_.CalledOnValidThread()); |
| 285 | 302 |
| 286 // Empty buffer, returned in Flushing. | |
| 287 if (picture.bitstream_buffer_id() == -1) { | |
| 288 buffers_pending_eos_.push(picture.picture_buffer_id()); | |
| 289 return; | |
| 290 } | |
| 291 InputRecord* input_record = FindInputRecord(picture.bitstream_buffer_id()); | 303 InputRecord* input_record = FindInputRecord(picture.bitstream_buffer_id()); |
| 292 if (input_record == nullptr) { | 304 if (input_record == nullptr) { |
| 293 DLOG(ERROR) << "Cannot find for bitstream buffer id: " | 305 DLOG(ERROR) << "Cannot find for bitstream buffer id: " |
| 294 << picture.bitstream_buffer_id(); | 306 << picture.bitstream_buffer_id(); |
| 295 arc_client_->OnError(PLATFORM_FAILURE); | 307 arc_client_->OnError(PLATFORM_FAILURE); |
| 296 return; | 308 return; |
| 297 } | 309 } |
| 298 | 310 |
| 299 BufferMetadata metadata; | 311 BufferMetadata metadata; |
| 300 metadata.timestamp = input_record->timestamp; | 312 metadata.timestamp = input_record->timestamp; |
| 301 metadata.bytes_used = output_buffer_size_; | 313 metadata.bytes_used = output_buffer_size_; |
| 302 arc_client_->OnBufferDone(PORT_OUTPUT, picture.picture_buffer_id(), metadata); | 314 arc_client_->OnBufferDone(PORT_OUTPUT, picture.picture_buffer_id(), metadata); |
| 303 } | 315 } |
| 304 | 316 |
| 305 void ArcGpuVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer( | 317 void ArcGpuVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer( |
| 306 int32_t bitstream_buffer_id) { | 318 int32_t bitstream_buffer_id) { |
| 307 DVLOG(5) << "NotifyEndOfBitstreamBuffer(" << bitstream_buffer_id << ")"; | 319 DVLOG(5) << "NotifyEndOfBitstreamBuffer(" << bitstream_buffer_id << ")"; |
| 308 DCHECK(thread_checker_.CalledOnValidThread()); | 320 DCHECK(thread_checker_.CalledOnValidThread()); |
| 309 InputRecord* input_record = FindInputRecord(bitstream_buffer_id); | 321 InputRecord* input_record = FindInputRecord(bitstream_buffer_id); |
| 310 if (input_record == nullptr) { | 322 if (input_record == nullptr) { |
| 311 arc_client_->OnError(PLATFORM_FAILURE); | 323 arc_client_->OnError(PLATFORM_FAILURE); |
| 312 return; | 324 return; |
| 313 } | 325 } |
| 314 arc_client_->OnBufferDone(PORT_INPUT, input_record->buffer_index, | 326 arc_client_->OnBufferDone(PORT_INPUT, input_record->buffer_index, |
| 315 BufferMetadata()); | 327 BufferMetadata()); |
| 316 } | 328 } |
| 317 | 329 |
| 318 void ArcGpuVideoDecodeAccelerator::NotifyFlushDone() { | 330 void ArcGpuVideoDecodeAccelerator::NotifyFlushDone() { |
| 319 DCHECK(thread_checker_.CalledOnValidThread()); | 331 DCHECK(thread_checker_.CalledOnValidThread()); |
| 320 pending_eos_output_buffer_ = true; | 332 arc_client_->OnFlushDone(); |
| 321 while (!buffers_pending_eos_.empty()) { | |
| 322 SendEosIfNeededOrReusePicture(buffers_pending_eos_.front()); | |
| 323 buffers_pending_eos_.pop(); | |
| 324 } | |
| 325 } | 333 } |
| 326 | 334 |
| 327 void ArcGpuVideoDecodeAccelerator::NotifyResetDone() { | 335 void ArcGpuVideoDecodeAccelerator::NotifyResetDone() { |
| 328 DCHECK(thread_checker_.CalledOnValidThread()); | 336 DCHECK(thread_checker_.CalledOnValidThread()); |
| 329 arc_client_->OnResetDone(); | 337 arc_client_->OnResetDone(); |
| 330 } | 338 } |
| 331 | 339 |
| 332 static ArcVideoAccelerator::Error ConvertErrorCode( | 340 static ArcVideoAccelerator::Error ConvertErrorCode( |
| 333 media::VideoDecodeAccelerator::Error error) { | 341 media::VideoDecodeAccelerator::Error error) { |
| 334 switch (error) { | 342 switch (error) { |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 346 } | 354 } |
| 347 } | 355 } |
| 348 | 356 |
| 349 void ArcGpuVideoDecodeAccelerator::NotifyError( | 357 void ArcGpuVideoDecodeAccelerator::NotifyError( |
| 350 media::VideoDecodeAccelerator::Error error) { | 358 media::VideoDecodeAccelerator::Error error) { |
| 351 DCHECK(thread_checker_.CalledOnValidThread()); | 359 DCHECK(thread_checker_.CalledOnValidThread()); |
| 352 DLOG(ERROR) << "Error notified: " << error; | 360 DLOG(ERROR) << "Error notified: " << error; |
| 353 arc_client_->OnError(ConvertErrorCode(error)); | 361 arc_client_->OnError(ConvertErrorCode(error)); |
| 354 } | 362 } |
| 355 | 363 |
| 356 void ArcGpuVideoDecodeAccelerator::SendEosIfNeededOrReusePicture( | |
| 357 uint32_t index) { | |
| 358 if (pending_eos_output_buffer_) { | |
| 359 BufferMetadata metadata; | |
| 360 metadata.flags = BUFFER_FLAG_EOS; | |
| 361 arc_client_->OnBufferDone(PORT_OUTPUT, index, metadata); | |
| 362 pending_eos_output_buffer_ = false; | |
| 363 } else { | |
| 364 if (buffers_pending_import_[index].is_valid()) { | |
| 365 std::vector<gfx::GpuMemoryBufferHandle> buffers; | |
| 366 buffers.push_back(gfx::GpuMemoryBufferHandle()); | |
| 367 #if defined(USE_OZONE) | |
| 368 buffers.back().native_pixmap_handle.fd = | |
| 369 base::FileDescriptor(buffers_pending_import_[index].release(), true); | |
| 370 #endif | |
| 371 vda_->ImportBufferForPicture(index, buffers); | |
| 372 } else { | |
| 373 vda_->ReusePictureBuffer(index); | |
| 374 } | |
| 375 } | |
| 376 } | |
| 377 | |
| 378 void ArcGpuVideoDecodeAccelerator::CreateInputRecord( | 364 void ArcGpuVideoDecodeAccelerator::CreateInputRecord( |
| 379 int32_t bitstream_buffer_id, | 365 int32_t bitstream_buffer_id, |
| 380 uint32_t buffer_index, | 366 uint32_t buffer_index, |
| 381 int64_t timestamp) { | 367 int64_t timestamp) { |
| 382 input_records_.push_front( | 368 input_records_.push_front( |
| 383 InputRecord(bitstream_buffer_id, buffer_index, timestamp)); | 369 InputRecord(bitstream_buffer_id, buffer_index, timestamp)); |
| 384 | 370 |
| 385 // The same value copied from media::GpuVideoDecoder. The input record is | 371 // The same value copied from media::GpuVideoDecoder. The input record is |
| 386 // needed when the input buffer or the corresponding output buffer are | 372 // needed when the input buffer or the corresponding output buffer are |
| 387 // returned from VDA. However there is no guarantee how much buffers will be | 373 // returned from VDA. However there is no guarantee how much buffers will be |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 417 } | 403 } |
| 418 return true; | 404 return true; |
| 419 default: | 405 default: |
| 420 DLOG(ERROR) << "Invalid port: " << port; | 406 DLOG(ERROR) << "Invalid port: " << port; |
| 421 return false; | 407 return false; |
| 422 } | 408 } |
| 423 } | 409 } |
| 424 | 410 |
| 425 } // namespace arc | 411 } // namespace arc |
| 426 } // namespace chromeos | 412 } // namespace chromeos |
| OLD | NEW |