| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "media/filters/gpu_video_decoder.h" | 5 #include "media/filters/gpu_video_decoder.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
| 11 #include "base/cpu.h" | 11 #include "base/cpu.h" |
| 12 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
| 13 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
| 14 #include "base/task_runner_util.h" | 14 #include "base/task_runner_util.h" |
| 15 #include "media/base/bind_to_loop.h" | 15 #include "media/base/bind_to_loop.h" |
| 16 #include "media/base/decoder_buffer.h" | 16 #include "media/base/decoder_buffer.h" |
| 17 #include "media/base/pipeline.h" | 17 #include "media/base/pipeline.h" |
| 18 #include "media/base/pipeline_status.h" | 18 #include "media/base/pipeline_status.h" |
| 19 #include "media/base/video_decoder_config.h" | 19 #include "media/base/video_decoder_config.h" |
| 20 | 20 |
| 21 namespace media { | 21 namespace media { |
| 22 | 22 |
| 23 // Proxies calls to a VideoDecodeAccelerator::Client from the calling thread to | 23 // Proxies calls to a VideoDecodeAccelerator::Client from the calling thread to |
| 24 // the client's thread. | 24 // the client's thread. |
| 25 // | 25 // |
| 26 // TODO(scherkus): VDAClientProxy should hold onto GpuVideoDecoder::Factories | 26 // TODO(scherkus): VDAClientProxy should hold onto GpuVideoDecoderFactories |
| 27 // and take care of some of the work that GpuVideoDecoder does to minimize | 27 // and take care of some of the work that GpuVideoDecoder does to minimize |
| 28 // thread hopping. See following for discussion: | 28 // thread hopping. See following for discussion: |
| 29 // | 29 // |
| 30 // https://codereview.chromium.org/12989009/diff/27035/media/filters/gpu_video_d
ecoder.cc#newcode23 | 30 // https://codereview.chromium.org/12989009/diff/27035/media/filters/gpu_video_d
ecoder.cc#newcode23 |
| 31 class VDAClientProxy | 31 class VDAClientProxy |
| 32 : public base::RefCountedThreadSafe<VDAClientProxy>, | 32 : public base::RefCountedThreadSafe<VDAClientProxy>, |
| 33 public VideoDecodeAccelerator::Client { | 33 public VideoDecodeAccelerator::Client { |
| 34 public: | 34 public: |
| 35 explicit VDAClientProxy(VideoDecodeAccelerator::Client* client); | 35 explicit VDAClientProxy(VideoDecodeAccelerator::Client* client); |
| 36 | 36 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 client_loop_->PostTask(FROM_HERE, base::Bind( | 124 client_loop_->PostTask(FROM_HERE, base::Bind( |
| 125 &VideoDecodeAccelerator::Client::NotifyError, weak_client_, error)); | 125 &VideoDecodeAccelerator::Client::NotifyError, weak_client_, error)); |
| 126 } | 126 } |
| 127 | 127 |
| 128 | 128 |
| 129 // Maximum number of concurrent VDA::Decode() operations GVD will maintain. | 129 // Maximum number of concurrent VDA::Decode() operations GVD will maintain. |
| 130 // Higher values allow better pipelining in the GPU, but also require more | 130 // Higher values allow better pipelining in the GPU, but also require more |
| 131 // resources. | 131 // resources. |
| 132 enum { kMaxInFlightDecodes = 4 }; | 132 enum { kMaxInFlightDecodes = 4 }; |
| 133 | 133 |
| 134 GpuVideoDecoder::Factories::~Factories() {} | |
| 135 | |
| 136 // Size of shared-memory segments we allocate. Since we reuse them we let them | 134 // Size of shared-memory segments we allocate. Since we reuse them we let them |
| 137 // be on the beefy side. | 135 // be on the beefy side. |
| 138 static const size_t kSharedMemorySegmentBytes = 100 << 10; | 136 static const size_t kSharedMemorySegmentBytes = 100 << 10; |
| 139 | 137 |
| 140 GpuVideoDecoder::SHMBuffer::SHMBuffer(base::SharedMemory* m, size_t s) | 138 GpuVideoDecoder::SHMBuffer::SHMBuffer(base::SharedMemory* m, size_t s) |
| 141 : shm(m), size(s) { | 139 : shm(m), size(s) { |
| 142 } | 140 } |
| 143 | 141 |
| 144 GpuVideoDecoder::SHMBuffer::~SHMBuffer() {} | 142 GpuVideoDecoder::SHMBuffer::~SHMBuffer() {} |
| 145 | 143 |
| 146 GpuVideoDecoder::BufferPair::BufferPair( | 144 GpuVideoDecoder::BufferPair::BufferPair( |
| 147 SHMBuffer* s, const scoped_refptr<DecoderBuffer>& b) | 145 SHMBuffer* s, const scoped_refptr<DecoderBuffer>& b) |
| 148 : shm_buffer(s), buffer(b) { | 146 : shm_buffer(s), buffer(b) { |
| 149 } | 147 } |
| 150 | 148 |
| 151 GpuVideoDecoder::BufferPair::~BufferPair() {} | 149 GpuVideoDecoder::BufferPair::~BufferPair() {} |
| 152 | 150 |
| 153 GpuVideoDecoder::BufferData::BufferData( | 151 GpuVideoDecoder::BufferData::BufferData( |
| 154 int32 bbid, base::TimeDelta ts, const gfx::Rect& vr, const gfx::Size& ns) | 152 int32 bbid, base::TimeDelta ts, const gfx::Rect& vr, const gfx::Size& ns) |
| 155 : bitstream_buffer_id(bbid), timestamp(ts), visible_rect(vr), | 153 : bitstream_buffer_id(bbid), timestamp(ts), visible_rect(vr), |
| 156 natural_size(ns) { | 154 natural_size(ns) { |
| 157 } | 155 } |
| 158 | 156 |
| 159 GpuVideoDecoder::BufferData::~BufferData() {} | 157 GpuVideoDecoder::BufferData::~BufferData() {} |
| 160 | 158 |
| 161 GpuVideoDecoder::GpuVideoDecoder( | 159 GpuVideoDecoder::GpuVideoDecoder( |
| 162 const scoped_refptr<base::MessageLoopProxy>& message_loop, | 160 const scoped_refptr<base::MessageLoopProxy>& message_loop, |
| 163 const scoped_refptr<Factories>& factories) | 161 const scoped_refptr<GpuVideoDecoderFactories>& factories) |
| 164 : needs_bitstream_conversion_(false), | 162 : needs_bitstream_conversion_(false), |
| 165 gvd_loop_proxy_(message_loop), | 163 gvd_loop_proxy_(message_loop), |
| 166 weak_factory_(this), | 164 weak_factory_(this), |
| 167 vda_loop_proxy_(factories->GetMessageLoop()), | 165 vda_loop_proxy_(factories->GetMessageLoop()), |
| 168 factories_(factories), | 166 factories_(factories), |
| 169 state_(kNormal), | 167 state_(kNormal), |
| 170 decoder_texture_target_(0), | 168 decoder_texture_target_(0), |
| 171 next_picture_buffer_id_(0), | 169 next_picture_buffer_id_(0), |
| 172 next_bitstream_buffer_id_(0), | 170 next_bitstream_buffer_id_(0), |
| 173 available_pictures_(0) { | 171 available_pictures_(0) { |
| (...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 540 const PictureBuffer& pb = it->second; | 538 const PictureBuffer& pb = it->second; |
| 541 | 539 |
| 542 // Update frame's timestamp. | 540 // Update frame's timestamp. |
| 543 base::TimeDelta timestamp; | 541 base::TimeDelta timestamp; |
| 544 gfx::Rect visible_rect; | 542 gfx::Rect visible_rect; |
| 545 gfx::Size natural_size; | 543 gfx::Size natural_size; |
| 546 GetBufferData(picture.bitstream_buffer_id(), ×tamp, &visible_rect, | 544 GetBufferData(picture.bitstream_buffer_id(), ×tamp, &visible_rect, |
| 547 &natural_size); | 545 &natural_size); |
| 548 DCHECK(decoder_texture_target_); | 546 DCHECK(decoder_texture_target_); |
| 549 | 547 |
| 550 scoped_refptr<VideoFrame> frame( | 548 scoped_refptr<VideoFrame> frame(VideoFrame::WrapNativeTexture( |
| 551 VideoFrame::WrapNativeTexture( | 549 new VideoFrame::MailboxHolder( |
| 552 new VideoFrame::MailboxHolder( | 550 pb.texture_mailbox(), |
| 553 pb.texture_mailbox(), | 551 0, // sync_point |
| 554 0, // sync_point | 552 BindToCurrentLoop(base::Bind(&GpuVideoDecoder::ReusePictureBuffer, |
| 555 BindToCurrentLoop(base::Bind( | 553 weak_this_, |
| 556 &GpuVideoDecoder::ReusePictureBuffer, weak_this_, | 554 picture.picture_buffer_id()))), |
| 557 picture.picture_buffer_id()))), | 555 decoder_texture_target_, |
| 558 decoder_texture_target_, | 556 pb.size(), |
| 559 pb.size(), visible_rect, | 557 visible_rect, |
| 560 natural_size, timestamp, | 558 natural_size, |
| 561 base::Bind(&Factories::ReadPixels, factories_, pb.texture_id(), | 559 timestamp, |
| 562 decoder_texture_target_, | 560 base::Bind(&GpuVideoDecoderFactories::ReadPixels, |
| 563 gfx::Size(visible_rect.width(), visible_rect.height())), | 561 factories_, |
| 564 base::Closure())); | 562 pb.texture_id(), |
| 563 decoder_texture_target_, |
| 564 gfx::Size(visible_rect.width(), visible_rect.height())), |
| 565 base::Closure())); |
| 565 CHECK_GT(available_pictures_, 0); | 566 CHECK_GT(available_pictures_, 0); |
| 566 --available_pictures_; | 567 --available_pictures_; |
| 567 bool inserted = | 568 bool inserted = |
| 568 picture_buffers_at_display_.insert(picture.picture_buffer_id()).second; | 569 picture_buffers_at_display_.insert(picture.picture_buffer_id()).second; |
| 569 DCHECK(inserted); | 570 DCHECK(inserted); |
| 570 | 571 |
| 571 EnqueueFrameAndTriggerFrameDelivery(frame); | 572 EnqueueFrameAndTriggerFrameDelivery(frame); |
| 572 } | 573 } |
| 573 | 574 |
| 574 void GpuVideoDecoder::EnqueueFrameAndTriggerFrameDelivery( | 575 void GpuVideoDecoder::EnqueueFrameAndTriggerFrameDelivery( |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 719 | 720 |
| 720 state_ = kError; | 721 state_ = kError; |
| 721 | 722 |
| 722 if (!pending_read_cb_.is_null()) { | 723 if (!pending_read_cb_.is_null()) { |
| 723 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); | 724 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); |
| 724 return; | 725 return; |
| 725 } | 726 } |
| 726 } | 727 } |
| 727 | 728 |
| 728 } // namespace media | 729 } // namespace media |
| OLD | NEW |