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