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

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

Powered by Google App Engine
This is Rietveld 408576698