| 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 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 | 45 |
| 46 GpuVideoDecoder::PendingDecoderBuffer::PendingDecoderBuffer( | 46 GpuVideoDecoder::PendingDecoderBuffer::PendingDecoderBuffer( |
| 47 SHMBuffer* s, | 47 SHMBuffer* s, |
| 48 const scoped_refptr<DecoderBuffer>& b, | 48 const scoped_refptr<DecoderBuffer>& b, |
| 49 const DecodeCB& done_cb) | 49 const DecodeCB& done_cb) |
| 50 : shm_buffer(s), buffer(b), done_cb(done_cb) { | 50 : shm_buffer(s), buffer(b), done_cb(done_cb) { |
| 51 } | 51 } |
| 52 | 52 |
| 53 GpuVideoDecoder::PendingDecoderBuffer::~PendingDecoderBuffer() {} | 53 GpuVideoDecoder::PendingDecoderBuffer::~PendingDecoderBuffer() {} |
| 54 | 54 |
| 55 GpuVideoDecoder::BufferData::BufferData( | 55 GpuVideoDecoder::BufferData::BufferData(int32_t bbid, |
| 56 int32 bbid, base::TimeDelta ts, const gfx::Rect& vr, const gfx::Size& ns) | 56 base::TimeDelta ts, |
| 57 : bitstream_buffer_id(bbid), timestamp(ts), visible_rect(vr), | 57 const gfx::Rect& vr, |
| 58 natural_size(ns) { | 58 const gfx::Size& ns) |
| 59 } | 59 : bitstream_buffer_id(bbid), |
| 60 timestamp(ts), |
| 61 visible_rect(vr), |
| 62 natural_size(ns) {} |
| 60 | 63 |
| 61 GpuVideoDecoder::BufferData::~BufferData() {} | 64 GpuVideoDecoder::BufferData::~BufferData() {} |
| 62 | 65 |
| 63 GpuVideoDecoder::GpuVideoDecoder(GpuVideoAcceleratorFactories* factories) | 66 GpuVideoDecoder::GpuVideoDecoder(GpuVideoAcceleratorFactories* factories) |
| 64 : needs_bitstream_conversion_(false), | 67 : needs_bitstream_conversion_(false), |
| 65 factories_(factories), | 68 factories_(factories), |
| 66 state_(kNormal), | 69 state_(kNormal), |
| 67 decoder_texture_target_(0), | 70 decoder_texture_target_(0), |
| 68 next_picture_buffer_id_(0), | 71 next_picture_buffer_id_(0), |
| 69 next_bitstream_buffer_id_(0), | 72 next_bitstream_buffer_id_(0), |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 // Why this value? Because why not. avformat.h:MAX_REORDER_DELAY is 16, but | 334 // Why this value? Because why not. avformat.h:MAX_REORDER_DELAY is 16, but |
| 332 // that's too small for some pathological B-frame test videos. The cost of | 335 // that's too small for some pathological B-frame test videos. The cost of |
| 333 // using too-high a value is low (192 bits per extra slot). | 336 // using too-high a value is low (192 bits per extra slot). |
| 334 static const size_t kMaxInputBufferDataSize = 128; | 337 static const size_t kMaxInputBufferDataSize = 128; |
| 335 // Pop from the back of the list, because that's the oldest and least likely | 338 // Pop from the back of the list, because that's the oldest and least likely |
| 336 // to be useful in the future data. | 339 // to be useful in the future data. |
| 337 if (input_buffer_data_.size() > kMaxInputBufferDataSize) | 340 if (input_buffer_data_.size() > kMaxInputBufferDataSize) |
| 338 input_buffer_data_.pop_back(); | 341 input_buffer_data_.pop_back(); |
| 339 } | 342 } |
| 340 | 343 |
| 341 void GpuVideoDecoder::GetBufferData(int32 id, base::TimeDelta* timestamp, | 344 void GpuVideoDecoder::GetBufferData(int32_t id, |
| 345 base::TimeDelta* timestamp, |
| 342 gfx::Rect* visible_rect, | 346 gfx::Rect* visible_rect, |
| 343 gfx::Size* natural_size) { | 347 gfx::Size* natural_size) { |
| 344 for (std::list<BufferData>::const_iterator it = | 348 for (std::list<BufferData>::const_iterator it = |
| 345 input_buffer_data_.begin(); it != input_buffer_data_.end(); | 349 input_buffer_data_.begin(); it != input_buffer_data_.end(); |
| 346 ++it) { | 350 ++it) { |
| 347 if (it->bitstream_buffer_id != id) | 351 if (it->bitstream_buffer_id != id) |
| 348 continue; | 352 continue; |
| 349 *timestamp = it->timestamp; | 353 *timestamp = it->timestamp; |
| 350 *visible_rect = it->visible_rect; | 354 *visible_rect = it->visible_rect; |
| 351 *natural_size = it->natural_size; | 355 *natural_size = it->natural_size; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 365 0 || // Decode() will ProvidePictureBuffers(). | 369 0 || // Decode() will ProvidePictureBuffers(). |
| 366 (!needs_all_picture_buffers_to_decode_ && available_pictures_ > 0) || | 370 (!needs_all_picture_buffers_to_decode_ && available_pictures_ > 0) || |
| 367 available_pictures_ == | 371 available_pictures_ == |
| 368 static_cast<int>(assigned_picture_buffers_.size()); | 372 static_cast<int>(assigned_picture_buffers_.size()); |
| 369 } | 373 } |
| 370 | 374 |
| 371 int GpuVideoDecoder::GetMaxDecodeRequests() const { | 375 int GpuVideoDecoder::GetMaxDecodeRequests() const { |
| 372 return kMaxInFlightDecodes; | 376 return kMaxInFlightDecodes; |
| 373 } | 377 } |
| 374 | 378 |
| 375 void GpuVideoDecoder::ProvidePictureBuffers(uint32 count, | 379 void GpuVideoDecoder::ProvidePictureBuffers(uint32_t count, |
| 376 const gfx::Size& size, | 380 const gfx::Size& size, |
| 377 uint32 texture_target) { | 381 uint32_t texture_target) { |
| 378 DVLOG(3) << "ProvidePictureBuffers(" << count << ", " | 382 DVLOG(3) << "ProvidePictureBuffers(" << count << ", " |
| 379 << size.width() << "x" << size.height() << ")"; | 383 << size.width() << "x" << size.height() << ")"; |
| 380 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 384 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
| 381 | 385 |
| 382 std::vector<uint32> texture_ids; | 386 std::vector<uint32_t> texture_ids; |
| 383 std::vector<gpu::Mailbox> texture_mailboxes; | 387 std::vector<gpu::Mailbox> texture_mailboxes; |
| 384 decoder_texture_target_ = texture_target; | 388 decoder_texture_target_ = texture_target; |
| 385 if (!factories_->CreateTextures(count, | 389 if (!factories_->CreateTextures(count, |
| 386 size, | 390 size, |
| 387 &texture_ids, | 391 &texture_ids, |
| 388 &texture_mailboxes, | 392 &texture_mailboxes, |
| 389 decoder_texture_target_)) { | 393 decoder_texture_target_)) { |
| 390 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); | 394 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); |
| 391 return; | 395 return; |
| 392 } | 396 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 403 bool inserted = assigned_picture_buffers_.insert(std::make_pair( | 407 bool inserted = assigned_picture_buffers_.insert(std::make_pair( |
| 404 picture_buffers.back().id(), picture_buffers.back())).second; | 408 picture_buffers.back().id(), picture_buffers.back())).second; |
| 405 DCHECK(inserted); | 409 DCHECK(inserted); |
| 406 } | 410 } |
| 407 | 411 |
| 408 available_pictures_ += count; | 412 available_pictures_ += count; |
| 409 | 413 |
| 410 vda_->AssignPictureBuffers(picture_buffers); | 414 vda_->AssignPictureBuffers(picture_buffers); |
| 411 } | 415 } |
| 412 | 416 |
| 413 void GpuVideoDecoder::DismissPictureBuffer(int32 id) { | 417 void GpuVideoDecoder::DismissPictureBuffer(int32_t id) { |
| 414 DVLOG(3) << "DismissPictureBuffer(" << id << ")"; | 418 DVLOG(3) << "DismissPictureBuffer(" << id << ")"; |
| 415 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 419 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
| 416 | 420 |
| 417 PictureBufferMap::iterator it = assigned_picture_buffers_.find(id); | 421 PictureBufferMap::iterator it = assigned_picture_buffers_.find(id); |
| 418 if (it == assigned_picture_buffers_.end()) { | 422 if (it == assigned_picture_buffers_.end()) { |
| 419 NOTREACHED() << "Missing picture buffer: " << id; | 423 NOTREACHED() << "Missing picture buffer: " << id; |
| 420 return; | 424 return; |
| 421 } | 425 } |
| 422 | 426 |
| 423 PictureBuffer buffer_to_dismiss = it->second; | 427 PictureBuffer buffer_to_dismiss = it->second; |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 504 if (!pending_reset_cb_.is_null()) | 508 if (!pending_reset_cb_.is_null()) |
| 505 return; | 509 return; |
| 506 | 510 |
| 507 output_cb_.Run(frame); | 511 output_cb_.Run(frame); |
| 508 } | 512 } |
| 509 | 513 |
| 510 // static | 514 // static |
| 511 void GpuVideoDecoder::ReleaseMailbox( | 515 void GpuVideoDecoder::ReleaseMailbox( |
| 512 base::WeakPtr<GpuVideoDecoder> decoder, | 516 base::WeakPtr<GpuVideoDecoder> decoder, |
| 513 media::GpuVideoAcceleratorFactories* factories, | 517 media::GpuVideoAcceleratorFactories* factories, |
| 514 int64 picture_buffer_id, | 518 int64_t picture_buffer_id, |
| 515 uint32 texture_id, | 519 uint32_t texture_id, |
| 516 const gpu::SyncToken& release_sync_token) { | 520 const gpu::SyncToken& release_sync_token) { |
| 517 DCHECK(factories->GetTaskRunner()->BelongsToCurrentThread()); | 521 DCHECK(factories->GetTaskRunner()->BelongsToCurrentThread()); |
| 518 factories->WaitSyncToken(release_sync_token); | 522 factories->WaitSyncToken(release_sync_token); |
| 519 | 523 |
| 520 if (decoder) { | 524 if (decoder) { |
| 521 decoder->ReusePictureBuffer(picture_buffer_id); | 525 decoder->ReusePictureBuffer(picture_buffer_id); |
| 522 return; | 526 return; |
| 523 } | 527 } |
| 524 // It's the last chance to delete the texture after display, | 528 // It's the last chance to delete the texture after display, |
| 525 // because GpuVideoDecoder was destructed. | 529 // because GpuVideoDecoder was destructed. |
| 526 factories->DeleteTexture(texture_id); | 530 factories->DeleteTexture(texture_id); |
| 527 } | 531 } |
| 528 | 532 |
| 529 void GpuVideoDecoder::ReusePictureBuffer(int64 picture_buffer_id) { | 533 void GpuVideoDecoder::ReusePictureBuffer(int64_t picture_buffer_id) { |
| 530 DVLOG(3) << "ReusePictureBuffer(" << picture_buffer_id << ")"; | 534 DVLOG(3) << "ReusePictureBuffer(" << picture_buffer_id << ")"; |
| 531 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 535 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
| 532 | 536 |
| 533 DCHECK(!picture_buffers_at_display_.empty()); | 537 DCHECK(!picture_buffers_at_display_.empty()); |
| 534 PictureBufferTextureMap::iterator display_iterator = | 538 PictureBufferTextureMap::iterator display_iterator = |
| 535 picture_buffers_at_display_.find(picture_buffer_id); | 539 picture_buffers_at_display_.find(picture_buffer_id); |
| 536 uint32 texture_id = display_iterator->second; | 540 uint32_t texture_id = display_iterator->second; |
| 537 DCHECK(display_iterator != picture_buffers_at_display_.end()); | 541 DCHECK(display_iterator != picture_buffers_at_display_.end()); |
| 538 picture_buffers_at_display_.erase(display_iterator); | 542 picture_buffers_at_display_.erase(display_iterator); |
| 539 | 543 |
| 540 if (!assigned_picture_buffers_.count(picture_buffer_id)) { | 544 if (!assigned_picture_buffers_.count(picture_buffer_id)) { |
| 541 // This picture was dismissed while in display, so we postponed deletion. | 545 // This picture was dismissed while in display, so we postponed deletion. |
| 542 factories_->DeleteTexture(texture_id); | 546 factories_->DeleteTexture(texture_id); |
| 543 return; | 547 return; |
| 544 } | 548 } |
| 545 | 549 |
| 546 ++available_pictures_; | 550 ++available_pictures_; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 566 scoped_ptr<SHMBuffer> ret(available_shm_segments_.back()); | 570 scoped_ptr<SHMBuffer> ret(available_shm_segments_.back()); |
| 567 available_shm_segments_.pop_back(); | 571 available_shm_segments_.pop_back(); |
| 568 return ret.Pass(); | 572 return ret.Pass(); |
| 569 } | 573 } |
| 570 | 574 |
| 571 void GpuVideoDecoder::PutSHM(scoped_ptr<SHMBuffer> shm_buffer) { | 575 void GpuVideoDecoder::PutSHM(scoped_ptr<SHMBuffer> shm_buffer) { |
| 572 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 576 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
| 573 available_shm_segments_.push_back(shm_buffer.release()); | 577 available_shm_segments_.push_back(shm_buffer.release()); |
| 574 } | 578 } |
| 575 | 579 |
| 576 void GpuVideoDecoder::NotifyEndOfBitstreamBuffer(int32 id) { | 580 void GpuVideoDecoder::NotifyEndOfBitstreamBuffer(int32_t id) { |
| 577 DVLOG(3) << "NotifyEndOfBitstreamBuffer(" << id << ")"; | 581 DVLOG(3) << "NotifyEndOfBitstreamBuffer(" << id << ")"; |
| 578 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 582 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
| 579 | 583 |
| 580 std::map<int32, PendingDecoderBuffer>::iterator it = | 584 std::map<int32_t, PendingDecoderBuffer>::iterator it = |
| 581 bitstream_buffers_in_decoder_.find(id); | 585 bitstream_buffers_in_decoder_.find(id); |
| 582 if (it == bitstream_buffers_in_decoder_.end()) { | 586 if (it == bitstream_buffers_in_decoder_.end()) { |
| 583 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); | 587 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); |
| 584 NOTREACHED() << "Missing bitstream buffer: " << id; | 588 NOTREACHED() << "Missing bitstream buffer: " << id; |
| 585 return; | 589 return; |
| 586 } | 590 } |
| 587 | 591 |
| 588 PutSHM(make_scoped_ptr(it->second.shm_buffer)); | 592 PutSHM(make_scoped_ptr(it->second.shm_buffer)); |
| 589 it->second.done_cb.Run(state_ == kError ? kDecodeError : kOk); | 593 it->second.done_cb.Run(state_ == kError ? kDecodeError : kOk); |
| 590 bitstream_buffers_in_decoder_.erase(it); | 594 bitstream_buffers_in_decoder_.erase(it); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 603 if (!cdm_attached_cb_.is_null()) | 607 if (!cdm_attached_cb_.is_null()) |
| 604 base::ResetAndReturn(&cdm_attached_cb_).Run(false); | 608 base::ResetAndReturn(&cdm_attached_cb_).Run(false); |
| 605 if (!init_cb_.is_null()) | 609 if (!init_cb_.is_null()) |
| 606 base::ResetAndReturn(&init_cb_).Run(false); | 610 base::ResetAndReturn(&init_cb_).Run(false); |
| 607 | 611 |
| 608 for (size_t i = 0; i < available_shm_segments_.size(); ++i) { | 612 for (size_t i = 0; i < available_shm_segments_.size(); ++i) { |
| 609 delete available_shm_segments_[i]; | 613 delete available_shm_segments_[i]; |
| 610 } | 614 } |
| 611 available_shm_segments_.clear(); | 615 available_shm_segments_.clear(); |
| 612 | 616 |
| 613 for (std::map<int32, PendingDecoderBuffer>::iterator it = | 617 for (std::map<int32_t, PendingDecoderBuffer>::iterator it = |
| 614 bitstream_buffers_in_decoder_.begin(); | 618 bitstream_buffers_in_decoder_.begin(); |
| 615 it != bitstream_buffers_in_decoder_.end(); ++it) { | 619 it != bitstream_buffers_in_decoder_.end(); ++it) { |
| 616 delete it->second.shm_buffer; | 620 delete it->second.shm_buffer; |
| 617 it->second.done_cb.Run(kAborted); | 621 it->second.done_cb.Run(kAborted); |
| 618 } | 622 } |
| 619 bitstream_buffers_in_decoder_.clear(); | 623 bitstream_buffers_in_decoder_.clear(); |
| 620 | 624 |
| 621 if (!pending_reset_cb_.is_null()) | 625 if (!pending_reset_cb_.is_null()) |
| 622 base::ResetAndReturn(&pending_reset_cb_).Run(); | 626 base::ResetAndReturn(&pending_reset_cb_).Run(); |
| 623 } | 627 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 668 } | 672 } |
| 669 return false; | 673 return false; |
| 670 } | 674 } |
| 671 | 675 |
| 672 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() | 676 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() |
| 673 const { | 677 const { |
| 674 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); | 678 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); |
| 675 } | 679 } |
| 676 | 680 |
| 677 } // namespace media | 681 } // namespace media |
| OLD | NEW |