OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "media/filters/gpu_video_decoder.h" | 5 #include "media/filters/gpu_video_decoder.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 | 314 |
315 void GpuVideoDecoder::NotifyInitializationComplete(bool success) { | 315 void GpuVideoDecoder::NotifyInitializationComplete(bool success) { |
316 DVLOG_IF(1, !success) << __func__ << " Deferred initialization failed."; | 316 DVLOG_IF(1, !success) << __func__ << " Deferred initialization failed."; |
317 DCHECK(!init_cb_.is_null()); | 317 DCHECK(!init_cb_.is_null()); |
318 | 318 |
319 base::ResetAndReturn(&init_cb_).Run(success); | 319 base::ResetAndReturn(&init_cb_).Run(success); |
320 } | 320 } |
321 | 321 |
322 void GpuVideoDecoder::DestroyPictureBuffers(PictureBufferMap* buffers) { | 322 void GpuVideoDecoder::DestroyPictureBuffers(PictureBufferMap* buffers) { |
323 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 323 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
324 for (PictureBufferMap::iterator it = buffers->begin(); it != buffers->end(); | 324 for (const auto& kv : *buffers) { |
325 ++it) { | 325 for (uint32_t id : kv.second.client_texture_ids()) |
326 for (uint32_t id : it->second.texture_ids()) | |
327 factories_->DeleteTexture(id); | 326 factories_->DeleteTexture(id); |
328 } | 327 } |
329 | 328 |
330 buffers->clear(); | 329 buffers->clear(); |
331 } | 330 } |
332 | 331 |
333 void GpuVideoDecoder::DestroyVDA() { | 332 void GpuVideoDecoder::DestroyVDA() { |
334 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 333 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
335 | 334 |
336 vda_.reset(); | 335 vda_.reset(); |
337 | 336 |
338 // Not destroying PictureBuffers in |picture_buffers_at_display_| yet, since | 337 // Not destroying PictureBuffers in |picture_buffers_at_display_| yet, since |
339 // their textures may still be in use by the user of this GpuVideoDecoder. | 338 // their textures may still be in use by the user of this GpuVideoDecoder. |
340 for (PictureBufferTextureMap::iterator it = | 339 for (const auto& kv : picture_buffers_at_display_) |
341 picture_buffers_at_display_.begin(); | 340 assigned_picture_buffers_.erase(kv.first); |
342 it != picture_buffers_at_display_.end(); | |
343 ++it) { | |
344 assigned_picture_buffers_.erase(it->first); | |
345 } | |
346 DestroyPictureBuffers(&assigned_picture_buffers_); | 341 DestroyPictureBuffers(&assigned_picture_buffers_); |
347 } | 342 } |
348 | 343 |
349 void GpuVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, | 344 void GpuVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, |
350 const DecodeCB& decode_cb) { | 345 const DecodeCB& decode_cb) { |
351 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 346 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
352 DCHECK(pending_reset_cb_.is_null()); | 347 DCHECK(pending_reset_cb_.is_null()); |
353 | 348 |
354 DVLOG(3) << __func__ << " " << buffer->AsHumanReadableString(); | 349 DVLOG(3) << __func__ << " " << buffer->AsHumanReadableString(); |
355 | 350 |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
531 | 526 |
532 PictureBufferMap::iterator it = assigned_picture_buffers_.find(id); | 527 PictureBufferMap::iterator it = assigned_picture_buffers_.find(id); |
533 if (it == assigned_picture_buffers_.end()) { | 528 if (it == assigned_picture_buffers_.end()) { |
534 NOTREACHED() << "Missing picture buffer: " << id; | 529 NOTREACHED() << "Missing picture buffer: " << id; |
535 return; | 530 return; |
536 } | 531 } |
537 | 532 |
538 PictureBuffer buffer_to_dismiss = it->second; | 533 PictureBuffer buffer_to_dismiss = it->second; |
539 assigned_picture_buffers_.erase(it); | 534 assigned_picture_buffers_.erase(it); |
540 | 535 |
541 if (!picture_buffers_at_display_.count(id)) { | 536 // If it's in |picture_buffers_at_display_|, postpone deletion of it until |
542 // We can delete the texture immediately as it's not being displayed. | 537 // it's returned to us. |
543 for (uint32_t id : buffer_to_dismiss.texture_ids()) | 538 if (picture_buffers_at_display_.count(id)) |
544 factories_->DeleteTexture(id); | 539 return; |
545 CHECK_GT(available_pictures_, 0); | 540 |
546 --available_pictures_; | 541 // Otherwise, we can delete the texture immediately. |
547 } | 542 for (uint32_t id : buffer_to_dismiss.client_texture_ids()) |
548 // Not destroying a texture in display in |picture_buffers_at_display_|. | 543 factories_->DeleteTexture(id); |
549 // Postpone deletion until after it's returned to us. | 544 CHECK_GT(available_pictures_, 0); |
| 545 --available_pictures_; |
550 } | 546 } |
551 | 547 |
552 void GpuVideoDecoder::PictureReady(const media::Picture& picture) { | 548 void GpuVideoDecoder::PictureReady(const media::Picture& picture) { |
553 DVLOG(3) << "PictureReady()"; | 549 DVLOG(3) << "PictureReady()"; |
554 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 550 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
555 | 551 |
556 PictureBufferMap::iterator it = | 552 PictureBufferMap::iterator it = |
557 assigned_picture_buffers_.find(picture.picture_buffer_id()); | 553 assigned_picture_buffers_.find(picture.picture_buffer_id()); |
558 if (it == assigned_picture_buffers_.end()) { | 554 if (it == assigned_picture_buffers_.end()) { |
559 DLOG(ERROR) << "Missing picture buffer: " << picture.picture_buffer_id(); | 555 DLOG(ERROR) << "Missing picture buffer: " << picture.picture_buffer_id(); |
(...skipping 28 matching lines...) Expand all Loading... |
588 } | 584 } |
589 if (!gfx::Rect(pb.size()).Contains(visible_rect)) { | 585 if (!gfx::Rect(pb.size()).Contains(visible_rect)) { |
590 LOG(WARNING) << "Visible size " << visible_rect.ToString() | 586 LOG(WARNING) << "Visible size " << visible_rect.ToString() |
591 << " is larger than coded size " << pb.size().ToString(); | 587 << " is larger than coded size " << pb.size().ToString(); |
592 visible_rect = gfx::Rect(pb.size()); | 588 visible_rect = gfx::Rect(pb.size()); |
593 } | 589 } |
594 | 590 |
595 DCHECK(decoder_texture_target_); | 591 DCHECK(decoder_texture_target_); |
596 | 592 |
597 gpu::MailboxHolder mailbox_holders[VideoFrame::kMaxPlanes]; | 593 gpu::MailboxHolder mailbox_holders[VideoFrame::kMaxPlanes]; |
598 for (size_t i = 0; i < pb.texture_ids().size(); ++i) { | 594 for (size_t i = 0; i < pb.client_texture_ids().size(); ++i) { |
599 mailbox_holders[i] = gpu::MailboxHolder(pb.texture_mailbox(i), sync_token_, | 595 mailbox_holders[i] = gpu::MailboxHolder(pb.texture_mailbox(i), sync_token_, |
600 decoder_texture_target_); | 596 decoder_texture_target_); |
601 } | 597 } |
602 | 598 |
603 scoped_refptr<VideoFrame> frame(VideoFrame::WrapNativeTextures( | 599 scoped_refptr<VideoFrame> frame(VideoFrame::WrapNativeTextures( |
604 pixel_format_, mailbox_holders, | 600 pixel_format_, mailbox_holders, |
605 base::Bind(&ReleaseMailboxTrampoline, factories_->GetTaskRunner(), | 601 base::Bind( |
606 base::Bind(&GpuVideoDecoder::ReleaseMailbox, | 602 &ReleaseMailboxTrampoline, factories_->GetTaskRunner(), |
607 weak_factory_.GetWeakPtr(), factories_, | 603 base::Bind(&GpuVideoDecoder::ReleaseMailbox, |
608 picture.picture_buffer_id(), pb.texture_ids())), | 604 weak_factory_.GetWeakPtr(), factories_, |
| 605 picture.picture_buffer_id(), pb.client_texture_ids())), |
609 pb.size(), visible_rect, natural_size, timestamp)); | 606 pb.size(), visible_rect, natural_size, timestamp)); |
610 if (!frame) { | 607 if (!frame) { |
611 DLOG(ERROR) << "Create frame failed for: " << picture.picture_buffer_id(); | 608 DLOG(ERROR) << "Create frame failed for: " << picture.picture_buffer_id(); |
612 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); | 609 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); |
613 return; | 610 return; |
614 } | 611 } |
615 if (picture.allow_overlay()) | 612 if (picture.allow_overlay()) |
616 frame->metadata()->SetBoolean(VideoFrameMetadata::ALLOW_OVERLAY, true); | 613 frame->metadata()->SetBoolean(VideoFrameMetadata::ALLOW_OVERLAY, true); |
617 #if defined(OS_MACOSX) || defined(OS_WIN) | 614 #if defined(OS_MACOSX) || defined(OS_WIN) |
618 frame->metadata()->SetBoolean(VideoFrameMetadata::DECODER_OWNS_FRAME, true); | 615 frame->metadata()->SetBoolean(VideoFrameMetadata::DECODER_OWNS_FRAME, true); |
619 #endif | 616 #endif |
620 | 617 |
621 if (requires_texture_copy_) | 618 if (requires_texture_copy_) |
622 frame->metadata()->SetBoolean(VideoFrameMetadata::COPY_REQUIRED, true); | 619 frame->metadata()->SetBoolean(VideoFrameMetadata::COPY_REQUIRED, true); |
623 | 620 |
624 CHECK_GT(available_pictures_, 0); | 621 CHECK_GT(available_pictures_, 0); |
625 --available_pictures_; | 622 --available_pictures_; |
626 | 623 |
627 bool inserted = | 624 bool inserted = picture_buffers_at_display_ |
628 picture_buffers_at_display_ | 625 .insert(std::make_pair(picture.picture_buffer_id(), |
629 .insert(std::make_pair(picture.picture_buffer_id(), pb.texture_ids())) | 626 pb.client_texture_ids())) |
630 .second; | 627 .second; |
631 DCHECK(inserted); | 628 DCHECK(inserted); |
632 | 629 |
633 DeliverFrame(frame); | 630 DeliverFrame(frame); |
634 } | 631 } |
635 | 632 |
636 void GpuVideoDecoder::DeliverFrame( | 633 void GpuVideoDecoder::DeliverFrame( |
637 const scoped_refptr<VideoFrame>& frame) { | 634 const scoped_refptr<VideoFrame>& frame) { |
638 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 635 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
639 | 636 |
640 // During a pending vda->Reset(), we don't accumulate frames. Drop it on the | 637 // During a pending vda->Reset(), we don't accumulate frames. Drop it on the |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
827 } | 824 } |
828 return false; | 825 return false; |
829 } | 826 } |
830 | 827 |
831 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() | 828 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() |
832 const { | 829 const { |
833 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); | 830 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); |
834 } | 831 } |
835 | 832 |
836 } // namespace media | 833 } // namespace media |
OLD | NEW |