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

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: sandersd's comments 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 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 needs_protected_surface_(false), 161 needs_protected_surface_(false),
162 state_(NO_ERROR), 162 state_(NO_ERROR),
163 picturebuffers_requested_(false), 163 picturebuffers_requested_(false),
164 gl_decoder_(decoder), 164 gl_decoder_(decoder),
165 cdm_registration_id_(0), 165 cdm_registration_id_(0),
166 pending_input_buf_index_(-1), 166 pending_input_buf_index_(-1),
167 error_sequence_token_(0), 167 error_sequence_token_(0),
168 defer_errors_(false), 168 defer_errors_(false),
169 weak_this_factory_(this) { 169 weak_this_factory_(this) {
170 if (UseDeferredRenderingStrategy()) 170 if (UseDeferredRenderingStrategy())
171 strategy_.reset(new AndroidDeferredRenderingBackingStrategy()); 171 strategy_.reset(new AndroidDeferredRenderingBackingStrategy(this));
172 else 172 else
173 strategy_.reset(new AndroidCopyingBackingStrategy()); 173 strategy_.reset(new AndroidCopyingBackingStrategy(this));
174 } 174 }
175 175
176 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { 176 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() {
177 DCHECK(thread_checker_.CalledOnValidThread()); 177 DCHECK(thread_checker_.CalledOnValidThread());
178 178
179 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) 179 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
180 if (cdm_) { 180 if (cdm_) {
181 DCHECK(cdm_registration_id_); 181 DCHECK(cdm_registration_id_);
182 static_cast<media::MediaDrmBridge*>(cdm_.get()) 182 static_cast<media::MediaDrmBridge*>(cdm_.get())
183 ->UnregisterPlayer(cdm_registration_id_); 183 ->UnregisterPlayer(cdm_registration_id_);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 if (!make_context_current_.Run()) { 223 if (!make_context_current_.Run()) {
224 LOG(ERROR) << "Failed to make this decoder's GL context current."; 224 LOG(ERROR) << "Failed to make this decoder's GL context current.";
225 return false; 225 return false;
226 } 226 }
227 227
228 if (!gl_decoder_) { 228 if (!gl_decoder_) {
229 LOG(ERROR) << "Failed to get gles2 decoder instance."; 229 LOG(ERROR) << "Failed to get gles2 decoder instance.";
230 return false; 230 return false;
231 } 231 }
232 232
233 strategy_->Initialize(this); 233 surface_ = strategy_->Initialize(config.surface_id);
234 if (surface_.IsEmpty()) {
235 LOG(ERROR) << "Failed to initialize the backing strategy. The returned "
236 "Java surface is empty.";
237 return false;
238 }
234 239
235 surface_texture_ = strategy_->CreateSurfaceTexture(); 240 // TODO(watk,liberato): move this into the strategy.
236 on_frame_available_handler_ = 241 scoped_refptr<gfx::SurfaceTexture> surface_texture =
237 new OnFrameAvailableHandler(this, surface_texture_); 242 strategy_->GetSurfaceTexture();
243 if (surface_texture) {
244 on_frame_available_handler_ =
245 new OnFrameAvailableHandler(this, surface_texture);
246 }
238 247
239 // For encrypted streams we postpone configuration until MediaCrypto is 248 // For encrypted streams we postpone configuration until MediaCrypto is
240 // available. 249 // available.
241 if (is_encrypted_) 250 if (is_encrypted_)
242 return true; 251 return true;
243 252
244 return ConfigureMediaCodec(); 253 return ConfigureMediaCodec();
245 } 254 }
246 255
247 void AndroidVideoDecodeAccelerator::SetCdm(int cdm_id) { 256 void AndroidVideoDecodeAccelerator::SetCdm(int cdm_id) {
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 base::Bind(&AndroidVideoDecodeAccelerator::RequestPictureBuffers, 505 base::Bind(&AndroidVideoDecodeAccelerator::RequestPictureBuffers,
497 weak_this_factory_.GetWeakPtr())); 506 weak_this_factory_.GetWeakPtr()));
498 return false; 507 return false;
499 } 508 }
500 509
501 case media::MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED: 510 case media::MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED:
502 break; 511 break;
503 512
504 case media::MEDIA_CODEC_OK: 513 case media::MEDIA_CODEC_OK:
505 DCHECK_GE(buf_index, 0); 514 DCHECK_GE(buf_index, 0);
506 DVLOG(3) << "AVDA::DequeueOutput: pts:" << presentation_timestamp 515 DVLOG(3) << __FUNCTION__ << ": pts:" << presentation_timestamp
507 << " buf_index:" << buf_index << " offset:" << offset 516 << " buf_index:" << buf_index << " offset:" << offset
508 << " size:" << size << " eos:" << eos; 517 << " size:" << size << " eos:" << eos;
509 break; 518 break;
510 519
511 default: 520 default:
512 NOTREACHED(); 521 NOTREACHED();
513 break; 522 break;
514 } 523 }
515 } while (buf_index < 0); 524 } while (buf_index < 0);
516 525
517 if (eos) { 526 if (eos) {
518 DVLOG(3) << "AVDA::DequeueOutput: Resetting codec state after EOS"; 527 DVLOG(3) << __FUNCTION__ << ": Resetting codec state after EOS";
519 ResetCodecState(); 528 ResetCodecState();
520 529
521 base::MessageLoop::current()->PostTask( 530 base::MessageLoop::current()->PostTask(
522 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyFlushDone, 531 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyFlushDone,
523 weak_this_factory_.GetWeakPtr())); 532 weak_this_factory_.GetWeakPtr()));
524 return false; 533 return false;
525 } 534 }
526 535
527 // Get the bitstream buffer id from the timestamp. 536 // Get the bitstream buffer id from the timestamp.
528 auto it = bitstream_buffers_in_decoder_.find(presentation_timestamp); 537 auto it = bitstream_buffers_in_decoder_.find(presentation_timestamp);
(...skipping 16 matching lines...) Expand all
545 bitstreams_notified_in_advance_.begin(), ++bitstream_it); 554 bitstreams_notified_in_advance_.begin(), ++bitstream_it);
546 break; 555 break;
547 } 556 }
548 } 557 }
549 } else { 558 } else {
550 // Normally we assume that the decoder makes at most one output frame for 559 // Normally we assume that the decoder makes at most one output frame for
551 // each distinct input timestamp. However MediaCodecBridge uses timestamp 560 // each distinct input timestamp. However MediaCodecBridge uses timestamp
552 // correction and provides a non-decreasing timestamp sequence, which might 561 // correction and provides a non-decreasing timestamp sequence, which might
553 // result in timestamp duplicates. Discard the frame if we cannot get the 562 // result in timestamp duplicates. Discard the frame if we cannot get the
554 // corresponding buffer id. 563 // corresponding buffer id.
555 DVLOG(3) << "AVDA::DequeueOutput: Releasing buffer with unexpected PTS: " 564 DVLOG(3) << __FUNCTION__ << ": Releasing buffer with unexpected PTS: "
556 << presentation_timestamp; 565 << presentation_timestamp;
557 media_codec_->ReleaseOutputBuffer(buf_index, false); 566 media_codec_->ReleaseOutputBuffer(buf_index, false);
558 } 567 }
559 568
560 // We got a decoded frame, so try for another. 569 // We got a decoded frame, so try for another.
561 return true; 570 return true;
562 } 571 }
563 572
564 void AndroidVideoDecodeAccelerator::SendDecodedFrameToClient( 573 void AndroidVideoDecodeAccelerator::SendDecodedFrameToClient(
565 int32_t codec_buffer_index, 574 int32_t codec_buffer_index,
(...skipping 17 matching lines...) Expand all
583 if (i == output_picture_buffers_.end()) { 592 if (i == output_picture_buffers_.end()) {
584 POST_ERROR(PLATFORM_FAILURE, 593 POST_ERROR(PLATFORM_FAILURE,
585 "Can't find PictureBuffer id: " << picture_buffer_id); 594 "Can't find PictureBuffer id: " << picture_buffer_id);
586 return; 595 return;
587 } 596 }
588 597
589 // Connect the PictureBuffer to the decoded frame, via whatever 598 // Connect the PictureBuffer to the decoded frame, via whatever
590 // mechanism the strategy likes. 599 // mechanism the strategy likes.
591 strategy_->UseCodecBufferForPictureBuffer(codec_buffer_index, i->second); 600 strategy_->UseCodecBufferForPictureBuffer(codec_buffer_index, i->second);
592 601
602 const bool allow_overlay = strategy_->ArePicturesOverlayable();
593 base::MessageLoop::current()->PostTask( 603 base::MessageLoop::current()->PostTask(
594 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyPictureReady, 604 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyPictureReady,
595 weak_this_factory_.GetWeakPtr(), 605 weak_this_factory_.GetWeakPtr(),
596 media::Picture(picture_buffer_id, bitstream_id, 606 media::Picture(picture_buffer_id, bitstream_id,
597 gfx::Rect(size_), false))); 607 gfx::Rect(size_), allow_overlay)));
598 } 608 }
599 609
600 void AndroidVideoDecodeAccelerator::Decode( 610 void AndroidVideoDecodeAccelerator::Decode(
601 const media::BitstreamBuffer& bitstream_buffer) { 611 const media::BitstreamBuffer& bitstream_buffer) {
602 DCHECK(thread_checker_.CalledOnValidThread()); 612 DCHECK(thread_checker_.CalledOnValidThread());
603 if (bitstream_buffer.id() != -1 && bitstream_buffer.size() == 0) { 613 if (bitstream_buffer.id() != -1 && bitstream_buffer.size() == 0) {
604 base::MessageLoop::current()->PostTask( 614 base::MessageLoop::current()->PostTask(
605 FROM_HERE, 615 FROM_HERE,
606 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, 616 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer,
607 weak_this_factory_.GetWeakPtr(), bitstream_buffer.id())); 617 weak_this_factory_.GetWeakPtr(), bitstream_buffer.id()));
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 } 693 }
684 694
685 void AndroidVideoDecodeAccelerator::Flush() { 695 void AndroidVideoDecodeAccelerator::Flush() {
686 DCHECK(thread_checker_.CalledOnValidThread()); 696 DCHECK(thread_checker_.CalledOnValidThread());
687 697
688 Decode(media::BitstreamBuffer(-1, base::SharedMemoryHandle(), 0)); 698 Decode(media::BitstreamBuffer(-1, base::SharedMemoryHandle(), 0));
689 } 699 }
690 700
691 bool AndroidVideoDecodeAccelerator::ConfigureMediaCodec() { 701 bool AndroidVideoDecodeAccelerator::ConfigureMediaCodec() {
692 DCHECK(thread_checker_.CalledOnValidThread()); 702 DCHECK(thread_checker_.CalledOnValidThread());
693 DCHECK(surface_texture_.get());
694 TRACE_EVENT0("media", "AVDA::ConfigureMediaCodec"); 703 TRACE_EVENT0("media", "AVDA::ConfigureMediaCodec");
695 704
696 gfx::ScopedJavaSurface surface(surface_texture_.get());
697
698 jobject media_crypto = media_crypto_ ? media_crypto_->obj() : nullptr; 705 jobject media_crypto = media_crypto_ ? media_crypto_->obj() : nullptr;
699 706
700 // |needs_protected_surface_| implies encrypted stream. 707 // |needs_protected_surface_| implies encrypted stream.
701 DCHECK(!needs_protected_surface_ || media_crypto); 708 DCHECK(!needs_protected_surface_ || media_crypto);
702 709
703 // Pass a dummy 320x240 canvas size and let the codec signal the real size 710 // Pass a dummy 320x240 canvas size and let the codec signal the real size
704 // when it's known from the bitstream. 711 // when it's known from the bitstream.
705 media_codec_.reset(media::VideoCodecBridge::CreateDecoder( 712 media_codec_.reset(media::VideoCodecBridge::CreateDecoder(
706 codec_, needs_protected_surface_, gfx::Size(320, 240), 713 codec_, needs_protected_surface_, gfx::Size(320, 240),
707 surface.j_surface().obj(), media_crypto)); 714 surface_.j_surface().obj(), media_crypto));
715
708 strategy_->CodecChanged(media_codec_.get(), output_picture_buffers_); 716 strategy_->CodecChanged(media_codec_.get(), output_picture_buffers_);
709 if (!media_codec_) { 717 if (!media_codec_) {
710 LOG(ERROR) << "Failed to create MediaCodec instance."; 718 LOG(ERROR) << "Failed to create MediaCodec instance.";
711 return false; 719 return false;
712 } 720 }
713 721
714 ManageTimer(true); 722 ManageTimer(true);
715 return true; 723 return true;
716 } 724 }
717 725
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
995 1003
996 if (UseDeferredRenderingStrategy()) { 1004 if (UseDeferredRenderingStrategy()) {
997 capabilities.flags = media::VideoDecodeAccelerator::Capabilities:: 1005 capabilities.flags = media::VideoDecodeAccelerator::Capabilities::
998 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE; 1006 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE;
999 } 1007 }
1000 1008
1001 return capabilities; 1009 return capabilities;
1002 } 1010 }
1003 1011
1004 } // namespace content 1012 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698