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

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

Powered by Google App Engine
This is Rietveld 408576698