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 #include <utility> | 10 #include <utility> |
(...skipping 638 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
649 | 649 |
650 private: | 650 private: |
651 void OnInitDone(bool success); | 651 void OnInitDone(bool success); |
652 void DoDecode(); | 652 void DoDecode(); |
653 void OnDecodeComplete(media::DecodeStatus status); | 653 void OnDecodeComplete(media::DecodeStatus status); |
654 void OnOutputComplete(const scoped_refptr<media::VideoFrame>& frame); | 654 void OnOutputComplete(const scoped_refptr<media::VideoFrame>& frame); |
655 void OnResetComplete(); | 655 void OnResetComplete(); |
656 | 656 |
657 // WeakPtr is bound to main_message_loop_. Use only in shim callbacks. | 657 // WeakPtr is bound to main_message_loop_. Use only in shim callbacks. |
658 base::WeakPtr<VideoDecoderShim> shim_; | 658 base::WeakPtr<VideoDecoderShim> shim_; |
659 scoped_ptr<media::VideoDecoder> decoder_; | 659 std::unique_ptr<media::VideoDecoder> decoder_; |
660 bool initialized_ = false; | 660 bool initialized_ = false; |
661 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; | 661 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; |
662 // Queue of decodes waiting for the decoder. | 662 // Queue of decodes waiting for the decoder. |
663 typedef std::queue<PendingDecode> PendingDecodeQueue; | 663 typedef std::queue<PendingDecode> PendingDecodeQueue; |
664 PendingDecodeQueue pending_decodes_; | 664 PendingDecodeQueue pending_decodes_; |
665 bool awaiting_decoder_ = false; | 665 bool awaiting_decoder_ = false; |
666 // VideoDecoder returns pictures without information about the decode buffer | 666 // VideoDecoder returns pictures without information about the decode buffer |
667 // that generated it, but VideoDecoder implementations used in this class | 667 // that generated it, but VideoDecoder implementations used in this class |
668 // (media::FFmpegVideoDecoder and media::VpxVideoDecoder) always generate | 668 // (media::FFmpegVideoDecoder and media::VpxVideoDecoder) always generate |
669 // corresponding frames before decode is finished. |decode_id_| is used to | 669 // corresponding frames before decode is finished. |decode_id_| is used to |
(...skipping 18 matching lines...) Expand all Loading... |
688 media::VideoDecoderConfig config) { | 688 media::VideoDecoderConfig config) { |
689 DCHECK(!decoder_); | 689 DCHECK(!decoder_); |
690 #if !defined(MEDIA_DISABLE_LIBVPX) | 690 #if !defined(MEDIA_DISABLE_LIBVPX) |
691 if (config.codec() == media::kCodecVP9) { | 691 if (config.codec() == media::kCodecVP9) { |
692 decoder_.reset(new media::VpxVideoDecoder()); | 692 decoder_.reset(new media::VpxVideoDecoder()); |
693 } else | 693 } else |
694 #endif | 694 #endif |
695 | 695 |
696 #if !defined(MEDIA_DISABLE_FFMPEG) && !defined(DISABLE_FFMPEG_VIDEO_DECODERS) | 696 #if !defined(MEDIA_DISABLE_FFMPEG) && !defined(DISABLE_FFMPEG_VIDEO_DECODERS) |
697 { | 697 { |
698 scoped_ptr<media::FFmpegVideoDecoder> ffmpeg_video_decoder( | 698 std::unique_ptr<media::FFmpegVideoDecoder> ffmpeg_video_decoder( |
699 new media::FFmpegVideoDecoder()); | 699 new media::FFmpegVideoDecoder()); |
700 ffmpeg_video_decoder->set_decode_nalus(true); | 700 ffmpeg_video_decoder->set_decode_nalus(true); |
701 decoder_ = std::move(ffmpeg_video_decoder); | 701 decoder_ = std::move(ffmpeg_video_decoder); |
702 } | 702 } |
703 #elif defined(MEDIA_DISABLE_LIBVPX) | 703 #elif defined(MEDIA_DISABLE_LIBVPX) |
704 OnInitDone(false); | 704 OnInitDone(false); |
705 return; | 705 return; |
706 #endif | 706 #endif |
707 | 707 |
708 // VpxVideoDecoder and FFmpegVideoDecoder support only one pending Decode() | 708 // VpxVideoDecoder and FFmpegVideoDecoder support only one pending Decode() |
(...skipping 14 matching lines...) Expand all Loading... |
723 DCHECK(decoder_); | 723 DCHECK(decoder_); |
724 pending_decodes_.push(PendingDecode(decode_id, buffer)); | 724 pending_decodes_.push(PendingDecode(decode_id, buffer)); |
725 DoDecode(); | 725 DoDecode(); |
726 } | 726 } |
727 | 727 |
728 void VideoDecoderShim::DecoderImpl::Reset() { | 728 void VideoDecoderShim::DecoderImpl::Reset() { |
729 DCHECK(decoder_); | 729 DCHECK(decoder_); |
730 // Abort all pending decodes. | 730 // Abort all pending decodes. |
731 while (!pending_decodes_.empty()) { | 731 while (!pending_decodes_.empty()) { |
732 const PendingDecode& decode = pending_decodes_.front(); | 732 const PendingDecode& decode = pending_decodes_.front(); |
733 scoped_ptr<PendingFrame> pending_frame(new PendingFrame(decode.decode_id)); | 733 std::unique_ptr<PendingFrame> pending_frame( |
| 734 new PendingFrame(decode.decode_id)); |
734 main_task_runner_->PostTask( | 735 main_task_runner_->PostTask( |
735 FROM_HERE, base::Bind(&VideoDecoderShim::OnDecodeComplete, shim_, PP_OK, | 736 FROM_HERE, base::Bind(&VideoDecoderShim::OnDecodeComplete, shim_, PP_OK, |
736 decode.decode_id)); | 737 decode.decode_id)); |
737 pending_decodes_.pop(); | 738 pending_decodes_.pop(); |
738 } | 739 } |
739 // Don't need to call Reset() if the |decoder_| hasn't been initialized. | 740 // Don't need to call Reset() if the |decoder_| hasn't been initialized. |
740 if (!initialized_) { | 741 if (!initialized_) { |
741 OnResetComplete(); | 742 OnResetComplete(); |
742 return; | 743 return; |
743 } | 744 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
802 | 803 |
803 DoDecode(); | 804 DoDecode(); |
804 } | 805 } |
805 | 806 |
806 void VideoDecoderShim::DecoderImpl::OnOutputComplete( | 807 void VideoDecoderShim::DecoderImpl::OnOutputComplete( |
807 const scoped_refptr<media::VideoFrame>& frame) { | 808 const scoped_refptr<media::VideoFrame>& frame) { |
808 // Software decoders are expected to generated frames only when a Decode() | 809 // Software decoders are expected to generated frames only when a Decode() |
809 // call is pending. | 810 // call is pending. |
810 DCHECK(awaiting_decoder_); | 811 DCHECK(awaiting_decoder_); |
811 | 812 |
812 scoped_ptr<PendingFrame> pending_frame; | 813 std::unique_ptr<PendingFrame> pending_frame; |
813 if (!frame->metadata()->IsTrue(media::VideoFrameMetadata::END_OF_STREAM)) | 814 if (!frame->metadata()->IsTrue(media::VideoFrameMetadata::END_OF_STREAM)) |
814 pending_frame.reset(new PendingFrame(decode_id_, frame)); | 815 pending_frame.reset(new PendingFrame(decode_id_, frame)); |
815 else | 816 else |
816 pending_frame.reset(new PendingFrame(decode_id_)); | 817 pending_frame.reset(new PendingFrame(decode_id_)); |
817 | 818 |
818 main_task_runner_->PostTask( | 819 main_task_runner_->PostTask( |
819 FROM_HERE, base::Bind(&VideoDecoderShim::OnOutputComplete, shim_, | 820 FROM_HERE, base::Bind(&VideoDecoderShim::OnOutputComplete, shim_, |
820 base::Passed(&pending_frame))); | 821 base::Passed(&pending_frame))); |
821 } | 822 } |
822 | 823 |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1004 num_pending_decodes_--; | 1005 num_pending_decodes_--; |
1005 completed_decodes_.push(decode_id); | 1006 completed_decodes_.push(decode_id); |
1006 | 1007 |
1007 // If frames are being queued because we're out of textures, don't notify | 1008 // If frames are being queued because we're out of textures, don't notify |
1008 // the host that decode has completed. This exerts "back pressure" to keep | 1009 // the host that decode has completed. This exerts "back pressure" to keep |
1009 // the host from sending buffers that will cause pending_frames_ to grow. | 1010 // the host from sending buffers that will cause pending_frames_ to grow. |
1010 if (pending_frames_.empty()) | 1011 if (pending_frames_.empty()) |
1011 NotifyCompletedDecodes(); | 1012 NotifyCompletedDecodes(); |
1012 } | 1013 } |
1013 | 1014 |
1014 void VideoDecoderShim::OnOutputComplete(scoped_ptr<PendingFrame> frame) { | 1015 void VideoDecoderShim::OnOutputComplete(std::unique_ptr<PendingFrame> frame) { |
1015 DCHECK(RenderThreadImpl::current()); | 1016 DCHECK(RenderThreadImpl::current()); |
1016 DCHECK(host_); | 1017 DCHECK(host_); |
1017 | 1018 |
1018 if (frame->video_frame) { | 1019 if (frame->video_frame) { |
1019 if (texture_size_ != frame->video_frame->coded_size()) { | 1020 if (texture_size_ != frame->video_frame->coded_size()) { |
1020 // If the size has changed, all current textures must be dismissed. Add | 1021 // If the size has changed, all current textures must be dismissed. Add |
1021 // all textures to |textures_to_dismiss_| and dismiss any that aren't in | 1022 // all textures to |textures_to_dismiss_| and dismiss any that aren't in |
1022 // use by the plugin. We will dismiss the rest as they are recycled. | 1023 // use by the plugin. We will dismiss the rest as they are recycled. |
1023 for (TextureIdMap::const_iterator it = texture_id_map_.begin(); | 1024 for (TextureIdMap::const_iterator it = texture_id_map_.begin(); |
1024 it != texture_id_map_.end(); | 1025 it != texture_id_map_.end(); |
(...skipping 20 matching lines...) Expand all Loading... |
1045 | 1046 |
1046 pending_frames_.push(std::move(frame)); | 1047 pending_frames_.push(std::move(frame)); |
1047 SendPictures(); | 1048 SendPictures(); |
1048 } | 1049 } |
1049 } | 1050 } |
1050 | 1051 |
1051 void VideoDecoderShim::SendPictures() { | 1052 void VideoDecoderShim::SendPictures() { |
1052 DCHECK(RenderThreadImpl::current()); | 1053 DCHECK(RenderThreadImpl::current()); |
1053 DCHECK(host_); | 1054 DCHECK(host_); |
1054 while (!pending_frames_.empty() && !available_textures_.empty()) { | 1055 while (!pending_frames_.empty() && !available_textures_.empty()) { |
1055 const scoped_ptr<PendingFrame>& frame = pending_frames_.front(); | 1056 const std::unique_ptr<PendingFrame>& frame = pending_frames_.front(); |
1056 | 1057 |
1057 TextureIdSet::iterator it = available_textures_.begin(); | 1058 TextureIdSet::iterator it = available_textures_.begin(); |
1058 uint32_t texture_id = *it; | 1059 uint32_t texture_id = *it; |
1059 available_textures_.erase(it); | 1060 available_textures_.erase(it); |
1060 | 1061 |
1061 uint32_t local_texture_id = texture_id_map_[texture_id]; | 1062 uint32_t local_texture_id = texture_id_map_[texture_id]; |
1062 | 1063 |
1063 yuv_converter_->Convert(frame->video_frame, local_texture_id); | 1064 yuv_converter_->Convert(frame->video_frame, local_texture_id); |
1064 | 1065 |
1065 host_->PictureReady(media::Picture(texture_id, frame->decode_id, | 1066 host_->PictureReady(media::Picture(texture_id, frame->decode_id, |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1117 void VideoDecoderShim::DeleteTexture(uint32_t texture_id) { | 1118 void VideoDecoderShim::DeleteTexture(uint32_t texture_id) { |
1118 gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); | 1119 gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); |
1119 gles2->DeleteTextures(1, &texture_id); | 1120 gles2->DeleteTextures(1, &texture_id); |
1120 } | 1121 } |
1121 | 1122 |
1122 void VideoDecoderShim::FlushCommandBuffer() { | 1123 void VideoDecoderShim::FlushCommandBuffer() { |
1123 context_provider_->ContextGL()->Flush(); | 1124 context_provider_->ContextGL()->Flush(); |
1124 } | 1125 } |
1125 | 1126 |
1126 } // namespace content | 1127 } // namespace content |
OLD | NEW |