| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "content/renderer/media/rtc_video_decoder.h" | 5 #include "content/renderer/media/rtc_video_decoder.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/memory/ref_counted.h" | 9 #include "base/memory/ref_counted.h" |
| 10 #include "base/message_loop/message_loop_proxy.h" | 10 #include "base/message_loop/message_loop_proxy.h" |
| (...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 396 if (IsBufferAfterReset(picture.bitstream_buffer_id(), | 396 if (IsBufferAfterReset(picture.bitstream_buffer_id(), |
| 397 reset_bitstream_buffer_id_)) { | 397 reset_bitstream_buffer_id_)) { |
| 398 decode_complete_callback_->Decoded(decoded_image); | 398 decode_complete_callback_->Decoded(decoded_image); |
| 399 } | 399 } |
| 400 } | 400 } |
| 401 } | 401 } |
| 402 | 402 |
| 403 static void ReadPixelsSyncInner( | 403 static void ReadPixelsSyncInner( |
| 404 const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories, | 404 const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories, |
| 405 uint32 texture_id, | 405 uint32 texture_id, |
| 406 const gfx::Rect& visible_rect, | 406 const scoped_refptr<media::VideoFrame>& frame, |
| 407 const SkBitmap& pixels, | 407 const SkBitmap& pixels, |
| 408 base::WaitableEvent* event) { | 408 base::WaitableEvent* event) { |
| 409 factories->ReadPixels(texture_id, visible_rect, pixels); | 409 factories->ReadPixels(texture_id, frame, pixels); |
| 410 event->Signal(); | 410 event->Signal(); |
| 411 } | 411 } |
| 412 | 412 |
| 413 static void ReadPixelsSync( | 413 static void ReadPixelsSync( |
| 414 const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories, | 414 const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories, |
| 415 uint32 texture_id, | 415 uint32 texture_id, |
| 416 const gfx::Rect& visible_rect, | 416 const scoped_refptr<media::VideoFrame>& frame, |
| 417 const SkBitmap& pixels) { | 417 const SkBitmap& pixels) { |
| 418 base::WaitableEvent event(true, false); | 418 base::WaitableEvent event(true, false); |
| 419 if (!factories->GetTaskRunner()->PostTask(FROM_HERE, | 419 if (!factories->GetTaskRunner()->PostTask(FROM_HERE, |
| 420 base::Bind(&ReadPixelsSyncInner, | 420 base::Bind(&ReadPixelsSyncInner, |
| 421 factories, | 421 factories, |
| 422 texture_id, | 422 texture_id, |
| 423 visible_rect, | 423 frame, |
| 424 pixels, | 424 pixels, |
| 425 &event))) | 425 &event))) |
| 426 return; | 426 return; |
| 427 event.Wait(); | 427 event.Wait(); |
| 428 } | 428 } |
| 429 | 429 |
| 430 scoped_refptr<media::VideoFrame> RTCVideoDecoder::CreateVideoFrame( | 430 scoped_refptr<media::VideoFrame> RTCVideoDecoder::CreateVideoFrame( |
| 431 const media::Picture& picture, | 431 const media::Picture& picture, |
| 432 const media::PictureBuffer& pb, | 432 const media::PictureBuffer& pb, |
| 433 uint32_t timestamp, | 433 uint32_t timestamp, |
| 434 uint32_t width, | 434 uint32_t width, |
| 435 uint32_t height, | 435 uint32_t height, |
| 436 size_t size) { | 436 size_t size) { |
| 437 gfx::Rect visible_rect(width, height); | 437 gfx::Rect visible_rect(width, height); |
| 438 DCHECK(decoder_texture_target_); | 438 DCHECK(decoder_texture_target_); |
| 439 // Convert timestamp from 90KHz to ms. | 439 // Convert timestamp from 90KHz to ms. |
| 440 base::TimeDelta timestamp_ms = base::TimeDelta::FromInternalValue( | 440 base::TimeDelta timestamp_ms = base::TimeDelta::FromInternalValue( |
| 441 base::checked_cast<uint64_t>(timestamp) * 1000 / 90); | 441 base::checked_cast<uint64_t>(timestamp) * 1000 / 90); |
| 442 return media::VideoFrame::WrapNativeTexture( | 442 return media::VideoFrame::WrapNativeTexture( |
| 443 make_scoped_ptr(new gpu::MailboxHolder( | 443 make_scoped_ptr(new gpu::MailboxHolder( |
| 444 pb.texture_mailbox(), decoder_texture_target_, 0)), | 444 pb.texture_mailbox(), decoder_texture_target_, 0)), |
| 445 media::BindToCurrentLoop(base::Bind(&RTCVideoDecoder::ReusePictureBuffer, | 445 media::BindToCurrentLoop(base::Bind(&RTCVideoDecoder::ReusePictureBuffer, |
| 446 weak_this_, | 446 weak_this_, |
| 447 picture.picture_buffer_id())), | 447 picture.picture_buffer_id())), |
| 448 pb.size(), | 448 pb.size(), |
| 449 visible_rect, | 449 visible_rect, |
| 450 visible_rect.size(), | 450 visible_rect.size(), |
| 451 timestamp_ms, | 451 timestamp_ms, |
| 452 base::Bind(&ReadPixelsSync, factories_, pb.texture_id(), visible_rect)); | 452 base::Bind(&ReadPixelsSync, factories_, pb.texture_id())); |
| 453 } | 453 } |
| 454 | 454 |
| 455 void RTCVideoDecoder::NotifyEndOfBitstreamBuffer(int32 id) { | 455 void RTCVideoDecoder::NotifyEndOfBitstreamBuffer(int32 id) { |
| 456 DVLOG(3) << "NotifyEndOfBitstreamBuffer. id=" << id; | 456 DVLOG(3) << "NotifyEndOfBitstreamBuffer. id=" << id; |
| 457 DCHECK(vda_task_runner_->BelongsToCurrentThread()); | 457 DCHECK(vda_task_runner_->BelongsToCurrentThread()); |
| 458 | 458 |
| 459 std::map<int32, SHMBuffer*>::iterator it = | 459 std::map<int32, SHMBuffer*>::iterator it = |
| 460 bitstream_buffers_in_decoder_.find(id); | 460 bitstream_buffers_in_decoder_.find(id); |
| 461 if (it == bitstream_buffers_in_decoder_.end()) { | 461 if (it == bitstream_buffers_in_decoder_.end()) { |
| 462 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); | 462 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 633 | 633 |
| 634 void RTCVideoDecoder::ResetInternal() { | 634 void RTCVideoDecoder::ResetInternal() { |
| 635 DCHECK(vda_task_runner_->BelongsToCurrentThread()); | 635 DCHECK(vda_task_runner_->BelongsToCurrentThread()); |
| 636 DVLOG(2) << "ResetInternal"; | 636 DVLOG(2) << "ResetInternal"; |
| 637 if (vda_) | 637 if (vda_) |
| 638 vda_->Reset(); | 638 vda_->Reset(); |
| 639 } | 639 } |
| 640 | 640 |
| 641 void RTCVideoDecoder::ReusePictureBuffer( | 641 void RTCVideoDecoder::ReusePictureBuffer( |
| 642 int64 picture_buffer_id, | 642 int64 picture_buffer_id, |
| 643 scoped_ptr<gpu::MailboxHolder> mailbox_holder) { | 643 scoped_ptr<gpu::MailboxHolder> mailbox_holder, |
| 644 const std::vector<uint32>& release_sync_points) { |
| 644 DCHECK(vda_task_runner_->BelongsToCurrentThread()); | 645 DCHECK(vda_task_runner_->BelongsToCurrentThread()); |
| 645 DVLOG(3) << "ReusePictureBuffer. id=" << picture_buffer_id; | 646 DVLOG(3) << "ReusePictureBuffer. id=" << picture_buffer_id; |
| 646 | 647 |
| 647 if (!vda_) | 648 if (!vda_) |
| 648 return; | 649 return; |
| 649 | 650 |
| 650 CHECK(!picture_buffers_at_display_.empty()); | 651 CHECK(!picture_buffers_at_display_.empty()); |
| 651 | 652 |
| 652 size_t num_erased = picture_buffers_at_display_.erase(picture_buffer_id); | 653 size_t num_erased = picture_buffers_at_display_.erase(picture_buffer_id); |
| 653 DCHECK(num_erased); | 654 DCHECK(num_erased); |
| 654 | 655 |
| 655 std::map<int32, media::PictureBuffer>::iterator it = | 656 std::map<int32, media::PictureBuffer>::iterator it = |
| 656 assigned_picture_buffers_.find(picture_buffer_id); | 657 assigned_picture_buffers_.find(picture_buffer_id); |
| 657 | 658 |
| 658 if (it == assigned_picture_buffers_.end()) { | 659 if (it == assigned_picture_buffers_.end()) { |
| 659 // This picture was dismissed while in display, so we postponed deletion. | 660 // This picture was dismissed while in display, so we postponed deletion. |
| 660 it = dismissed_picture_buffers_.find(picture_buffer_id); | 661 it = dismissed_picture_buffers_.find(picture_buffer_id); |
| 661 DCHECK(it != dismissed_picture_buffers_.end()); | 662 DCHECK(it != dismissed_picture_buffers_.end()); |
| 662 factories_->DeleteTexture(it->second.texture_id()); | 663 factories_->DeleteTexture(it->second.texture_id()); |
| 663 dismissed_picture_buffers_.erase(it); | 664 dismissed_picture_buffers_.erase(it); |
| 664 return; | 665 return; |
| 665 } | 666 } |
| 666 | 667 |
| 667 factories_->WaitSyncPoint(mailbox_holder->sync_point); | 668 for (size_t i = 0; i < release_sync_points.size(); i++) |
| 669 factories_->WaitSyncPoint(release_sync_points[i]); |
| 668 | 670 |
| 669 vda_->ReusePictureBuffer(picture_buffer_id); | 671 vda_->ReusePictureBuffer(picture_buffer_id); |
| 670 } | 672 } |
| 671 | 673 |
| 672 void RTCVideoDecoder::CreateVDA(media::VideoCodecProfile profile, | 674 void RTCVideoDecoder::CreateVDA(media::VideoCodecProfile profile, |
| 673 base::WaitableEvent* waiter) { | 675 base::WaitableEvent* waiter) { |
| 674 DCHECK(vda_task_runner_->BelongsToCurrentThread()); | 676 DCHECK(vda_task_runner_->BelongsToCurrentThread()); |
| 675 vda_ = factories_->CreateVideoDecodeAccelerator(profile); | 677 vda_ = factories_->CreateVideoDecodeAccelerator(profile); |
| 676 if (vda_ && !vda_->Initialize(profile, this)) | 678 if (vda_ && !vda_->Initialize(profile, this)) |
| 677 vda_.release()->Destroy(); | 679 vda_.release()->Destroy(); |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 786 | 788 |
| 787 int32_t RTCVideoDecoder::RecordInitDecodeUMA(int32_t status) { | 789 int32_t RTCVideoDecoder::RecordInitDecodeUMA(int32_t status) { |
| 788 // Logging boolean is enough to know if HW decoding has been used. Also, | 790 // Logging boolean is enough to know if HW decoding has been used. Also, |
| 789 // InitDecode is less likely to return an error so enum is not used here. | 791 // InitDecode is less likely to return an error so enum is not used here. |
| 790 bool sample = (status == WEBRTC_VIDEO_CODEC_OK) ? true : false; | 792 bool sample = (status == WEBRTC_VIDEO_CODEC_OK) ? true : false; |
| 791 UMA_HISTOGRAM_BOOLEAN("Media.RTCVideoDecoderInitDecodeSuccess", sample); | 793 UMA_HISTOGRAM_BOOLEAN("Media.RTCVideoDecoderInitDecodeSuccess", sample); |
| 792 return status; | 794 return status; |
| 793 } | 795 } |
| 794 | 796 |
| 795 } // namespace content | 797 } // namespace content |
| OLD | NEW |