Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(132)

Side by Side Diff: media/filters/gpu_video_decoder.cc

Issue 1751323002: Allow multiple texture ids per picture buffer. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 DVLOG_IF(2, !success) << __FUNCTION__ << ": CDM not attached."; 258 DVLOG_IF(2, !success) << __FUNCTION__ << ": CDM not attached.";
259 DCHECK(!init_cb_.is_null()); 259 DCHECK(!init_cb_.is_null());
260 260
261 base::ResetAndReturn(&init_cb_).Run(success); 261 base::ResetAndReturn(&init_cb_).Run(success);
262 } 262 }
263 263
264 void GpuVideoDecoder::DestroyPictureBuffers(PictureBufferMap* buffers) { 264 void GpuVideoDecoder::DestroyPictureBuffers(PictureBufferMap* buffers) {
265 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 265 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
266 for (PictureBufferMap::iterator it = buffers->begin(); it != buffers->end(); 266 for (PictureBufferMap::iterator it = buffers->begin(); it != buffers->end();
267 ++it) { 267 ++it) {
268 factories_->DeleteTexture(it->second.texture_id()); 268 for (uint32_t id : it->second.texture_ids().ids) {
269 if (id)
270 factories_->DeleteTexture(id);
271 }
269 } 272 }
270 273
271 buffers->clear(); 274 buffers->clear();
272 } 275 }
273 276
274 void GpuVideoDecoder::DestroyVDA() { 277 void GpuVideoDecoder::DestroyVDA() {
275 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 278 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
276 279
277 vda_.reset(); 280 vda_.reset();
278 281
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 (!needs_all_picture_buffers_to_decode_ && available_pictures_ > 0) || 401 (!needs_all_picture_buffers_to_decode_ && available_pictures_ > 0) ||
399 available_pictures_ == 402 available_pictures_ ==
400 static_cast<int>(assigned_picture_buffers_.size()); 403 static_cast<int>(assigned_picture_buffers_.size());
401 } 404 }
402 405
403 int GpuVideoDecoder::GetMaxDecodeRequests() const { 406 int GpuVideoDecoder::GetMaxDecodeRequests() const {
404 return kMaxInFlightDecodes; 407 return kMaxInFlightDecodes;
405 } 408 }
406 409
407 void GpuVideoDecoder::ProvidePictureBuffers(uint32_t count, 410 void GpuVideoDecoder::ProvidePictureBuffers(uint32_t count,
411 uint32_t textures_per_buffer,
408 const gfx::Size& size, 412 const gfx::Size& size,
409 uint32_t texture_target) { 413 uint32_t texture_target) {
410 DVLOG(3) << "ProvidePictureBuffers(" << count << ", " 414 DVLOG(3) << "ProvidePictureBuffers(" << count << ", "
411 << size.width() << "x" << size.height() << ")"; 415 << size.width() << "x" << size.height() << ")";
412 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 416 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
413 417
414 std::vector<uint32_t> texture_ids; 418 std::vector<uint32_t> texture_ids;
415 std::vector<gpu::Mailbox> texture_mailboxes; 419 std::vector<gpu::Mailbox> texture_mailboxes;
416 decoder_texture_target_ = texture_target; 420 decoder_texture_target_ = texture_target;
417 if (!factories_->CreateTextures(count, 421 if (!factories_->CreateTextures(count * textures_per_buffer, size,
418 size, 422 &texture_ids, &texture_mailboxes,
419 &texture_ids,
420 &texture_mailboxes,
421 decoder_texture_target_)) { 423 decoder_texture_target_)) {
422 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); 424 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE);
423 return; 425 return;
424 } 426 }
425 DCHECK_EQ(count, texture_ids.size()); 427 DCHECK_EQ(count * textures_per_buffer, texture_ids.size());
426 DCHECK_EQ(count, texture_mailboxes.size()); 428 DCHECK_EQ(count * textures_per_buffer, texture_mailboxes.size());
427 429
428 if (!vda_) 430 if (!vda_)
429 return; 431 return;
430 432
431 std::vector<PictureBuffer> picture_buffers; 433 std::vector<PictureBuffer> picture_buffers;
432 for (size_t i = 0; i < texture_ids.size(); ++i) { 434 size_t index = 0;
433 picture_buffers.push_back(PictureBuffer( 435 for (size_t i = 0; i < count; ++i) {
434 next_picture_buffer_id_++, size, texture_ids[i], texture_mailboxes[i])); 436 PictureBuffer::TextureIds ids;
437 gpu::Mailbox mailboxes[PictureBuffer::kMaxPlanes];
438 for (size_t j = 0; j < textures_per_buffer; j++) {
439 ids.ids[j] = texture_ids[index];
440 mailboxes[j] = texture_mailboxes[index];
441 index++;
442 }
443
444 picture_buffers.push_back(
445 PictureBuffer(next_picture_buffer_id_++, size, ids, mailboxes));
435 bool inserted = assigned_picture_buffers_.insert(std::make_pair( 446 bool inserted = assigned_picture_buffers_.insert(std::make_pair(
436 picture_buffers.back().id(), picture_buffers.back())).second; 447 picture_buffers.back().id(), picture_buffers.back())).second;
437 DCHECK(inserted); 448 DCHECK(inserted);
438 } 449 }
439 450
440 available_pictures_ += count; 451 available_pictures_ += count;
441 452
442 vda_->AssignPictureBuffers(picture_buffers); 453 vda_->AssignPictureBuffers(picture_buffers);
443 } 454 }
444 455
445 void GpuVideoDecoder::DismissPictureBuffer(int32_t id) { 456 void GpuVideoDecoder::DismissPictureBuffer(int32_t id) {
446 DVLOG(3) << "DismissPictureBuffer(" << id << ")"; 457 DVLOG(3) << "DismissPictureBuffer(" << id << ")";
447 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 458 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
448 459
449 PictureBufferMap::iterator it = assigned_picture_buffers_.find(id); 460 PictureBufferMap::iterator it = assigned_picture_buffers_.find(id);
450 if (it == assigned_picture_buffers_.end()) { 461 if (it == assigned_picture_buffers_.end()) {
451 NOTREACHED() << "Missing picture buffer: " << id; 462 NOTREACHED() << "Missing picture buffer: " << id;
452 return; 463 return;
453 } 464 }
454 465
455 PictureBuffer buffer_to_dismiss = it->second; 466 PictureBuffer buffer_to_dismiss = it->second;
456 assigned_picture_buffers_.erase(it); 467 assigned_picture_buffers_.erase(it);
457 468
458 if (!picture_buffers_at_display_.count(id)) { 469 if (!picture_buffers_at_display_.count(id)) {
459 // We can delete the texture immediately as it's not being displayed. 470 // We can delete the texture immediately as it's not being displayed.
460 factories_->DeleteTexture(buffer_to_dismiss.texture_id()); 471 for (uint32_t id : buffer_to_dismiss.texture_ids().ids) {
472 if (id)
473 factories_->DeleteTexture(id);
474 }
461 CHECK_GT(available_pictures_, 0); 475 CHECK_GT(available_pictures_, 0);
462 --available_pictures_; 476 --available_pictures_;
463 } 477 }
464 // Not destroying a texture in display in |picture_buffers_at_display_|. 478 // Not destroying a texture in display in |picture_buffers_at_display_|.
465 // Postpone deletion until after it's returned to us. 479 // Postpone deletion until after it's returned to us.
466 } 480 }
467 481
468 void GpuVideoDecoder::PictureReady(const media::Picture& picture) { 482 void GpuVideoDecoder::PictureReady(const media::Picture& picture) {
469 DVLOG(3) << "PictureReady()"; 483 DVLOG(3) << "PictureReady()";
470 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 484 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 << " is larger than coded size " << pb.size().ToString(); 521 << " is larger than coded size " << pb.size().ToString();
508 visible_rect = gfx::Rect(pb.size()); 522 visible_rect = gfx::Rect(pb.size());
509 } 523 }
510 524
511 DCHECK(decoder_texture_target_); 525 DCHECK(decoder_texture_target_);
512 526
513 bool opaque = IsOpaque(config_.format()); 527 bool opaque = IsOpaque(config_.format());
514 528
515 scoped_refptr<VideoFrame> frame(VideoFrame::WrapNativeTexture( 529 scoped_refptr<VideoFrame> frame(VideoFrame::WrapNativeTexture(
516 opaque ? PIXEL_FORMAT_XRGB : PIXEL_FORMAT_ARGB, 530 opaque ? PIXEL_FORMAT_XRGB : PIXEL_FORMAT_ARGB,
517 gpu::MailboxHolder(pb.texture_mailbox(), gpu::SyncToken(), 531 gpu::MailboxHolder(pb.texture_mailbox(0), gpu::SyncToken(),
518 decoder_texture_target_), 532 decoder_texture_target_),
519 BindToCurrentLoop(base::Bind( 533 BindToCurrentLoop(base::Bind(
520 &GpuVideoDecoder::ReleaseMailbox, weak_factory_.GetWeakPtr(), 534 &GpuVideoDecoder::ReleaseMailbox, weak_factory_.GetWeakPtr(),
521 factories_, picture.picture_buffer_id(), pb.texture_id())), 535 factories_, picture.picture_buffer_id(), pb.texture_ids())),
522 pb.size(), visible_rect, natural_size, timestamp)); 536 pb.size(), visible_rect, natural_size, timestamp));
523 if (!frame) { 537 if (!frame) {
524 DLOG(ERROR) << "Create frame failed for: " << picture.picture_buffer_id(); 538 DLOG(ERROR) << "Create frame failed for: " << picture.picture_buffer_id();
525 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); 539 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE);
526 return; 540 return;
527 } 541 }
528 if (picture.allow_overlay()) 542 if (picture.allow_overlay())
529 frame->metadata()->SetBoolean(VideoFrameMetadata::ALLOW_OVERLAY, true); 543 frame->metadata()->SetBoolean(VideoFrameMetadata::ALLOW_OVERLAY, true);
530 CHECK_GT(available_pictures_, 0); 544 CHECK_GT(available_pictures_, 0);
531 --available_pictures_; 545 --available_pictures_;
546
532 bool inserted = 547 bool inserted =
533 picture_buffers_at_display_.insert(std::make_pair( 548 picture_buffers_at_display_
534 picture.picture_buffer_id(), 549 .insert(std::make_pair(picture.picture_buffer_id(), pb.texture_ids()))
535 pb.texture_id())).second; 550 .second;
536 DCHECK(inserted); 551 DCHECK(inserted);
537 552
538 DeliverFrame(frame); 553 DeliverFrame(frame);
539 } 554 }
540 555
541 void GpuVideoDecoder::DeliverFrame( 556 void GpuVideoDecoder::DeliverFrame(
542 const scoped_refptr<VideoFrame>& frame) { 557 const scoped_refptr<VideoFrame>& frame) {
543 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 558 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
544 559
545 // During a pending vda->Reset(), we don't accumulate frames. Drop it on the 560 // During a pending vda->Reset(), we don't accumulate frames. Drop it on the
546 // floor and return. 561 // floor and return.
547 if (!pending_reset_cb_.is_null()) 562 if (!pending_reset_cb_.is_null())
548 return; 563 return;
549 564
550 output_cb_.Run(frame); 565 output_cb_.Run(frame);
551 } 566 }
552 567
553 // static 568 // static
554 void GpuVideoDecoder::ReleaseMailbox( 569 void GpuVideoDecoder::ReleaseMailbox(
555 base::WeakPtr<GpuVideoDecoder> decoder, 570 base::WeakPtr<GpuVideoDecoder> decoder,
556 media::GpuVideoAcceleratorFactories* factories, 571 media::GpuVideoAcceleratorFactories* factories,
557 int64_t picture_buffer_id, 572 int64_t picture_buffer_id,
558 uint32_t texture_id, 573 PictureBuffer::TextureIds ids,
559 const gpu::SyncToken& release_sync_token) { 574 const gpu::SyncToken& release_sync_token) {
560 DCHECK(factories->GetTaskRunner()->BelongsToCurrentThread()); 575 DCHECK(factories->GetTaskRunner()->BelongsToCurrentThread());
561 factories->WaitSyncToken(release_sync_token); 576 factories->WaitSyncToken(release_sync_token);
562 577
563 if (decoder) { 578 if (decoder) {
564 decoder->ReusePictureBuffer(picture_buffer_id); 579 decoder->ReusePictureBuffer(picture_buffer_id);
565 return; 580 return;
566 } 581 }
567 // It's the last chance to delete the texture after display, 582 // It's the last chance to delete the texture after display,
568 // because GpuVideoDecoder was destructed. 583 // because GpuVideoDecoder was destructed.
569 factories->DeleteTexture(texture_id); 584 for (uint32_t id : ids.ids) {
585 if (id)
586 factories->DeleteTexture(id);
587 }
570 } 588 }
571 589
572 void GpuVideoDecoder::ReusePictureBuffer(int64_t picture_buffer_id) { 590 void GpuVideoDecoder::ReusePictureBuffer(int64_t picture_buffer_id) {
573 DVLOG(3) << "ReusePictureBuffer(" << picture_buffer_id << ")"; 591 DVLOG(3) << "ReusePictureBuffer(" << picture_buffer_id << ")";
574 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 592 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
575 593
576 DCHECK(!picture_buffers_at_display_.empty()); 594 DCHECK(!picture_buffers_at_display_.empty());
577 PictureBufferTextureMap::iterator display_iterator = 595 PictureBufferTextureMap::iterator display_iterator =
578 picture_buffers_at_display_.find(picture_buffer_id); 596 picture_buffers_at_display_.find(picture_buffer_id);
579 uint32_t texture_id = display_iterator->second; 597 PictureBuffer::TextureIds ids = display_iterator->second;
580 DCHECK(display_iterator != picture_buffers_at_display_.end()); 598 DCHECK(display_iterator != picture_buffers_at_display_.end());
581 picture_buffers_at_display_.erase(display_iterator); 599 picture_buffers_at_display_.erase(display_iterator);
582 600
583 if (!assigned_picture_buffers_.count(picture_buffer_id)) { 601 if (!assigned_picture_buffers_.count(picture_buffer_id)) {
584 // This picture was dismissed while in display, so we postponed deletion. 602 // This picture was dismissed while in display, so we postponed deletion.
585 factories_->DeleteTexture(texture_id); 603 for (uint32_t id : ids.ids) {
604 if (id)
605 factories_->DeleteTexture(id);
606 }
586 return; 607 return;
587 } 608 }
588 609
589 ++available_pictures_; 610 ++available_pictures_;
590 611
591 // DestroyVDA() might already have been called. 612 // DestroyVDA() might already have been called.
592 if (vda_) 613 if (vda_)
593 vda_->ReusePictureBuffer(picture_buffer_id); 614 vda_->ReusePictureBuffer(picture_buffer_id);
594 } 615 }
595 616
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
719 } 740 }
720 return false; 741 return false;
721 } 742 }
722 743
723 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() 744 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent()
724 const { 745 const {
725 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); 746 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread());
726 } 747 }
727 748
728 } // namespace media 749 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/gpu_video_decoder.h ('k') | media/video/picture.h » ('j') | media/video/picture.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698