OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "content/renderer/media/rtc_video_decoder.h" | 5 #include "content/renderer/media/rtc_video_decoder.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/memory/ref_counted.h" | 9 #include "base/memory/ref_counted.h" |
10 #include "base/message_loop/message_loop_proxy.h" | 10 #include "base/message_loop/message_loop_proxy.h" |
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
396 if (IsBufferAfterReset(picture.bitstream_buffer_id(), | 396 if (IsBufferAfterReset(picture.bitstream_buffer_id(), |
397 reset_bitstream_buffer_id_)) { | 397 reset_bitstream_buffer_id_)) { |
398 decode_complete_callback_->Decoded(decoded_image); | 398 decode_complete_callback_->Decoded(decoded_image); |
399 } | 399 } |
400 } | 400 } |
401 } | 401 } |
402 | 402 |
403 static void ReadPixelsSyncInner( | 403 static void ReadPixelsSyncInner( |
404 const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories, | 404 const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories, |
405 uint32 texture_id, | 405 uint32 texture_id, |
406 const gfx::Rect& visible_rect, | 406 const scoped_refptr<media::VideoFrame>& frame, |
407 const SkBitmap& pixels, | 407 const SkBitmap& pixels, |
408 base::WaitableEvent* event) { | 408 base::WaitableEvent* event) { |
409 factories->ReadPixels(texture_id, visible_rect, pixels); | 409 factories->ReadPixels(texture_id, frame, pixels); |
410 event->Signal(); | 410 event->Signal(); |
411 } | 411 } |
412 | 412 |
413 static void ReadPixelsSync( | 413 static void ReadPixelsSync( |
414 const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories, | 414 const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories, |
415 uint32 texture_id, | 415 uint32 texture_id, |
416 const gfx::Rect& visible_rect, | 416 const scoped_refptr<media::VideoFrame>& frame, |
417 const SkBitmap& pixels) { | 417 const SkBitmap& pixels) { |
418 base::WaitableEvent event(true, false); | 418 base::WaitableEvent event(true, false); |
419 if (!factories->GetTaskRunner()->PostTask(FROM_HERE, | 419 if (!factories->GetTaskRunner()->PostTask(FROM_HERE, |
420 base::Bind(&ReadPixelsSyncInner, | 420 base::Bind(&ReadPixelsSyncInner, |
421 factories, | 421 factories, |
422 texture_id, | 422 texture_id, |
423 visible_rect, | 423 frame, |
424 pixels, | 424 pixels, |
425 &event))) | 425 &event))) |
426 return; | 426 return; |
427 event.Wait(); | 427 event.Wait(); |
428 } | 428 } |
429 | 429 |
430 scoped_refptr<media::VideoFrame> RTCVideoDecoder::CreateVideoFrame( | 430 scoped_refptr<media::VideoFrame> RTCVideoDecoder::CreateVideoFrame( |
431 const media::Picture& picture, | 431 const media::Picture& picture, |
432 const media::PictureBuffer& pb, | 432 const media::PictureBuffer& pb, |
433 uint32_t timestamp, | 433 uint32_t timestamp, |
434 uint32_t width, | 434 uint32_t width, |
435 uint32_t height, | 435 uint32_t height, |
436 size_t size) { | 436 size_t size) { |
437 gfx::Rect visible_rect(width, height); | 437 gfx::Rect visible_rect(width, height); |
438 DCHECK(decoder_texture_target_); | 438 DCHECK(decoder_texture_target_); |
439 // Convert timestamp from 90KHz to ms. | 439 // Convert timestamp from 90KHz to ms. |
440 base::TimeDelta timestamp_ms = base::TimeDelta::FromInternalValue( | 440 base::TimeDelta timestamp_ms = base::TimeDelta::FromInternalValue( |
441 base::checked_cast<uint64_t>(timestamp) * 1000 / 90); | 441 base::checked_cast<uint64_t>(timestamp) * 1000 / 90); |
442 return media::VideoFrame::WrapNativeTexture( | 442 return media::VideoFrame::WrapNativeTexture( |
443 make_scoped_ptr(new gpu::MailboxHolder( | 443 make_scoped_ptr(new gpu::MailboxHolder( |
444 pb.texture_mailbox(), decoder_texture_target_, 0)), | 444 pb.texture_mailbox(), decoder_texture_target_, 0)), |
445 media::BindToCurrentLoop(base::Bind(&RTCVideoDecoder::ReusePictureBuffer, | 445 media::BindToCurrentLoop(base::Bind(&RTCVideoDecoder::ReusePictureBuffer, |
446 weak_this_, | 446 weak_this_, |
447 picture.picture_buffer_id())), | 447 picture.picture_buffer_id())), |
448 pb.size(), | 448 pb.size(), |
449 visible_rect, | 449 visible_rect, |
450 visible_rect.size(), | 450 visible_rect.size(), |
451 timestamp_ms, | 451 timestamp_ms, |
452 base::Bind(&ReadPixelsSync, factories_, pb.texture_id(), visible_rect)); | 452 base::Bind(&ReadPixelsSync, factories_, pb.texture_id())); |
453 } | 453 } |
454 | 454 |
455 void RTCVideoDecoder::NotifyEndOfBitstreamBuffer(int32 id) { | 455 void RTCVideoDecoder::NotifyEndOfBitstreamBuffer(int32 id) { |
456 DVLOG(3) << "NotifyEndOfBitstreamBuffer. id=" << id; | 456 DVLOG(3) << "NotifyEndOfBitstreamBuffer. id=" << id; |
457 DCHECK(vda_task_runner_->BelongsToCurrentThread()); | 457 DCHECK(vda_task_runner_->BelongsToCurrentThread()); |
458 | 458 |
459 std::map<int32, SHMBuffer*>::iterator it = | 459 std::map<int32, SHMBuffer*>::iterator it = |
460 bitstream_buffers_in_decoder_.find(id); | 460 bitstream_buffers_in_decoder_.find(id); |
461 if (it == bitstream_buffers_in_decoder_.end()) { | 461 if (it == bitstream_buffers_in_decoder_.end()) { |
462 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); | 462 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
633 | 633 |
634 void RTCVideoDecoder::ResetInternal() { | 634 void RTCVideoDecoder::ResetInternal() { |
635 DCHECK(vda_task_runner_->BelongsToCurrentThread()); | 635 DCHECK(vda_task_runner_->BelongsToCurrentThread()); |
636 DVLOG(2) << "ResetInternal"; | 636 DVLOG(2) << "ResetInternal"; |
637 if (vda_) | 637 if (vda_) |
638 vda_->Reset(); | 638 vda_->Reset(); |
639 } | 639 } |
640 | 640 |
641 void RTCVideoDecoder::ReusePictureBuffer( | 641 void RTCVideoDecoder::ReusePictureBuffer( |
642 int64 picture_buffer_id, | 642 int64 picture_buffer_id, |
643 scoped_ptr<gpu::MailboxHolder> mailbox_holder) { | 643 scoped_ptr<gpu::MailboxHolder> mailbox_holder, |
| 644 const std::vector<uint32>& release_sync_points) { |
644 DCHECK(vda_task_runner_->BelongsToCurrentThread()); | 645 DCHECK(vda_task_runner_->BelongsToCurrentThread()); |
645 DVLOG(3) << "ReusePictureBuffer. id=" << picture_buffer_id; | 646 DVLOG(3) << "ReusePictureBuffer. id=" << picture_buffer_id; |
646 | 647 |
647 if (!vda_) | 648 if (!vda_) |
648 return; | 649 return; |
649 | 650 |
650 CHECK(!picture_buffers_at_display_.empty()); | 651 CHECK(!picture_buffers_at_display_.empty()); |
651 | 652 |
652 size_t num_erased = picture_buffers_at_display_.erase(picture_buffer_id); | 653 size_t num_erased = picture_buffers_at_display_.erase(picture_buffer_id); |
653 DCHECK(num_erased); | 654 DCHECK(num_erased); |
654 | 655 |
655 std::map<int32, media::PictureBuffer>::iterator it = | 656 std::map<int32, media::PictureBuffer>::iterator it = |
656 assigned_picture_buffers_.find(picture_buffer_id); | 657 assigned_picture_buffers_.find(picture_buffer_id); |
657 | 658 |
658 if (it == assigned_picture_buffers_.end()) { | 659 if (it == assigned_picture_buffers_.end()) { |
659 // This picture was dismissed while in display, so we postponed deletion. | 660 // This picture was dismissed while in display, so we postponed deletion. |
660 it = dismissed_picture_buffers_.find(picture_buffer_id); | 661 it = dismissed_picture_buffers_.find(picture_buffer_id); |
661 DCHECK(it != dismissed_picture_buffers_.end()); | 662 DCHECK(it != dismissed_picture_buffers_.end()); |
662 factories_->DeleteTexture(it->second.texture_id()); | 663 factories_->DeleteTexture(it->second.texture_id()); |
663 dismissed_picture_buffers_.erase(it); | 664 dismissed_picture_buffers_.erase(it); |
664 return; | 665 return; |
665 } | 666 } |
666 | 667 |
667 factories_->WaitSyncPoint(mailbox_holder->sync_point); | 668 for (size_t i = 0; i < release_sync_points.size(); i++) |
| 669 factories_->WaitSyncPoint(release_sync_points[i]); |
668 | 670 |
669 vda_->ReusePictureBuffer(picture_buffer_id); | 671 vda_->ReusePictureBuffer(picture_buffer_id); |
670 } | 672 } |
671 | 673 |
672 void RTCVideoDecoder::CreateVDA(media::VideoCodecProfile profile, | 674 void RTCVideoDecoder::CreateVDA(media::VideoCodecProfile profile, |
673 base::WaitableEvent* waiter) { | 675 base::WaitableEvent* waiter) { |
674 DCHECK(vda_task_runner_->BelongsToCurrentThread()); | 676 DCHECK(vda_task_runner_->BelongsToCurrentThread()); |
675 vda_ = factories_->CreateVideoDecodeAccelerator(profile); | 677 vda_ = factories_->CreateVideoDecodeAccelerator(profile); |
676 if (vda_ && !vda_->Initialize(profile, this)) | 678 if (vda_ && !vda_->Initialize(profile, this)) |
677 vda_.release()->Destroy(); | 679 vda_.release()->Destroy(); |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
786 | 788 |
787 int32_t RTCVideoDecoder::RecordInitDecodeUMA(int32_t status) { | 789 int32_t RTCVideoDecoder::RecordInitDecodeUMA(int32_t status) { |
788 // Logging boolean is enough to know if HW decoding has been used. Also, | 790 // Logging boolean is enough to know if HW decoding has been used. Also, |
789 // InitDecode is less likely to return an error so enum is not used here. | 791 // InitDecode is less likely to return an error so enum is not used here. |
790 bool sample = (status == WEBRTC_VIDEO_CODEC_OK) ? true : false; | 792 bool sample = (status == WEBRTC_VIDEO_CODEC_OK) ? true : false; |
791 UMA_HISTOGRAM_BOOLEAN("Media.RTCVideoDecoderInitDecodeSuccess", sample); | 793 UMA_HISTOGRAM_BOOLEAN("Media.RTCVideoDecoderInitDecodeSuccess", sample); |
792 return status; | 794 return status; |
793 } | 795 } |
794 | 796 |
795 } // namespace content | 797 } // namespace content |
OLD | NEW |