Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(179)

Side by Side Diff: media/filters/gpu_video_decoder.cc

Issue 19534002: Make RendererGpuVideoDecoderFactories live on arbitrary threads. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: address review comments Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
24 // the client's thread.
25 //
26 // TODO(scherkus): VDAClientProxy should hold onto GpuVideoDecoder::Factories
27 // and take care of some of the work that GpuVideoDecoder does to minimize
28 // thread hopping. See following for discussion:
29 //
30 // https://codereview.chromium.org/12989009/diff/27035/media/filters/gpu_video_d ecoder.cc#newcode23
31 class VDAClientProxy
32 : public base::RefCountedThreadSafe<VDAClientProxy>,
33 public VideoDecodeAccelerator::Client {
34 public:
35 explicit VDAClientProxy(VideoDecodeAccelerator::Client* client);
36
37 // Detaches the proxy. |weak_client_| will no longer be called and can be
38 // safely deleted. Any pending/future calls will be discarded.
39 //
40 // Must be called on |client_loop_|.
41 void Detach();
42
43 // VideoDecodeAccelerator::Client implementation.
44 virtual void NotifyInitializeDone() OVERRIDE;
45 virtual void ProvidePictureBuffers(uint32 count,
46 const gfx::Size& size,
47 uint32 texture_target) OVERRIDE;
48 virtual void DismissPictureBuffer(int32 id) OVERRIDE;
49 virtual void PictureReady(const media::Picture& picture) OVERRIDE;
50 virtual void NotifyEndOfBitstreamBuffer(int32 id) OVERRIDE;
51 virtual void NotifyFlushDone() OVERRIDE;
52 virtual void NotifyResetDone() OVERRIDE;
53 virtual void NotifyError(media::VideoDecodeAccelerator::Error error) OVERRIDE;
54
55 private:
56 friend class base::RefCountedThreadSafe<VDAClientProxy>;
57 virtual ~VDAClientProxy();
58
59 scoped_refptr<base::MessageLoopProxy> client_loop_;
60
61 // Weak pointers are used to invalidate tasks posted to |client_loop_| after
62 // Detach() has been called.
63 base::WeakPtrFactory<VideoDecodeAccelerator::Client> weak_client_factory_;
64 base::WeakPtr<VideoDecodeAccelerator::Client> weak_client_;
65
66 DISALLOW_COPY_AND_ASSIGN(VDAClientProxy);
67 };
68
69 VDAClientProxy::VDAClientProxy(VideoDecodeAccelerator::Client* client)
70 : client_loop_(base::MessageLoopProxy::current()),
71 weak_client_factory_(client),
72 weak_client_(weak_client_factory_.GetWeakPtr()) {
73 DCHECK(weak_client_.get());
74 }
75
76 VDAClientProxy::~VDAClientProxy() {}
77
78 void VDAClientProxy::Detach() {
79 DCHECK(client_loop_->BelongsToCurrentThread());
80 DCHECK(weak_client_.get()) << "Detach() already called";
81 weak_client_factory_.InvalidateWeakPtrs();
82 }
83
84 void VDAClientProxy::NotifyInitializeDone() {
85 client_loop_->PostTask(FROM_HERE, base::Bind(
86 &VideoDecodeAccelerator::Client::NotifyInitializeDone, weak_client_));
87 }
88
89 void VDAClientProxy::ProvidePictureBuffers(uint32 count,
90 const gfx::Size& size,
91 uint32 texture_target) {
92 client_loop_->PostTask(FROM_HERE, base::Bind(
93 &VideoDecodeAccelerator::Client::ProvidePictureBuffers, weak_client_,
94 count, size, texture_target));
95 }
96
97 void VDAClientProxy::DismissPictureBuffer(int32 id) {
98 client_loop_->PostTask(FROM_HERE, base::Bind(
99 &VideoDecodeAccelerator::Client::DismissPictureBuffer, weak_client_, id));
100 }
101
102 void VDAClientProxy::PictureReady(const media::Picture& picture) {
103 client_loop_->PostTask(FROM_HERE, base::Bind(
104 &VideoDecodeAccelerator::Client::PictureReady, weak_client_, picture));
105 }
106
107 void VDAClientProxy::NotifyEndOfBitstreamBuffer(int32 id) {
108 client_loop_->PostTask(FROM_HERE, base::Bind(
109 &VideoDecodeAccelerator::Client::NotifyEndOfBitstreamBuffer, weak_client_,
110 id));
111 }
112
113 void VDAClientProxy::NotifyFlushDone() {
114 client_loop_->PostTask(FROM_HERE, base::Bind(
115 &VideoDecodeAccelerator::Client::NotifyFlushDone, weak_client_));
116 }
117
118 void VDAClientProxy::NotifyResetDone() {
119 client_loop_->PostTask(FROM_HERE, base::Bind(
120 &VideoDecodeAccelerator::Client::NotifyResetDone, weak_client_));
121 }
122
123 void VDAClientProxy::NotifyError(media::VideoDecodeAccelerator::Error error) {
124 client_loop_->PostTask(FROM_HERE, base::Bind(
125 &VideoDecodeAccelerator::Client::NotifyError, weak_client_, error));
126 }
127
128
129 // Maximum number of concurrent VDA::Decode() operations GVD will maintain. 23 // Maximum number of concurrent VDA::Decode() operations GVD will maintain.
130 // Higher values allow better pipelining in the GPU, but also require more 24 // Higher values allow better pipelining in the GPU, but also require more
131 // resources. 25 // resources.
132 enum { kMaxInFlightDecodes = 4 }; 26 enum { kMaxInFlightDecodes = 4 };
133 27
134 GpuVideoDecoder::Factories::~Factories() {} 28 GpuVideoDecoder::Factories::~Factories() {}
135 29
136 // Size of shared-memory segments we allocate. Since we reuse them we let them 30 // Size of shared-memory segments we allocate. Since we reuse them we let them
137 // be on the beefy side. 31 // be on the beefy side.
138 static const size_t kSharedMemorySegmentBytes = 100 << 10; 32 static const size_t kSharedMemorySegmentBytes = 100 << 10;
(...skipping 18 matching lines...) Expand all
157 } 51 }
158 52
159 GpuVideoDecoder::BufferData::~BufferData() {} 53 GpuVideoDecoder::BufferData::~BufferData() {}
160 54
161 GpuVideoDecoder::GpuVideoDecoder( 55 GpuVideoDecoder::GpuVideoDecoder(
162 const scoped_refptr<base::MessageLoopProxy>& message_loop, 56 const scoped_refptr<base::MessageLoopProxy>& message_loop,
163 const scoped_refptr<Factories>& factories) 57 const scoped_refptr<Factories>& factories)
164 : needs_bitstream_conversion_(false), 58 : needs_bitstream_conversion_(false),
165 gvd_loop_proxy_(message_loop), 59 gvd_loop_proxy_(message_loop),
166 weak_factory_(this), 60 weak_factory_(this),
167 vda_loop_proxy_(factories->GetMessageLoop()),
168 factories_(factories), 61 factories_(factories),
169 state_(kNormal), 62 state_(kNormal),
170 decoder_texture_target_(0), 63 decoder_texture_target_(0),
171 next_picture_buffer_id_(0), 64 next_picture_buffer_id_(0),
172 next_bitstream_buffer_id_(0), 65 next_bitstream_buffer_id_(0),
173 available_pictures_(0) { 66 available_pictures_(0) {
174 DCHECK(factories_.get()); 67 DCHECK(factories_.get());
68 DCHECK_EQ(message_loop.get(), factories->GetMessageLoop().get());
175 } 69 }
176 70
177 void GpuVideoDecoder::Reset(const base::Closure& closure) { 71 void GpuVideoDecoder::Reset(const base::Closure& closure) {
178 DVLOG(3) << "Reset()"; 72 DVLOG(3) << "Reset()";
179 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 73 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
180 74
181 if (state_ == kDrainingDecoder && !factories_->IsAborted()) { 75 if (state_ == kDrainingDecoder && !factories_->IsAborted()) {
182 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 76 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
183 &GpuVideoDecoder::Reset, weak_this_, closure)); 77 &GpuVideoDecoder::Reset, weak_this_, closure));
184 // NOTE: if we're deferring Reset() until a Flush() completes, return 78 // NOTE: if we're deferring Reset() until a Flush() completes, return
(...skipping 10 matching lines...) Expand all
195 gvd_loop_proxy_->PostTask(FROM_HERE, closure); 89 gvd_loop_proxy_->PostTask(FROM_HERE, closure);
196 return; 90 return;
197 } 91 }
198 92
199 if (!pending_read_cb_.is_null()) 93 if (!pending_read_cb_.is_null())
200 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); 94 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame());
201 95
202 DCHECK(pending_reset_cb_.is_null()); 96 DCHECK(pending_reset_cb_.is_null());
203 pending_reset_cb_ = BindToCurrentLoop(closure); 97 pending_reset_cb_ = BindToCurrentLoop(closure);
204 98
205 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( 99 vda_->Reset();
206 &VideoDecodeAccelerator::Reset, weak_vda_));
207 } 100 }
208 101
209 void GpuVideoDecoder::Stop(const base::Closure& closure) { 102 void GpuVideoDecoder::Stop(const base::Closure& closure) {
210 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 103 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
211 if (vda_) 104 if (vda_)
212 DestroyVDA(); 105 DestroyVDA();
213 if (!pending_read_cb_.is_null()) 106 if (!pending_read_cb_.is_null())
214 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); 107 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame());
215 if (!pending_reset_cb_.is_null()) 108 if (!pending_reset_cb_.is_null())
216 base::ResetAndReturn(&pending_reset_cb_).Run(); 109 base::ResetAndReturn(&pending_reset_cb_).Run();
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 DVLOG(1) << "GpuVideoDecoder reinitialization not supported."; 145 DVLOG(1) << "GpuVideoDecoder reinitialization not supported.";
253 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); 146 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED);
254 return; 147 return;
255 } 148 }
256 149
257 if (!IsCodedSizeSupported(config.coded_size())) { 150 if (!IsCodedSizeSupported(config.coded_size())) {
258 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); 151 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED);
259 return; 152 return;
260 } 153 }
261 154
262 client_proxy_ = new VDAClientProxy(this); 155 VideoDecodeAccelerator* vda =
263 VideoDecodeAccelerator* vda = factories_->CreateVideoDecodeAccelerator( 156 factories_->CreateVideoDecodeAccelerator(config.profile(), this);
264 config.profile(), client_proxy_.get());
265 if (!vda) { 157 if (!vda) {
266 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); 158 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED);
267 return; 159 return;
268 } 160 }
269 161
270 config_ = config; 162 config_ = config;
271 needs_bitstream_conversion_ = (config.codec() == kCodecH264); 163 needs_bitstream_conversion_ = (config.codec() == kCodecH264);
272 164
273 DVLOG(3) << "GpuVideoDecoder::Initialize() succeeded."; 165 DVLOG(3) << "GpuVideoDecoder::Initialize() succeeded.";
274 PostTaskAndReplyWithResult(
275 vda_loop_proxy_.get(),
276 FROM_HERE,
277 base::Bind(&VideoDecodeAccelerator::AsWeakPtr, base::Unretained(vda)),
278 base::Bind(&GpuVideoDecoder::SetVDA, weak_this_, status_cb, vda));
279 }
280
281 void GpuVideoDecoder::SetVDA(
282 const PipelineStatusCB& status_cb,
283 VideoDecodeAccelerator* vda,
284 base::WeakPtr<VideoDecodeAccelerator> weak_vda) {
285 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
286 DCHECK(!vda_.get());
287 vda_.reset(vda); 166 vda_.reset(vda);
288 weak_vda_ = weak_vda;
289 status_cb.Run(PIPELINE_OK); 167 status_cb.Run(PIPELINE_OK);
290 } 168 }
291 169
292 void GpuVideoDecoder::DestroyTextures() { 170 void GpuVideoDecoder::DestroyTextures() {
293 std::map<int32, PictureBuffer>::iterator it; 171 std::map<int32, PictureBuffer>::iterator it;
294 172
295 for (it = assigned_picture_buffers_.begin(); 173 for (it = assigned_picture_buffers_.begin();
296 it != assigned_picture_buffers_.end(); ++it) { 174 it != assigned_picture_buffers_.end(); ++it) {
297 factories_->DeleteTexture(it->second.texture_id()); 175 factories_->DeleteTexture(it->second.texture_id());
298 } 176 }
299 assigned_picture_buffers_.clear(); 177 assigned_picture_buffers_.clear();
300 178
301 for (it = dismissed_picture_buffers_.begin(); 179 for (it = dismissed_picture_buffers_.begin();
302 it != dismissed_picture_buffers_.end(); ++it) { 180 it != dismissed_picture_buffers_.end(); ++it) {
303 factories_->DeleteTexture(it->second.texture_id()); 181 factories_->DeleteTexture(it->second.texture_id());
304 } 182 }
305 dismissed_picture_buffers_.clear(); 183 dismissed_picture_buffers_.clear();
306 } 184 }
307 185
308 static void DestroyVDAWithClientProxy(
309 const scoped_refptr<VDAClientProxy>& client_proxy,
310 base::WeakPtr<VideoDecodeAccelerator> weak_vda) {
311 if (weak_vda.get()) {
312 weak_vda->Destroy();
313 DCHECK(!weak_vda.get()); // Check VDA::Destroy() contract.
314 }
315 }
316
317 void GpuVideoDecoder::DestroyVDA() { 186 void GpuVideoDecoder::DestroyVDA() {
318 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 187 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
319 188
320 // |client_proxy| must stay alive until |weak_vda_| has been destroyed. 189 if (vda_)
321 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( 190 vda_.release()->Destroy();
322 &DestroyVDAWithClientProxy, client_proxy_, weak_vda_));
323
324 VideoDecodeAccelerator* vda ALLOW_UNUSED = vda_.release();
325 client_proxy_->Detach();
326 client_proxy_ = NULL;
327 191
328 DestroyTextures(); 192 DestroyTextures();
329 } 193 }
330 194
331 void GpuVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, 195 void GpuVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer,
332 const ReadCB& read_cb) { 196 const ReadCB& read_cb) {
333 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 197 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
334 DCHECK(pending_reset_cb_.is_null()); 198 DCHECK(pending_reset_cb_.is_null());
335 DCHECK(pending_read_cb_.is_null()); 199 DCHECK(pending_read_cb_.is_null());
336 200
(...skipping 20 matching lines...) Expand all
357 // NotifyFlushDone below. 221 // NotifyFlushDone below.
358 return; 222 return;
359 case kError: 223 case kError:
360 NOTREACHED(); 224 NOTREACHED();
361 return; 225 return;
362 } 226 }
363 227
364 if (buffer->IsEndOfStream()) { 228 if (buffer->IsEndOfStream()) {
365 if (state_ == kNormal) { 229 if (state_ == kNormal) {
366 state_ = kDrainingDecoder; 230 state_ = kDrainingDecoder;
367 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( 231 vda_->Flush();
368 &VideoDecodeAccelerator::Flush, weak_vda_));
369 } 232 }
370 return; 233 return;
371 } 234 }
372 235
373 size_t size = buffer->GetDataSize(); 236 size_t size = buffer->GetDataSize();
374 SHMBuffer* shm_buffer = GetSHM(size); 237 SHMBuffer* shm_buffer = GetSHM(size);
375 if (!shm_buffer) { 238 if (!shm_buffer) {
376 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); 239 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL);
377 return; 240 return;
378 } 241 }
379 242
380 memcpy(shm_buffer->shm->memory(), buffer->GetData(), size); 243 memcpy(shm_buffer->shm->memory(), buffer->GetData(), size);
381 BitstreamBuffer bitstream_buffer( 244 BitstreamBuffer bitstream_buffer(
382 next_bitstream_buffer_id_, shm_buffer->shm->handle(), size); 245 next_bitstream_buffer_id_, shm_buffer->shm->handle(), size);
383 // Mask against 30 bits, to avoid (undefined) wraparound on signed integer. 246 // Mask against 30 bits, to avoid (undefined) wraparound on signed integer.
384 next_bitstream_buffer_id_ = (next_bitstream_buffer_id_ + 1) & 0x3FFFFFFF; 247 next_bitstream_buffer_id_ = (next_bitstream_buffer_id_ + 1) & 0x3FFFFFFF;
385 bool inserted = bitstream_buffers_in_decoder_.insert(std::make_pair( 248 bool inserted = bitstream_buffers_in_decoder_.insert(std::make_pair(
386 bitstream_buffer.id(), BufferPair(shm_buffer, buffer))).second; 249 bitstream_buffer.id(), BufferPair(shm_buffer, buffer))).second;
387 DCHECK(inserted); 250 DCHECK(inserted);
388 RecordBufferData(bitstream_buffer, *buffer.get()); 251 RecordBufferData(bitstream_buffer, *buffer.get());
389 252
390 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( 253 vda_->Decode(bitstream_buffer);
391 &VideoDecodeAccelerator::Decode, weak_vda_, bitstream_buffer));
392 254
393 if (!ready_video_frames_.empty()) { 255 if (!ready_video_frames_.empty()) {
394 EnqueueFrameAndTriggerFrameDelivery(NULL); 256 EnqueueFrameAndTriggerFrameDelivery(NULL);
395 return; 257 return;
396 } 258 }
397 259
398 if (CanMoreDecodeWorkBeDone()) 260 if (CanMoreDecodeWorkBeDone())
399 base::ResetAndReturn(&pending_read_cb_).Run(kNotEnoughData, NULL); 261 base::ResetAndReturn(&pending_read_cb_).Run(kNotEnoughData, NULL);
400 } 262 }
401 263
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 for (size_t i = 0; i < texture_ids.size(); ++i) { 346 for (size_t i = 0; i < texture_ids.size(); ++i) {
485 picture_buffers.push_back(PictureBuffer( 347 picture_buffers.push_back(PictureBuffer(
486 next_picture_buffer_id_++, size, texture_ids[i], texture_mailboxes[i])); 348 next_picture_buffer_id_++, size, texture_ids[i], texture_mailboxes[i]));
487 bool inserted = assigned_picture_buffers_.insert(std::make_pair( 349 bool inserted = assigned_picture_buffers_.insert(std::make_pair(
488 picture_buffers.back().id(), picture_buffers.back())).second; 350 picture_buffers.back().id(), picture_buffers.back())).second;
489 DCHECK(inserted); 351 DCHECK(inserted);
490 } 352 }
491 353
492 available_pictures_ += count; 354 available_pictures_ += count;
493 355
494 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( 356 vda_->AssignPictureBuffers(picture_buffers);
495 &VideoDecodeAccelerator::AssignPictureBuffers, weak_vda_,
496 picture_buffers));
497 } 357 }
498 358
499 void GpuVideoDecoder::DismissPictureBuffer(int32 id) { 359 void GpuVideoDecoder::DismissPictureBuffer(int32 id) {
500 DVLOG(3) << "DismissPictureBuffer(" << id << ")"; 360 DVLOG(3) << "DismissPictureBuffer(" << id << ")";
501 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 361 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
502 362
503 std::map<int32, PictureBuffer>::iterator it = 363 std::map<int32, PictureBuffer>::iterator it =
504 assigned_picture_buffers_.find(id); 364 assigned_picture_buffers_.find(id);
505 if (it == assigned_picture_buffers_.end()) { 365 if (it == assigned_picture_buffers_.end()) {
506 NOTREACHED() << "Missing picture buffer: " << id; 366 NOTREACHED() << "Missing picture buffer: " << id;
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 it = dismissed_picture_buffers_.find(picture_buffer_id); 473 it = dismissed_picture_buffers_.find(picture_buffer_id);
614 DCHECK(it != dismissed_picture_buffers_.end()); 474 DCHECK(it != dismissed_picture_buffers_.end());
615 factories_->DeleteTexture(it->second.texture_id()); 475 factories_->DeleteTexture(it->second.texture_id());
616 dismissed_picture_buffers_.erase(it); 476 dismissed_picture_buffers_.erase(it);
617 return; 477 return;
618 } 478 }
619 479
620 factories_->WaitSyncPoint(sync_point); 480 factories_->WaitSyncPoint(sync_point);
621 ++available_pictures_; 481 ++available_pictures_;
622 482
623 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( 483 vda_->ReusePictureBuffer(picture_buffer_id);
624 &VideoDecodeAccelerator::ReusePictureBuffer, weak_vda_,
625 picture_buffer_id));
626 } 484 }
627 485
628 GpuVideoDecoder::SHMBuffer* GpuVideoDecoder::GetSHM(size_t min_size) { 486 GpuVideoDecoder::SHMBuffer* GpuVideoDecoder::GetSHM(size_t min_size) {
629 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 487 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
630 if (available_shm_segments_.empty() || 488 if (available_shm_segments_.empty() ||
631 available_shm_segments_.back()->size < min_size) { 489 available_shm_segments_.back()->size < min_size) {
632 size_t size_to_allocate = std::max(min_size, kSharedMemorySegmentBytes); 490 size_t size_to_allocate = std::max(min_size, kSharedMemorySegmentBytes);
633 base::SharedMemory* shm = factories_->CreateSharedMemory(size_to_allocate); 491 base::SharedMemory* shm = factories_->CreateSharedMemory(size_to_allocate);
634 // CreateSharedMemory() can return NULL during Shutdown. 492 // CreateSharedMemory() can return NULL during Shutdown.
635 if (!shm) 493 if (!shm)
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
719 577
720 state_ = kError; 578 state_ = kError;
721 579
722 if (!pending_read_cb_.is_null()) { 580 if (!pending_read_cb_.is_null()) {
723 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); 581 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL);
724 return; 582 return;
725 } 583 }
726 } 584 }
727 585
728 } // namespace media 586 } // namespace media
OLDNEW
« media/filters/gpu_video_decoder.h ('K') | « media/filters/gpu_video_decoder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698