| 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 |