OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/filters/gpu_video_decoder.h" | 5 #include "media/filters/gpu_video_decoder.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
73 | 73 |
74 void GpuVideoDecoder::Reset(const base::Closure& closure) { | 74 void GpuVideoDecoder::Reset(const base::Closure& closure) { |
75 DVLOG(3) << "Reset()"; | 75 DVLOG(3) << "Reset()"; |
76 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 76 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
77 | 77 |
78 if (state_ == kDrainingDecoder) { | 78 if (state_ == kDrainingDecoder) { |
79 base::MessageLoop::current()->PostTask( | 79 base::MessageLoop::current()->PostTask( |
80 FROM_HERE, | 80 FROM_HERE, |
81 base::Bind( | 81 base::Bind( |
82 &GpuVideoDecoder::Reset, weak_factory_.GetWeakPtr(), closure)); | 82 &GpuVideoDecoder::Reset, weak_factory_.GetWeakPtr(), closure)); |
83 // NOTE: if we're deferring Reset() until a Flush() completes, return | |
84 // queued pictures to the VDA so they can be used to finish that Flush(). | |
85 if (pending_decode_cb_.is_null()) | |
86 ready_video_frames_.clear(); | |
87 return; | 83 return; |
88 } | 84 } |
89 | 85 |
90 // Throw away any already-decoded, not-yet-delivered frames. | |
91 ready_video_frames_.clear(); | |
92 | |
93 if (!vda_) { | 86 if (!vda_) { |
94 base::MessageLoop::current()->PostTask(FROM_HERE, closure); | 87 base::MessageLoop::current()->PostTask(FROM_HERE, closure); |
95 return; | 88 return; |
96 } | 89 } |
97 | 90 |
98 if (!pending_decode_cb_.is_null()) | 91 while (!pending_decode_callbacks_.empty()) { |
99 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEOSFrame()); | 92 DeliverFrame(VideoFrame::CreateEOSFrame()); |
93 } | |
100 | 94 |
101 DCHECK(pending_reset_cb_.is_null()); | 95 DCHECK(pending_reset_cb_.is_null()); |
102 pending_reset_cb_ = BindToCurrentLoop(closure); | 96 pending_reset_cb_ = BindToCurrentLoop(closure); |
103 | 97 |
104 vda_->Reset(); | 98 vda_->Reset(); |
105 } | 99 } |
106 | 100 |
107 void GpuVideoDecoder::Stop() { | 101 void GpuVideoDecoder::Stop() { |
108 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 102 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
109 if (vda_) | 103 if (vda_) |
110 DestroyVDA(); | 104 DestroyVDA(); |
111 if (!pending_decode_cb_.is_null()) | 105 while (!pending_decode_callbacks_.empty()) { |
112 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEOSFrame()); | 106 DeliverFrame(VideoFrame::CreateEOSFrame()); |
107 } | |
113 if (!pending_reset_cb_.is_null()) | 108 if (!pending_reset_cb_.is_null()) |
114 base::ResetAndReturn(&pending_reset_cb_).Run(); | 109 base::ResetAndReturn(&pending_reset_cb_).Run(); |
115 } | 110 } |
116 | 111 |
117 static bool IsCodedSizeSupported(const gfx::Size& coded_size) { | 112 static bool IsCodedSizeSupported(const gfx::Size& coded_size) { |
118 // Only non-Windows, Ivy Bridge+ platforms can support more than 1920x1080. | 113 // Only non-Windows, Ivy Bridge+ platforms can support more than 1920x1080. |
119 // We test against 1088 to account for 16x16 macroblocks. | 114 // We test against 1088 to account for 16x16 macroblocks. |
120 if (coded_size.width() <= 1920 && coded_size.height() <= 1088) | 115 if (coded_size.width() <= 1920 && coded_size.height() <= 1088) |
121 return true; | 116 return true; |
122 | 117 |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
215 ++it) { | 210 ++it) { |
216 assigned_picture_buffers_.erase(it->first); | 211 assigned_picture_buffers_.erase(it->first); |
217 } | 212 } |
218 DestroyPictureBuffers(&assigned_picture_buffers_); | 213 DestroyPictureBuffers(&assigned_picture_buffers_); |
219 } | 214 } |
220 | 215 |
221 void GpuVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, | 216 void GpuVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, |
222 const DecodeCB& decode_cb) { | 217 const DecodeCB& decode_cb) { |
223 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 218 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
224 DCHECK(pending_reset_cb_.is_null()); | 219 DCHECK(pending_reset_cb_.is_null()); |
225 DCHECK(pending_decode_cb_.is_null()); | |
226 | |
227 pending_decode_cb_ = BindToCurrentLoop(decode_cb); | |
228 | 220 |
229 if (state_ == kError || !vda_) { | 221 if (state_ == kError || !vda_) { |
230 base::ResetAndReturn(&pending_decode_cb_).Run(kDecodeError, NULL); | 222 decode_cb.Run(kDecodeError, NULL); |
231 return; | 223 return; |
232 } | 224 } |
233 | 225 |
234 switch (state_) { | 226 switch (state_) { |
235 case kDecoderDrained: | 227 case kDecoderDrained: |
236 if (!ready_video_frames_.empty()) { | |
237 EnqueueFrameAndTriggerFrameDelivery(NULL); | |
238 return; | |
239 } | |
240 state_ = kNormal; | 228 state_ = kNormal; |
241 // Fall-through. | 229 // Fall-through. |
242 case kNormal: | 230 case kNormal: |
243 break; | 231 break; |
244 case kDrainingDecoder: | 232 case kDrainingDecoder: |
245 DCHECK(buffer->end_of_stream()); | 233 DCHECK(buffer->end_of_stream()); |
246 // Do nothing. Will be satisfied either by a PictureReady or | 234 // Do nothing. Will be satisfied either by a PictureReady or |
247 // NotifyFlushDone below. | 235 // NotifyFlushDone below. |
248 return; | 236 return; |
249 case kError: | 237 case kError: |
250 NOTREACHED(); | 238 NOTREACHED(); |
251 return; | 239 return; |
252 } | 240 } |
253 | 241 |
254 if (buffer->end_of_stream()) { | 242 if (buffer->end_of_stream()) { |
255 if (state_ == kNormal) { | 243 if (state_ == kNormal) { |
256 state_ = kDrainingDecoder; | 244 state_ = kDrainingDecoder; |
245 pending_decode_callbacks_.push_back(BindToCurrentLoop(decode_cb)); | |
246 DCHECK_LE(static_cast<int>(pending_decode_callbacks_.size()), | |
247 kMaxInFlightDecodes); | |
257 vda_->Flush(); | 248 vda_->Flush(); |
258 // If we have ready frames, go ahead and process them to ensure that the | |
259 // Flush operation does not block in the VDA due to lack of picture | |
260 // buffers. | |
261 if (!ready_video_frames_.empty()) | |
262 EnqueueFrameAndTriggerFrameDelivery(NULL); | |
263 } | 249 } |
264 return; | 250 return; |
265 } | 251 } |
266 | 252 |
267 size_t size = buffer->data_size(); | 253 size_t size = buffer->data_size(); |
268 SHMBuffer* shm_buffer = GetSHM(size); | 254 SHMBuffer* shm_buffer = GetSHM(size); |
269 if (!shm_buffer) { | 255 if (!shm_buffer) { |
270 base::ResetAndReturn(&pending_decode_cb_).Run(kDecodeError, NULL); | 256 decode_cb.Run(kDecodeError, NULL); |
271 return; | 257 return; |
272 } | 258 } |
273 | 259 |
260 pending_decode_callbacks_.push_back(BindToCurrentLoop(decode_cb)); | |
261 DCHECK_LE(static_cast<int>(pending_decode_callbacks_.size()), | |
262 kMaxInFlightDecodes); | |
263 | |
274 memcpy(shm_buffer->shm->memory(), buffer->data(), size); | 264 memcpy(shm_buffer->shm->memory(), buffer->data(), size); |
275 BitstreamBuffer bitstream_buffer( | 265 BitstreamBuffer bitstream_buffer( |
276 next_bitstream_buffer_id_, shm_buffer->shm->handle(), size); | 266 next_bitstream_buffer_id_, shm_buffer->shm->handle(), size); |
277 // Mask against 30 bits, to avoid (undefined) wraparound on signed integer. | 267 // Mask against 30 bits, to avoid (undefined) wraparound on signed integer. |
278 next_bitstream_buffer_id_ = (next_bitstream_buffer_id_ + 1) & 0x3FFFFFFF; | 268 next_bitstream_buffer_id_ = (next_bitstream_buffer_id_ + 1) & 0x3FFFFFFF; |
279 bool inserted = bitstream_buffers_in_decoder_.insert(std::make_pair( | 269 bool inserted = bitstream_buffers_in_decoder_.insert(std::make_pair( |
280 bitstream_buffer.id(), BufferPair(shm_buffer, buffer))).second; | 270 bitstream_buffer.id(), BufferPair(shm_buffer, buffer))).second; |
281 DCHECK(inserted); | 271 DCHECK(inserted); |
282 RecordBufferData(bitstream_buffer, *buffer.get()); | 272 RecordBufferData(bitstream_buffer, *buffer.get()); |
283 | 273 |
284 vda_->Decode(bitstream_buffer); | 274 vda_->Decode(bitstream_buffer); |
285 | |
286 if (!ready_video_frames_.empty()) { | |
287 EnqueueFrameAndTriggerFrameDelivery(NULL); | |
288 return; | |
289 } | |
290 | |
291 if (CanMoreDecodeWorkBeDone()) | |
292 base::ResetAndReturn(&pending_decode_cb_).Run(kNotEnoughData, NULL); | |
293 } | |
294 | |
295 bool GpuVideoDecoder::CanMoreDecodeWorkBeDone() { | |
296 return bitstream_buffers_in_decoder_.size() < kMaxInFlightDecodes; | |
297 } | 275 } |
298 | 276 |
299 void GpuVideoDecoder::RecordBufferData(const BitstreamBuffer& bitstream_buffer, | 277 void GpuVideoDecoder::RecordBufferData(const BitstreamBuffer& bitstream_buffer, |
300 const DecoderBuffer& buffer) { | 278 const DecoderBuffer& buffer) { |
301 input_buffer_data_.push_front(BufferData(bitstream_buffer.id(), | 279 input_buffer_data_.push_front(BufferData(bitstream_buffer.id(), |
302 buffer.timestamp(), | 280 buffer.timestamp(), |
303 config_.visible_rect(), | 281 config_.visible_rect(), |
304 config_.natural_size())); | 282 config_.natural_size())); |
305 // Why this value? Because why not. avformat.h:MAX_REORDER_DELAY is 16, but | 283 // Why this value? Because why not. avformat.h:MAX_REORDER_DELAY is 16, but |
306 // that's too small for some pathological B-frame test videos. The cost of | 284 // that's too small for some pathological B-frame test videos. The cost of |
(...skipping 28 matching lines...) Expand all Loading... | |
335 | 313 |
336 bool GpuVideoDecoder::NeedsBitstreamConversion() const { | 314 bool GpuVideoDecoder::NeedsBitstreamConversion() const { |
337 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 315 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
338 return needs_bitstream_conversion_; | 316 return needs_bitstream_conversion_; |
339 } | 317 } |
340 | 318 |
341 bool GpuVideoDecoder::CanReadWithoutStalling() const { | 319 bool GpuVideoDecoder::CanReadWithoutStalling() const { |
342 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 320 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
343 return | 321 return |
344 next_picture_buffer_id_ == 0 || // Decode() will ProvidePictureBuffers(). | 322 next_picture_buffer_id_ == 0 || // Decode() will ProvidePictureBuffers(). |
345 available_pictures_ > 0 || !ready_video_frames_.empty(); | 323 available_pictures_ > 0; |
324 } | |
325 | |
326 int GpuVideoDecoder::GetMaxDecodeRequests() const { | |
327 return kMaxInFlightDecodes; | |
xhwang
2014/04/17 01:06:47
[not related to this CL]
fischman: Do you know wh
Sergey Ulanov
2014/04/23 02:44:21
per e-mail thread VDA decoder shouldn't have any d
| |
346 } | 328 } |
347 | 329 |
348 void GpuVideoDecoder::NotifyInitializeDone() { | 330 void GpuVideoDecoder::NotifyInitializeDone() { |
349 NOTREACHED() << "GpuVideoDecodeAcceleratorHost::Initialize is synchronous!"; | 331 NOTREACHED() << "GpuVideoDecodeAcceleratorHost::Initialize is synchronous!"; |
350 } | 332 } |
351 | 333 |
352 void GpuVideoDecoder::ProvidePictureBuffers(uint32 count, | 334 void GpuVideoDecoder::ProvidePictureBuffers(uint32 count, |
353 const gfx::Size& size, | 335 const gfx::Size& size, |
354 uint32 texture_target) { | 336 uint32 texture_target) { |
355 DVLOG(3) << "ProvidePictureBuffers(" << count << ", " | 337 DVLOG(3) << "ProvidePictureBuffers(" << count << ", " |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
472 timestamp, | 454 timestamp, |
473 base::Bind(&ReadPixelsSync, factories_, pb.texture_id(), visible_rect))); | 455 base::Bind(&ReadPixelsSync, factories_, pb.texture_id(), visible_rect))); |
474 CHECK_GT(available_pictures_, 0); | 456 CHECK_GT(available_pictures_, 0); |
475 --available_pictures_; | 457 --available_pictures_; |
476 bool inserted = | 458 bool inserted = |
477 picture_buffers_at_display_.insert(std::make_pair( | 459 picture_buffers_at_display_.insert(std::make_pair( |
478 picture.picture_buffer_id(), | 460 picture.picture_buffer_id(), |
479 pb.texture_id())).second; | 461 pb.texture_id())).second; |
480 DCHECK(inserted); | 462 DCHECK(inserted); |
481 | 463 |
482 EnqueueFrameAndTriggerFrameDelivery(frame); | 464 DeliverFrame(frame); |
483 } | 465 } |
484 | 466 |
485 void GpuVideoDecoder::EnqueueFrameAndTriggerFrameDelivery( | 467 void GpuVideoDecoder::DeliverFrame( |
486 const scoped_refptr<VideoFrame>& frame) { | 468 const scoped_refptr<VideoFrame>& frame) { |
487 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 469 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
488 | 470 |
489 // During a pending vda->Reset(), we don't accumulate frames. Drop it on the | 471 // During a pending vda->Reset(), we don't accumulate frames. Drop it on the |
490 // floor and return. | 472 // floor and return. |
491 if (!pending_reset_cb_.is_null()) | 473 if (!pending_reset_cb_.is_null()) |
492 return; | 474 return; |
493 | 475 |
494 if (frame.get()) | 476 CHECK(!pending_decode_callbacks_.empty()); |
xhwang
2014/04/17 01:06:47
This is catching a coding error, use DCHECK?
Sergey Ulanov
2014/04/23 02:44:21
Done.
| |
495 ready_video_frames_.push_back(frame); | |
496 else | |
497 DCHECK(!ready_video_frames_.empty()); | |
498 | 477 |
499 if (pending_decode_cb_.is_null()) | 478 DecodeCB decode_cb = pending_decode_callbacks_.front(); |
500 return; | 479 pending_decode_callbacks_.pop_front(); |
501 | 480 |
502 base::ResetAndReturn(&pending_decode_cb_) | 481 decode_cb.Run(kOk, frame); |
503 .Run(kOk, ready_video_frames_.front()); | |
504 ready_video_frames_.pop_front(); | |
505 } | 482 } |
506 | 483 |
507 // static | 484 // static |
508 void GpuVideoDecoder::ReleaseMailbox( | 485 void GpuVideoDecoder::ReleaseMailbox( |
509 base::WeakPtr<GpuVideoDecoder> decoder, | 486 base::WeakPtr<GpuVideoDecoder> decoder, |
510 const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories, | 487 const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories, |
511 int64 picture_buffer_id, | 488 int64 picture_buffer_id, |
512 uint32 texture_id, | 489 uint32 texture_id, |
513 scoped_ptr<gpu::MailboxHolder> mailbox_holder) { | 490 scoped_ptr<gpu::MailboxHolder> mailbox_holder) { |
514 DCHECK(factories->GetTaskRunner()->BelongsToCurrentThread()); | 491 DCHECK(factories->GetTaskRunner()->BelongsToCurrentThread()); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
575 std::map<int32, BufferPair>::iterator it = | 552 std::map<int32, BufferPair>::iterator it = |
576 bitstream_buffers_in_decoder_.find(id); | 553 bitstream_buffers_in_decoder_.find(id); |
577 if (it == bitstream_buffers_in_decoder_.end()) { | 554 if (it == bitstream_buffers_in_decoder_.end()) { |
578 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); | 555 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); |
579 NOTREACHED() << "Missing bitstream buffer: " << id; | 556 NOTREACHED() << "Missing bitstream buffer: " << id; |
580 return; | 557 return; |
581 } | 558 } |
582 | 559 |
583 PutSHM(it->second.shm_buffer); | 560 PutSHM(it->second.shm_buffer); |
584 bitstream_buffers_in_decoder_.erase(it); | 561 bitstream_buffers_in_decoder_.erase(it); |
585 | |
586 if (pending_reset_cb_.is_null() && state_ != kDrainingDecoder && | |
587 CanMoreDecodeWorkBeDone() && !pending_decode_cb_.is_null()) { | |
588 base::ResetAndReturn(&pending_decode_cb_).Run(kNotEnoughData, NULL); | |
589 } | |
xhwang
2014/04/17 01:06:47
Kudos for removing this logic!
| |
590 } | 562 } |
591 | 563 |
592 GpuVideoDecoder::~GpuVideoDecoder() { | 564 GpuVideoDecoder::~GpuVideoDecoder() { |
593 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 565 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
594 // Stop should have been already called. | 566 // Stop should have been already called. |
595 DCHECK(!vda_.get() && assigned_picture_buffers_.empty()); | 567 DCHECK(!vda_.get() && assigned_picture_buffers_.empty()); |
596 DCHECK(pending_decode_cb_.is_null()); | 568 DCHECK(pending_decode_callbacks_.empty()); |
597 for (size_t i = 0; i < available_shm_segments_.size(); ++i) { | 569 for (size_t i = 0; i < available_shm_segments_.size(); ++i) { |
598 available_shm_segments_[i]->shm->Close(); | 570 available_shm_segments_[i]->shm->Close(); |
599 delete available_shm_segments_[i]; | 571 delete available_shm_segments_[i]; |
600 } | 572 } |
601 available_shm_segments_.clear(); | 573 available_shm_segments_.clear(); |
602 for (std::map<int32, BufferPair>::iterator it = | 574 for (std::map<int32, BufferPair>::iterator it = |
603 bitstream_buffers_in_decoder_.begin(); | 575 bitstream_buffers_in_decoder_.begin(); |
604 it != bitstream_buffers_in_decoder_.end(); ++it) { | 576 it != bitstream_buffers_in_decoder_.end(); ++it) { |
605 it->second.shm_buffer->shm->Close(); | 577 it->second.shm_buffer->shm->Close(); |
606 } | 578 } |
607 bitstream_buffers_in_decoder_.clear(); | 579 bitstream_buffers_in_decoder_.clear(); |
608 } | 580 } |
609 | 581 |
610 void GpuVideoDecoder::NotifyFlushDone() { | 582 void GpuVideoDecoder::NotifyFlushDone() { |
611 DVLOG(3) << "NotifyFlushDone()"; | 583 DVLOG(3) << "NotifyFlushDone()"; |
612 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 584 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
613 DCHECK_EQ(state_, kDrainingDecoder); | 585 DCHECK_EQ(state_, kDrainingDecoder); |
614 state_ = kDecoderDrained; | 586 state_ = kDecoderDrained; |
615 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEOSFrame()); | 587 DeliverFrame(VideoFrame::CreateEOSFrame()); |
xhwang
2014/04/17 01:06:47
I suspect that after FlushDone, we'll still have u
Sergey Ulanov
2014/04/23 02:44:21
Added DCHECK_EQ(pending_decode_callbacks_.size(),
| |
616 } | 588 } |
617 | 589 |
618 void GpuVideoDecoder::NotifyResetDone() { | 590 void GpuVideoDecoder::NotifyResetDone() { |
619 DVLOG(3) << "NotifyResetDone()"; | 591 DVLOG(3) << "NotifyResetDone()"; |
620 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 592 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
621 DCHECK(ready_video_frames_.empty()); | 593 DCHECK(pending_decode_callbacks_.empty()); |
622 | 594 |
623 // This needs to happen after the Reset() on vda_ is done to ensure pictures | 595 // This needs to happen after the Reset() on vda_ is done to ensure pictures |
624 // delivered during the reset can find their time data. | 596 // delivered during the reset can find their time data. |
625 input_buffer_data_.clear(); | 597 input_buffer_data_.clear(); |
626 | 598 |
627 if (!pending_reset_cb_.is_null()) | 599 if (!pending_reset_cb_.is_null()) |
628 base::ResetAndReturn(&pending_reset_cb_).Run(); | 600 base::ResetAndReturn(&pending_reset_cb_).Run(); |
629 | |
630 if (!pending_decode_cb_.is_null()) | |
631 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEOSFrame()); | |
632 } | 601 } |
633 | 602 |
634 void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) { | 603 void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) { |
635 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 604 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
636 if (!vda_) | 605 if (!vda_) |
637 return; | 606 return; |
638 | 607 |
639 DLOG(ERROR) << "VDA Error: " << error; | 608 DLOG(ERROR) << "VDA Error: " << error; |
640 DestroyVDA(); | 609 DestroyVDA(); |
641 | 610 |
642 state_ = kError; | 611 state_ = kError; |
643 | 612 |
644 if (!pending_decode_cb_.is_null()) { | 613 while (!pending_decode_callbacks_.empty()) { |
645 base::ResetAndReturn(&pending_decode_cb_).Run(kDecodeError, NULL); | 614 pending_decode_callbacks_.front().Run(kDecodeError, NULL); |
646 return; | 615 pending_decode_callbacks_.pop_front(); |
647 } | 616 } |
648 } | 617 } |
649 | 618 |
650 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() | 619 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() |
651 const { | 620 const { |
652 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); | 621 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); |
653 } | 622 } |
654 | 623 |
655 } // namespace media | 624 } // namespace media |
OLD | NEW |