Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(458)

Side by Side Diff: content/common/gpu/media/android_video_decode_accelerator.cc

Issue 1639963002: AndroidVideoDecodeAccelerator can now render to a SurfaceView (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Frank's suggestion Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698