Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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/common/gpu/media/android_video_decode_accelerator.h" | 5 #include "content/common/gpu/media/android_video_decode_accelerator.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include "base/android/build_info.h" | 9 #include "base/android/build_info.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 213 if (!make_context_current_.Run()) { | 213 if (!make_context_current_.Run()) { |
| 214 LOG(ERROR) << "Failed to make this decoder's GL context current."; | 214 LOG(ERROR) << "Failed to make this decoder's GL context current."; |
| 215 return false; | 215 return false; |
| 216 } | 216 } |
| 217 | 217 |
| 218 if (!gl_decoder_) { | 218 if (!gl_decoder_) { |
| 219 LOG(ERROR) << "Failed to get gles2 decoder instance."; | 219 LOG(ERROR) << "Failed to get gles2 decoder instance."; |
| 220 return false; | 220 return false; |
| 221 } | 221 } |
| 222 | 222 |
| 223 strategy_->Initialize(this); | 223 surface_ = strategy_->Initialize(this, config.surface_id); |
| 224 if (surface_.IsEmpty()) { | |
| 225 LOG(ERROR) << "Failed to initialize the backing strategy. The returned " | |
| 226 "Java surface is empty."; | |
| 227 } | |
| 224 | 228 |
| 225 surface_texture_ = strategy_->CreateSurfaceTexture(); | 229 // TODO(watk,liberato): move this into the strategy. |
| 226 on_frame_available_handler_ = | 230 scoped_refptr<gfx::SurfaceTexture> surface_texture = |
|
liberato (no reviews please)
2016/01/27 16:15:33
i forgot about the onFrameAvailable listener. not
| |
| 227 new OnFrameAvailableHandler(this, surface_texture_); | 231 strategy_->GetSurfaceTexture(); |
| 232 if (surface_texture) { | |
| 233 on_frame_available_handler_ = | |
| 234 new OnFrameAvailableHandler(this, surface_texture); | |
| 235 } | |
| 228 | 236 |
| 229 // For encrypted streams we postpone configuration until MediaCrypto is | 237 // For encrypted streams we postpone configuration until MediaCrypto is |
| 230 // available. | 238 // available. |
| 231 if (is_encrypted_) | 239 if (is_encrypted_) |
| 232 return true; | 240 return true; |
| 233 | 241 |
| 234 return ConfigureMediaCodec(); | 242 return ConfigureMediaCodec(); |
| 235 } | 243 } |
| 236 | 244 |
| 237 void AndroidVideoDecodeAccelerator::SetCdm(int cdm_id) { | 245 void AndroidVideoDecodeAccelerator::SetCdm(int cdm_id) { |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 484 base::Bind(&AndroidVideoDecodeAccelerator::RequestPictureBuffers, | 492 base::Bind(&AndroidVideoDecodeAccelerator::RequestPictureBuffers, |
| 485 weak_this_factory_.GetWeakPtr())); | 493 weak_this_factory_.GetWeakPtr())); |
| 486 return false; | 494 return false; |
| 487 } | 495 } |
| 488 | 496 |
| 489 case media::MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED: | 497 case media::MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED: |
| 490 break; | 498 break; |
| 491 | 499 |
| 492 case media::MEDIA_CODEC_OK: | 500 case media::MEDIA_CODEC_OK: |
| 493 DCHECK_GE(buf_index, 0); | 501 DCHECK_GE(buf_index, 0); |
| 494 DVLOG(3) << "AVDA::DequeueOutput: pts:" << presentation_timestamp | 502 DVLOG(3) << __FUNCTION__ << ": pts:" << presentation_timestamp |
| 495 << " buf_index:" << buf_index << " offset:" << offset | 503 << " buf_index:" << buf_index << " offset:" << offset |
| 496 << " size:" << size << " eos:" << eos; | 504 << " size:" << size << " eos:" << eos; |
| 497 break; | 505 break; |
| 498 | 506 |
| 499 default: | 507 default: |
| 500 NOTREACHED(); | 508 NOTREACHED(); |
| 501 break; | 509 break; |
| 502 } | 510 } |
| 503 } while (buf_index < 0); | 511 } while (buf_index < 0); |
| 504 | 512 |
| 505 if (eos) { | 513 if (eos) { |
| 506 DVLOG(3) << "AVDA::DequeueOutput: Resetting codec state after EOS"; | 514 DVLOG(3) << __FUNCTION__ << ": Resetting codec state after EOS"; |
| 507 ResetCodecState(); | 515 ResetCodecState(); |
| 508 | 516 |
| 509 base::MessageLoop::current()->PostTask( | 517 base::MessageLoop::current()->PostTask( |
| 510 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyFlushDone, | 518 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyFlushDone, |
| 511 weak_this_factory_.GetWeakPtr())); | 519 weak_this_factory_.GetWeakPtr())); |
| 512 return false; | 520 return false; |
| 513 } | 521 } |
| 514 | 522 |
| 515 // Get the bitstream buffer id from the timestamp. | 523 // Get the bitstream buffer id from the timestamp. |
| 516 auto it = bitstream_buffers_in_decoder_.find(presentation_timestamp); | 524 auto it = bitstream_buffers_in_decoder_.find(presentation_timestamp); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 533 bitstreams_notified_in_advance_.begin(), ++bitstream_it); | 541 bitstreams_notified_in_advance_.begin(), ++bitstream_it); |
| 534 break; | 542 break; |
| 535 } | 543 } |
| 536 } | 544 } |
| 537 } else { | 545 } else { |
| 538 // Normally we assume that the decoder makes at most one output frame for | 546 // Normally we assume that the decoder makes at most one output frame for |
| 539 // each distinct input timestamp. However MediaCodecBridge uses timestamp | 547 // each distinct input timestamp. However MediaCodecBridge uses timestamp |
| 540 // correction and provides a non-decreasing timestamp sequence, which might | 548 // correction and provides a non-decreasing timestamp sequence, which might |
| 541 // result in timestamp duplicates. Discard the frame if we cannot get the | 549 // result in timestamp duplicates. Discard the frame if we cannot get the |
| 542 // corresponding buffer id. | 550 // corresponding buffer id. |
| 543 DVLOG(3) << "AVDA::DequeueOutput: Releasing buffer with unexpected PTS: " | 551 DVLOG(3) << __FUNCTION__ << ": Releasing buffer with unexpected PTS: " |
| 544 << presentation_timestamp; | 552 << presentation_timestamp; |
| 545 media_codec_->ReleaseOutputBuffer(buf_index, false); | 553 media_codec_->ReleaseOutputBuffer(buf_index, false); |
| 546 } | 554 } |
| 547 | 555 |
| 548 // We got a decoded frame, so try for another. | 556 // We got a decoded frame, so try for another. |
| 549 return true; | 557 return true; |
| 550 } | 558 } |
| 551 | 559 |
| 552 void AndroidVideoDecodeAccelerator::SendDecodedFrameToClient( | 560 void AndroidVideoDecodeAccelerator::SendDecodedFrameToClient( |
| 553 int32_t codec_buffer_index, | 561 int32_t codec_buffer_index, |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 571 if (i == output_picture_buffers_.end()) { | 579 if (i == output_picture_buffers_.end()) { |
| 572 POST_ERROR(PLATFORM_FAILURE, | 580 POST_ERROR(PLATFORM_FAILURE, |
| 573 "Can't find PictureBuffer id: " << picture_buffer_id); | 581 "Can't find PictureBuffer id: " << picture_buffer_id); |
| 574 return; | 582 return; |
| 575 } | 583 } |
| 576 | 584 |
| 577 // Connect the PictureBuffer to the decoded frame, via whatever | 585 // Connect the PictureBuffer to the decoded frame, via whatever |
| 578 // mechanism the strategy likes. | 586 // mechanism the strategy likes. |
| 579 strategy_->UseCodecBufferForPictureBuffer(codec_buffer_index, i->second); | 587 strategy_->UseCodecBufferForPictureBuffer(codec_buffer_index, i->second); |
| 580 | 588 |
| 589 const bool allow_overlay = strategy_->PicturesAreOverlayable(); | |
| 581 base::MessageLoop::current()->PostTask( | 590 base::MessageLoop::current()->PostTask( |
| 582 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyPictureReady, | 591 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyPictureReady, |
| 583 weak_this_factory_.GetWeakPtr(), | 592 weak_this_factory_.GetWeakPtr(), |
| 584 media::Picture(picture_buffer_id, bitstream_id, | 593 media::Picture(picture_buffer_id, bitstream_id, |
| 585 gfx::Rect(size_), false))); | 594 gfx::Rect(size_), allow_overlay))); |
| 586 } | 595 } |
| 587 | 596 |
| 588 void AndroidVideoDecodeAccelerator::Decode( | 597 void AndroidVideoDecodeAccelerator::Decode( |
| 589 const media::BitstreamBuffer& bitstream_buffer) { | 598 const media::BitstreamBuffer& bitstream_buffer) { |
| 590 DCHECK(thread_checker_.CalledOnValidThread()); | 599 DCHECK(thread_checker_.CalledOnValidThread()); |
| 591 if (bitstream_buffer.id() != -1 && bitstream_buffer.size() == 0) { | 600 if (bitstream_buffer.id() != -1 && bitstream_buffer.size() == 0) { |
| 592 base::MessageLoop::current()->PostTask( | 601 base::MessageLoop::current()->PostTask( |
| 593 FROM_HERE, | 602 FROM_HERE, |
| 594 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, | 603 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, |
| 595 weak_this_factory_.GetWeakPtr(), bitstream_buffer.id())); | 604 weak_this_factory_.GetWeakPtr(), bitstream_buffer.id())); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 671 } | 680 } |
| 672 | 681 |
| 673 void AndroidVideoDecodeAccelerator::Flush() { | 682 void AndroidVideoDecodeAccelerator::Flush() { |
| 674 DCHECK(thread_checker_.CalledOnValidThread()); | 683 DCHECK(thread_checker_.CalledOnValidThread()); |
| 675 | 684 |
| 676 Decode(media::BitstreamBuffer(-1, base::SharedMemoryHandle(), 0)); | 685 Decode(media::BitstreamBuffer(-1, base::SharedMemoryHandle(), 0)); |
| 677 } | 686 } |
| 678 | 687 |
| 679 bool AndroidVideoDecodeAccelerator::ConfigureMediaCodec() { | 688 bool AndroidVideoDecodeAccelerator::ConfigureMediaCodec() { |
| 680 DCHECK(thread_checker_.CalledOnValidThread()); | 689 DCHECK(thread_checker_.CalledOnValidThread()); |
| 681 DCHECK(surface_texture_.get()); | |
| 682 TRACE_EVENT0("media", "AVDA::ConfigureMediaCodec"); | 690 TRACE_EVENT0("media", "AVDA::ConfigureMediaCodec"); |
| 683 | 691 |
| 684 gfx::ScopedJavaSurface surface(surface_texture_.get()); | |
| 685 | |
| 686 jobject media_crypto = media_crypto_ ? media_crypto_->obj() : nullptr; | 692 jobject media_crypto = media_crypto_ ? media_crypto_->obj() : nullptr; |
| 687 | 693 |
| 688 // |needs_protected_surface_| implies encrypted stream. | 694 // |needs_protected_surface_| implies encrypted stream. |
| 689 DCHECK(!needs_protected_surface_ || media_crypto); | 695 DCHECK(!needs_protected_surface_ || media_crypto); |
| 690 | 696 |
| 691 // Pass a dummy 320x240 canvas size and let the codec signal the real size | 697 // Pass a dummy 320x240 canvas size and let the codec signal the real size |
| 692 // when it's known from the bitstream. | 698 // when it's known from the bitstream. |
| 693 media_codec_.reset(media::VideoCodecBridge::CreateDecoder( | 699 media_codec_.reset(media::VideoCodecBridge::CreateDecoder( |
| 694 codec_, needs_protected_surface_, gfx::Size(320, 240), | 700 codec_, needs_protected_surface_, gfx::Size(320, 240), |
| 695 surface.j_surface().obj(), media_crypto)); | 701 surface_.j_surface().obj(), media_crypto)); |
| 702 | |
| 696 strategy_->CodecChanged(media_codec_.get(), output_picture_buffers_); | 703 strategy_->CodecChanged(media_codec_.get(), output_picture_buffers_); |
| 697 if (!media_codec_) { | 704 if (!media_codec_) { |
| 698 LOG(ERROR) << "Failed to create MediaCodec instance."; | 705 LOG(ERROR) << "Failed to create MediaCodec instance."; |
| 699 return false; | 706 return false; |
| 700 } | 707 } |
| 701 | 708 |
| 702 ManageTimer(true); | 709 ManageTimer(true); |
| 703 return true; | 710 return true; |
| 704 } | 711 } |
| 705 | 712 |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 963 | 970 |
| 964 if (UseDeferredRenderingStrategy()) { | 971 if (UseDeferredRenderingStrategy()) { |
| 965 capabilities.flags = media::VideoDecodeAccelerator::Capabilities:: | 972 capabilities.flags = media::VideoDecodeAccelerator::Capabilities:: |
| 966 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE; | 973 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE; |
| 967 } | 974 } |
| 968 | 975 |
| 969 return capabilities; | 976 return capabilities; |
| 970 } | 977 } |
| 971 | 978 |
| 972 } // namespace content | 979 } // namespace content |
| OLD | NEW |