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 23 matching lines...) Expand all Loading... |
330 | 308 |
331 bool GpuVideoDecoder::NeedsBitstreamConversion() const { | 309 bool GpuVideoDecoder::NeedsBitstreamConversion() const { |
332 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 310 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
333 return needs_bitstream_conversion_; | 311 return needs_bitstream_conversion_; |
334 } | 312 } |
335 | 313 |
336 bool GpuVideoDecoder::CanReadWithoutStalling() const { | 314 bool GpuVideoDecoder::CanReadWithoutStalling() const { |
337 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 315 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
338 return | 316 return |
339 next_picture_buffer_id_ == 0 || // Decode() will ProvidePictureBuffers(). | 317 next_picture_buffer_id_ == 0 || // Decode() will ProvidePictureBuffers(). |
340 available_pictures_ > 0 || !ready_video_frames_.empty(); | 318 available_pictures_ > 0; |
| 319 } |
| 320 |
| 321 int GpuVideoDecoder::GetMaxDecodeRequests() const { |
| 322 return kMaxInFlightDecodes; |
341 } | 323 } |
342 | 324 |
343 void GpuVideoDecoder::ProvidePictureBuffers(uint32 count, | 325 void GpuVideoDecoder::ProvidePictureBuffers(uint32 count, |
344 const gfx::Size& size, | 326 const gfx::Size& size, |
345 uint32 texture_target) { | 327 uint32 texture_target) { |
346 DVLOG(3) << "ProvidePictureBuffers(" << count << ", " | 328 DVLOG(3) << "ProvidePictureBuffers(" << count << ", " |
347 << size.width() << "x" << size.height() << ")"; | 329 << size.width() << "x" << size.height() << ")"; |
348 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 330 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
349 | 331 |
350 std::vector<uint32> texture_ids; | 332 std::vector<uint32> texture_ids; |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
463 timestamp, | 445 timestamp, |
464 base::Bind(&ReadPixelsSync, factories_, pb.texture_id(), visible_rect))); | 446 base::Bind(&ReadPixelsSync, factories_, pb.texture_id(), visible_rect))); |
465 CHECK_GT(available_pictures_, 0); | 447 CHECK_GT(available_pictures_, 0); |
466 --available_pictures_; | 448 --available_pictures_; |
467 bool inserted = | 449 bool inserted = |
468 picture_buffers_at_display_.insert(std::make_pair( | 450 picture_buffers_at_display_.insert(std::make_pair( |
469 picture.picture_buffer_id(), | 451 picture.picture_buffer_id(), |
470 pb.texture_id())).second; | 452 pb.texture_id())).second; |
471 DCHECK(inserted); | 453 DCHECK(inserted); |
472 | 454 |
473 EnqueueFrameAndTriggerFrameDelivery(frame); | 455 DeliverFrame(frame); |
474 } | 456 } |
475 | 457 |
476 void GpuVideoDecoder::EnqueueFrameAndTriggerFrameDelivery( | 458 void GpuVideoDecoder::DeliverFrame( |
477 const scoped_refptr<VideoFrame>& frame) { | 459 const scoped_refptr<VideoFrame>& frame) { |
478 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 460 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
479 | 461 |
480 // During a pending vda->Reset(), we don't accumulate frames. Drop it on the | 462 // During a pending vda->Reset(), we don't accumulate frames. Drop it on the |
481 // floor and return. | 463 // floor and return. |
482 if (!pending_reset_cb_.is_null()) | 464 if (!pending_reset_cb_.is_null()) |
483 return; | 465 return; |
484 | 466 |
485 if (frame.get()) | 467 DCHECK(!pending_decode_callbacks_.empty()); |
486 ready_video_frames_.push_back(frame); | |
487 else | |
488 DCHECK(!ready_video_frames_.empty()); | |
489 | 468 |
490 if (pending_decode_cb_.is_null()) | 469 DecodeCB decode_cb = pending_decode_callbacks_.front(); |
491 return; | 470 pending_decode_callbacks_.pop_front(); |
492 | 471 |
493 base::ResetAndReturn(&pending_decode_cb_) | 472 decode_cb.Run(kOk, frame); |
494 .Run(kOk, ready_video_frames_.front()); | |
495 ready_video_frames_.pop_front(); | |
496 } | 473 } |
497 | 474 |
498 // static | 475 // static |
499 void GpuVideoDecoder::ReleaseMailbox( | 476 void GpuVideoDecoder::ReleaseMailbox( |
500 base::WeakPtr<GpuVideoDecoder> decoder, | 477 base::WeakPtr<GpuVideoDecoder> decoder, |
501 const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories, | 478 const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories, |
502 int64 picture_buffer_id, | 479 int64 picture_buffer_id, |
503 uint32 texture_id, | 480 uint32 texture_id, |
504 scoped_ptr<gpu::MailboxHolder> mailbox_holder) { | 481 scoped_ptr<gpu::MailboxHolder> mailbox_holder) { |
505 DCHECK(factories->GetTaskRunner()->BelongsToCurrentThread()); | 482 DCHECK(factories->GetTaskRunner()->BelongsToCurrentThread()); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
566 std::map<int32, BufferPair>::iterator it = | 543 std::map<int32, BufferPair>::iterator it = |
567 bitstream_buffers_in_decoder_.find(id); | 544 bitstream_buffers_in_decoder_.find(id); |
568 if (it == bitstream_buffers_in_decoder_.end()) { | 545 if (it == bitstream_buffers_in_decoder_.end()) { |
569 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); | 546 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); |
570 NOTREACHED() << "Missing bitstream buffer: " << id; | 547 NOTREACHED() << "Missing bitstream buffer: " << id; |
571 return; | 548 return; |
572 } | 549 } |
573 | 550 |
574 PutSHM(it->second.shm_buffer); | 551 PutSHM(it->second.shm_buffer); |
575 bitstream_buffers_in_decoder_.erase(it); | 552 bitstream_buffers_in_decoder_.erase(it); |
576 | |
577 if (pending_reset_cb_.is_null() && state_ != kDrainingDecoder && | |
578 CanMoreDecodeWorkBeDone() && !pending_decode_cb_.is_null()) { | |
579 base::ResetAndReturn(&pending_decode_cb_).Run(kNotEnoughData, NULL); | |
580 } | |
581 } | 553 } |
582 | 554 |
583 GpuVideoDecoder::~GpuVideoDecoder() { | 555 GpuVideoDecoder::~GpuVideoDecoder() { |
584 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 556 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
585 // Stop should have been already called. | 557 // Stop should have been already called. |
586 DCHECK(!vda_.get() && assigned_picture_buffers_.empty()); | 558 DCHECK(!vda_.get() && assigned_picture_buffers_.empty()); |
587 DCHECK(pending_decode_cb_.is_null()); | 559 DCHECK(pending_decode_callbacks_.empty()); |
588 for (size_t i = 0; i < available_shm_segments_.size(); ++i) { | 560 for (size_t i = 0; i < available_shm_segments_.size(); ++i) { |
589 available_shm_segments_[i]->shm->Close(); | 561 available_shm_segments_[i]->shm->Close(); |
590 delete available_shm_segments_[i]; | 562 delete available_shm_segments_[i]; |
591 } | 563 } |
592 available_shm_segments_.clear(); | 564 available_shm_segments_.clear(); |
593 for (std::map<int32, BufferPair>::iterator it = | 565 for (std::map<int32, BufferPair>::iterator it = |
594 bitstream_buffers_in_decoder_.begin(); | 566 bitstream_buffers_in_decoder_.begin(); |
595 it != bitstream_buffers_in_decoder_.end(); ++it) { | 567 it != bitstream_buffers_in_decoder_.end(); ++it) { |
596 it->second.shm_buffer->shm->Close(); | 568 it->second.shm_buffer->shm->Close(); |
597 } | 569 } |
598 bitstream_buffers_in_decoder_.clear(); | 570 bitstream_buffers_in_decoder_.clear(); |
599 } | 571 } |
600 | 572 |
601 void GpuVideoDecoder::NotifyFlushDone() { | 573 void GpuVideoDecoder::NotifyFlushDone() { |
602 DVLOG(3) << "NotifyFlushDone()"; | 574 DVLOG(3) << "NotifyFlushDone()"; |
603 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 575 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
604 DCHECK_EQ(state_, kDrainingDecoder); | 576 DCHECK_EQ(state_, kDrainingDecoder); |
| 577 DCHECK_EQ(pending_decode_callbacks_.size(), 1U); |
605 state_ = kDecoderDrained; | 578 state_ = kDecoderDrained; |
606 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEOSFrame()); | 579 DeliverFrame(VideoFrame::CreateEOSFrame()); |
607 } | 580 } |
608 | 581 |
609 void GpuVideoDecoder::NotifyResetDone() { | 582 void GpuVideoDecoder::NotifyResetDone() { |
610 DVLOG(3) << "NotifyResetDone()"; | 583 DVLOG(3) << "NotifyResetDone()"; |
611 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 584 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
612 DCHECK(ready_video_frames_.empty()); | 585 DCHECK(pending_decode_callbacks_.empty()); |
613 | 586 |
614 // This needs to happen after the Reset() on vda_ is done to ensure pictures | 587 // This needs to happen after the Reset() on vda_ is done to ensure pictures |
615 // delivered during the reset can find their time data. | 588 // delivered during the reset can find their time data. |
616 input_buffer_data_.clear(); | 589 input_buffer_data_.clear(); |
617 | 590 |
618 if (!pending_reset_cb_.is_null()) | 591 if (!pending_reset_cb_.is_null()) |
619 base::ResetAndReturn(&pending_reset_cb_).Run(); | 592 base::ResetAndReturn(&pending_reset_cb_).Run(); |
620 | |
621 if (!pending_decode_cb_.is_null()) | |
622 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEOSFrame()); | |
623 } | 593 } |
624 | 594 |
625 void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) { | 595 void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) { |
626 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 596 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
627 if (!vda_) | 597 if (!vda_) |
628 return; | 598 return; |
629 | 599 |
630 DLOG(ERROR) << "VDA Error: " << error; | 600 DLOG(ERROR) << "VDA Error: " << error; |
631 DestroyVDA(); | 601 DestroyVDA(); |
632 | 602 |
633 state_ = kError; | 603 state_ = kError; |
634 | 604 |
635 if (!pending_decode_cb_.is_null()) { | 605 while (!pending_decode_callbacks_.empty()) { |
636 base::ResetAndReturn(&pending_decode_cb_).Run(kDecodeError, NULL); | 606 pending_decode_callbacks_.front().Run(kDecodeError, NULL); |
637 return; | 607 pending_decode_callbacks_.pop_front(); |
638 } | 608 } |
639 } | 609 } |
640 | 610 |
641 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() | 611 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() |
642 const { | 612 const { |
643 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); | 613 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); |
644 } | 614 } |
645 | 615 |
646 } // namespace media | 616 } // namespace media |
OLD | NEW |