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 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 void GpuVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, | 292 void GpuVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, |
293 const DecodeCB& decode_cb) { | 293 const DecodeCB& decode_cb) { |
294 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 294 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
295 DCHECK(pending_reset_cb_.is_null()); | 295 DCHECK(pending_reset_cb_.is_null()); |
296 | 296 |
297 DVLOG(3) << __FUNCTION__ << " " << buffer->AsHumanReadableString(); | 297 DVLOG(3) << __FUNCTION__ << " " << buffer->AsHumanReadableString(); |
298 | 298 |
299 DecodeCB bound_decode_cb = BindToCurrentLoop(decode_cb); | 299 DecodeCB bound_decode_cb = BindToCurrentLoop(decode_cb); |
300 | 300 |
301 if (state_ == kError || !vda_) { | 301 if (state_ == kError || !vda_) { |
302 bound_decode_cb.Run(kDecodeError); | 302 bound_decode_cb.Run(DecodeStatus::DECODE_ERROR); |
303 return; | 303 return; |
304 } | 304 } |
305 | 305 |
306 switch (state_) { | 306 switch (state_) { |
307 case kDecoderDrained: | 307 case kDecoderDrained: |
308 state_ = kNormal; | 308 state_ = kNormal; |
309 // Fall-through. | 309 // Fall-through. |
310 case kNormal: | 310 case kNormal: |
311 break; | 311 break; |
312 case kDrainingDecoder: | 312 case kDrainingDecoder: |
313 case kError: | 313 case kError: |
314 NOTREACHED(); | 314 NOTREACHED(); |
315 return; | 315 return; |
316 } | 316 } |
317 | 317 |
318 DCHECK_EQ(state_, kNormal); | 318 DCHECK_EQ(state_, kNormal); |
319 | 319 |
320 if (buffer->end_of_stream()) { | 320 if (buffer->end_of_stream()) { |
321 DVLOG(3) << __FUNCTION__ << " Initiating Flush for EOS."; | 321 DVLOG(3) << __FUNCTION__ << " Initiating Flush for EOS."; |
322 state_ = kDrainingDecoder; | 322 state_ = kDrainingDecoder; |
323 eos_decode_cb_ = bound_decode_cb; | 323 eos_decode_cb_ = bound_decode_cb; |
324 vda_->Flush(); | 324 vda_->Flush(); |
325 return; | 325 return; |
326 } | 326 } |
327 | 327 |
328 size_t size = buffer->data_size(); | 328 size_t size = buffer->data_size(); |
329 scoped_ptr<SHMBuffer> shm_buffer = GetSHM(size); | 329 scoped_ptr<SHMBuffer> shm_buffer = GetSHM(size); |
330 if (!shm_buffer) { | 330 if (!shm_buffer) { |
331 bound_decode_cb.Run(kDecodeError); | 331 bound_decode_cb.Run(DecodeStatus::DECODE_ERROR); |
332 return; | 332 return; |
333 } | 333 } |
334 | 334 |
335 memcpy(shm_buffer->shm->memory(), buffer->data(), size); | 335 memcpy(shm_buffer->shm->memory(), buffer->data(), size); |
336 // AndroidVideoDecodeAccelerator needs the timestamp to output frames in | 336 // AndroidVideoDecodeAccelerator needs the timestamp to output frames in |
337 // presentation order. | 337 // presentation order. |
338 BitstreamBuffer bitstream_buffer(next_bitstream_buffer_id_, | 338 BitstreamBuffer bitstream_buffer(next_bitstream_buffer_id_, |
339 shm_buffer->shm->handle(), size, 0, | 339 shm_buffer->shm->handle(), size, 0, |
340 buffer->timestamp()); | 340 buffer->timestamp()); |
341 | 341 |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
624 | 624 |
625 std::map<int32_t, PendingDecoderBuffer>::iterator it = | 625 std::map<int32_t, PendingDecoderBuffer>::iterator it = |
626 bitstream_buffers_in_decoder_.find(id); | 626 bitstream_buffers_in_decoder_.find(id); |
627 if (it == bitstream_buffers_in_decoder_.end()) { | 627 if (it == bitstream_buffers_in_decoder_.end()) { |
628 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); | 628 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); |
629 NOTREACHED() << "Missing bitstream buffer: " << id; | 629 NOTREACHED() << "Missing bitstream buffer: " << id; |
630 return; | 630 return; |
631 } | 631 } |
632 | 632 |
633 PutSHM(make_scoped_ptr(it->second.shm_buffer)); | 633 PutSHM(make_scoped_ptr(it->second.shm_buffer)); |
634 it->second.done_cb.Run(state_ == kError ? kDecodeError : kOk); | 634 it->second.done_cb.Run(state_ == kError ? DecodeStatus::DECODE_ERROR |
| 635 : DecodeStatus::OK); |
635 bitstream_buffers_in_decoder_.erase(it); | 636 bitstream_buffers_in_decoder_.erase(it); |
636 } | 637 } |
637 | 638 |
638 GpuVideoDecoder::~GpuVideoDecoder() { | 639 GpuVideoDecoder::~GpuVideoDecoder() { |
639 DVLOG(3) << __FUNCTION__; | 640 DVLOG(3) << __FUNCTION__; |
640 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 641 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
641 | 642 |
642 if (vda_) | 643 if (vda_) |
643 DestroyVDA(); | 644 DestroyVDA(); |
644 DCHECK(assigned_picture_buffers_.empty()); | 645 DCHECK(assigned_picture_buffers_.empty()); |
645 | 646 |
646 if (!init_cb_.is_null()) | 647 if (!init_cb_.is_null()) |
647 base::ResetAndReturn(&init_cb_).Run(false); | 648 base::ResetAndReturn(&init_cb_).Run(false); |
648 if (!request_surface_cb_.is_null()) | 649 if (!request_surface_cb_.is_null()) |
649 base::ResetAndReturn(&request_surface_cb_).Run(SurfaceCreatedCB()); | 650 base::ResetAndReturn(&request_surface_cb_).Run(SurfaceCreatedCB()); |
650 | 651 |
651 for (size_t i = 0; i < available_shm_segments_.size(); ++i) { | 652 for (size_t i = 0; i < available_shm_segments_.size(); ++i) { |
652 delete available_shm_segments_[i]; | 653 delete available_shm_segments_[i]; |
653 } | 654 } |
654 available_shm_segments_.clear(); | 655 available_shm_segments_.clear(); |
655 | 656 |
656 for (std::map<int32_t, PendingDecoderBuffer>::iterator it = | 657 for (std::map<int32_t, PendingDecoderBuffer>::iterator it = |
657 bitstream_buffers_in_decoder_.begin(); | 658 bitstream_buffers_in_decoder_.begin(); |
658 it != bitstream_buffers_in_decoder_.end(); ++it) { | 659 it != bitstream_buffers_in_decoder_.end(); ++it) { |
659 delete it->second.shm_buffer; | 660 delete it->second.shm_buffer; |
660 it->second.done_cb.Run(kAborted); | 661 it->second.done_cb.Run(DecodeStatus::ABORTED); |
661 } | 662 } |
662 bitstream_buffers_in_decoder_.clear(); | 663 bitstream_buffers_in_decoder_.clear(); |
663 | 664 |
664 if (!pending_reset_cb_.is_null()) | 665 if (!pending_reset_cb_.is_null()) |
665 base::ResetAndReturn(&pending_reset_cb_).Run(); | 666 base::ResetAndReturn(&pending_reset_cb_).Run(); |
666 } | 667 } |
667 | 668 |
668 void GpuVideoDecoder::NotifyFlushDone() { | 669 void GpuVideoDecoder::NotifyFlushDone() { |
669 DVLOG(3) << "NotifyFlushDone()"; | 670 DVLOG(3) << "NotifyFlushDone()"; |
670 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 671 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
671 DCHECK_EQ(state_, kDrainingDecoder); | 672 DCHECK_EQ(state_, kDrainingDecoder); |
672 state_ = kDecoderDrained; | 673 state_ = kDecoderDrained; |
673 base::ResetAndReturn(&eos_decode_cb_).Run(kOk); | 674 base::ResetAndReturn(&eos_decode_cb_).Run(DecodeStatus::OK); |
674 } | 675 } |
675 | 676 |
676 void GpuVideoDecoder::NotifyResetDone() { | 677 void GpuVideoDecoder::NotifyResetDone() { |
677 DVLOG(3) << "NotifyResetDone()"; | 678 DVLOG(3) << "NotifyResetDone()"; |
678 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 679 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
679 DCHECK(bitstream_buffers_in_decoder_.empty()); | 680 DCHECK(bitstream_buffers_in_decoder_.empty()); |
680 | 681 |
681 // This needs to happen after the Reset() on vda_ is done to ensure pictures | 682 // This needs to happen after the Reset() on vda_ is done to ensure pictures |
682 // delivered during the reset can find their time data. | 683 // delivered during the reset can find their time data. |
683 input_buffer_data_.clear(); | 684 input_buffer_data_.clear(); |
684 | 685 |
685 if (!pending_reset_cb_.is_null()) | 686 if (!pending_reset_cb_.is_null()) |
686 base::ResetAndReturn(&pending_reset_cb_).Run(); | 687 base::ResetAndReturn(&pending_reset_cb_).Run(); |
687 } | 688 } |
688 | 689 |
689 void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) { | 690 void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) { |
690 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 691 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
691 if (!vda_) | 692 if (!vda_) |
692 return; | 693 return; |
693 | 694 |
694 state_ = kError; | 695 state_ = kError; |
695 | 696 |
696 // If we have any bitstream buffers, then notify one that an error has | 697 // If we have any bitstream buffers, then notify one that an error has |
697 // occurred. This guarantees that somebody finds out about the error. If | 698 // occurred. This guarantees that somebody finds out about the error. If |
698 // we don't do this, and if the max decodes are already in flight, then there | 699 // we don't do this, and if the max decodes are already in flight, then there |
699 // won't be another decode request to report the error. | 700 // won't be another decode request to report the error. |
700 if (!bitstream_buffers_in_decoder_.empty()) { | 701 if (!bitstream_buffers_in_decoder_.empty()) { |
701 auto it = bitstream_buffers_in_decoder_.begin(); | 702 auto it = bitstream_buffers_in_decoder_.begin(); |
702 it->second.done_cb.Run(kDecodeError); | 703 it->second.done_cb.Run(DecodeStatus::DECODE_ERROR); |
703 bitstream_buffers_in_decoder_.erase(it); | 704 bitstream_buffers_in_decoder_.erase(it); |
704 } | 705 } |
705 | 706 |
706 DLOG(ERROR) << "VDA Error: " << error; | 707 DLOG(ERROR) << "VDA Error: " << error; |
707 UMA_HISTOGRAM_ENUMERATION("Media.GpuVideoDecoderError", error, | 708 UMA_HISTOGRAM_ENUMERATION("Media.GpuVideoDecoderError", error, |
708 media::VideoDecodeAccelerator::ERROR_MAX + 1); | 709 media::VideoDecodeAccelerator::ERROR_MAX + 1); |
709 | 710 |
710 DestroyVDA(); | 711 DestroyVDA(); |
711 } | 712 } |
712 | 713 |
(...skipping 15 matching lines...) Expand all Loading... |
728 } | 729 } |
729 return false; | 730 return false; |
730 } | 731 } |
731 | 732 |
732 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() | 733 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() |
733 const { | 734 const { |
734 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); | 735 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); |
735 } | 736 } |
736 | 737 |
737 } // namespace media | 738 } // namespace media |
OLD | NEW |