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

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: rebase only 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/auto_reset.h" 10 #include "base/auto_reset.h"
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 cdm_registration_id_(0), 168 cdm_registration_id_(0),
169 pending_input_buf_index_(-1), 169 pending_input_buf_index_(-1),
170 error_sequence_token_(0), 170 error_sequence_token_(0),
171 defer_errors_(false), 171 defer_errors_(false),
172 weak_this_factory_(this) { 172 weak_this_factory_(this) {
173 if (UseDeferredRenderingStrategy()) { 173 if (UseDeferredRenderingStrategy()) {
174 // TODO(liberato, watk): Figure out what we want to do about zero copy for 174 // TODO(liberato, watk): Figure out what we want to do about zero copy for
175 // fullscreen external SurfaceView in WebView. http://crbug.com/582170. 175 // fullscreen external SurfaceView in WebView. http://crbug.com/582170.
176 DCHECK(!gl_decoder_->GetContextGroup()->mailbox_manager()->UsesSync()); 176 DCHECK(!gl_decoder_->GetContextGroup()->mailbox_manager()->UsesSync());
177 DVLOG(1) << __FUNCTION__ << ", using deferred rendering strategy."; 177 DVLOG(1) << __FUNCTION__ << ", using deferred rendering strategy.";
178 strategy_.reset(new AndroidDeferredRenderingBackingStrategy()); 178 strategy_.reset(new AndroidDeferredRenderingBackingStrategy(this));
179 } else { 179 } else {
180 DVLOG(1) << __FUNCTION__ << ", using copy back strategy."; 180 DVLOG(1) << __FUNCTION__ << ", using copy back strategy.";
181 strategy_.reset(new AndroidCopyingBackingStrategy()); 181 strategy_.reset(new AndroidCopyingBackingStrategy(this));
182 } 182 }
183 } 183 }
184 184
185 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { 185 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() {
186 DCHECK(thread_checker_.CalledOnValidThread()); 186 DCHECK(thread_checker_.CalledOnValidThread());
187 187
188 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) 188 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
189 if (cdm_) { 189 if (cdm_) {
190 DCHECK(cdm_registration_id_); 190 DCHECK(cdm_registration_id_);
191 static_cast<media::MediaDrmBridge*>(cdm_.get()) 191 static_cast<media::MediaDrmBridge*>(cdm_.get())
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 if (!make_context_current_.Run()) { 232 if (!make_context_current_.Run()) {
233 LOG(ERROR) << "Failed to make this decoder's GL context current."; 233 LOG(ERROR) << "Failed to make this decoder's GL context current.";
234 return false; 234 return false;
235 } 235 }
236 236
237 if (!gl_decoder_) { 237 if (!gl_decoder_) {
238 LOG(ERROR) << "Failed to get gles2 decoder instance."; 238 LOG(ERROR) << "Failed to get gles2 decoder instance.";
239 return false; 239 return false;
240 } 240 }
241 241
242 strategy_->Initialize(this); 242 surface_ = strategy_->Initialize(config.surface_id);
243 if (surface_.IsEmpty()) {
244 LOG(ERROR) << "Failed to initialize the backing strategy. The returned "
245 "Java surface is empty.";
246 return false;
247 }
243 248
244 surface_texture_ = strategy_->CreateSurfaceTexture(); 249 // TODO(watk,liberato): move this into the strategy.
245 on_frame_available_handler_ = 250 scoped_refptr<gfx::SurfaceTexture> surface_texture =
246 new OnFrameAvailableHandler(this, surface_texture_); 251 strategy_->GetSurfaceTexture();
252 if (surface_texture) {
253 on_frame_available_handler_ =
254 new OnFrameAvailableHandler(this, surface_texture);
255 }
247 256
248 // For encrypted streams we postpone configuration until MediaCrypto is 257 // For encrypted streams we postpone configuration until MediaCrypto is
249 // available. 258 // available.
250 if (is_encrypted_) 259 if (is_encrypted_)
251 return true; 260 return true;
252 261
253 return ConfigureMediaCodec(); 262 return ConfigureMediaCodec();
254 } 263 }
255 264
256 void AndroidVideoDecodeAccelerator::SetCdm(int cdm_id) { 265 void AndroidVideoDecodeAccelerator::SetCdm(int cdm_id) {
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 base::Bind(&AndroidVideoDecodeAccelerator::RequestPictureBuffers, 514 base::Bind(&AndroidVideoDecodeAccelerator::RequestPictureBuffers,
506 weak_this_factory_.GetWeakPtr())); 515 weak_this_factory_.GetWeakPtr()));
507 return false; 516 return false;
508 } 517 }
509 518
510 case media::MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED: 519 case media::MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED:
511 break; 520 break;
512 521
513 case media::MEDIA_CODEC_OK: 522 case media::MEDIA_CODEC_OK:
514 DCHECK_GE(buf_index, 0); 523 DCHECK_GE(buf_index, 0);
515 DVLOG(3) << "AVDA::DequeueOutput: pts:" << presentation_timestamp 524 DVLOG(3) << __FUNCTION__ << ": pts:" << presentation_timestamp
516 << " buf_index:" << buf_index << " offset:" << offset 525 << " buf_index:" << buf_index << " offset:" << offset
517 << " size:" << size << " eos:" << eos; 526 << " size:" << size << " eos:" << eos;
518 break; 527 break;
519 528
520 default: 529 default:
521 NOTREACHED(); 530 NOTREACHED();
522 break; 531 break;
523 } 532 }
524 } while (buf_index < 0); 533 } while (buf_index < 0);
525 534
526 if (eos) { 535 if (eos) {
527 DVLOG(3) << "AVDA::DequeueOutput: Resetting codec state after EOS"; 536 DVLOG(3) << __FUNCTION__ << ": Resetting codec state after EOS";
528 ResetCodecState(); 537 ResetCodecState();
529 538
530 base::MessageLoop::current()->PostTask( 539 base::MessageLoop::current()->PostTask(
531 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyFlushDone, 540 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyFlushDone,
532 weak_this_factory_.GetWeakPtr())); 541 weak_this_factory_.GetWeakPtr()));
533 return false; 542 return false;
534 } 543 }
535 544
536 // Get the bitstream buffer id from the timestamp. 545 // Get the bitstream buffer id from the timestamp.
537 auto it = bitstream_buffers_in_decoder_.find(presentation_timestamp); 546 auto it = bitstream_buffers_in_decoder_.find(presentation_timestamp);
(...skipping 16 matching lines...) Expand all
554 bitstreams_notified_in_advance_.begin(), ++bitstream_it); 563 bitstreams_notified_in_advance_.begin(), ++bitstream_it);
555 break; 564 break;
556 } 565 }
557 } 566 }
558 } else { 567 } else {
559 // Normally we assume that the decoder makes at most one output frame for 568 // Normally we assume that the decoder makes at most one output frame for
560 // each distinct input timestamp. However MediaCodecBridge uses timestamp 569 // each distinct input timestamp. However MediaCodecBridge uses timestamp
561 // correction and provides a non-decreasing timestamp sequence, which might 570 // correction and provides a non-decreasing timestamp sequence, which might
562 // result in timestamp duplicates. Discard the frame if we cannot get the 571 // result in timestamp duplicates. Discard the frame if we cannot get the
563 // corresponding buffer id. 572 // corresponding buffer id.
564 DVLOG(3) << "AVDA::DequeueOutput: Releasing buffer with unexpected PTS: " 573 DVLOG(3) << __FUNCTION__ << ": Releasing buffer with unexpected PTS: "
565 << presentation_timestamp; 574 << presentation_timestamp;
566 media_codec_->ReleaseOutputBuffer(buf_index, false); 575 media_codec_->ReleaseOutputBuffer(buf_index, false);
567 } 576 }
568 577
569 // We got a decoded frame, so try for another. 578 // We got a decoded frame, so try for another.
570 return true; 579 return true;
571 } 580 }
572 581
573 void AndroidVideoDecodeAccelerator::SendDecodedFrameToClient( 582 void AndroidVideoDecodeAccelerator::SendDecodedFrameToClient(
574 int32_t codec_buffer_index, 583 int32_t codec_buffer_index,
(...skipping 17 matching lines...) Expand all
592 if (i == output_picture_buffers_.end()) { 601 if (i == output_picture_buffers_.end()) {
593 POST_ERROR(PLATFORM_FAILURE, 602 POST_ERROR(PLATFORM_FAILURE,
594 "Can't find PictureBuffer id: " << picture_buffer_id); 603 "Can't find PictureBuffer id: " << picture_buffer_id);
595 return; 604 return;
596 } 605 }
597 606
598 // Connect the PictureBuffer to the decoded frame, via whatever 607 // Connect the PictureBuffer to the decoded frame, via whatever
599 // mechanism the strategy likes. 608 // mechanism the strategy likes.
600 strategy_->UseCodecBufferForPictureBuffer(codec_buffer_index, i->second); 609 strategy_->UseCodecBufferForPictureBuffer(codec_buffer_index, i->second);
601 610
611 const bool allow_overlay = strategy_->ArePicturesOverlayable();
602 base::MessageLoop::current()->PostTask( 612 base::MessageLoop::current()->PostTask(
603 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyPictureReady, 613 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyPictureReady,
604 weak_this_factory_.GetWeakPtr(), 614 weak_this_factory_.GetWeakPtr(),
605 media::Picture(picture_buffer_id, bitstream_id, 615 media::Picture(picture_buffer_id, bitstream_id,
606 gfx::Rect(size_), false))); 616 gfx::Rect(size_), allow_overlay)));
607 } 617 }
608 618
609 void AndroidVideoDecodeAccelerator::Decode( 619 void AndroidVideoDecodeAccelerator::Decode(
610 const media::BitstreamBuffer& bitstream_buffer) { 620 const media::BitstreamBuffer& bitstream_buffer) {
611 DCHECK(thread_checker_.CalledOnValidThread()); 621 DCHECK(thread_checker_.CalledOnValidThread());
612 if (bitstream_buffer.id() != -1 && bitstream_buffer.size() == 0) { 622 if (bitstream_buffer.id() != -1 && bitstream_buffer.size() == 0) {
613 base::MessageLoop::current()->PostTask( 623 base::MessageLoop::current()->PostTask(
614 FROM_HERE, 624 FROM_HERE,
615 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, 625 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer,
616 weak_this_factory_.GetWeakPtr(), bitstream_buffer.id())); 626 weak_this_factory_.GetWeakPtr(), bitstream_buffer.id()));
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
692 } 702 }
693 703
694 void AndroidVideoDecodeAccelerator::Flush() { 704 void AndroidVideoDecodeAccelerator::Flush() {
695 DCHECK(thread_checker_.CalledOnValidThread()); 705 DCHECK(thread_checker_.CalledOnValidThread());
696 706
697 Decode(media::BitstreamBuffer(-1, base::SharedMemoryHandle(), 0)); 707 Decode(media::BitstreamBuffer(-1, base::SharedMemoryHandle(), 0));
698 } 708 }
699 709
700 bool AndroidVideoDecodeAccelerator::ConfigureMediaCodec() { 710 bool AndroidVideoDecodeAccelerator::ConfigureMediaCodec() {
701 DCHECK(thread_checker_.CalledOnValidThread()); 711 DCHECK(thread_checker_.CalledOnValidThread());
702 DCHECK(surface_texture_.get());
703 TRACE_EVENT0("media", "AVDA::ConfigureMediaCodec"); 712 TRACE_EVENT0("media", "AVDA::ConfigureMediaCodec");
704 713
705 gfx::ScopedJavaSurface surface(surface_texture_.get());
706
707 jobject media_crypto = media_crypto_ ? media_crypto_->obj() : nullptr; 714 jobject media_crypto = media_crypto_ ? media_crypto_->obj() : nullptr;
708 715
709 // |needs_protected_surface_| implies encrypted stream. 716 // |needs_protected_surface_| implies encrypted stream.
710 DCHECK(!needs_protected_surface_ || media_crypto); 717 DCHECK(!needs_protected_surface_ || media_crypto);
711 718
712 // Pass a dummy 320x240 canvas size and let the codec signal the real size 719 // Pass a dummy 320x240 canvas size and let the codec signal the real size
713 // when it's known from the bitstream. 720 // when it's known from the bitstream.
714 media_codec_.reset(media::VideoCodecBridge::CreateDecoder( 721 media_codec_.reset(media::VideoCodecBridge::CreateDecoder(
715 codec_, needs_protected_surface_, gfx::Size(320, 240), 722 codec_, needs_protected_surface_, gfx::Size(320, 240),
716 surface.j_surface().obj(), media_crypto)); 723 surface_.j_surface().obj(), media_crypto));
724
717 strategy_->CodecChanged(media_codec_.get(), output_picture_buffers_); 725 strategy_->CodecChanged(media_codec_.get(), output_picture_buffers_);
718 if (!media_codec_) { 726 if (!media_codec_) {
719 LOG(ERROR) << "Failed to create MediaCodec instance."; 727 LOG(ERROR) << "Failed to create MediaCodec instance.";
720 return false; 728 return false;
721 } 729 }
722 730
723 ManageTimer(true); 731 ManageTimer(true);
724 return true; 732 return true;
725 } 733 }
726 734
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
1007 1015
1008 if (UseDeferredRenderingStrategy()) { 1016 if (UseDeferredRenderingStrategy()) {
1009 capabilities.flags = media::VideoDecodeAccelerator::Capabilities:: 1017 capabilities.flags = media::VideoDecodeAccelerator::Capabilities::
1010 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE; 1018 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE;
1011 } 1019 }
1012 1020
1013 return capabilities; 1021 return capabilities;
1014 } 1022 }
1015 1023
1016 } // namespace content 1024 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698