OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/pepper/video_decoder_shim.h" | 5 #include "content/renderer/pepper/video_decoder_shim.h" |
6 | 6 |
7 #include <GLES2/gl2.h> | 7 #include <GLES2/gl2.h> |
8 #include <GLES2/gl2ext.h> | 8 #include <GLES2/gl2ext.h> |
9 #include <GLES2/gl2extchromium.h> | 9 #include <GLES2/gl2extchromium.h> |
10 | 10 |
(...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
620 | 620 |
621 // DecoderImpl runs the underlying VideoDecoder on the media thread, receiving | 621 // DecoderImpl runs the underlying VideoDecoder on the media thread, receiving |
622 // calls from the VideoDecodeShim on the main thread and sending results back. | 622 // calls from the VideoDecodeShim on the main thread and sending results back. |
623 // This class is constructed on the main thread, but used and destructed on the | 623 // This class is constructed on the main thread, but used and destructed on the |
624 // media thread. | 624 // media thread. |
625 class VideoDecoderShim::DecoderImpl { | 625 class VideoDecoderShim::DecoderImpl { |
626 public: | 626 public: |
627 explicit DecoderImpl(const base::WeakPtr<VideoDecoderShim>& proxy); | 627 explicit DecoderImpl(const base::WeakPtr<VideoDecoderShim>& proxy); |
628 ~DecoderImpl(); | 628 ~DecoderImpl(); |
629 | 629 |
630 void Initialize(media::VideoDecoderConfig config); | 630 void Initialize(media::VideoDecoderConfig config, uint32_t min_picture_count); |
631 void Decode(uint32_t decode_id, scoped_refptr<media::DecoderBuffer> buffer); | 631 void Decode(uint32_t decode_id, scoped_refptr<media::DecoderBuffer> buffer); |
632 void Reset(); | 632 void Reset(); |
633 void Stop(); | 633 void Stop(); |
634 | 634 |
635 private: | 635 private: |
636 void OnInitDone(bool success); | 636 void OnInitDone(uint32_t min_picture_count, bool success); |
637 void DoDecode(); | 637 void DoDecode(); |
638 void OnDecodeComplete(media::VideoDecoder::Status status); | 638 void OnDecodeComplete(media::VideoDecoder::Status status); |
639 void OnOutputComplete(const scoped_refptr<media::VideoFrame>& frame); | 639 void OnOutputComplete(const scoped_refptr<media::VideoFrame>& frame); |
640 void OnResetComplete(); | 640 void OnResetComplete(); |
641 | 641 |
642 // WeakPtr is bound to main_message_loop_. Use only in shim callbacks. | 642 // WeakPtr is bound to main_message_loop_. Use only in shim callbacks. |
643 base::WeakPtr<VideoDecoderShim> shim_; | 643 base::WeakPtr<VideoDecoderShim> shim_; |
644 scoped_ptr<media::VideoDecoder> decoder_; | 644 scoped_ptr<media::VideoDecoder> decoder_; |
645 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; | 645 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; |
646 // Queue of decodes waiting for the decoder. | 646 // Queue of decodes waiting for the decoder. |
(...skipping 17 matching lines...) Expand all Loading... |
664 awaiting_decoder_(false), | 664 awaiting_decoder_(false), |
665 decode_id_(0), | 665 decode_id_(0), |
666 weak_ptr_factory_(this) { | 666 weak_ptr_factory_(this) { |
667 } | 667 } |
668 | 668 |
669 VideoDecoderShim::DecoderImpl::~DecoderImpl() { | 669 VideoDecoderShim::DecoderImpl::~DecoderImpl() { |
670 DCHECK(pending_decodes_.empty()); | 670 DCHECK(pending_decodes_.empty()); |
671 } | 671 } |
672 | 672 |
673 void VideoDecoderShim::DecoderImpl::Initialize( | 673 void VideoDecoderShim::DecoderImpl::Initialize( |
674 media::VideoDecoderConfig config) { | 674 media::VideoDecoderConfig config, uint32_t min_picture_count) { |
675 DCHECK(!decoder_); | 675 DCHECK(!decoder_); |
676 #if !defined(MEDIA_DISABLE_LIBVPX) | 676 #if !defined(MEDIA_DISABLE_LIBVPX) |
677 if (config.codec() == media::kCodecVP9) { | 677 if (config.codec() == media::kCodecVP9) { |
678 decoder_.reset( | 678 decoder_.reset( |
679 new media::VpxVideoDecoder(base::ThreadTaskRunnerHandle::Get())); | 679 new media::VpxVideoDecoder(base::ThreadTaskRunnerHandle::Get())); |
680 } else | 680 } else |
681 #endif | 681 #endif |
682 { | 682 { |
683 scoped_ptr<media::FFmpegVideoDecoder> ffmpeg_video_decoder( | 683 scoped_ptr<media::FFmpegVideoDecoder> ffmpeg_video_decoder( |
684 new media::FFmpegVideoDecoder(base::ThreadTaskRunnerHandle::Get())); | 684 new media::FFmpegVideoDecoder(base::ThreadTaskRunnerHandle::Get())); |
685 ffmpeg_video_decoder->set_decode_nalus(true); | 685 ffmpeg_video_decoder->set_decode_nalus(true); |
686 decoder_ = ffmpeg_video_decoder.Pass(); | 686 decoder_ = ffmpeg_video_decoder.Pass(); |
687 } | 687 } |
688 | 688 |
689 // VpxVideoDecoder and FFmpegVideoDecoder support only one pending Decode() | 689 // VpxVideoDecoder and FFmpegVideoDecoder support only one pending Decode() |
690 // request. | 690 // request. |
691 DCHECK_EQ(decoder_->GetMaxDecodeRequests(), 1); | 691 DCHECK_EQ(decoder_->GetMaxDecodeRequests(), 1); |
692 | 692 |
693 decoder_->Initialize( | 693 decoder_->Initialize( |
694 config, true /* low_delay */, | 694 config, true /* low_delay */, |
695 base::Bind(&VideoDecoderShim::DecoderImpl::OnInitDone, | 695 base::Bind(&VideoDecoderShim::DecoderImpl::OnInitDone, |
696 weak_ptr_factory_.GetWeakPtr()), | 696 weak_ptr_factory_.GetWeakPtr(), min_picture_count), |
697 base::Bind(&VideoDecoderShim::DecoderImpl::OnOutputComplete, | 697 base::Bind(&VideoDecoderShim::DecoderImpl::OnOutputComplete, |
698 weak_ptr_factory_.GetWeakPtr())); | 698 weak_ptr_factory_.GetWeakPtr())); |
699 } | 699 } |
700 | 700 |
701 void VideoDecoderShim::DecoderImpl::Decode( | 701 void VideoDecoderShim::DecoderImpl::Decode( |
702 uint32_t decode_id, | 702 uint32_t decode_id, |
703 scoped_refptr<media::DecoderBuffer> buffer) { | 703 scoped_refptr<media::DecoderBuffer> buffer) { |
704 DCHECK(decoder_); | 704 DCHECK(decoder_); |
705 pending_decodes_.push(PendingDecode(decode_id, buffer)); | 705 pending_decodes_.push(PendingDecode(decode_id, buffer)); |
706 DoDecode(); | 706 DoDecode(); |
(...skipping 17 matching lines...) Expand all Loading... |
724 void VideoDecoderShim::DecoderImpl::Stop() { | 724 void VideoDecoderShim::DecoderImpl::Stop() { |
725 DCHECK(decoder_); | 725 DCHECK(decoder_); |
726 // Clear pending decodes now. We don't want OnDecodeComplete to call DoDecode | 726 // Clear pending decodes now. We don't want OnDecodeComplete to call DoDecode |
727 // again. | 727 // again. |
728 while (!pending_decodes_.empty()) | 728 while (!pending_decodes_.empty()) |
729 pending_decodes_.pop(); | 729 pending_decodes_.pop(); |
730 decoder_.reset(); | 730 decoder_.reset(); |
731 // This instance is deleted once we exit this scope. | 731 // This instance is deleted once we exit this scope. |
732 } | 732 } |
733 | 733 |
734 void VideoDecoderShim::DecoderImpl::OnInitDone(bool success) { | 734 void VideoDecoderShim::DecoderImpl::OnInitDone( |
| 735 uint32_t min_picture_count, bool success) { |
735 int32_t result = success ? PP_OK : PP_ERROR_NOTSUPPORTED; | 736 int32_t result = success ? PP_OK : PP_ERROR_NOTSUPPORTED; |
736 | 737 |
737 // Calculate how many textures the shim should create. | 738 // Calculate how many textures the shim should create. |
738 uint32_t shim_texture_pool_size = media::limits::kMaxVideoFrames + 1; | 739 uint32_t shim_texture_pool_size = |
| 740 std::max(static_cast<uint32_t>(media::limits::kMaxVideoFrames + 1), |
| 741 min_picture_count); |
739 main_task_runner_->PostTask( | 742 main_task_runner_->PostTask( |
740 FROM_HERE, base::Bind(&VideoDecoderShim::OnInitializeComplete, shim_, | 743 FROM_HERE, base::Bind(&VideoDecoderShim::OnInitializeComplete, shim_, |
741 result, shim_texture_pool_size)); | 744 result, shim_texture_pool_size)); |
742 } | 745 } |
743 | 746 |
744 void VideoDecoderShim::DecoderImpl::DoDecode() { | 747 void VideoDecoderShim::DecoderImpl::DoDecode() { |
745 if (pending_decodes_.empty() || awaiting_decoder_) | 748 if (pending_decodes_.empty() || awaiting_decoder_) |
746 return; | 749 return; |
747 | 750 |
748 awaiting_decoder_ = true; | 751 awaiting_decoder_ = true; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
836 // The callback now holds the only reference to the DecoderImpl, which will be | 839 // The callback now holds the only reference to the DecoderImpl, which will be |
837 // deleted when Stop completes. | 840 // deleted when Stop completes. |
838 media_task_runner_->PostTask( | 841 media_task_runner_->PostTask( |
839 FROM_HERE, | 842 FROM_HERE, |
840 base::Bind(&VideoDecoderShim::DecoderImpl::Stop, | 843 base::Bind(&VideoDecoderShim::DecoderImpl::Stop, |
841 base::Owned(decoder_impl_.release()))); | 844 base::Owned(decoder_impl_.release()))); |
842 } | 845 } |
843 | 846 |
844 bool VideoDecoderShim::Initialize( | 847 bool VideoDecoderShim::Initialize( |
845 media::VideoCodecProfile profile, | 848 media::VideoCodecProfile profile, |
| 849 uint32 min_picture_count, |
846 media::VideoDecodeAccelerator::Client* client) { | 850 media::VideoDecodeAccelerator::Client* client) { |
847 DCHECK_EQ(client, host_); | 851 DCHECK_EQ(client, host_); |
848 DCHECK(RenderThreadImpl::current()); | 852 DCHECK(RenderThreadImpl::current()); |
849 DCHECK_EQ(state_, UNINITIALIZED); | 853 DCHECK_EQ(state_, UNINITIALIZED); |
850 media::VideoCodec codec = media::kUnknownVideoCodec; | 854 media::VideoCodec codec = media::kUnknownVideoCodec; |
851 if (profile <= media::H264PROFILE_MAX) | 855 if (profile <= media::H264PROFILE_MAX) |
852 codec = media::kCodecH264; | 856 codec = media::kCodecH264; |
853 else if (profile <= media::VP8PROFILE_MAX) | 857 else if (profile <= media::VP8PROFILE_MAX) |
854 codec = media::kCodecVP8; | 858 codec = media::kCodecVP8; |
855 else if (profile <= media::VP9PROFILE_MAX) | 859 else if (profile <= media::VP9PROFILE_MAX) |
(...skipping 12 matching lines...) Expand all Loading... |
868 gfx::Rect(32, 24), | 872 gfx::Rect(32, 24), |
869 gfx::Size(32, 24), | 873 gfx::Size(32, 24), |
870 NULL /* extra_data */, // TODO(bbudge) Verify this isn't needed. | 874 NULL /* extra_data */, // TODO(bbudge) Verify this isn't needed. |
871 0 /* extra_data_size */, | 875 0 /* extra_data_size */, |
872 false /* decryption */); | 876 false /* decryption */); |
873 | 877 |
874 media_task_runner_->PostTask( | 878 media_task_runner_->PostTask( |
875 FROM_HERE, | 879 FROM_HERE, |
876 base::Bind(&VideoDecoderShim::DecoderImpl::Initialize, | 880 base::Bind(&VideoDecoderShim::DecoderImpl::Initialize, |
877 base::Unretained(decoder_impl_.get()), | 881 base::Unretained(decoder_impl_.get()), |
878 config)); | 882 config, |
| 883 min_picture_count)); |
879 // Return success, even though we are asynchronous, to mimic | 884 // Return success, even though we are asynchronous, to mimic |
880 // media::VideoDecodeAccelerator. | 885 // media::VideoDecodeAccelerator. |
881 return true; | 886 return true; |
882 } | 887 } |
883 | 888 |
884 void VideoDecoderShim::Decode(const media::BitstreamBuffer& bitstream_buffer) { | 889 void VideoDecoderShim::Decode(const media::BitstreamBuffer& bitstream_buffer) { |
885 DCHECK(RenderThreadImpl::current()); | 890 DCHECK(RenderThreadImpl::current()); |
886 DCHECK_EQ(state_, DECODING); | 891 DCHECK_EQ(state_, DECODING); |
887 | 892 |
888 // We need the address of the shared memory, so we can copy the buffer. | 893 // We need the address of the shared memory, so we can copy the buffer. |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1094 void VideoDecoderShim::DeleteTexture(uint32_t texture_id) { | 1099 void VideoDecoderShim::DeleteTexture(uint32_t texture_id) { |
1095 gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); | 1100 gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); |
1096 gles2->DeleteTextures(1, &texture_id); | 1101 gles2->DeleteTextures(1, &texture_id); |
1097 } | 1102 } |
1098 | 1103 |
1099 void VideoDecoderShim::FlushCommandBuffer() { | 1104 void VideoDecoderShim::FlushCommandBuffer() { |
1100 context_provider_->ContextGL()->Flush(); | 1105 context_provider_->ContextGL()->Flush(); |
1101 } | 1106 } |
1102 | 1107 |
1103 } // namespace content | 1108 } // namespace content |
OLD | NEW |