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

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

Issue 65803002: Replace MessageLoopProxy with SingleThreadTaskRunner for media/filters/ + associated code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 1 month 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 | Annotate | Revision Log
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"
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 : bitstream_buffer_id(bbid), timestamp(ts), visible_rect(vr), 49 : bitstream_buffer_id(bbid), timestamp(ts), visible_rect(vr),
50 natural_size(ns) { 50 natural_size(ns) {
51 } 51 }
52 52
53 GpuVideoDecoder::BufferData::~BufferData() {} 53 GpuVideoDecoder::BufferData::~BufferData() {}
54 54
55 GpuVideoDecoder::GpuVideoDecoder( 55 GpuVideoDecoder::GpuVideoDecoder(
56 const scoped_refptr<GpuVideoAcceleratorFactories>& factories, 56 const scoped_refptr<GpuVideoAcceleratorFactories>& factories,
57 const scoped_refptr<MediaLog>& media_log) 57 const scoped_refptr<MediaLog>& media_log)
58 : needs_bitstream_conversion_(false), 58 : needs_bitstream_conversion_(false),
59 gvd_loop_proxy_(factories->GetMessageLoop()), 59 gvd_task_runner_(factories->GetTaskRunner()),
60 weak_factory_(this), 60 weak_factory_(this),
61 factories_(factories), 61 factories_(factories),
62 state_(kNormal), 62 state_(kNormal),
63 media_log_(media_log), 63 media_log_(media_log),
64 decoder_texture_target_(0), 64 decoder_texture_target_(0),
65 next_picture_buffer_id_(0), 65 next_picture_buffer_id_(0),
66 next_bitstream_buffer_id_(0), 66 next_bitstream_buffer_id_(0),
67 available_pictures_(0) { 67 available_pictures_(0) {
68 DCHECK(factories_.get()); 68 DCHECK(factories_.get());
69 } 69 }
70 70
71 void GpuVideoDecoder::Reset(const base::Closure& closure) { 71 void GpuVideoDecoder::Reset(const base::Closure& closure) {
72 DVLOG(3) << "Reset()"; 72 DVLOG(3) << "Reset()";
73 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 73 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
74 74
75 if (state_ == kDrainingDecoder && !factories_->IsAborted()) { 75 if (state_ == kDrainingDecoder && !factories_->IsAborted()) {
76 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 76 gvd_task_runner_->PostTask(FROM_HERE, base::Bind(
77 &GpuVideoDecoder::Reset, weak_this_, closure)); 77 &GpuVideoDecoder::Reset, weak_this_, closure));
78 // NOTE: if we're deferring Reset() until a Flush() completes, return 78 // NOTE: if we're deferring Reset() until a Flush() completes, return
79 // queued pictures to the VDA so they can be used to finish that Flush(). 79 // queued pictures to the VDA so they can be used to finish that Flush().
80 if (pending_decode_cb_.is_null()) 80 if (pending_decode_cb_.is_null())
81 ready_video_frames_.clear(); 81 ready_video_frames_.clear();
82 return; 82 return;
83 } 83 }
84 84
85 // Throw away any already-decoded, not-yet-delivered frames. 85 // Throw away any already-decoded, not-yet-delivered frames.
86 ready_video_frames_.clear(); 86 ready_video_frames_.clear();
87 87
88 if (!vda_) { 88 if (!vda_) {
89 gvd_loop_proxy_->PostTask(FROM_HERE, closure); 89 gvd_task_runner_->PostTask(FROM_HERE, closure);
90 return; 90 return;
91 } 91 }
92 92
93 if (!pending_decode_cb_.is_null()) 93 if (!pending_decode_cb_.is_null())
94 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); 94 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame());
95 95
96 DCHECK(pending_reset_cb_.is_null()); 96 DCHECK(pending_reset_cb_.is_null());
97 pending_reset_cb_ = BindToCurrentLoop(closure); 97 pending_reset_cb_ = BindToCurrentLoop(closure);
98 98
99 vda_->Reset(); 99 vda_->Reset();
100 } 100 }
101 101
102 void GpuVideoDecoder::Stop(const base::Closure& closure) { 102 void GpuVideoDecoder::Stop(const base::Closure& closure) {
103 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 103 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
104 if (vda_) 104 if (vda_)
105 DestroyVDA(); 105 DestroyVDA();
106 if (!pending_decode_cb_.is_null()) 106 if (!pending_decode_cb_.is_null())
107 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); 107 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame());
108 if (!pending_reset_cb_.is_null()) 108 if (!pending_reset_cb_.is_null())
109 base::ResetAndReturn(&pending_reset_cb_).Run(); 109 base::ResetAndReturn(&pending_reset_cb_).Run();
110 BindToCurrentLoop(closure).Run(); 110 BindToCurrentLoop(closure).Run();
111 } 111 }
112 112
113 static bool IsCodedSizeSupported(const gfx::Size& coded_size) { 113 static bool IsCodedSizeSupported(const gfx::Size& coded_size) {
114 // Only non-Windows, Ivy Bridge+ platforms can support more than 1920x1080. 114 // Only non-Windows, Ivy Bridge+ platforms can support more than 1920x1080.
115 // We test against 1088 to account for 16x16 macroblocks. 115 // We test against 1088 to account for 16x16 macroblocks.
116 if (coded_size.width() <= 1920 && coded_size.height() <= 1088) 116 if (coded_size.width() <= 1920 && coded_size.height() <= 1088)
117 return true; 117 return true;
118 118
119 base::CPU cpu; 119 base::CPU cpu;
120 bool hw_large_video_support = 120 bool hw_large_video_support =
121 (cpu.vendor_name() == "GenuineIntel") && cpu.model() >= 58; 121 (cpu.vendor_name() == "GenuineIntel") && cpu.model() >= 58;
122 bool os_large_video_support = true; 122 bool os_large_video_support = true;
123 #if defined(OS_WIN) 123 #if defined(OS_WIN)
124 os_large_video_support = false; 124 os_large_video_support = false;
125 #endif 125 #endif
126 return os_large_video_support && hw_large_video_support; 126 return os_large_video_support && hw_large_video_support;
127 } 127 }
128 128
129 void GpuVideoDecoder::Initialize(const VideoDecoderConfig& config, 129 void GpuVideoDecoder::Initialize(const VideoDecoderConfig& config,
130 const PipelineStatusCB& orig_status_cb) { 130 const PipelineStatusCB& orig_status_cb) {
131 DVLOG(3) << "Initialize()"; 131 DVLOG(3) << "Initialize()";
132 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 132 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
133 DCHECK(config.IsValidConfig()); 133 DCHECK(config.IsValidConfig());
134 DCHECK(!config.is_encrypted()); 134 DCHECK(!config.is_encrypted());
135 135
136 weak_this_ = weak_factory_.GetWeakPtr(); 136 weak_this_ = weak_factory_.GetWeakPtr();
137 137
138 PipelineStatusCB status_cb = CreateUMAReportingPipelineCB( 138 PipelineStatusCB status_cb = CreateUMAReportingPipelineCB(
139 "Media.GpuVideoDecoderInitializeStatus", 139 "Media.GpuVideoDecoderInitializeStatus",
140 BindToCurrentLoop(orig_status_cb)); 140 BindToCurrentLoop(orig_status_cb));
141 141
142 bool previously_initialized = config_.IsValidConfig(); 142 bool previously_initialized = config_.IsValidConfig();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); 182 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED);
183 return; 183 return;
184 } 184 }
185 185
186 DVLOG(3) << "GpuVideoDecoder::Initialize() succeeded."; 186 DVLOG(3) << "GpuVideoDecoder::Initialize() succeeded.";
187 media_log_->SetStringProperty("video_decoder", "gpu"); 187 media_log_->SetStringProperty("video_decoder", "gpu");
188 status_cb.Run(PIPELINE_OK); 188 status_cb.Run(PIPELINE_OK);
189 } 189 }
190 190
191 void GpuVideoDecoder::DestroyPictureBuffers(PictureBufferMap* buffers) { 191 void GpuVideoDecoder::DestroyPictureBuffers(PictureBufferMap* buffers) {
192 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 192 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
193 for (PictureBufferMap::iterator it = buffers->begin(); it != buffers->end(); 193 for (PictureBufferMap::iterator it = buffers->begin(); it != buffers->end();
194 ++it) { 194 ++it) {
195 factories_->DeleteTexture(it->second.texture_id()); 195 factories_->DeleteTexture(it->second.texture_id());
196 } 196 }
197 197
198 buffers->clear(); 198 buffers->clear();
199 } 199 }
200 200
201 void GpuVideoDecoder::DestroyVDA() { 201 void GpuVideoDecoder::DestroyVDA() {
202 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 202 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
203 203
204 if (vda_) 204 if (vda_)
205 vda_.release()->Destroy(); 205 vda_.release()->Destroy();
206 206
207 DestroyPictureBuffers(&assigned_picture_buffers_); 207 DestroyPictureBuffers(&assigned_picture_buffers_);
208 // Not destroying PictureBuffers in |dismissed_picture_buffers_| yet, since 208 // Not destroying PictureBuffers in |dismissed_picture_buffers_| yet, since
209 // their textures may still be in use by the user of this GpuVideoDecoder. 209 // their textures may still be in use by the user of this GpuVideoDecoder.
210 } 210 }
211 211
212 void GpuVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, 212 void GpuVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer,
213 const DecodeCB& decode_cb) { 213 const DecodeCB& decode_cb) {
214 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 214 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
215 DCHECK(pending_reset_cb_.is_null()); 215 DCHECK(pending_reset_cb_.is_null());
216 DCHECK(pending_decode_cb_.is_null()); 216 DCHECK(pending_decode_cb_.is_null());
217 217
218 pending_decode_cb_ = BindToCurrentLoop(decode_cb); 218 pending_decode_cb_ = BindToCurrentLoop(decode_cb);
219 219
220 if (state_ == kError || !vda_) { 220 if (state_ == kError || !vda_) {
221 base::ResetAndReturn(&pending_decode_cb_).Run(kDecodeError, NULL); 221 base::ResetAndReturn(&pending_decode_cb_).Run(kDecodeError, NULL);
222 return; 222 return;
223 } 223 }
224 224
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 continue; 313 continue;
314 *timestamp = it->timestamp; 314 *timestamp = it->timestamp;
315 *visible_rect = it->visible_rect; 315 *visible_rect = it->visible_rect;
316 *natural_size = it->natural_size; 316 *natural_size = it->natural_size;
317 return; 317 return;
318 } 318 }
319 NOTREACHED() << "Missing bitstreambuffer id: " << id; 319 NOTREACHED() << "Missing bitstreambuffer id: " << id;
320 } 320 }
321 321
322 bool GpuVideoDecoder::HasAlpha() const { 322 bool GpuVideoDecoder::HasAlpha() const {
323 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 323 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
324 return true; 324 return true;
325 } 325 }
326 326
327 bool GpuVideoDecoder::NeedsBitstreamConversion() const { 327 bool GpuVideoDecoder::NeedsBitstreamConversion() const {
328 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 328 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
329 return needs_bitstream_conversion_; 329 return needs_bitstream_conversion_;
330 } 330 }
331 331
332 bool GpuVideoDecoder::CanReadWithoutStalling() const { 332 bool GpuVideoDecoder::CanReadWithoutStalling() const {
333 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 333 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
334 return available_pictures_ > 0 || !ready_video_frames_.empty(); 334 return available_pictures_ > 0 || !ready_video_frames_.empty();
335 } 335 }
336 336
337 void GpuVideoDecoder::NotifyInitializeDone() { 337 void GpuVideoDecoder::NotifyInitializeDone() {
338 NOTREACHED() << "GpuVideoDecodeAcceleratorHost::Initialize is synchronous!"; 338 NOTREACHED() << "GpuVideoDecodeAcceleratorHost::Initialize is synchronous!";
339 } 339 }
340 340
341 void GpuVideoDecoder::ProvidePictureBuffers(uint32 count, 341 void GpuVideoDecoder::ProvidePictureBuffers(uint32 count,
342 const gfx::Size& size, 342 const gfx::Size& size,
343 uint32 texture_target) { 343 uint32 texture_target) {
344 DVLOG(3) << "ProvidePictureBuffers(" << count << ", " 344 DVLOG(3) << "ProvidePictureBuffers(" << count << ", "
345 << size.width() << "x" << size.height() << ")"; 345 << size.width() << "x" << size.height() << ")";
346 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 346 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
347 347
348 std::vector<uint32> texture_ids; 348 std::vector<uint32> texture_ids;
349 std::vector<gpu::Mailbox> texture_mailboxes; 349 std::vector<gpu::Mailbox> texture_mailboxes;
350 decoder_texture_target_ = texture_target; 350 decoder_texture_target_ = texture_target;
351 // Discards the sync point returned here since PictureReady will imply that 351 // Discards the sync point returned here since PictureReady will imply that
352 // the produce has already happened, and the texture is ready for use. 352 // the produce has already happened, and the texture is ready for use.
353 if (!factories_->CreateTextures(count, 353 if (!factories_->CreateTextures(count,
354 size, 354 size,
355 &texture_ids, 355 &texture_ids,
356 &texture_mailboxes, 356 &texture_mailboxes,
(...skipping 16 matching lines...) Expand all
373 DCHECK(inserted); 373 DCHECK(inserted);
374 } 374 }
375 375
376 available_pictures_ += count; 376 available_pictures_ += count;
377 377
378 vda_->AssignPictureBuffers(picture_buffers); 378 vda_->AssignPictureBuffers(picture_buffers);
379 } 379 }
380 380
381 void GpuVideoDecoder::DismissPictureBuffer(int32 id) { 381 void GpuVideoDecoder::DismissPictureBuffer(int32 id) {
382 DVLOG(3) << "DismissPictureBuffer(" << id << ")"; 382 DVLOG(3) << "DismissPictureBuffer(" << id << ")";
383 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 383 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
384 384
385 PictureBufferMap::iterator it = assigned_picture_buffers_.find(id); 385 PictureBufferMap::iterator it = assigned_picture_buffers_.find(id);
386 if (it == assigned_picture_buffers_.end()) { 386 if (it == assigned_picture_buffers_.end()) {
387 NOTREACHED() << "Missing picture buffer: " << id; 387 NOTREACHED() << "Missing picture buffer: " << id;
388 return; 388 return;
389 } 389 }
390 390
391 PictureBuffer buffer_to_dismiss = it->second; 391 PictureBuffer buffer_to_dismiss = it->second;
392 assigned_picture_buffers_.erase(it); 392 assigned_picture_buffers_.erase(it);
393 393
394 std::set<int32>::iterator at_display_it = 394 std::set<int32>::iterator at_display_it =
395 picture_buffers_at_display_.find(id); 395 picture_buffers_at_display_.find(id);
396 396
397 if (at_display_it == picture_buffers_at_display_.end()) { 397 if (at_display_it == picture_buffers_at_display_.end()) {
398 // We can delete the texture immediately as it's not being displayed. 398 // We can delete the texture immediately as it's not being displayed.
399 factories_->DeleteTexture(buffer_to_dismiss.texture_id()); 399 factories_->DeleteTexture(buffer_to_dismiss.texture_id());
400 CHECK_GT(available_pictures_, 0); 400 CHECK_GT(available_pictures_, 0);
401 --available_pictures_; 401 --available_pictures_;
402 } else { 402 } else {
403 // Texture in display. Postpone deletion until after it's returned to us. 403 // Texture in display. Postpone deletion until after it's returned to us.
404 bool inserted = dismissed_picture_buffers_.insert(std::make_pair( 404 bool inserted = dismissed_picture_buffers_.insert(std::make_pair(
405 id, buffer_to_dismiss)).second; 405 id, buffer_to_dismiss)).second;
406 DCHECK(inserted); 406 DCHECK(inserted);
407 } 407 }
408 } 408 }
409 409
410 void GpuVideoDecoder::PictureReady(const media::Picture& picture) { 410 void GpuVideoDecoder::PictureReady(const media::Picture& picture) {
411 DVLOG(3) << "PictureReady()"; 411 DVLOG(3) << "PictureReady()";
412 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 412 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
413 413
414 PictureBufferMap::iterator it = 414 PictureBufferMap::iterator it =
415 assigned_picture_buffers_.find(picture.picture_buffer_id()); 415 assigned_picture_buffers_.find(picture.picture_buffer_id());
416 if (it == assigned_picture_buffers_.end()) { 416 if (it == assigned_picture_buffers_.end()) {
417 NOTREACHED() << "Missing picture buffer: " << picture.picture_buffer_id(); 417 NOTREACHED() << "Missing picture buffer: " << picture.picture_buffer_id();
418 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); 418 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE);
419 return; 419 return;
420 } 420 }
421 const PictureBuffer& pb = it->second; 421 const PictureBuffer& pb = it->second;
422 422
(...skipping 26 matching lines...) Expand all
449 --available_pictures_; 449 --available_pictures_;
450 bool inserted = 450 bool inserted =
451 picture_buffers_at_display_.insert(picture.picture_buffer_id()).second; 451 picture_buffers_at_display_.insert(picture.picture_buffer_id()).second;
452 DCHECK(inserted); 452 DCHECK(inserted);
453 453
454 EnqueueFrameAndTriggerFrameDelivery(frame); 454 EnqueueFrameAndTriggerFrameDelivery(frame);
455 } 455 }
456 456
457 void GpuVideoDecoder::EnqueueFrameAndTriggerFrameDelivery( 457 void GpuVideoDecoder::EnqueueFrameAndTriggerFrameDelivery(
458 const scoped_refptr<VideoFrame>& frame) { 458 const scoped_refptr<VideoFrame>& frame) {
459 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 459 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
460 460
461 // During a pending vda->Reset(), we don't accumulate frames. Drop it on the 461 // During a pending vda->Reset(), we don't accumulate frames. Drop it on the
462 // floor and return. 462 // floor and return.
463 if (!pending_reset_cb_.is_null()) 463 if (!pending_reset_cb_.is_null())
464 return; 464 return;
465 465
466 if (frame.get()) 466 if (frame.get())
467 ready_video_frames_.push_back(frame); 467 ready_video_frames_.push_back(frame);
468 else 468 else
469 DCHECK(!ready_video_frames_.empty()); 469 DCHECK(!ready_video_frames_.empty());
470 470
471 if (pending_decode_cb_.is_null()) 471 if (pending_decode_cb_.is_null())
472 return; 472 return;
473 473
474 base::ResetAndReturn(&pending_decode_cb_) 474 base::ResetAndReturn(&pending_decode_cb_)
475 .Run(kOk, ready_video_frames_.front()); 475 .Run(kOk, ready_video_frames_.front());
476 ready_video_frames_.pop_front(); 476 ready_video_frames_.pop_front();
477 } 477 }
478 478
479 void GpuVideoDecoder::ReusePictureBuffer(int64 picture_buffer_id, 479 void GpuVideoDecoder::ReusePictureBuffer(int64 picture_buffer_id,
480 uint32 sync_point) { 480 uint32 sync_point) {
481 DVLOG(3) << "ReusePictureBuffer(" << picture_buffer_id << ")"; 481 DVLOG(3) << "ReusePictureBuffer(" << picture_buffer_id << ")";
482 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 482 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
483 483
484 if (!vda_) 484 if (!vda_)
485 return; 485 return;
486 486
487 CHECK(!picture_buffers_at_display_.empty()); 487 CHECK(!picture_buffers_at_display_.empty());
488 488
489 size_t num_erased = picture_buffers_at_display_.erase(picture_buffer_id); 489 size_t num_erased = picture_buffers_at_display_.erase(picture_buffer_id);
490 DCHECK(num_erased); 490 DCHECK(num_erased);
491 491
492 PictureBufferMap::iterator it = 492 PictureBufferMap::iterator it =
493 assigned_picture_buffers_.find(picture_buffer_id); 493 assigned_picture_buffers_.find(picture_buffer_id);
494 494
495 if (it == assigned_picture_buffers_.end()) { 495 if (it == assigned_picture_buffers_.end()) {
496 // This picture was dismissed while in display, so we postponed deletion. 496 // This picture was dismissed while in display, so we postponed deletion.
497 it = dismissed_picture_buffers_.find(picture_buffer_id); 497 it = dismissed_picture_buffers_.find(picture_buffer_id);
498 DCHECK(it != dismissed_picture_buffers_.end()); 498 DCHECK(it != dismissed_picture_buffers_.end());
499 factories_->DeleteTexture(it->second.texture_id()); 499 factories_->DeleteTexture(it->second.texture_id());
500 dismissed_picture_buffers_.erase(it); 500 dismissed_picture_buffers_.erase(it);
501 return; 501 return;
502 } 502 }
503 503
504 factories_->WaitSyncPoint(sync_point); 504 factories_->WaitSyncPoint(sync_point);
505 ++available_pictures_; 505 ++available_pictures_;
506 506
507 vda_->ReusePictureBuffer(picture_buffer_id); 507 vda_->ReusePictureBuffer(picture_buffer_id);
508 } 508 }
509 509
510 GpuVideoDecoder::SHMBuffer* GpuVideoDecoder::GetSHM(size_t min_size) { 510 GpuVideoDecoder::SHMBuffer* GpuVideoDecoder::GetSHM(size_t min_size) {
511 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 511 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
512 if (available_shm_segments_.empty() || 512 if (available_shm_segments_.empty() ||
513 available_shm_segments_.back()->size < min_size) { 513 available_shm_segments_.back()->size < min_size) {
514 size_t size_to_allocate = std::max(min_size, kSharedMemorySegmentBytes); 514 size_t size_to_allocate = std::max(min_size, kSharedMemorySegmentBytes);
515 base::SharedMemory* shm = factories_->CreateSharedMemory(size_to_allocate); 515 base::SharedMemory* shm = factories_->CreateSharedMemory(size_to_allocate);
516 // CreateSharedMemory() can return NULL during Shutdown. 516 // CreateSharedMemory() can return NULL during Shutdown.
517 if (!shm) 517 if (!shm)
518 return NULL; 518 return NULL;
519 return new SHMBuffer(shm, size_to_allocate); 519 return new SHMBuffer(shm, size_to_allocate);
520 } 520 }
521 SHMBuffer* ret = available_shm_segments_.back(); 521 SHMBuffer* ret = available_shm_segments_.back();
522 available_shm_segments_.pop_back(); 522 available_shm_segments_.pop_back();
523 return ret; 523 return ret;
524 } 524 }
525 525
526 void GpuVideoDecoder::PutSHM(SHMBuffer* shm_buffer) { 526 void GpuVideoDecoder::PutSHM(SHMBuffer* shm_buffer) {
527 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 527 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
528 available_shm_segments_.push_back(shm_buffer); 528 available_shm_segments_.push_back(shm_buffer);
529 } 529 }
530 530
531 void GpuVideoDecoder::NotifyEndOfBitstreamBuffer(int32 id) { 531 void GpuVideoDecoder::NotifyEndOfBitstreamBuffer(int32 id) {
532 DVLOG(3) << "NotifyEndOfBitstreamBuffer(" << id << ")"; 532 DVLOG(3) << "NotifyEndOfBitstreamBuffer(" << id << ")";
533 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 533 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
534 534
535 std::map<int32, BufferPair>::iterator it = 535 std::map<int32, BufferPair>::iterator it =
536 bitstream_buffers_in_decoder_.find(id); 536 bitstream_buffers_in_decoder_.find(id);
537 if (it == bitstream_buffers_in_decoder_.end()) { 537 if (it == bitstream_buffers_in_decoder_.end()) {
538 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); 538 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE);
539 NOTREACHED() << "Missing bitstream buffer: " << id; 539 NOTREACHED() << "Missing bitstream buffer: " << id;
540 return; 540 return;
541 } 541 }
542 542
543 PutSHM(it->second.shm_buffer); 543 PutSHM(it->second.shm_buffer);
544 bitstream_buffers_in_decoder_.erase(it); 544 bitstream_buffers_in_decoder_.erase(it);
545 545
546 if (pending_reset_cb_.is_null() && state_ != kDrainingDecoder && 546 if (pending_reset_cb_.is_null() && state_ != kDrainingDecoder &&
547 CanMoreDecodeWorkBeDone() && !pending_decode_cb_.is_null()) { 547 CanMoreDecodeWorkBeDone() && !pending_decode_cb_.is_null()) {
548 base::ResetAndReturn(&pending_decode_cb_).Run(kNotEnoughData, NULL); 548 base::ResetAndReturn(&pending_decode_cb_).Run(kNotEnoughData, NULL);
549 } 549 }
550 } 550 }
551 551
552 GpuVideoDecoder::~GpuVideoDecoder() { 552 GpuVideoDecoder::~GpuVideoDecoder() {
553 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 553 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
554 DCHECK(!vda_.get()); // Stop should have been already called. 554 DCHECK(!vda_.get()); // Stop should have been already called.
555 DCHECK(pending_decode_cb_.is_null()); 555 DCHECK(pending_decode_cb_.is_null());
556 for (size_t i = 0; i < available_shm_segments_.size(); ++i) { 556 for (size_t i = 0; i < available_shm_segments_.size(); ++i) {
557 available_shm_segments_[i]->shm->Close(); 557 available_shm_segments_[i]->shm->Close();
558 delete available_shm_segments_[i]; 558 delete available_shm_segments_[i];
559 } 559 }
560 available_shm_segments_.clear(); 560 available_shm_segments_.clear();
561 for (std::map<int32, BufferPair>::iterator it = 561 for (std::map<int32, BufferPair>::iterator it =
562 bitstream_buffers_in_decoder_.begin(); 562 bitstream_buffers_in_decoder_.begin();
563 it != bitstream_buffers_in_decoder_.end(); ++it) { 563 it != bitstream_buffers_in_decoder_.end(); ++it) {
564 it->second.shm_buffer->shm->Close(); 564 it->second.shm_buffer->shm->Close();
565 } 565 }
566 bitstream_buffers_in_decoder_.clear(); 566 bitstream_buffers_in_decoder_.clear();
567 567
568 DestroyPictureBuffers(&assigned_picture_buffers_); 568 DestroyPictureBuffers(&assigned_picture_buffers_);
569 DestroyPictureBuffers(&dismissed_picture_buffers_); 569 DestroyPictureBuffers(&dismissed_picture_buffers_);
570 } 570 }
571 571
572 void GpuVideoDecoder::NotifyFlushDone() { 572 void GpuVideoDecoder::NotifyFlushDone() {
573 DVLOG(3) << "NotifyFlushDone()"; 573 DVLOG(3) << "NotifyFlushDone()";
574 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 574 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
575 DCHECK_EQ(state_, kDrainingDecoder); 575 DCHECK_EQ(state_, kDrainingDecoder);
576 state_ = kDecoderDrained; 576 state_ = kDecoderDrained;
577 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); 577 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame());
578 } 578 }
579 579
580 void GpuVideoDecoder::NotifyResetDone() { 580 void GpuVideoDecoder::NotifyResetDone() {
581 DVLOG(3) << "NotifyResetDone()"; 581 DVLOG(3) << "NotifyResetDone()";
582 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 582 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
583 DCHECK(ready_video_frames_.empty()); 583 DCHECK(ready_video_frames_.empty());
584 584
585 // This needs to happen after the Reset() on vda_ is done to ensure pictures 585 // This needs to happen after the Reset() on vda_ is done to ensure pictures
586 // delivered during the reset can find their time data. 586 // delivered during the reset can find their time data.
587 input_buffer_data_.clear(); 587 input_buffer_data_.clear();
588 588
589 if (!pending_reset_cb_.is_null()) 589 if (!pending_reset_cb_.is_null())
590 base::ResetAndReturn(&pending_reset_cb_).Run(); 590 base::ResetAndReturn(&pending_reset_cb_).Run();
591 591
592 if (!pending_decode_cb_.is_null()) 592 if (!pending_decode_cb_.is_null())
593 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); 593 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame());
594 } 594 }
595 595
596 void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) { 596 void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) {
597 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 597 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
598 if (!vda_) 598 if (!vda_)
599 return; 599 return;
600 600
601 DLOG(ERROR) << "VDA Error: " << error; 601 DLOG(ERROR) << "VDA Error: " << error;
602 DestroyVDA(); 602 DestroyVDA();
603 603
604 state_ = kError; 604 state_ = kError;
605 605
606 if (!pending_decode_cb_.is_null()) { 606 if (!pending_decode_cb_.is_null()) {
607 base::ResetAndReturn(&pending_decode_cb_).Run(kDecodeError, NULL); 607 base::ResetAndReturn(&pending_decode_cb_).Run(kDecodeError, NULL);
608 return; 608 return;
609 } 609 }
610 } 610 }
611 611
612 } // namespace media 612 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698