| 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/chrome_arc_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/metrics/histogram_macros.h" | 9 #include "base/metrics/histogram_macros.h" |
| 10 #include "base/numerics/safe_math.h" | 10 #include "base/numerics/safe_math.h" |
| 11 #include "base/run_loop.h" | 11 #include "base/run_loop.h" |
| 12 #include "base/unguessable_token.h" | 12 #include "base/unguessable_token.h" |
| 13 #include "media/base/video_frame.h" | 13 #include "media/base/video_frame.h" |
| 14 #include "media/gpu/gpu_video_decode_accelerator_factory.h" | 14 #include "media/gpu/gpu_video_decode_accelerator_factory.h" |
| 15 | 15 |
| 16 namespace chromeos { | 16 namespace chromeos { |
| 17 namespace arc { | 17 namespace arc { |
| 18 | 18 |
| 19 namespace { | 19 namespace { |
| 20 | 20 |
| 21 // An arbitrary chosen limit of the number of buffers. The number of | 21 // An arbitrary chosen limit of the number of buffers. The number of |
| 22 // buffers used is requested from the untrusted client side. | 22 // buffers used is requested from the untrusted client side. |
| 23 const size_t kMaxBufferCount = 128; | 23 const size_t kMaxBufferCount = 128; |
| 24 | 24 |
| 25 // Maximum number of concurrent ARC video clients. | 25 // Maximum number of concurrent ARC video clients. |
| 26 // Currently we have no way to know the resources are not enough to create more | 26 // Currently we have no way to know the resources are not enough to create more |
| 27 // VDA. Arbitrarily chosen a reasonable constant as the limit. | 27 // VDA. Arbitrarily chosen a reasonable constant as the limit. |
| 28 const int kMaxConcurrentClients = 8; | 28 const int kMaxConcurrentClients = 8; |
| 29 | 29 |
| 30 } // anonymous namespace | 30 } // anonymous namespace |
| 31 | 31 |
| 32 int ArcGpuVideoDecodeAccelerator::client_count_ = 0; | 32 int ChromeArcVideoDecodeAccelerator::client_count_ = 0; |
| 33 | 33 |
| 34 ArcGpuVideoDecodeAccelerator::InputRecord::InputRecord( | 34 ChromeArcVideoDecodeAccelerator::InputRecord::InputRecord( |
| 35 int32_t bitstream_buffer_id, | 35 int32_t bitstream_buffer_id, |
| 36 uint32_t buffer_index, | 36 uint32_t buffer_index, |
| 37 int64_t timestamp) | 37 int64_t timestamp) |
| 38 : bitstream_buffer_id(bitstream_buffer_id), | 38 : bitstream_buffer_id(bitstream_buffer_id), |
| 39 buffer_index(buffer_index), | 39 buffer_index(buffer_index), |
| 40 timestamp(timestamp) {} | 40 timestamp(timestamp) {} |
| 41 | 41 |
| 42 ArcGpuVideoDecodeAccelerator::InputBufferInfo::InputBufferInfo() = default; | 42 ChromeArcVideoDecodeAccelerator::InputBufferInfo::InputBufferInfo() = default; |
| 43 | 43 |
| 44 ArcGpuVideoDecodeAccelerator::InputBufferInfo::InputBufferInfo( | 44 ChromeArcVideoDecodeAccelerator::InputBufferInfo::InputBufferInfo( |
| 45 InputBufferInfo&& other) = default; | 45 InputBufferInfo&& other) = default; |
| 46 | 46 |
| 47 ArcGpuVideoDecodeAccelerator::InputBufferInfo::~InputBufferInfo() = default; | 47 ChromeArcVideoDecodeAccelerator::InputBufferInfo::~InputBufferInfo() = default; |
| 48 | 48 |
| 49 ArcGpuVideoDecodeAccelerator::OutputBufferInfo::OutputBufferInfo() = default; | 49 ChromeArcVideoDecodeAccelerator::OutputBufferInfo::OutputBufferInfo() = default; |
| 50 | 50 |
| 51 ArcGpuVideoDecodeAccelerator::OutputBufferInfo::OutputBufferInfo( | 51 ChromeArcVideoDecodeAccelerator::OutputBufferInfo::OutputBufferInfo( |
| 52 OutputBufferInfo&& other) = default; | 52 OutputBufferInfo&& other) = default; |
| 53 | 53 |
| 54 ArcGpuVideoDecodeAccelerator::OutputBufferInfo::~OutputBufferInfo() = default; | 54 ChromeArcVideoDecodeAccelerator::OutputBufferInfo::~OutputBufferInfo() = |
| 55 default; |
| 55 | 56 |
| 56 ArcGpuVideoDecodeAccelerator::ArcGpuVideoDecodeAccelerator( | 57 ChromeArcVideoDecodeAccelerator::ChromeArcVideoDecodeAccelerator( |
| 57 const gpu::GpuPreferences& gpu_preferences) | 58 const gpu::GpuPreferences& gpu_preferences) |
| 58 : arc_client_(nullptr), | 59 : arc_client_(nullptr), |
| 59 next_bitstream_buffer_id_(0), | 60 next_bitstream_buffer_id_(0), |
| 60 output_pixel_format_(media::PIXEL_FORMAT_UNKNOWN), | 61 output_pixel_format_(media::PIXEL_FORMAT_UNKNOWN), |
| 61 output_buffer_size_(0), | 62 output_buffer_size_(0), |
| 62 requested_num_of_output_buffers_(0), | 63 requested_num_of_output_buffers_(0), |
| 63 gpu_preferences_(gpu_preferences) {} | 64 gpu_preferences_(gpu_preferences) {} |
| 64 | 65 |
| 65 ArcGpuVideoDecodeAccelerator::~ArcGpuVideoDecodeAccelerator() { | 66 ChromeArcVideoDecodeAccelerator::~ChromeArcVideoDecodeAccelerator() { |
| 66 DCHECK(thread_checker_.CalledOnValidThread()); | 67 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 67 if (vda_) { | 68 if (vda_) { |
| 68 client_count_--; | 69 client_count_--; |
| 69 } | 70 } |
| 70 } | 71 } |
| 71 | 72 |
| 72 ArcVideoAccelerator::Result ArcGpuVideoDecodeAccelerator::Initialize( | 73 ArcVideoDecodeAccelerator::Result ChromeArcVideoDecodeAccelerator::Initialize( |
| 73 const Config& config, | 74 const Config& config, |
| 74 ArcVideoAccelerator::Client* client) { | 75 ArcVideoDecodeAccelerator::Client* client) { |
| 75 auto result = InitializeTask(config, client); | 76 auto result = InitializeTask(config, client); |
| 76 // Report initialization status to UMA. | 77 // Report initialization status to UMA. |
| 77 UMA_HISTOGRAM_ENUMERATION( | 78 UMA_HISTOGRAM_ENUMERATION( |
| 78 "Media.ArcGpuVideoDecodeAccelerator.InitializeResult", result, | 79 "Media.ChromeArcVideoDecodeAccelerator.InitializeResult", result, |
| 79 RESULT_MAX); | 80 RESULT_MAX); |
| 80 return result; | 81 return result; |
| 81 } | 82 } |
| 82 | 83 |
| 83 ArcVideoAccelerator::Result ArcGpuVideoDecodeAccelerator::InitializeTask( | 84 ArcVideoDecodeAccelerator::Result |
| 85 ChromeArcVideoDecodeAccelerator::InitializeTask( |
| 84 const Config& config, | 86 const Config& config, |
| 85 ArcVideoAccelerator::Client* client) { | 87 ArcVideoDecodeAccelerator::Client* client) { |
| 86 DVLOG(5) << "Initialize(device=" << config.device_type | 88 DVLOG(5) << "Initialize(input_pixel_format=" << config.input_pixel_format |
| 87 << ", input_pixel_format=" << config.input_pixel_format | |
| 88 << ", num_input_buffers=" << config.num_input_buffers << ")"; | 89 << ", num_input_buffers=" << config.num_input_buffers << ")"; |
| 89 DCHECK(thread_checker_.CalledOnValidThread()); | 90 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 90 if (config.device_type != Config::DEVICE_DECODER) | |
| 91 return INVALID_ARGUMENT; | |
| 92 DCHECK(client); | 91 DCHECK(client); |
| 93 | 92 |
| 94 if (arc_client_) { | 93 if (arc_client_) { |
| 95 DLOG(ERROR) << "Re-Initialize() is not allowed"; | 94 DLOG(ERROR) << "Re-Initialize() is not allowed"; |
| 96 return ILLEGAL_STATE; | 95 return ILLEGAL_STATE; |
| 97 } | 96 } |
| 98 | 97 |
| 99 if (client_count_ >= kMaxConcurrentClients) { | 98 if (client_count_ >= kMaxConcurrentClients) { |
| 100 LOG(WARNING) << "Reject to Initialize() due to too many clients: " | 99 LOG(WARNING) << "Reject to Initialize() due to too many clients: " |
| 101 << client_count_; | 100 << client_count_; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 130 | 129 |
| 131 auto vda_factory = media::GpuVideoDecodeAcceleratorFactory::CreateWithNoGL(); | 130 auto vda_factory = media::GpuVideoDecodeAcceleratorFactory::CreateWithNoGL(); |
| 132 vda_ = vda_factory->CreateVDA( | 131 vda_ = vda_factory->CreateVDA( |
| 133 this, vda_config, gpu::GpuDriverBugWorkarounds(), gpu_preferences_); | 132 this, vda_config, gpu::GpuDriverBugWorkarounds(), gpu_preferences_); |
| 134 if (!vda_) { | 133 if (!vda_) { |
| 135 DLOG(ERROR) << "Failed to create VDA."; | 134 DLOG(ERROR) << "Failed to create VDA."; |
| 136 return PLATFORM_FAILURE; | 135 return PLATFORM_FAILURE; |
| 137 } | 136 } |
| 138 | 137 |
| 139 client_count_++; | 138 client_count_++; |
| 140 DVLOG(5) << "Number of concurrent ArcVideoAccelerator clients: " | 139 DVLOG(5) << "Number of concurrent ArcVideoDecodeAccelerator clients: " |
| 141 << client_count_; | 140 << client_count_; |
| 142 | 141 |
| 143 return SUCCESS; | 142 return SUCCESS; |
| 144 } | 143 } |
| 145 | 144 |
| 146 void ArcGpuVideoDecodeAccelerator::SetNumberOfOutputBuffers(size_t number) { | 145 void ChromeArcVideoDecodeAccelerator::SetNumberOfOutputBuffers(size_t number) { |
| 147 DVLOG(5) << "SetNumberOfOutputBuffers(" << number << ")"; | 146 DVLOG(5) << "SetNumberOfOutputBuffers(" << number << ")"; |
| 148 DCHECK(thread_checker_.CalledOnValidThread()); | 147 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 149 if (!vda_) { | 148 if (!vda_) { |
| 150 DLOG(ERROR) << "VDA not initialized"; | 149 DLOG(ERROR) << "VDA not initialized"; |
| 151 return; | 150 return; |
| 152 } | 151 } |
| 153 | 152 |
| 154 if (number > kMaxBufferCount) { | 153 if (number > kMaxBufferCount) { |
| 155 DLOG(ERROR) << "Too many buffers: " << number; | 154 DLOG(ERROR) << "Too many buffers: " << number; |
| 156 arc_client_->OnError(INVALID_ARGUMENT); | 155 arc_client_->OnError(INVALID_ARGUMENT); |
| 157 return; | 156 return; |
| 158 } | 157 } |
| 159 | 158 |
| 160 std::vector<media::PictureBuffer> buffers; | 159 std::vector<media::PictureBuffer> buffers; |
| 161 for (size_t id = 0; id < number; ++id) { | 160 for (size_t id = 0; id < number; ++id) { |
| 162 // TODO(owenlin): Make sure the |coded_size| is what we want. | 161 // TODO(owenlin): Make sure the |coded_size| is what we want. |
| 163 buffers.push_back( | 162 buffers.push_back( |
| 164 media::PictureBuffer(base::checked_cast<int32_t>(id), coded_size_)); | 163 media::PictureBuffer(base::checked_cast<int32_t>(id), coded_size_)); |
| 165 } | 164 } |
| 166 vda_->AssignPictureBuffers(buffers); | 165 vda_->AssignPictureBuffers(buffers); |
| 167 | 166 |
| 168 buffers_pending_import_.clear(); | 167 buffers_pending_import_.clear(); |
| 169 buffers_pending_import_.resize(number); | 168 buffers_pending_import_.resize(number); |
| 170 } | 169 } |
| 171 | 170 |
| 172 void ArcGpuVideoDecodeAccelerator::BindSharedMemory(PortType port, | 171 void ChromeArcVideoDecodeAccelerator::BindSharedMemory(PortType port, |
| 173 uint32_t index, | 172 uint32_t index, |
| 174 base::ScopedFD ashmem_fd, | 173 base::ScopedFD ashmem_fd, |
| 175 off_t offset, | 174 off_t offset, |
| 176 size_t length) { | 175 size_t length) { |
| 177 DVLOG(5) << "ArcGVDA::BindSharedMemory, offset: " << offset | 176 DVLOG(5) << "ArcGVDA::BindSharedMemory, offset: " << offset |
| 178 << ", length: " << length; | 177 << ", length: " << length; |
| 179 DCHECK(thread_checker_.CalledOnValidThread()); | 178 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 180 if (!vda_) { | 179 if (!vda_) { |
| 181 DLOG(ERROR) << "VDA not initialized"; | 180 DLOG(ERROR) << "VDA not initialized"; |
| 182 return; | 181 return; |
| 183 } | 182 } |
| 184 | 183 |
| 185 if (port != PORT_INPUT) { | 184 if (port != PORT_INPUT) { |
| 186 DLOG(ERROR) << "SharedBuffer is only supported for input"; | 185 DLOG(ERROR) << "SharedBuffer is only supported for input"; |
| 187 arc_client_->OnError(INVALID_ARGUMENT); | 186 arc_client_->OnError(INVALID_ARGUMENT); |
| 188 return; | 187 return; |
| 189 } | 188 } |
| 190 if (!ValidatePortAndIndex(port, index)) { | 189 if (!ValidatePortAndIndex(port, index)) { |
| 191 arc_client_->OnError(INVALID_ARGUMENT); | 190 arc_client_->OnError(INVALID_ARGUMENT); |
| 192 return; | 191 return; |
| 193 } | 192 } |
| 194 InputBufferInfo* input_info = &input_buffer_info_[index]; | 193 InputBufferInfo* input_info = &input_buffer_info_[index]; |
| 195 input_info->handle = std::move(ashmem_fd); | 194 input_info->handle = std::move(ashmem_fd); |
| 196 input_info->offset = offset; | 195 input_info->offset = offset; |
| 197 input_info->length = length; | 196 input_info->length = length; |
| 198 } | 197 } |
| 199 | 198 |
| 200 bool ArcGpuVideoDecodeAccelerator::VerifyDmabuf( | 199 bool ChromeArcVideoDecodeAccelerator::VerifyDmabuf( |
| 201 const base::ScopedFD& dmabuf_fd, | 200 const base::ScopedFD& dmabuf_fd, |
| 202 const std::vector<::arc::ArcVideoAcceleratorDmabufPlane>& dmabuf_planes) | 201 const std::vector<::arc::ArcVideoAcceleratorDmabufPlane>& dmabuf_planes) |
| 203 const { | 202 const { |
| 204 size_t num_planes = media::VideoFrame::NumPlanes(output_pixel_format_); | 203 size_t num_planes = media::VideoFrame::NumPlanes(output_pixel_format_); |
| 205 if (dmabuf_planes.size() != num_planes) { | 204 if (dmabuf_planes.size() != num_planes) { |
| 206 DLOG(ERROR) << "Invalid number of dmabuf planes passed: " | 205 DLOG(ERROR) << "Invalid number of dmabuf planes passed: " |
| 207 << dmabuf_planes.size() << ", expected: " << num_planes; | 206 << dmabuf_planes.size() << ", expected: " << num_planes; |
| 208 return false; | 207 return false; |
| 209 } | 208 } |
| 210 | 209 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 229 DLOG(ERROR) << "Invalid strides/offsets"; | 228 DLOG(ERROR) << "Invalid strides/offsets"; |
| 230 return false; | 229 return false; |
| 231 } | 230 } |
| 232 | 231 |
| 233 ++i; | 232 ++i; |
| 234 } | 233 } |
| 235 | 234 |
| 236 return true; | 235 return true; |
| 237 } | 236 } |
| 238 | 237 |
| 239 void ArcGpuVideoDecodeAccelerator::BindDmabuf( | 238 void ChromeArcVideoDecodeAccelerator::BindDmabuf( |
| 240 PortType port, | 239 PortType port, |
| 241 uint32_t index, | 240 uint32_t index, |
| 242 base::ScopedFD dmabuf_fd, | 241 base::ScopedFD dmabuf_fd, |
| 243 const std::vector<::arc::ArcVideoAcceleratorDmabufPlane>& dmabuf_planes) { | 242 const std::vector<::arc::ArcVideoAcceleratorDmabufPlane>& dmabuf_planes) { |
| 244 DCHECK(thread_checker_.CalledOnValidThread()); | 243 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 245 | 244 |
| 246 if (!vda_) { | 245 if (!vda_) { |
| 247 DLOG(ERROR) << "VDA not initialized"; | 246 DLOG(ERROR) << "VDA not initialized"; |
| 248 return; | 247 return; |
| 249 } | 248 } |
| 250 | 249 |
| 251 if (port != PORT_OUTPUT) { | 250 if (port != PORT_OUTPUT) { |
| 252 DLOG(ERROR) << "Dmabuf is only supported for input"; | 251 DLOG(ERROR) << "Dmabuf is only supported for input"; |
| 253 arc_client_->OnError(INVALID_ARGUMENT); | 252 arc_client_->OnError(INVALID_ARGUMENT); |
| 254 return; | 253 return; |
| 255 } | 254 } |
| 256 if (!ValidatePortAndIndex(port, index)) { | 255 if (!ValidatePortAndIndex(port, index)) { |
| 257 arc_client_->OnError(INVALID_ARGUMENT); | 256 arc_client_->OnError(INVALID_ARGUMENT); |
| 258 return; | 257 return; |
| 259 } | 258 } |
| 260 if (!VerifyDmabuf(dmabuf_fd, dmabuf_planes)) { | 259 if (!VerifyDmabuf(dmabuf_fd, dmabuf_planes)) { |
| 261 arc_client_->OnError(INVALID_ARGUMENT); | 260 arc_client_->OnError(INVALID_ARGUMENT); |
| 262 return; | 261 return; |
| 263 } | 262 } |
| 264 | 263 |
| 265 OutputBufferInfo& info = buffers_pending_import_[index]; | 264 OutputBufferInfo& info = buffers_pending_import_[index]; |
| 266 info.handle = std::move(dmabuf_fd); | 265 info.handle = std::move(dmabuf_fd); |
| 267 info.planes = dmabuf_planes; | 266 info.planes = dmabuf_planes; |
| 268 } | 267 } |
| 269 | 268 |
| 270 void ArcGpuVideoDecodeAccelerator::UseBuffer(PortType port, | 269 void ChromeArcVideoDecodeAccelerator::UseBuffer( |
| 271 uint32_t index, | 270 PortType port, |
| 272 const BufferMetadata& metadata) { | 271 uint32_t index, |
| 272 const BufferMetadata& metadata) { |
| 273 DVLOG(5) << "UseBuffer(port=" << port << ", index=" << index | 273 DVLOG(5) << "UseBuffer(port=" << port << ", index=" << index |
| 274 << ", metadata=(bytes_used=" << metadata.bytes_used | 274 << ", metadata=(bytes_used=" << metadata.bytes_used |
| 275 << ", timestamp=" << metadata.timestamp << ")"; | 275 << ", timestamp=" << metadata.timestamp << ")"; |
| 276 DCHECK(thread_checker_.CalledOnValidThread()); | 276 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 277 if (!vda_) { | 277 if (!vda_) { |
| 278 DLOG(ERROR) << "VDA not initialized"; | 278 DLOG(ERROR) << "VDA not initialized"; |
| 279 return; | 279 return; |
| 280 } | 280 } |
| 281 if (!ValidatePortAndIndex(port, index)) { | 281 if (!ValidatePortAndIndex(port, index)) { |
| 282 arc_client_->OnError(INVALID_ARGUMENT); | 282 arc_client_->OnError(INVALID_ARGUMENT); |
| 283 return; | 283 return; |
| 284 } | 284 } |
| 285 switch (port) { | 285 switch (port) { |
| 286 case PORT_INPUT: { | 286 case PORT_INPUT: { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 327 } else { | 327 } else { |
| 328 vda_->ReusePictureBuffer(index); | 328 vda_->ReusePictureBuffer(index); |
| 329 } | 329 } |
| 330 break; | 330 break; |
| 331 } | 331 } |
| 332 default: | 332 default: |
| 333 NOTREACHED(); | 333 NOTREACHED(); |
| 334 } | 334 } |
| 335 } | 335 } |
| 336 | 336 |
| 337 void ArcGpuVideoDecodeAccelerator::Reset() { | 337 void ChromeArcVideoDecodeAccelerator::Reset() { |
| 338 DCHECK(thread_checker_.CalledOnValidThread()); | 338 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 339 if (!vda_) { | 339 if (!vda_) { |
| 340 DLOG(ERROR) << "VDA not initialized"; | 340 DLOG(ERROR) << "VDA not initialized"; |
| 341 return; | 341 return; |
| 342 } | 342 } |
| 343 vda_->Reset(); | 343 vda_->Reset(); |
| 344 } | 344 } |
| 345 | 345 |
| 346 void ArcGpuVideoDecodeAccelerator::Flush() { | 346 void ChromeArcVideoDecodeAccelerator::Flush() { |
| 347 DCHECK(thread_checker_.CalledOnValidThread()); | 347 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 348 if (!vda_) { | 348 if (!vda_) { |
| 349 DLOG(ERROR) << "VDA not initialized"; | 349 DLOG(ERROR) << "VDA not initialized"; |
| 350 return; | 350 return; |
| 351 } | 351 } |
| 352 vda_->Flush(); | 352 vda_->Flush(); |
| 353 } | 353 } |
| 354 | 354 |
| 355 void ArcGpuVideoDecodeAccelerator::ProvidePictureBuffers( | 355 void ChromeArcVideoDecodeAccelerator::ProvidePictureBuffers( |
| 356 uint32_t requested_num_of_buffers, | 356 uint32_t requested_num_of_buffers, |
| 357 media::VideoPixelFormat output_pixel_format, | 357 media::VideoPixelFormat output_pixel_format, |
| 358 uint32_t textures_per_buffer, | 358 uint32_t textures_per_buffer, |
| 359 const gfx::Size& dimensions, | 359 const gfx::Size& dimensions, |
| 360 uint32_t texture_target) { | 360 uint32_t texture_target) { |
| 361 DVLOG(5) << "ProvidePictureBuffers(" | 361 DVLOG(5) << "ProvidePictureBuffers(" |
| 362 << "requested_num_of_buffers=" << requested_num_of_buffers | 362 << "requested_num_of_buffers=" << requested_num_of_buffers |
| 363 << ", dimensions=" << dimensions.ToString() << ")"; | 363 << ", dimensions=" << dimensions.ToString() << ")"; |
| 364 DCHECK(thread_checker_.CalledOnValidThread()); | 364 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 365 coded_size_ = dimensions; | 365 coded_size_ = dimensions; |
| 366 | 366 |
| 367 // By default, use an empty rect to indicate the visible rectangle is not | 367 // By default, use an empty rect to indicate the visible rectangle is not |
| 368 // available. | 368 // available. |
| 369 visible_rect_ = gfx::Rect(); | 369 visible_rect_ = gfx::Rect(); |
| 370 if ((output_pixel_format_ != media::PIXEL_FORMAT_UNKNOWN) && | 370 if ((output_pixel_format_ != media::PIXEL_FORMAT_UNKNOWN) && |
| 371 (output_pixel_format_ != output_pixel_format)) { | 371 (output_pixel_format_ != output_pixel_format)) { |
| 372 arc_client_->OnError(PLATFORM_FAILURE); | 372 arc_client_->OnError(PLATFORM_FAILURE); |
| 373 return; | 373 return; |
| 374 } | 374 } |
| 375 output_pixel_format_ = output_pixel_format; | 375 output_pixel_format_ = output_pixel_format; |
| 376 requested_num_of_output_buffers_ = requested_num_of_buffers; | 376 requested_num_of_output_buffers_ = requested_num_of_buffers; |
| 377 output_buffer_size_ = | 377 output_buffer_size_ = |
| 378 media::VideoFrame::AllocationSize(output_pixel_format_, coded_size_); | 378 media::VideoFrame::AllocationSize(output_pixel_format_, coded_size_); |
| 379 | 379 |
| 380 NotifyOutputFormatChanged(); | 380 NotifyOutputFormatChanged(); |
| 381 } | 381 } |
| 382 | 382 |
| 383 void ArcGpuVideoDecodeAccelerator::NotifyOutputFormatChanged() { | 383 void ChromeArcVideoDecodeAccelerator::NotifyOutputFormatChanged() { |
| 384 VideoFormat video_format; | 384 VideoFormat video_format; |
| 385 switch (output_pixel_format_) { | 385 switch (output_pixel_format_) { |
| 386 case media::PIXEL_FORMAT_I420: | 386 case media::PIXEL_FORMAT_I420: |
| 387 case media::PIXEL_FORMAT_YV12: | 387 case media::PIXEL_FORMAT_YV12: |
| 388 case media::PIXEL_FORMAT_NV12: | 388 case media::PIXEL_FORMAT_NV12: |
| 389 case media::PIXEL_FORMAT_NV21: | 389 case media::PIXEL_FORMAT_NV21: |
| 390 // HAL_PIXEL_FORMAT_YCbCr_420_888 is the flexible pixel format in Android | 390 // HAL_PIXEL_FORMAT_YCbCr_420_888 is the flexible pixel format in Android |
| 391 // which handles all 420 formats, with both orderings of chroma (CbCr and | 391 // which handles all 420 formats, with both orderings of chroma (CbCr and |
| 392 // CrCb) as well as planar and semi-planar layouts. | 392 // CrCb) as well as planar and semi-planar layouts. |
| 393 video_format.pixel_format = HAL_PIXEL_FORMAT_YCbCr_420_888; | 393 video_format.pixel_format = HAL_PIXEL_FORMAT_YCbCr_420_888; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 404 video_format.min_num_buffers = requested_num_of_output_buffers_; | 404 video_format.min_num_buffers = requested_num_of_output_buffers_; |
| 405 video_format.coded_width = coded_size_.width(); | 405 video_format.coded_width = coded_size_.width(); |
| 406 video_format.coded_height = coded_size_.height(); | 406 video_format.coded_height = coded_size_.height(); |
| 407 video_format.crop_top = visible_rect_.y(); | 407 video_format.crop_top = visible_rect_.y(); |
| 408 video_format.crop_left = visible_rect_.x(); | 408 video_format.crop_left = visible_rect_.x(); |
| 409 video_format.crop_width = visible_rect_.width(); | 409 video_format.crop_width = visible_rect_.width(); |
| 410 video_format.crop_height = visible_rect_.height(); | 410 video_format.crop_height = visible_rect_.height(); |
| 411 arc_client_->OnOutputFormatChanged(video_format); | 411 arc_client_->OnOutputFormatChanged(video_format); |
| 412 } | 412 } |
| 413 | 413 |
| 414 void ArcGpuVideoDecodeAccelerator::DismissPictureBuffer( | 414 void ChromeArcVideoDecodeAccelerator::DismissPictureBuffer( |
| 415 int32_t picture_buffer) { | 415 int32_t picture_buffer) { |
| 416 // no-op | 416 // no-op |
| 417 } | 417 } |
| 418 | 418 |
| 419 void ArcGpuVideoDecodeAccelerator::PictureReady(const media::Picture& picture) { | 419 void ChromeArcVideoDecodeAccelerator::PictureReady( |
| 420 const media::Picture& picture) { |
| 420 DVLOG(5) << "PictureReady(picture_buffer_id=" << picture.picture_buffer_id() | 421 DVLOG(5) << "PictureReady(picture_buffer_id=" << picture.picture_buffer_id() |
| 421 << ", bitstream_buffer_id=" << picture.bitstream_buffer_id(); | 422 << ", bitstream_buffer_id=" << picture.bitstream_buffer_id(); |
| 422 DCHECK(thread_checker_.CalledOnValidThread()); | 423 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 423 | 424 |
| 424 // Handle visible size change. | 425 // Handle visible size change. |
| 425 if (visible_rect_ != picture.visible_rect()) { | 426 if (visible_rect_ != picture.visible_rect()) { |
| 426 DVLOG(5) << "visible size changed: " << picture.visible_rect().ToString(); | 427 DVLOG(5) << "visible size changed: " << picture.visible_rect().ToString(); |
| 427 visible_rect_ = picture.visible_rect(); | 428 visible_rect_ = picture.visible_rect(); |
| 428 NotifyOutputFormatChanged(); | 429 NotifyOutputFormatChanged(); |
| 429 } | 430 } |
| 430 | 431 |
| 431 InputRecord* input_record = FindInputRecord(picture.bitstream_buffer_id()); | 432 InputRecord* input_record = FindInputRecord(picture.bitstream_buffer_id()); |
| 432 if (input_record == nullptr) { | 433 if (input_record == nullptr) { |
| 433 DLOG(ERROR) << "Cannot find for bitstream buffer id: " | 434 DLOG(ERROR) << "Cannot find for bitstream buffer id: " |
| 434 << picture.bitstream_buffer_id(); | 435 << picture.bitstream_buffer_id(); |
| 435 arc_client_->OnError(PLATFORM_FAILURE); | 436 arc_client_->OnError(PLATFORM_FAILURE); |
| 436 return; | 437 return; |
| 437 } | 438 } |
| 438 | 439 |
| 439 BufferMetadata metadata; | 440 BufferMetadata metadata; |
| 440 metadata.timestamp = input_record->timestamp; | 441 metadata.timestamp = input_record->timestamp; |
| 441 metadata.bytes_used = output_buffer_size_; | 442 metadata.bytes_used = output_buffer_size_; |
| 442 arc_client_->OnBufferDone(PORT_OUTPUT, picture.picture_buffer_id(), metadata); | 443 arc_client_->OnBufferDone(PORT_OUTPUT, picture.picture_buffer_id(), metadata); |
| 443 } | 444 } |
| 444 | 445 |
| 445 void ArcGpuVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer( | 446 void ChromeArcVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer( |
| 446 int32_t bitstream_buffer_id) { | 447 int32_t bitstream_buffer_id) { |
| 447 DVLOG(5) << "NotifyEndOfBitstreamBuffer(" << bitstream_buffer_id << ")"; | 448 DVLOG(5) << "NotifyEndOfBitstreamBuffer(" << bitstream_buffer_id << ")"; |
| 448 DCHECK(thread_checker_.CalledOnValidThread()); | 449 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 449 InputRecord* input_record = FindInputRecord(bitstream_buffer_id); | 450 InputRecord* input_record = FindInputRecord(bitstream_buffer_id); |
| 450 if (input_record == nullptr) { | 451 if (input_record == nullptr) { |
| 451 arc_client_->OnError(PLATFORM_FAILURE); | 452 arc_client_->OnError(PLATFORM_FAILURE); |
| 452 return; | 453 return; |
| 453 } | 454 } |
| 454 arc_client_->OnBufferDone(PORT_INPUT, input_record->buffer_index, | 455 arc_client_->OnBufferDone(PORT_INPUT, input_record->buffer_index, |
| 455 BufferMetadata()); | 456 BufferMetadata()); |
| 456 } | 457 } |
| 457 | 458 |
| 458 void ArcGpuVideoDecodeAccelerator::NotifyFlushDone() { | 459 void ChromeArcVideoDecodeAccelerator::NotifyFlushDone() { |
| 459 DCHECK(thread_checker_.CalledOnValidThread()); | 460 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 460 arc_client_->OnFlushDone(); | 461 arc_client_->OnFlushDone(); |
| 461 } | 462 } |
| 462 | 463 |
| 463 void ArcGpuVideoDecodeAccelerator::NotifyResetDone() { | 464 void ChromeArcVideoDecodeAccelerator::NotifyResetDone() { |
| 464 DCHECK(thread_checker_.CalledOnValidThread()); | 465 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 465 arc_client_->OnResetDone(); | 466 arc_client_->OnResetDone(); |
| 466 } | 467 } |
| 467 | 468 |
| 468 static ArcVideoAccelerator::Result ConvertErrorCode( | 469 static ArcVideoDecodeAccelerator::Result ConvertErrorCode( |
| 469 media::VideoDecodeAccelerator::Error error) { | 470 media::VideoDecodeAccelerator::Error error) { |
| 470 switch (error) { | 471 switch (error) { |
| 471 case media::VideoDecodeAccelerator::ILLEGAL_STATE: | 472 case media::VideoDecodeAccelerator::ILLEGAL_STATE: |
| 472 return ArcVideoAccelerator::ILLEGAL_STATE; | 473 return ArcVideoDecodeAccelerator::ILLEGAL_STATE; |
| 473 case media::VideoDecodeAccelerator::INVALID_ARGUMENT: | 474 case media::VideoDecodeAccelerator::INVALID_ARGUMENT: |
| 474 return ArcVideoAccelerator::INVALID_ARGUMENT; | 475 return ArcVideoDecodeAccelerator::INVALID_ARGUMENT; |
| 475 case media::VideoDecodeAccelerator::UNREADABLE_INPUT: | 476 case media::VideoDecodeAccelerator::UNREADABLE_INPUT: |
| 476 return ArcVideoAccelerator::UNREADABLE_INPUT; | 477 return ArcVideoDecodeAccelerator::UNREADABLE_INPUT; |
| 477 case media::VideoDecodeAccelerator::PLATFORM_FAILURE: | 478 case media::VideoDecodeAccelerator::PLATFORM_FAILURE: |
| 478 return ArcVideoAccelerator::PLATFORM_FAILURE; | 479 return ArcVideoDecodeAccelerator::PLATFORM_FAILURE; |
| 479 default: | 480 default: |
| 480 DLOG(ERROR) << "Unknown error: " << error; | 481 DLOG(ERROR) << "Unknown error: " << error; |
| 481 return ArcVideoAccelerator::PLATFORM_FAILURE; | 482 return ArcVideoDecodeAccelerator::PLATFORM_FAILURE; |
| 482 } | 483 } |
| 483 } | 484 } |
| 484 | 485 |
| 485 void ArcGpuVideoDecodeAccelerator::NotifyError( | 486 void ChromeArcVideoDecodeAccelerator::NotifyError( |
| 486 media::VideoDecodeAccelerator::Error error) { | 487 media::VideoDecodeAccelerator::Error error) { |
| 487 DCHECK(thread_checker_.CalledOnValidThread()); | 488 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 488 DLOG(ERROR) << "Error notified: " << error; | 489 DLOG(ERROR) << "Error notified: " << error; |
| 489 arc_client_->OnError(ConvertErrorCode(error)); | 490 arc_client_->OnError(ConvertErrorCode(error)); |
| 490 } | 491 } |
| 491 | 492 |
| 492 void ArcGpuVideoDecodeAccelerator::CreateInputRecord( | 493 void ChromeArcVideoDecodeAccelerator::CreateInputRecord( |
| 493 int32_t bitstream_buffer_id, | 494 int32_t bitstream_buffer_id, |
| 494 uint32_t buffer_index, | 495 uint32_t buffer_index, |
| 495 int64_t timestamp) { | 496 int64_t timestamp) { |
| 496 input_records_.push_front( | 497 input_records_.push_front( |
| 497 InputRecord(bitstream_buffer_id, buffer_index, timestamp)); | 498 InputRecord(bitstream_buffer_id, buffer_index, timestamp)); |
| 498 | 499 |
| 499 // The same value copied from media::GpuVideoDecoder. The input record is | 500 // The same value copied from media::GpuVideoDecoder. The input record is |
| 500 // needed when the input buffer or the corresponding output buffer are | 501 // needed when the input buffer or the corresponding output buffer are |
| 501 // returned from VDA. However there is no guarantee how much buffers will be | 502 // returned from VDA. However there is no guarantee how much buffers will be |
| 502 // kept in the VDA. We kept the last |kMaxNumberOfInputRecords| in | 503 // kept in the VDA. We kept the last |kMaxNumberOfInputRecords| in |
| 503 // |input_records_| and drop the others. | 504 // |input_records_| and drop the others. |
| 504 const size_t kMaxNumberOfInputRecords = 128; | 505 const size_t kMaxNumberOfInputRecords = 128; |
| 505 if (input_records_.size() > kMaxNumberOfInputRecords) | 506 if (input_records_.size() > kMaxNumberOfInputRecords) |
| 506 input_records_.pop_back(); | 507 input_records_.pop_back(); |
| 507 } | 508 } |
| 508 | 509 |
| 509 ArcGpuVideoDecodeAccelerator::InputRecord* | 510 ChromeArcVideoDecodeAccelerator::InputRecord* |
| 510 ArcGpuVideoDecodeAccelerator::FindInputRecord(int32_t bitstream_buffer_id) { | 511 ChromeArcVideoDecodeAccelerator::FindInputRecord(int32_t bitstream_buffer_id) { |
| 511 for (auto& record : input_records_) { | 512 for (auto& record : input_records_) { |
| 512 if (record.bitstream_buffer_id == bitstream_buffer_id) | 513 if (record.bitstream_buffer_id == bitstream_buffer_id) |
| 513 return &record; | 514 return &record; |
| 514 } | 515 } |
| 515 return nullptr; | 516 return nullptr; |
| 516 } | 517 } |
| 517 | 518 |
| 518 bool ArcGpuVideoDecodeAccelerator::ValidatePortAndIndex(PortType port, | 519 bool ChromeArcVideoDecodeAccelerator::ValidatePortAndIndex( |
| 519 uint32_t index) const { | 520 PortType port, |
| 521 uint32_t index) const { |
| 520 switch (port) { | 522 switch (port) { |
| 521 case PORT_INPUT: | 523 case PORT_INPUT: |
| 522 if (index >= input_buffer_info_.size()) { | 524 if (index >= input_buffer_info_.size()) { |
| 523 DLOG(ERROR) << "Invalid index: " << index; | 525 DLOG(ERROR) << "Invalid index: " << index; |
| 524 return false; | 526 return false; |
| 525 } | 527 } |
| 526 return true; | 528 return true; |
| 527 case PORT_OUTPUT: | 529 case PORT_OUTPUT: |
| 528 if (index >= buffers_pending_import_.size()) { | 530 if (index >= buffers_pending_import_.size()) { |
| 529 DLOG(ERROR) << "Invalid index: " << index; | 531 DLOG(ERROR) << "Invalid index: " << index; |
| 530 return false; | 532 return false; |
| 531 } | 533 } |
| 532 return true; | 534 return true; |
| 533 default: | 535 default: |
| 534 DLOG(ERROR) << "Invalid port: " << port; | 536 DLOG(ERROR) << "Invalid port: " << port; |
| 535 return false; | 537 return false; |
| 536 } | 538 } |
| 537 } | 539 } |
| 538 | 540 |
| 539 } // namespace arc | 541 } // namespace arc |
| 540 } // namespace chromeos | 542 } // namespace chromeos |
| OLD | NEW |