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