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

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: rebase Created 7 years 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
« no previous file with comments | « media/filters/gpu_video_decoder.h ('k') | media/filters/mock_gpu_video_accelerator_factories.h » ('j') | 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"
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 : bitstream_buffer_id(bbid), timestamp(ts), visible_rect(vr), 50 : bitstream_buffer_id(bbid), timestamp(ts), visible_rect(vr),
51 natural_size(ns) { 51 natural_size(ns) {
52 } 52 }
53 53
54 GpuVideoDecoder::BufferData::~BufferData() {} 54 GpuVideoDecoder::BufferData::~BufferData() {}
55 55
56 GpuVideoDecoder::GpuVideoDecoder( 56 GpuVideoDecoder::GpuVideoDecoder(
57 const scoped_refptr<GpuVideoAcceleratorFactories>& factories, 57 const scoped_refptr<GpuVideoAcceleratorFactories>& factories,
58 const scoped_refptr<MediaLog>& media_log) 58 const scoped_refptr<MediaLog>& media_log)
59 : needs_bitstream_conversion_(false), 59 : needs_bitstream_conversion_(false),
60 gvd_loop_proxy_(factories->GetMessageLoop()), 60 gvd_task_runner_(factories->GetTaskRunner()),
61 weak_factory_(this), 61 weak_factory_(this),
62 factories_(factories), 62 factories_(factories),
63 state_(kNormal), 63 state_(kNormal),
64 media_log_(media_log), 64 media_log_(media_log),
65 decoder_texture_target_(0), 65 decoder_texture_target_(0),
66 next_picture_buffer_id_(0), 66 next_picture_buffer_id_(0),
67 next_bitstream_buffer_id_(0), 67 next_bitstream_buffer_id_(0),
68 available_pictures_(0) { 68 available_pictures_(0) {
69 DCHECK(factories_.get()); 69 DCHECK(factories_.get());
70 } 70 }
71 71
72 void GpuVideoDecoder::Reset(const base::Closure& closure) { 72 void GpuVideoDecoder::Reset(const base::Closure& closure) {
73 DVLOG(3) << "Reset()"; 73 DVLOG(3) << "Reset()";
74 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 74 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
75 75
76 if (state_ == kDrainingDecoder && !factories_->IsAborted()) { 76 if (state_ == kDrainingDecoder && !factories_->IsAborted()) {
77 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 77 gvd_task_runner_->PostTask(FROM_HERE, base::Bind(
78 &GpuVideoDecoder::Reset, weak_this_, closure)); 78 &GpuVideoDecoder::Reset, weak_this_, closure));
79 // NOTE: if we're deferring Reset() until a Flush() completes, return 79 // NOTE: if we're deferring Reset() until a Flush() completes, return
80 // queued pictures to the VDA so they can be used to finish that Flush(). 80 // queued pictures to the VDA so they can be used to finish that Flush().
81 if (pending_decode_cb_.is_null()) 81 if (pending_decode_cb_.is_null())
82 ready_video_frames_.clear(); 82 ready_video_frames_.clear();
83 return; 83 return;
84 } 84 }
85 85
86 // Throw away any already-decoded, not-yet-delivered frames. 86 // Throw away any already-decoded, not-yet-delivered frames.
87 ready_video_frames_.clear(); 87 ready_video_frames_.clear();
88 88
89 if (!vda_) { 89 if (!vda_) {
90 gvd_loop_proxy_->PostTask(FROM_HERE, closure); 90 gvd_task_runner_->PostTask(FROM_HERE, closure);
91 return; 91 return;
92 } 92 }
93 93
94 if (!pending_decode_cb_.is_null()) 94 if (!pending_decode_cb_.is_null())
95 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEOSFrame()); 95 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEOSFrame());
96 96
97 DCHECK(pending_reset_cb_.is_null()); 97 DCHECK(pending_reset_cb_.is_null());
98 pending_reset_cb_ = BindToCurrentLoop(closure); 98 pending_reset_cb_ = BindToCurrentLoop(closure);
99 99
100 vda_->Reset(); 100 vda_->Reset();
101 } 101 }
102 102
103 void GpuVideoDecoder::Stop(const base::Closure& closure) { 103 void GpuVideoDecoder::Stop(const base::Closure& closure) {
104 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 104 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
105 if (vda_) 105 if (vda_)
106 DestroyVDA(); 106 DestroyVDA();
107 if (!pending_decode_cb_.is_null()) 107 if (!pending_decode_cb_.is_null())
108 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEOSFrame()); 108 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEOSFrame());
109 if (!pending_reset_cb_.is_null()) 109 if (!pending_reset_cb_.is_null())
110 base::ResetAndReturn(&pending_reset_cb_).Run(); 110 base::ResetAndReturn(&pending_reset_cb_).Run();
111 BindToCurrentLoop(closure).Run(); 111 BindToCurrentLoop(closure).Run();
112 } 112 }
113 113
114 static bool IsCodedSizeSupported(const gfx::Size& coded_size) { 114 static bool IsCodedSizeSupported(const gfx::Size& coded_size) {
(...skipping 19 matching lines...) Expand all
134 const PipelineStatusCB& cb, 134 const PipelineStatusCB& cb,
135 PipelineStatus status) { 135 PipelineStatus status) {
136 UMA_HISTOGRAM_ENUMERATION( 136 UMA_HISTOGRAM_ENUMERATION(
137 "Media.GpuVideoDecoderInitializeStatus", status, PIPELINE_STATUS_MAX); 137 "Media.GpuVideoDecoderInitializeStatus", status, PIPELINE_STATUS_MAX);
138 cb.Run(status); 138 cb.Run(status);
139 } 139 }
140 140
141 void GpuVideoDecoder::Initialize(const VideoDecoderConfig& config, 141 void GpuVideoDecoder::Initialize(const VideoDecoderConfig& config,
142 const PipelineStatusCB& orig_status_cb) { 142 const PipelineStatusCB& orig_status_cb) {
143 DVLOG(3) << "Initialize()"; 143 DVLOG(3) << "Initialize()";
144 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 144 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
145 DCHECK(config.IsValidConfig()); 145 DCHECK(config.IsValidConfig());
146 DCHECK(!config.is_encrypted()); 146 DCHECK(!config.is_encrypted());
147 147
148 weak_this_ = weak_factory_.GetWeakPtr(); 148 weak_this_ = weak_factory_.GetWeakPtr();
149 149
150 PipelineStatusCB status_cb = 150 PipelineStatusCB status_cb =
151 base::Bind(&ReportGpuVideoDecoderInitializeStatusToUMAAndRunCB, 151 base::Bind(&ReportGpuVideoDecoderInitializeStatusToUMAAndRunCB,
152 BindToCurrentLoop(orig_status_cb)); 152 BindToCurrentLoop(orig_status_cb));
153 153
154 bool previously_initialized = config_.IsValidConfig(); 154 bool previously_initialized = config_.IsValidConfig();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); 194 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED);
195 return; 195 return;
196 } 196 }
197 197
198 DVLOG(3) << "GpuVideoDecoder::Initialize() succeeded."; 198 DVLOG(3) << "GpuVideoDecoder::Initialize() succeeded.";
199 media_log_->SetStringProperty("video_decoder", "gpu"); 199 media_log_->SetStringProperty("video_decoder", "gpu");
200 status_cb.Run(PIPELINE_OK); 200 status_cb.Run(PIPELINE_OK);
201 } 201 }
202 202
203 void GpuVideoDecoder::DestroyPictureBuffers(PictureBufferMap* buffers) { 203 void GpuVideoDecoder::DestroyPictureBuffers(PictureBufferMap* buffers) {
204 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 204 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
205 for (PictureBufferMap::iterator it = buffers->begin(); it != buffers->end(); 205 for (PictureBufferMap::iterator it = buffers->begin(); it != buffers->end();
206 ++it) { 206 ++it) {
207 factories_->DeleteTexture(it->second.texture_id()); 207 factories_->DeleteTexture(it->second.texture_id());
208 } 208 }
209 209
210 buffers->clear(); 210 buffers->clear();
211 } 211 }
212 212
213 void GpuVideoDecoder::DestroyVDA() { 213 void GpuVideoDecoder::DestroyVDA() {
214 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 214 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
215 215
216 if (vda_) 216 if (vda_)
217 vda_.release()->Destroy(); 217 vda_.release()->Destroy();
218 218
219 DestroyPictureBuffers(&assigned_picture_buffers_); 219 DestroyPictureBuffers(&assigned_picture_buffers_);
220 // Not destroying PictureBuffers in |dismissed_picture_buffers_| yet, since 220 // Not destroying PictureBuffers in |dismissed_picture_buffers_| yet, since
221 // their textures may still be in use by the user of this GpuVideoDecoder. 221 // their textures may still be in use by the user of this GpuVideoDecoder.
222 } 222 }
223 223
224 void GpuVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, 224 void GpuVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer,
225 const DecodeCB& decode_cb) { 225 const DecodeCB& decode_cb) {
226 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 226 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
227 DCHECK(pending_reset_cb_.is_null()); 227 DCHECK(pending_reset_cb_.is_null());
228 DCHECK(pending_decode_cb_.is_null()); 228 DCHECK(pending_decode_cb_.is_null());
229 229
230 pending_decode_cb_ = BindToCurrentLoop(decode_cb); 230 pending_decode_cb_ = BindToCurrentLoop(decode_cb);
231 231
232 if (state_ == kError || !vda_) { 232 if (state_ == kError || !vda_) {
233 base::ResetAndReturn(&pending_decode_cb_).Run(kDecodeError, NULL); 233 base::ResetAndReturn(&pending_decode_cb_).Run(kDecodeError, NULL);
234 return; 234 return;
235 } 235 }
236 236
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 continue; 325 continue;
326 *timestamp = it->timestamp; 326 *timestamp = it->timestamp;
327 *visible_rect = it->visible_rect; 327 *visible_rect = it->visible_rect;
328 *natural_size = it->natural_size; 328 *natural_size = it->natural_size;
329 return; 329 return;
330 } 330 }
331 NOTREACHED() << "Missing bitstreambuffer id: " << id; 331 NOTREACHED() << "Missing bitstreambuffer id: " << id;
332 } 332 }
333 333
334 bool GpuVideoDecoder::HasAlpha() const { 334 bool GpuVideoDecoder::HasAlpha() const {
335 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 335 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
336 return true; 336 return true;
337 } 337 }
338 338
339 bool GpuVideoDecoder::NeedsBitstreamConversion() const { 339 bool GpuVideoDecoder::NeedsBitstreamConversion() const {
340 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 340 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
341 return needs_bitstream_conversion_; 341 return needs_bitstream_conversion_;
342 } 342 }
343 343
344 bool GpuVideoDecoder::CanReadWithoutStalling() const { 344 bool GpuVideoDecoder::CanReadWithoutStalling() const {
345 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 345 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
346 return 346 return
347 next_picture_buffer_id_ == 0 || // Decode() will ProvidePictureBuffers(). 347 next_picture_buffer_id_ == 0 || // Decode() will ProvidePictureBuffers().
348 available_pictures_ > 0 || !ready_video_frames_.empty(); 348 available_pictures_ > 0 || !ready_video_frames_.empty();
349 } 349 }
350 350
351 void GpuVideoDecoder::NotifyInitializeDone() { 351 void GpuVideoDecoder::NotifyInitializeDone() {
352 NOTREACHED() << "GpuVideoDecodeAcceleratorHost::Initialize is synchronous!"; 352 NOTREACHED() << "GpuVideoDecodeAcceleratorHost::Initialize is synchronous!";
353 } 353 }
354 354
355 void GpuVideoDecoder::ProvidePictureBuffers(uint32 count, 355 void GpuVideoDecoder::ProvidePictureBuffers(uint32 count,
356 const gfx::Size& size, 356 const gfx::Size& size,
357 uint32 texture_target) { 357 uint32 texture_target) {
358 DVLOG(3) << "ProvidePictureBuffers(" << count << ", " 358 DVLOG(3) << "ProvidePictureBuffers(" << count << ", "
359 << size.width() << "x" << size.height() << ")"; 359 << size.width() << "x" << size.height() << ")";
360 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 360 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
361 361
362 std::vector<uint32> texture_ids; 362 std::vector<uint32> texture_ids;
363 std::vector<gpu::Mailbox> texture_mailboxes; 363 std::vector<gpu::Mailbox> texture_mailboxes;
364 decoder_texture_target_ = texture_target; 364 decoder_texture_target_ = texture_target;
365 // Discards the sync point returned here since PictureReady will imply that 365 // Discards the sync point returned here since PictureReady will imply that
366 // the produce has already happened, and the texture is ready for use. 366 // the produce has already happened, and the texture is ready for use.
367 if (!factories_->CreateTextures(count, 367 if (!factories_->CreateTextures(count,
368 size, 368 size,
369 &texture_ids, 369 &texture_ids,
370 &texture_mailboxes, 370 &texture_mailboxes,
(...skipping 16 matching lines...) Expand all
387 DCHECK(inserted); 387 DCHECK(inserted);
388 } 388 }
389 389
390 available_pictures_ += count; 390 available_pictures_ += count;
391 391
392 vda_->AssignPictureBuffers(picture_buffers); 392 vda_->AssignPictureBuffers(picture_buffers);
393 } 393 }
394 394
395 void GpuVideoDecoder::DismissPictureBuffer(int32 id) { 395 void GpuVideoDecoder::DismissPictureBuffer(int32 id) {
396 DVLOG(3) << "DismissPictureBuffer(" << id << ")"; 396 DVLOG(3) << "DismissPictureBuffer(" << id << ")";
397 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 397 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
398 398
399 PictureBufferMap::iterator it = assigned_picture_buffers_.find(id); 399 PictureBufferMap::iterator it = assigned_picture_buffers_.find(id);
400 if (it == assigned_picture_buffers_.end()) { 400 if (it == assigned_picture_buffers_.end()) {
401 NOTREACHED() << "Missing picture buffer: " << id; 401 NOTREACHED() << "Missing picture buffer: " << id;
402 return; 402 return;
403 } 403 }
404 404
405 PictureBuffer buffer_to_dismiss = it->second; 405 PictureBuffer buffer_to_dismiss = it->second;
406 assigned_picture_buffers_.erase(it); 406 assigned_picture_buffers_.erase(it);
407 407
408 std::set<int32>::iterator at_display_it = 408 std::set<int32>::iterator at_display_it =
409 picture_buffers_at_display_.find(id); 409 picture_buffers_at_display_.find(id);
410 410
411 if (at_display_it == picture_buffers_at_display_.end()) { 411 if (at_display_it == picture_buffers_at_display_.end()) {
412 // We can delete the texture immediately as it's not being displayed. 412 // We can delete the texture immediately as it's not being displayed.
413 factories_->DeleteTexture(buffer_to_dismiss.texture_id()); 413 factories_->DeleteTexture(buffer_to_dismiss.texture_id());
414 CHECK_GT(available_pictures_, 0); 414 CHECK_GT(available_pictures_, 0);
415 --available_pictures_; 415 --available_pictures_;
416 } else { 416 } else {
417 // Texture in display. Postpone deletion until after it's returned to us. 417 // Texture in display. Postpone deletion until after it's returned to us.
418 bool inserted = dismissed_picture_buffers_.insert(std::make_pair( 418 bool inserted = dismissed_picture_buffers_.insert(std::make_pair(
419 id, buffer_to_dismiss)).second; 419 id, buffer_to_dismiss)).second;
420 DCHECK(inserted); 420 DCHECK(inserted);
421 } 421 }
422 } 422 }
423 423
424 void GpuVideoDecoder::PictureReady(const media::Picture& picture) { 424 void GpuVideoDecoder::PictureReady(const media::Picture& picture) {
425 DVLOG(3) << "PictureReady()"; 425 DVLOG(3) << "PictureReady()";
426 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 426 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
427 427
428 PictureBufferMap::iterator it = 428 PictureBufferMap::iterator it =
429 assigned_picture_buffers_.find(picture.picture_buffer_id()); 429 assigned_picture_buffers_.find(picture.picture_buffer_id());
430 if (it == assigned_picture_buffers_.end()) { 430 if (it == assigned_picture_buffers_.end()) {
431 NOTREACHED() << "Missing picture buffer: " << picture.picture_buffer_id(); 431 NOTREACHED() << "Missing picture buffer: " << picture.picture_buffer_id();
432 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); 432 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE);
433 return; 433 return;
434 } 434 }
435 const PictureBuffer& pb = it->second; 435 const PictureBuffer& pb = it->second;
436 436
(...skipping 26 matching lines...) Expand all
463 --available_pictures_; 463 --available_pictures_;
464 bool inserted = 464 bool inserted =
465 picture_buffers_at_display_.insert(picture.picture_buffer_id()).second; 465 picture_buffers_at_display_.insert(picture.picture_buffer_id()).second;
466 DCHECK(inserted); 466 DCHECK(inserted);
467 467
468 EnqueueFrameAndTriggerFrameDelivery(frame); 468 EnqueueFrameAndTriggerFrameDelivery(frame);
469 } 469 }
470 470
471 void GpuVideoDecoder::EnqueueFrameAndTriggerFrameDelivery( 471 void GpuVideoDecoder::EnqueueFrameAndTriggerFrameDelivery(
472 const scoped_refptr<VideoFrame>& frame) { 472 const scoped_refptr<VideoFrame>& frame) {
473 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 473 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
474 474
475 // During a pending vda->Reset(), we don't accumulate frames. Drop it on the 475 // During a pending vda->Reset(), we don't accumulate frames. Drop it on the
476 // floor and return. 476 // floor and return.
477 if (!pending_reset_cb_.is_null()) 477 if (!pending_reset_cb_.is_null())
478 return; 478 return;
479 479
480 if (frame.get()) 480 if (frame.get())
481 ready_video_frames_.push_back(frame); 481 ready_video_frames_.push_back(frame);
482 else 482 else
483 DCHECK(!ready_video_frames_.empty()); 483 DCHECK(!ready_video_frames_.empty());
484 484
485 if (pending_decode_cb_.is_null()) 485 if (pending_decode_cb_.is_null())
486 return; 486 return;
487 487
488 base::ResetAndReturn(&pending_decode_cb_) 488 base::ResetAndReturn(&pending_decode_cb_)
489 .Run(kOk, ready_video_frames_.front()); 489 .Run(kOk, ready_video_frames_.front());
490 ready_video_frames_.pop_front(); 490 ready_video_frames_.pop_front();
491 } 491 }
492 492
493 void GpuVideoDecoder::ReusePictureBuffer(int64 picture_buffer_id, 493 void GpuVideoDecoder::ReusePictureBuffer(int64 picture_buffer_id,
494 uint32 sync_point) { 494 uint32 sync_point) {
495 DVLOG(3) << "ReusePictureBuffer(" << picture_buffer_id << ")"; 495 DVLOG(3) << "ReusePictureBuffer(" << picture_buffer_id << ")";
496 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 496 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
497 497
498 if (!vda_) 498 if (!vda_)
499 return; 499 return;
500 500
501 CHECK(!picture_buffers_at_display_.empty()); 501 CHECK(!picture_buffers_at_display_.empty());
502 502
503 size_t num_erased = picture_buffers_at_display_.erase(picture_buffer_id); 503 size_t num_erased = picture_buffers_at_display_.erase(picture_buffer_id);
504 DCHECK(num_erased); 504 DCHECK(num_erased);
505 505
506 PictureBufferMap::iterator it = 506 PictureBufferMap::iterator it =
507 assigned_picture_buffers_.find(picture_buffer_id); 507 assigned_picture_buffers_.find(picture_buffer_id);
508 508
509 if (it == assigned_picture_buffers_.end()) { 509 if (it == assigned_picture_buffers_.end()) {
510 // This picture was dismissed while in display, so we postponed deletion. 510 // This picture was dismissed while in display, so we postponed deletion.
511 it = dismissed_picture_buffers_.find(picture_buffer_id); 511 it = dismissed_picture_buffers_.find(picture_buffer_id);
512 DCHECK(it != dismissed_picture_buffers_.end()); 512 DCHECK(it != dismissed_picture_buffers_.end());
513 factories_->DeleteTexture(it->second.texture_id()); 513 factories_->DeleteTexture(it->second.texture_id());
514 dismissed_picture_buffers_.erase(it); 514 dismissed_picture_buffers_.erase(it);
515 return; 515 return;
516 } 516 }
517 517
518 factories_->WaitSyncPoint(sync_point); 518 factories_->WaitSyncPoint(sync_point);
519 ++available_pictures_; 519 ++available_pictures_;
520 520
521 vda_->ReusePictureBuffer(picture_buffer_id); 521 vda_->ReusePictureBuffer(picture_buffer_id);
522 } 522 }
523 523
524 GpuVideoDecoder::SHMBuffer* GpuVideoDecoder::GetSHM(size_t min_size) { 524 GpuVideoDecoder::SHMBuffer* GpuVideoDecoder::GetSHM(size_t min_size) {
525 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 525 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
526 if (available_shm_segments_.empty() || 526 if (available_shm_segments_.empty() ||
527 available_shm_segments_.back()->size < min_size) { 527 available_shm_segments_.back()->size < min_size) {
528 size_t size_to_allocate = std::max(min_size, kSharedMemorySegmentBytes); 528 size_t size_to_allocate = std::max(min_size, kSharedMemorySegmentBytes);
529 base::SharedMemory* shm = factories_->CreateSharedMemory(size_to_allocate); 529 base::SharedMemory* shm = factories_->CreateSharedMemory(size_to_allocate);
530 // CreateSharedMemory() can return NULL during Shutdown. 530 // CreateSharedMemory() can return NULL during Shutdown.
531 if (!shm) 531 if (!shm)
532 return NULL; 532 return NULL;
533 return new SHMBuffer(shm, size_to_allocate); 533 return new SHMBuffer(shm, size_to_allocate);
534 } 534 }
535 SHMBuffer* ret = available_shm_segments_.back(); 535 SHMBuffer* ret = available_shm_segments_.back();
536 available_shm_segments_.pop_back(); 536 available_shm_segments_.pop_back();
537 return ret; 537 return ret;
538 } 538 }
539 539
540 void GpuVideoDecoder::PutSHM(SHMBuffer* shm_buffer) { 540 void GpuVideoDecoder::PutSHM(SHMBuffer* shm_buffer) {
541 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 541 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
542 available_shm_segments_.push_back(shm_buffer); 542 available_shm_segments_.push_back(shm_buffer);
543 } 543 }
544 544
545 void GpuVideoDecoder::NotifyEndOfBitstreamBuffer(int32 id) { 545 void GpuVideoDecoder::NotifyEndOfBitstreamBuffer(int32 id) {
546 DVLOG(3) << "NotifyEndOfBitstreamBuffer(" << id << ")"; 546 DVLOG(3) << "NotifyEndOfBitstreamBuffer(" << id << ")";
547 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 547 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
548 548
549 std::map<int32, BufferPair>::iterator it = 549 std::map<int32, BufferPair>::iterator it =
550 bitstream_buffers_in_decoder_.find(id); 550 bitstream_buffers_in_decoder_.find(id);
551 if (it == bitstream_buffers_in_decoder_.end()) { 551 if (it == bitstream_buffers_in_decoder_.end()) {
552 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); 552 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE);
553 NOTREACHED() << "Missing bitstream buffer: " << id; 553 NOTREACHED() << "Missing bitstream buffer: " << id;
554 return; 554 return;
555 } 555 }
556 556
557 PutSHM(it->second.shm_buffer); 557 PutSHM(it->second.shm_buffer);
558 bitstream_buffers_in_decoder_.erase(it); 558 bitstream_buffers_in_decoder_.erase(it);
559 559
560 if (pending_reset_cb_.is_null() && state_ != kDrainingDecoder && 560 if (pending_reset_cb_.is_null() && state_ != kDrainingDecoder &&
561 CanMoreDecodeWorkBeDone() && !pending_decode_cb_.is_null()) { 561 CanMoreDecodeWorkBeDone() && !pending_decode_cb_.is_null()) {
562 base::ResetAndReturn(&pending_decode_cb_).Run(kNotEnoughData, NULL); 562 base::ResetAndReturn(&pending_decode_cb_).Run(kNotEnoughData, NULL);
563 } 563 }
564 } 564 }
565 565
566 GpuVideoDecoder::~GpuVideoDecoder() { 566 GpuVideoDecoder::~GpuVideoDecoder() {
567 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 567 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
568 DCHECK(!vda_.get()); // Stop should have been already called. 568 DCHECK(!vda_.get()); // Stop should have been already called.
569 DCHECK(pending_decode_cb_.is_null()); 569 DCHECK(pending_decode_cb_.is_null());
570 for (size_t i = 0; i < available_shm_segments_.size(); ++i) { 570 for (size_t i = 0; i < available_shm_segments_.size(); ++i) {
571 available_shm_segments_[i]->shm->Close(); 571 available_shm_segments_[i]->shm->Close();
572 delete available_shm_segments_[i]; 572 delete available_shm_segments_[i];
573 } 573 }
574 available_shm_segments_.clear(); 574 available_shm_segments_.clear();
575 for (std::map<int32, BufferPair>::iterator it = 575 for (std::map<int32, BufferPair>::iterator it =
576 bitstream_buffers_in_decoder_.begin(); 576 bitstream_buffers_in_decoder_.begin();
577 it != bitstream_buffers_in_decoder_.end(); ++it) { 577 it != bitstream_buffers_in_decoder_.end(); ++it) {
578 it->second.shm_buffer->shm->Close(); 578 it->second.shm_buffer->shm->Close();
579 } 579 }
580 bitstream_buffers_in_decoder_.clear(); 580 bitstream_buffers_in_decoder_.clear();
581 581
582 DestroyPictureBuffers(&assigned_picture_buffers_); 582 DestroyPictureBuffers(&assigned_picture_buffers_);
583 DestroyPictureBuffers(&dismissed_picture_buffers_); 583 DestroyPictureBuffers(&dismissed_picture_buffers_);
584 } 584 }
585 585
586 void GpuVideoDecoder::NotifyFlushDone() { 586 void GpuVideoDecoder::NotifyFlushDone() {
587 DVLOG(3) << "NotifyFlushDone()"; 587 DVLOG(3) << "NotifyFlushDone()";
588 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 588 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
589 DCHECK_EQ(state_, kDrainingDecoder); 589 DCHECK_EQ(state_, kDrainingDecoder);
590 state_ = kDecoderDrained; 590 state_ = kDecoderDrained;
591 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEOSFrame()); 591 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEOSFrame());
592 } 592 }
593 593
594 void GpuVideoDecoder::NotifyResetDone() { 594 void GpuVideoDecoder::NotifyResetDone() {
595 DVLOG(3) << "NotifyResetDone()"; 595 DVLOG(3) << "NotifyResetDone()";
596 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 596 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
597 DCHECK(ready_video_frames_.empty()); 597 DCHECK(ready_video_frames_.empty());
598 598
599 // This needs to happen after the Reset() on vda_ is done to ensure pictures 599 // This needs to happen after the Reset() on vda_ is done to ensure pictures
600 // delivered during the reset can find their time data. 600 // delivered during the reset can find their time data.
601 input_buffer_data_.clear(); 601 input_buffer_data_.clear();
602 602
603 if (!pending_reset_cb_.is_null()) 603 if (!pending_reset_cb_.is_null())
604 base::ResetAndReturn(&pending_reset_cb_).Run(); 604 base::ResetAndReturn(&pending_reset_cb_).Run();
605 605
606 if (!pending_decode_cb_.is_null()) 606 if (!pending_decode_cb_.is_null())
607 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEOSFrame()); 607 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEOSFrame());
608 } 608 }
609 609
610 void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) { 610 void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) {
611 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 611 DCHECK(gvd_task_runner_->BelongsToCurrentThread());
612 if (!vda_) 612 if (!vda_)
613 return; 613 return;
614 614
615 DLOG(ERROR) << "VDA Error: " << error; 615 DLOG(ERROR) << "VDA Error: " << error;
616 DestroyVDA(); 616 DestroyVDA();
617 617
618 state_ = kError; 618 state_ = kError;
619 619
620 if (!pending_decode_cb_.is_null()) { 620 if (!pending_decode_cb_.is_null()) {
621 base::ResetAndReturn(&pending_decode_cb_).Run(kDecodeError, NULL); 621 base::ResetAndReturn(&pending_decode_cb_).Run(kDecodeError, NULL);
622 return; 622 return;
623 } 623 }
624 } 624 }
625 625
626 } // namespace media 626 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/gpu_video_decoder.h ('k') | media/filters/mock_gpu_video_accelerator_factories.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698