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(index, {handle}); |
| 222 } else { |
| 223 vda_->ReusePictureBuffer(index); |
213 } | 224 } |
214 break; | 225 break; |
215 } | 226 } |
216 case PORT_OUTPUT: { | |
217 SendEosIfNeededOrReusePicture(index); | |
218 break; | |
219 } | |
220 default: | 227 default: |
221 NOTREACHED(); | 228 NOTREACHED(); |
222 } | 229 } |
223 } | 230 } |
224 | 231 |
225 void ArcGpuVideoDecodeAccelerator::Reset() { | 232 void ArcGpuVideoDecodeAccelerator::Reset() { |
226 DCHECK(thread_checker_.CalledOnValidThread()); | 233 DCHECK(thread_checker_.CalledOnValidThread()); |
227 if (!vda_) { | 234 if (!vda_) { |
228 DLOG(ERROR) << "VDA not initialized"; | 235 DLOG(ERROR) << "VDA not initialized"; |
229 return; | 236 return; |
230 } | 237 } |
231 vda_->Reset(); | 238 vda_->Reset(); |
232 } | 239 } |
233 | 240 |
| 241 void ArcGpuVideoDecodeAccelerator::Flush() { |
| 242 DCHECK(thread_checker_.CalledOnValidThread()); |
| 243 if (!vda_) { |
| 244 DLOG(ERROR) << "VDA not initialized"; |
| 245 return; |
| 246 } |
| 247 vda_->Flush(); |
| 248 } |
| 249 |
234 void ArcGpuVideoDecodeAccelerator::ProvidePictureBuffers( | 250 void ArcGpuVideoDecodeAccelerator::ProvidePictureBuffers( |
235 uint32_t requested_num_of_buffers, | 251 uint32_t requested_num_of_buffers, |
236 uint32_t textures_per_buffer, | 252 uint32_t textures_per_buffer, |
237 const gfx::Size& dimensions, | 253 const gfx::Size& dimensions, |
238 uint32_t texture_target) { | 254 uint32_t texture_target) { |
239 DVLOG(5) << "ProvidePictureBuffers(" | 255 DVLOG(5) << "ProvidePictureBuffers(" |
240 << "requested_num_of_buffers=" << requested_num_of_buffers | 256 << "requested_num_of_buffers=" << requested_num_of_buffers |
241 << ", dimensions=" << dimensions.ToString() << ")"; | 257 << ", dimensions=" << dimensions.ToString() << ")"; |
242 DCHECK(thread_checker_.CalledOnValidThread()); | 258 DCHECK(thread_checker_.CalledOnValidThread()); |
243 coded_size_ = dimensions; | 259 coded_size_ = dimensions; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 void ArcGpuVideoDecodeAccelerator::DismissPictureBuffer( | 295 void ArcGpuVideoDecodeAccelerator::DismissPictureBuffer( |
280 int32_t picture_buffer) { | 296 int32_t picture_buffer) { |
281 // no-op | 297 // no-op |
282 } | 298 } |
283 | 299 |
284 void ArcGpuVideoDecodeAccelerator::PictureReady(const media::Picture& picture) { | 300 void ArcGpuVideoDecodeAccelerator::PictureReady(const media::Picture& picture) { |
285 DVLOG(5) << "PictureReady(picture_buffer_id=" << picture.picture_buffer_id() | 301 DVLOG(5) << "PictureReady(picture_buffer_id=" << picture.picture_buffer_id() |
286 << ", bitstream_buffer_id=" << picture.bitstream_buffer_id(); | 302 << ", bitstream_buffer_id=" << picture.bitstream_buffer_id(); |
287 DCHECK(thread_checker_.CalledOnValidThread()); | 303 DCHECK(thread_checker_.CalledOnValidThread()); |
288 | 304 |
289 // Empty buffer, returned in Flushing. | |
290 if (picture.bitstream_buffer_id() == -1) { | |
291 buffers_pending_eos_.push(picture.picture_buffer_id()); | |
292 return; | |
293 } | |
294 InputRecord* input_record = FindInputRecord(picture.bitstream_buffer_id()); | 305 InputRecord* input_record = FindInputRecord(picture.bitstream_buffer_id()); |
295 if (input_record == nullptr) { | 306 if (input_record == nullptr) { |
296 DLOG(ERROR) << "Cannot find for bitstream buffer id: " | 307 DLOG(ERROR) << "Cannot find for bitstream buffer id: " |
297 << picture.bitstream_buffer_id(); | 308 << picture.bitstream_buffer_id(); |
298 arc_client_->OnError(PLATFORM_FAILURE); | 309 arc_client_->OnError(PLATFORM_FAILURE); |
299 return; | 310 return; |
300 } | 311 } |
301 | 312 |
302 BufferMetadata metadata; | 313 BufferMetadata metadata; |
303 metadata.timestamp = input_record->timestamp; | 314 metadata.timestamp = input_record->timestamp; |
304 metadata.bytes_used = output_buffer_size_; | 315 metadata.bytes_used = output_buffer_size_; |
305 arc_client_->OnBufferDone(PORT_OUTPUT, picture.picture_buffer_id(), metadata); | 316 arc_client_->OnBufferDone(PORT_OUTPUT, picture.picture_buffer_id(), metadata); |
306 } | 317 } |
307 | 318 |
308 void ArcGpuVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer( | 319 void ArcGpuVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer( |
309 int32_t bitstream_buffer_id) { | 320 int32_t bitstream_buffer_id) { |
310 DVLOG(5) << "NotifyEndOfBitstreamBuffer(" << bitstream_buffer_id << ")"; | 321 DVLOG(5) << "NotifyEndOfBitstreamBuffer(" << bitstream_buffer_id << ")"; |
311 DCHECK(thread_checker_.CalledOnValidThread()); | 322 DCHECK(thread_checker_.CalledOnValidThread()); |
312 InputRecord* input_record = FindInputRecord(bitstream_buffer_id); | 323 InputRecord* input_record = FindInputRecord(bitstream_buffer_id); |
313 if (input_record == nullptr) { | 324 if (input_record == nullptr) { |
314 arc_client_->OnError(PLATFORM_FAILURE); | 325 arc_client_->OnError(PLATFORM_FAILURE); |
315 return; | 326 return; |
316 } | 327 } |
317 arc_client_->OnBufferDone(PORT_INPUT, input_record->buffer_index, | 328 arc_client_->OnBufferDone(PORT_INPUT, input_record->buffer_index, |
318 BufferMetadata()); | 329 BufferMetadata()); |
319 } | 330 } |
320 | 331 |
321 void ArcGpuVideoDecodeAccelerator::NotifyFlushDone() { | 332 void ArcGpuVideoDecodeAccelerator::NotifyFlushDone() { |
322 DCHECK(thread_checker_.CalledOnValidThread()); | 333 DCHECK(thread_checker_.CalledOnValidThread()); |
323 pending_eos_output_buffer_ = true; | 334 arc_client_->OnFlushDone(); |
324 while (!buffers_pending_eos_.empty()) { | |
325 SendEosIfNeededOrReusePicture(buffers_pending_eos_.front()); | |
326 buffers_pending_eos_.pop(); | |
327 } | |
328 } | 335 } |
329 | 336 |
330 void ArcGpuVideoDecodeAccelerator::NotifyResetDone() { | 337 void ArcGpuVideoDecodeAccelerator::NotifyResetDone() { |
331 DCHECK(thread_checker_.CalledOnValidThread()); | 338 DCHECK(thread_checker_.CalledOnValidThread()); |
332 arc_client_->OnResetDone(); | 339 arc_client_->OnResetDone(); |
333 } | 340 } |
334 | 341 |
335 static ArcVideoAccelerator::Error ConvertErrorCode( | 342 static ArcVideoAccelerator::Error ConvertErrorCode( |
336 media::VideoDecodeAccelerator::Error error) { | 343 media::VideoDecodeAccelerator::Error error) { |
337 switch (error) { | 344 switch (error) { |
(...skipping 11 matching lines...) Expand all Loading... |
349 } | 356 } |
350 } | 357 } |
351 | 358 |
352 void ArcGpuVideoDecodeAccelerator::NotifyError( | 359 void ArcGpuVideoDecodeAccelerator::NotifyError( |
353 media::VideoDecodeAccelerator::Error error) { | 360 media::VideoDecodeAccelerator::Error error) { |
354 DCHECK(thread_checker_.CalledOnValidThread()); | 361 DCHECK(thread_checker_.CalledOnValidThread()); |
355 DLOG(ERROR) << "Error notified: " << error; | 362 DLOG(ERROR) << "Error notified: " << error; |
356 arc_client_->OnError(ConvertErrorCode(error)); | 363 arc_client_->OnError(ConvertErrorCode(error)); |
357 } | 364 } |
358 | 365 |
359 void ArcGpuVideoDecodeAccelerator::SendEosIfNeededOrReusePicture( | |
360 uint32_t index) { | |
361 if (pending_eos_output_buffer_) { | |
362 BufferMetadata metadata; | |
363 metadata.flags = BUFFER_FLAG_EOS; | |
364 arc_client_->OnBufferDone(PORT_OUTPUT, index, metadata); | |
365 pending_eos_output_buffer_ = false; | |
366 } else { | |
367 if (buffers_pending_import_[index].is_valid()) { | |
368 std::vector<gfx::GpuMemoryBufferHandle> buffers; | |
369 buffers.push_back(gfx::GpuMemoryBufferHandle()); | |
370 #if defined(USE_OZONE) | |
371 buffers.back().native_pixmap_handle.fd = | |
372 base::FileDescriptor(buffers_pending_import_[index].release(), true); | |
373 #endif | |
374 vda_->ImportBufferForPicture(index, buffers); | |
375 } else { | |
376 vda_->ReusePictureBuffer(index); | |
377 } | |
378 } | |
379 } | |
380 | |
381 void ArcGpuVideoDecodeAccelerator::CreateInputRecord( | 366 void ArcGpuVideoDecodeAccelerator::CreateInputRecord( |
382 int32_t bitstream_buffer_id, | 367 int32_t bitstream_buffer_id, |
383 uint32_t buffer_index, | 368 uint32_t buffer_index, |
384 int64_t timestamp) { | 369 int64_t timestamp) { |
385 input_records_.push_front( | 370 input_records_.push_front( |
386 InputRecord(bitstream_buffer_id, buffer_index, timestamp)); | 371 InputRecord(bitstream_buffer_id, buffer_index, timestamp)); |
387 | 372 |
388 // The same value copied from media::GpuVideoDecoder. The input record is | 373 // The same value copied from media::GpuVideoDecoder. The input record is |
389 // needed when the input buffer or the corresponding output buffer are | 374 // needed when the input buffer or the corresponding output buffer are |
390 // returned from VDA. However there is no guarantee how much buffers will be | 375 // returned from VDA. However there is no guarantee how much buffers will be |
(...skipping 29 matching lines...) Expand all Loading... |
420 } | 405 } |
421 return true; | 406 return true; |
422 default: | 407 default: |
423 DLOG(ERROR) << "Invalid port: " << port; | 408 DLOG(ERROR) << "Invalid port: " << port; |
424 return false; | 409 return false; |
425 } | 410 } |
426 } | 411 } |
427 | 412 |
428 } // namespace arc | 413 } // namespace arc |
429 } // namespace chromeos | 414 } // namespace chromeos |
OLD | NEW |