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 |