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 |