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

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

Issue 2296513003: Delete AVDACopyingBackingStrategy and rename AVDADeferredRenderingBackingStrategy (Closed)
Patch Set: Undelete & fix unittest Created 4 years, 3 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 "media/gpu/android_video_decode_accelerator.h" 5 #include "media/gpu/android_video_decode_accelerator.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <memory> 9 #include <memory>
10 10
(...skipping 15 matching lines...) Expand all
26 #include "gpu/command_buffer/service/mailbox_manager.h" 26 #include "gpu/command_buffer/service/mailbox_manager.h"
27 #include "gpu/ipc/service/gpu_channel.h" 27 #include "gpu/ipc/service/gpu_channel.h"
28 #include "media/base/android/media_codec_bridge.h" 28 #include "media/base/android/media_codec_bridge.h"
29 #include "media/base/android/media_codec_util.h" 29 #include "media/base/android/media_codec_util.h"
30 #include "media/base/bind_to_current_loop.h" 30 #include "media/base/bind_to_current_loop.h"
31 #include "media/base/bitstream_buffer.h" 31 #include "media/base/bitstream_buffer.h"
32 #include "media/base/limits.h" 32 #include "media/base/limits.h"
33 #include "media/base/media.h" 33 #include "media/base/media.h"
34 #include "media/base/timestamp_constants.h" 34 #include "media/base/timestamp_constants.h"
35 #include "media/base/video_decoder_config.h" 35 #include "media/base/video_decoder_config.h"
36 #include "media/gpu/android_copying_backing_strategy.h" 36 #include "media/gpu/avda_picture_buffer_manager.h"
37 #include "media/gpu/android_deferred_rendering_backing_strategy.h"
38 #include "media/gpu/avda_return_on_failure.h"
39 #include "media/gpu/shared_memory_region.h" 37 #include "media/gpu/shared_memory_region.h"
40 #include "media/video/picture.h" 38 #include "media/video/picture.h"
41 #include "ui/gl/android/scoped_java_surface.h" 39 #include "ui/gl/android/scoped_java_surface.h"
42 #include "ui/gl/android/surface_texture.h" 40 #include "ui/gl/android/surface_texture.h"
43 #include "ui/gl/gl_bindings.h" 41 #include "ui/gl/gl_bindings.h"
44 42
45 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) 43 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
46 #include "media/mojo/services/mojo_cdm_service.h" 44 #include "media/mojo/services/mojo_cdm_service.h"
47 #endif 45 #endif
48 46
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 CodecInitialized = false, 117 CodecInitialized = false,
120 MissingFormatChanged = true 118 MissingFormatChanged = true
121 }; 119 };
122 120
123 inline void RecordFormatChangedMetric(FormatChangedValue value) { 121 inline void RecordFormatChangedMetric(FormatChangedValue value) {
124 UMA_HISTOGRAM_BOOLEAN("Media.AVDA.MissingFormatChanged", !!value); 122 UMA_HISTOGRAM_BOOLEAN("Media.AVDA.MissingFormatChanged", !!value);
125 } 123 }
126 124
127 } // namespace 125 } // namespace
128 126
129 // Handle OnFrameAvailable callbacks safely. Since they occur asynchronously,
130 // we take care that the AVDA that wants them still exists. A WeakPtr to
131 // the AVDA would be preferable, except that OnFrameAvailable callbacks can
132 // occur off the gpu main thread. We also can't guarantee when the
133 // SurfaceTexture will quit sending callbacks to coordinate with the
134 // destruction of the AVDA, so we have a separate object that the cb can own.
135 class AndroidVideoDecodeAccelerator::OnFrameAvailableHandler
136 : public base::RefCountedThreadSafe<OnFrameAvailableHandler> {
137 public:
138 // We do not retain ownership of |owner|. It must remain valid until
139 // after ClearOwner() is called. This will register with
140 // |surface_texture| to receive OnFrameAvailable callbacks.
141 OnFrameAvailableHandler(
142 AndroidVideoDecodeAccelerator* owner,
143 const scoped_refptr<gl::SurfaceTexture>& surface_texture)
144 : owner_(owner) {
145 // Note that the callback owns a strong ref to us.
146 surface_texture->SetFrameAvailableCallbackOnAnyThread(
147 base::Bind(&OnFrameAvailableHandler::OnFrameAvailable,
148 scoped_refptr<OnFrameAvailableHandler>(this)));
149 }
150
151 // Forget about our owner, which is required before one deletes it.
152 // No further callbacks will happen once this completes.
153 void ClearOwner() {
154 base::AutoLock lock(lock_);
155 // No callback can happen until we release the lock.
156 owner_ = nullptr;
157 }
158
159 // Call back into our owner if it hasn't been deleted.
160 void OnFrameAvailable() {
161 base::AutoLock auto_lock(lock_);
162 // |owner_| can't be deleted while we have the lock.
163 if (owner_)
164 owner_->OnFrameAvailable();
165 }
166
167 private:
168 friend class base::RefCountedThreadSafe<OnFrameAvailableHandler>;
169 virtual ~OnFrameAvailableHandler() {}
170
171 // Protects changes to owner_.
172 base::Lock lock_;
173
174 // AVDA that wants the OnFrameAvailable callback.
175 AndroidVideoDecodeAccelerator* owner_;
176
177 DISALLOW_COPY_AND_ASSIGN(OnFrameAvailableHandler);
178 };
179
180 // AVDAManager manages shared resources for a number of AVDA instances. 127 // AVDAManager manages shared resources for a number of AVDA instances.
181 // Its responsibilities include: 128 // Its responsibilities include:
182 // - Starting and stopping a shared "construction" thread for instantiating and 129 // - Starting and stopping a shared "construction" thread for instantiating and
183 // releasing MediaCodecs. 130 // releasing MediaCodecs.
184 // - Detecting when a task has hung on the construction thread so AVDAs can 131 // - Detecting when a task has hung on the construction thread so AVDAs can
185 // stop using it. 132 // stop using it.
186 // - Running a RepeatingTimer so that AVDAs can get a regular callback to 133 // - Running a RepeatingTimer so that AVDAs can get a regular callback to
187 // DoIOTask(). 134 // DoIOTask().
188 // - Tracking the allocation of surfaces to AVDAs and delivering callbacks when 135 // - Tracking the allocation of surfaces to AVDAs and delivering callbacks when
189 // surfaces are released. 136 // surfaces are released.
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
539 // or if the stream is encrypted. 486 // or if the stream is encrypted.
540 if (IsMediaCodecSoftwareDecodingForbidden() && 487 if (IsMediaCodecSoftwareDecodingForbidden() &&
541 VideoCodecBridge::IsKnownUnaccelerated(codec_config_->codec_, 488 VideoCodecBridge::IsKnownUnaccelerated(codec_config_->codec_,
542 MEDIA_CODEC_DECODER)) { 489 MEDIA_CODEC_DECODER)) {
543 DVLOG(1) << "Initialization failed: " 490 DVLOG(1) << "Initialization failed: "
544 << (codec_config_->codec_ == kCodecVP8 ? "vp8" : "vp9") 491 << (codec_config_->codec_ == kCodecVP8 ? "vp8" : "vp9")
545 << " is not hardware accelerated"; 492 << " is not hardware accelerated";
546 return false; 493 return false;
547 } 494 }
548 495
549 auto gles_decoder = get_gles2_decoder_cb_.Run(); 496 auto gles_decoder = get_gles2_decoder_cb_.Run();
Pawel Osciak 2016/09/01 01:04:29 I think gles_decoder is not needed anymore? Could
watk 2016/09/01 17:03:33 I would love to, but we still use it. We pass it t
Pawel Osciak 2016/09/02 06:03:03 I see, thanks!
550 if (!gles_decoder) { 497 if (!gles_decoder) {
551 LOG(ERROR) << "Failed to get gles2 decoder instance."; 498 LOG(ERROR) << "Failed to get gles2 decoder instance.";
552 return false; 499 return false;
553 } 500 }
554 501
555 const gpu::GpuPreferences& gpu_preferences =
556 gles_decoder->GetContextGroup()->gpu_preferences();
557
558 if (UseDeferredRenderingStrategy(gpu_preferences)) {
559 DVLOG(1) << __FUNCTION__ << ", using deferred rendering strategy.";
560 strategy_.reset(new AndroidDeferredRenderingBackingStrategy(this));
561 } else {
562 DVLOG(1) << __FUNCTION__ << ", using copy back strategy.";
563 strategy_.reset(new AndroidCopyingBackingStrategy(this));
564 }
565
566 if (!make_context_current_cb_.Run()) { 502 if (!make_context_current_cb_.Run()) {
567 LOG(ERROR) << "Failed to make this decoder's GL context current."; 503 LOG(ERROR) << "Failed to make this decoder's GL context current.";
568 return false; 504 return false;
569 } 505 }
570 506
571 if (g_avda_manager.Get().AllocateSurface(config_.surface_id, this)) { 507 if (g_avda_manager.Get().AllocateSurface(config_.surface_id, this)) {
572 // We have succesfully owned the surface, so finish initialization now. 508 // We have succesfully owned the surface, so finish initialization now.
573 return InitializeStrategy(); 509 return InitializePictureBufferManager();
574 } 510 }
575 511
576 // We have to wait for some other AVDA instance to free up the surface. 512 // We have to wait for some other AVDA instance to free up the surface.
577 // OnSurfaceAvailable will be called when it's available. 513 // OnSurfaceAvailable will be called when it's available.
578 return true; 514 return true;
579 } 515 }
580 516
581 void AndroidVideoDecodeAccelerator::OnSurfaceAvailable(bool success) { 517 void AndroidVideoDecodeAccelerator::OnSurfaceAvailable(bool success) {
582 DCHECK(deferred_initialization_pending_); 518 DCHECK(deferred_initialization_pending_);
583 519
584 if (!success || !InitializeStrategy()) { 520 if (!success || !InitializePictureBufferManager()) {
585 NotifyInitializationComplete(false); 521 NotifyInitializationComplete(false);
586 deferred_initialization_pending_ = false; 522 deferred_initialization_pending_ = false;
587 } 523 }
588 } 524 }
589 525
590 bool AndroidVideoDecodeAccelerator::InitializeStrategy() { 526 bool AndroidVideoDecodeAccelerator::InitializePictureBufferManager() {
591 codec_config_->surface_ = strategy_->Initialize(config_.surface_id); 527 codec_config_->surface_ =
592 if (codec_config_->surface_.IsEmpty()) { 528 picture_buffer_manager_.Initialize(this, config_.surface_id);
593 LOG(ERROR) << "Failed to initialize the backing strategy. The returned " 529 if (codec_config_->surface_.IsEmpty())
594 "Java surface is empty.";
595 return false; 530 return false;
596 }
597 531
598 on_destroying_surface_cb_ = 532 on_destroying_surface_cb_ =
599 base::Bind(&AndroidVideoDecodeAccelerator::OnDestroyingSurface, 533 base::Bind(&AndroidVideoDecodeAccelerator::OnDestroyingSurface,
600 weak_this_factory_.GetWeakPtr()); 534 weak_this_factory_.GetWeakPtr());
601 AVDASurfaceTracker::GetInstance()->RegisterOnDestroyingSurfaceCallback( 535 AVDASurfaceTracker::GetInstance()->RegisterOnDestroyingSurfaceCallback(
602 on_destroying_surface_cb_); 536 on_destroying_surface_cb_);
603 537
604 // TODO(watk,liberato): move this into the strategy.
605 scoped_refptr<gl::SurfaceTexture> surface_texture =
606 strategy_->GetSurfaceTexture();
607 if (surface_texture) {
608 on_frame_available_handler_ =
609 new OnFrameAvailableHandler(this, surface_texture);
610 }
611
612 if (!g_avda_manager.Get().StartThread(this)) 538 if (!g_avda_manager.Get().StartThread(this))
613 return false; 539 return false;
614 540
615 // If we are encrypted, then we aren't able to create the codec yet. 541 // If we are encrypted, then we aren't able to create the codec yet.
616 if (config_.is_encrypted) { 542 if (config_.is_encrypted) {
617 InitializeCdm(); 543 InitializeCdm();
618 return true; 544 return true;
619 } 545 }
620 546
621 if (deferred_initialization_pending_) { 547 if (deferred_initialization_pending_) {
(...skipping 11 matching lines...) Expand all
633 } 559 }
634 560
635 void AndroidVideoDecodeAccelerator::DoIOTask(bool start_timer) { 561 void AndroidVideoDecodeAccelerator::DoIOTask(bool start_timer) {
636 DCHECK(thread_checker_.CalledOnValidThread()); 562 DCHECK(thread_checker_.CalledOnValidThread());
637 TRACE_EVENT0("media", "AVDA::DoIOTask"); 563 TRACE_EVENT0("media", "AVDA::DoIOTask");
638 if (state_ == ERROR || state_ == WAITING_FOR_CODEC || 564 if (state_ == ERROR || state_ == WAITING_FOR_CODEC ||
639 state_ == SURFACE_DESTROYED) { 565 state_ == SURFACE_DESTROYED) {
640 return; 566 return;
641 } 567 }
642 568
643 strategy_->MaybeRenderEarly(); 569 picture_buffer_manager_.MaybeRenderEarly();
644 bool did_work = false, did_input = false, did_output = false; 570 bool did_work = false, did_input = false, did_output = false;
645 do { 571 do {
646 did_input = QueueInput(); 572 did_input = QueueInput();
647 did_output = DequeueOutput(); 573 did_output = DequeueOutput();
648 if (did_input || did_output) 574 if (did_input || did_output)
649 did_work = true; 575 did_work = true;
650 } while (did_input || did_output); 576 } while (did_input || did_output);
651 577
652 ManageTimer(did_work || start_timer); 578 ManageTimer(did_work || start_timer);
653 } 579 }
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
946 872
947 if (!make_context_current_cb_.Run()) { 873 if (!make_context_current_cb_.Run()) {
948 POST_ERROR(PLATFORM_FAILURE, "Failed to make the GL context current."); 874 POST_ERROR(PLATFORM_FAILURE, "Failed to make the GL context current.");
949 return; 875 return;
950 } 876 }
951 877
952 int32_t picture_buffer_id = free_picture_ids_.front(); 878 int32_t picture_buffer_id = free_picture_ids_.front();
953 free_picture_ids_.pop(); 879 free_picture_ids_.pop();
954 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); 880 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size());
955 881
956 const auto& i = output_picture_buffers_.find(picture_buffer_id); 882 const auto it = output_picture_buffers_.find(picture_buffer_id);
957 if (i == output_picture_buffers_.end()) { 883 if (it == output_picture_buffers_.end()) {
958 POST_ERROR(PLATFORM_FAILURE, 884 POST_ERROR(PLATFORM_FAILURE,
959 "Can't find PictureBuffer id: " << picture_buffer_id); 885 "Can't find PictureBuffer id: " << picture_buffer_id);
960 return; 886 return;
961 } 887 }
962 888
963 bool size_changed = false; 889 PictureBuffer& picture_buffer = it->second;
964 if (i->second.size() != size_) { 890 const bool size_changed = picture_buffer.size() != size_;
965 // Size may have changed due to resolution change since the last time this 891 if (size_changed)
966 // PictureBuffer was used. 892 picture_buffer.set_size(size_);
967 strategy_->UpdatePictureBufferSize(&i->second, size_);
968 size_changed = true;
969 }
970 893
971 const bool allow_overlay = strategy_->ArePicturesOverlayable(); 894 const bool allow_overlay = picture_buffer_manager_.ArePicturesOverlayable();
972 UMA_HISTOGRAM_BOOLEAN("Media.AVDA.FrameSentAsOverlay", allow_overlay); 895 UMA_HISTOGRAM_BOOLEAN("Media.AVDA.FrameSentAsOverlay", allow_overlay);
973 Picture picture(picture_buffer_id, bitstream_id, gfx::Rect(size_), 896 Picture picture(picture_buffer_id, bitstream_id, gfx::Rect(size_),
974 allow_overlay); 897 allow_overlay);
975 picture.set_size_changed(size_changed); 898 picture.set_size_changed(size_changed);
976 899
977 // Notify picture ready before calling UseCodecBufferForPictureBuffer() since 900 // Notify picture ready before calling UseCodecBufferForPictureBuffer() since
978 // that process may be slow and shouldn't delay delivery of the frame to the 901 // that process may be slow and shouldn't delay delivery of the frame to the
979 // renderer. The picture is only used on the same thread as this method is 902 // renderer. The picture is only used on the same thread as this method is
980 // called, so it is safe to do this. 903 // called, so it is safe to do this.
981 NotifyPictureReady(picture); 904 NotifyPictureReady(picture);
982 905
983 // Connect the PictureBuffer to the decoded frame, via whatever mechanism the 906 // Connect the PictureBuffer to the decoded frame.
984 // strategy likes. 907 picture_buffer_manager_.UseCodecBufferForPictureBuffer(codec_buffer_index,
985 strategy_->UseCodecBufferForPictureBuffer(codec_buffer_index, i->second); 908 picture_buffer);
986 } 909 }
987 910
988 void AndroidVideoDecodeAccelerator::Decode( 911 void AndroidVideoDecodeAccelerator::Decode(
989 const BitstreamBuffer& bitstream_buffer) { 912 const BitstreamBuffer& bitstream_buffer) {
990 DCHECK(thread_checker_.CalledOnValidThread()); 913 DCHECK(thread_checker_.CalledOnValidThread());
991 914
992 // If we previously deferred a codec restart, take care of it now. This can 915 // If we previously deferred a codec restart, take care of it now. This can
993 // happen on older devices where configuration changes require a codec reset. 916 // happen on older devices where configuration changes require a codec reset.
994 if (codec_needs_reset_) { 917 if (codec_needs_reset_) {
995 DCHECK_EQ(drain_type_, DRAIN_TYPE_NONE); 918 DCHECK_EQ(drain_type_, DRAIN_TYPE_NONE);
(...skipping 23 matching lines...) Expand all
1019 const BitstreamBuffer& bitstream_buffer) { 942 const BitstreamBuffer& bitstream_buffer) {
1020 pending_bitstream_records_.push(BitstreamRecord(bitstream_buffer)); 943 pending_bitstream_records_.push(BitstreamRecord(bitstream_buffer));
1021 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 944 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount",
1022 pending_bitstream_records_.size()); 945 pending_bitstream_records_.size());
1023 946
1024 DoIOTask(true); 947 DoIOTask(true);
1025 } 948 }
1026 949
1027 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() { 950 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() {
1028 if (client_) { 951 if (client_) {
1029 client_->ProvidePictureBuffers(kNumPictureBuffers, PIXEL_FORMAT_UNKNOWN, 1, 952 client_->ProvidePictureBuffers(
1030 strategy_->GetPictureBufferSize(), 953 kNumPictureBuffers, PIXEL_FORMAT_UNKNOWN, 1,
1031 strategy_->GetTextureTarget()); 954 picture_buffer_manager_.GetPictureBufferSize(),
955 picture_buffer_manager_.GetTextureTarget());
1032 } 956 }
1033 } 957 }
1034 958
1035 void AndroidVideoDecodeAccelerator::AssignPictureBuffers( 959 void AndroidVideoDecodeAccelerator::AssignPictureBuffers(
1036 const std::vector<PictureBuffer>& buffers) { 960 const std::vector<PictureBuffer>& buffers) {
1037 DCHECK(thread_checker_.CalledOnValidThread()); 961 DCHECK(thread_checker_.CalledOnValidThread());
1038 DCHECK(output_picture_buffers_.empty()); 962 DCHECK(output_picture_buffers_.empty());
1039 DCHECK(free_picture_ids_.empty()); 963 DCHECK(free_picture_ids_.empty());
1040 964
1041 if (buffers.size() < kNumPictureBuffers) { 965 if (buffers.size() < kNumPictureBuffers) {
1042 POST_ERROR(INVALID_ARGUMENT, "Not enough picture buffers assigned."); 966 POST_ERROR(INVALID_ARGUMENT, "Not enough picture buffers assigned.");
1043 return; 967 return;
1044 } 968 }
1045 969
1046 const bool have_context = make_context_current_cb_.Run(); 970 const bool have_context = make_context_current_cb_.Run();
1047 LOG_IF(WARNING, !have_context) 971 LOG_IF(WARNING, !have_context)
1048 << "Failed to make GL context current for Assign, continuing."; 972 << "Failed to make GL context current for Assign, continuing.";
1049 973
1050 for (size_t i = 0; i < buffers.size(); ++i) { 974 for (size_t i = 0; i < buffers.size(); ++i) {
1051 if (buffers[i].size() != strategy_->GetPictureBufferSize()) { 975 if (buffers[i].size() != picture_buffer_manager_.GetPictureBufferSize()) {
1052 POST_ERROR(INVALID_ARGUMENT, 976 POST_ERROR(INVALID_ARGUMENT,
1053 "Invalid picture buffer size assigned. Wanted " 977 "Invalid picture buffer size assigned. Wanted "
1054 << size_.ToString() << ", but got " 978 << size_.ToString() << ", but got "
1055 << buffers[i].size().ToString()); 979 << buffers[i].size().ToString());
1056 return; 980 return;
1057 } 981 }
1058 int32_t id = buffers[i].id(); 982 int32_t id = buffers[i].id();
1059 output_picture_buffers_.insert(std::make_pair(id, buffers[i])); 983 output_picture_buffers_.insert(std::make_pair(id, buffers[i]));
1060 free_picture_ids_.push(id); 984 free_picture_ids_.push(id);
1061 985
1062 strategy_->AssignOnePictureBuffer(buffers[i], have_context); 986 picture_buffer_manager_.AssignOnePictureBuffer(buffers[i], have_context);
1063 } 987 }
1064 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); 988 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size());
1065 DoIOTask(true); 989 DoIOTask(true);
1066 } 990 }
1067 991
1068 void AndroidVideoDecodeAccelerator::ReusePictureBuffer( 992 void AndroidVideoDecodeAccelerator::ReusePictureBuffer(
1069 int32_t picture_buffer_id) { 993 int32_t picture_buffer_id) {
1070 DCHECK(thread_checker_.CalledOnValidThread()); 994 DCHECK(thread_checker_.CalledOnValidThread());
1071 995
1072 free_picture_ids_.push(picture_buffer_id); 996 free_picture_ids_.push(picture_buffer_id);
1073 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); 997 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size());
1074 998
1075 OutputBufferMap::const_iterator i = 999 auto it = output_picture_buffers_.find(picture_buffer_id);
1076 output_picture_buffers_.find(picture_buffer_id); 1000 if (it == output_picture_buffers_.end()) {
1077 if (i == output_picture_buffers_.end()) {
1078 POST_ERROR(PLATFORM_FAILURE, "Can't find PictureBuffer id " 1001 POST_ERROR(PLATFORM_FAILURE, "Can't find PictureBuffer id "
1079 << picture_buffer_id); 1002 << picture_buffer_id);
1080 return; 1003 return;
1081 } 1004 }
1082 1005
1083 strategy_->ReuseOnePictureBuffer(i->second); 1006 picture_buffer_manager_.ReuseOnePictureBuffer(it->second);
1084 DoIOTask(true); 1007 DoIOTask(true);
1085 } 1008 }
1086 1009
1087 void AndroidVideoDecodeAccelerator::Flush() { 1010 void AndroidVideoDecodeAccelerator::Flush() {
1088 DVLOG(1) << __FUNCTION__; 1011 DVLOG(1) << __FUNCTION__;
1089 DCHECK(thread_checker_.CalledOnValidThread()); 1012 DCHECK(thread_checker_.CalledOnValidThread());
1090 1013
1091 if (state_ == SURFACE_DESTROYED) 1014 if (state_ == SURFACE_DESTROYED)
1092 NotifyFlushDone(); 1015 NotifyFlushDone();
1093 else 1016 else
1094 StartCodecDrain(DRAIN_FOR_FLUSH); 1017 StartCodecDrain(DRAIN_FOR_FLUSH);
1095 } 1018 }
1096 1019
1097 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() { 1020 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() {
1098 DCHECK(thread_checker_.CalledOnValidThread()); 1021 DCHECK(thread_checker_.CalledOnValidThread());
1099 1022
1100 // It's probably okay just to return here, since the codec will be configured 1023 // It's probably okay just to return here, since the codec will be configured
1101 // asynchronously. It's unclear that any state for the new request could 1024 // asynchronously. It's unclear that any state for the new request could
1102 // be different, unless somebody modifies |codec_config_| while we're already 1025 // be different, unless somebody modifies |codec_config_| while we're already
1103 // waiting for a codec. One shouldn't do that for thread safety. 1026 // waiting for a codec. One shouldn't do that for thread safety.
1104 DCHECK_NE(state_, WAITING_FOR_CODEC); 1027 DCHECK_NE(state_, WAITING_FOR_CODEC);
1105 1028
1106 state_ = WAITING_FOR_CODEC; 1029 state_ = WAITING_FOR_CODEC;
1107 1030
1108 // Tell the strategy that we're changing codecs. The codec itself could be 1031 // Tell the picture buffer manager that we're changing codecs. The codec
1109 // used normally, since we don't replace it until we're back on the main 1032 // itself could be used normally, since we don't replace it until we're back
1110 // thread. However, if we're using an output surface, then the incoming codec 1033 // on the main thread. However, if we're using an output surface, then the
1111 // might access that surface while the main thread is drawing. Telling the 1034 // incoming codec might access that surface while the main thread is drawing.
1112 // strategy to forget the codec avoids this. 1035 // Telling the manager to forget the codec avoids this.
1113 if (media_codec_) { 1036 if (media_codec_) {
1114 ReleaseMediaCodec(); 1037 ReleaseMediaCodec();
1115 strategy_->CodecChanged(nullptr); 1038 picture_buffer_manager_.CodecChanged(nullptr);
1116 } 1039 }
1117 1040
1118 // Choose whether to autodetect the codec type. Note that we do this after 1041 // Choose whether to autodetect the codec type. Note that we do this after
1119 // releasing any outgoing codec, so that |codec_config_| still matches the 1042 // releasing any outgoing codec, so that |codec_config_| still matches the
1120 // outgoing codec for ReleaseMediaCodec(). 1043 // outgoing codec for ReleaseMediaCodec().
1121 codec_config_->allow_autodetection_ = 1044 codec_config_->allow_autodetection_ =
1122 !g_avda_manager.Get().IsConstructionThreadLikelyHung(); 1045 !g_avda_manager.Get().IsConstructionThreadLikelyHung();
1123 1046
1124 // If autodetection is disallowed, fall back to Chrome's software decoders 1047 // If autodetection is disallowed, fall back to Chrome's software decoders
1125 // instead of using the software decoders provided by MediaCodec. 1048 // instead of using the software decoders provided by MediaCodec.
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1198 deferred_initialization_pending_ = false; 1121 deferred_initialization_pending_ = false;
1199 } 1122 }
1200 1123
1201 // If |state_| changed to SURFACE_DESTROYED while we were configuring a codec, 1124 // If |state_| changed to SURFACE_DESTROYED while we were configuring a codec,
1202 // then the codec is already invalid so we return early and drop it. 1125 // then the codec is already invalid so we return early and drop it.
1203 if (state_ == SURFACE_DESTROYED) 1126 if (state_ == SURFACE_DESTROYED)
1204 return; 1127 return;
1205 1128
1206 DCHECK(!media_codec_); 1129 DCHECK(!media_codec_);
1207 media_codec_ = std::move(media_codec); 1130 media_codec_ = std::move(media_codec);
1208 strategy_->CodecChanged(media_codec_.get()); 1131 picture_buffer_manager_.CodecChanged(media_codec_.get());
1209 if (!media_codec_) { 1132 if (!media_codec_) {
1210 POST_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec."); 1133 POST_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec.");
1211 return; 1134 return;
1212 } 1135 }
1213 1136
1214 state_ = NO_ERROR; 1137 state_ = NO_ERROR;
1215 1138
1216 ManageTimer(true); 1139 ManageTimer(true);
1217 } 1140 }
1218 1141
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
1317 // conservative approach and let the errors post. 1240 // conservative approach and let the errors post.
1318 // TODO(liberato): revisit this once we sort out the error state a bit more. 1241 // TODO(liberato): revisit this once we sort out the error state a bit more.
1319 1242
1320 // Flush the codec if possible, or create a new one if not. 1243 // Flush the codec if possible, or create a new one if not.
1321 if (!did_codec_error_happen && 1244 if (!did_codec_error_happen &&
1322 !media::MediaCodecUtil::CodecNeedsFlushWorkaround(media_codec_.get())) { 1245 !media::MediaCodecUtil::CodecNeedsFlushWorkaround(media_codec_.get())) {
1323 DVLOG(3) << __FUNCTION__ << " Flushing MediaCodec."; 1246 DVLOG(3) << __FUNCTION__ << " Flushing MediaCodec.";
1324 media_codec_->Flush(); 1247 media_codec_->Flush();
1325 // Since we just flushed all the output buffers, make sure that nothing is 1248 // Since we just flushed all the output buffers, make sure that nothing is
1326 // using them. 1249 // using them.
1327 strategy_->CodecChanged(media_codec_.get()); 1250 picture_buffer_manager_.CodecChanged(media_codec_.get());
1328 } else { 1251 } else {
1329 DVLOG(3) << __FUNCTION__ 1252 DVLOG(3) << __FUNCTION__
1330 << " Deleting the MediaCodec and creating a new one."; 1253 << " Deleting the MediaCodec and creating a new one.";
1331 g_avda_manager.Get().StopTimer(this); 1254 g_avda_manager.Get().StopTimer(this);
1332 ConfigureMediaCodecAsynchronously(); 1255 ConfigureMediaCodecAsynchronously();
1333 } 1256 }
1334 } 1257 }
1335 1258
1336 void AndroidVideoDecodeAccelerator::Reset() { 1259 void AndroidVideoDecodeAccelerator::Reset() {
1337 DVLOG(1) << __FUNCTION__; 1260 DVLOG(1) << __FUNCTION__;
(...skipping 11 matching lines...) Expand all
1349 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, 1272 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer,
1350 weak_this_factory_.GetWeakPtr(), bitstream_buffer_id)); 1273 weak_this_factory_.GetWeakPtr(), bitstream_buffer_id));
1351 } 1274 }
1352 } 1275 }
1353 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 0); 1276 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 0);
1354 bitstreams_notified_in_advance_.clear(); 1277 bitstreams_notified_in_advance_.clear();
1355 1278
1356 // Any error that is waiting to post can be ignored. 1279 // Any error that is waiting to post can be ignored.
1357 error_sequence_token_++; 1280 error_sequence_token_++;
1358 1281
1359 DCHECK(strategy_); 1282 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_);
1360 strategy_->ReleaseCodecBuffers(output_picture_buffers_);
1361 1283
1362 // Some VP8 files require complete MediaCodec drain before we can call 1284 // Some VP8 files require complete MediaCodec drain before we can call
1363 // MediaCodec.flush() or MediaCodec.reset(). http://crbug.com/598963. 1285 // MediaCodec.flush() or MediaCodec.reset(). http://crbug.com/598963.
1364 if (media_codec_ && codec_config_->codec_ == kCodecVP8 && 1286 if (media_codec_ && codec_config_->codec_ == kCodecVP8 &&
1365 !bitstream_buffers_in_decoder_.empty()) { 1287 !bitstream_buffers_in_decoder_.empty()) {
1366 // Postpone ResetCodecState() after the drain. 1288 // Postpone ResetCodecState() after the drain.
1367 StartCodecDrain(DRAIN_FOR_RESET); 1289 StartCodecDrain(DRAIN_FOR_RESET);
1368 } else { 1290 } else {
1369 ResetCodecState(); 1291 ResetCodecState();
1370 base::ThreadTaskRunnerHandle::Get()->PostTask( 1292 base::ThreadTaskRunnerHandle::Get()->PostTask(
1371 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, 1293 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone,
1372 weak_this_factory_.GetWeakPtr())); 1294 weak_this_factory_.GetWeakPtr()));
1373 } 1295 }
1374 } 1296 }
1375 1297
1376 void AndroidVideoDecodeAccelerator::Destroy() { 1298 void AndroidVideoDecodeAccelerator::Destroy() {
1377 DVLOG(1) << __FUNCTION__; 1299 DVLOG(1) << __FUNCTION__;
1378 DCHECK(thread_checker_.CalledOnValidThread()); 1300 DCHECK(thread_checker_.CalledOnValidThread());
1379 1301
1380 bool have_context = make_context_current_cb_.Run(); 1302 picture_buffer_manager_.Destroy(output_picture_buffers_);
1381 if (!have_context)
1382 LOG(WARNING) << "Failed make GL context current for Destroy, continuing.";
1383
1384 if (strategy_)
1385 strategy_->BeginCleanup(have_context, output_picture_buffers_);
1386
1387 // If we have an OnFrameAvailable handler, tell it that we're going away.
1388 if (on_frame_available_handler_) {
1389 on_frame_available_handler_->ClearOwner();
1390 on_frame_available_handler_ = nullptr;
1391 }
1392 1303
1393 client_ = nullptr; 1304 client_ = nullptr;
1394 1305
1395 // Some VP8 files require complete MediaCodec drain before we can call 1306 // Some VP8 files require a complete MediaCodec drain before we can call
1396 // MediaCodec.flush() or MediaCodec.reset(). http://crbug.com/598963. 1307 // MediaCodec.flush() or MediaCodec.release(). http://crbug.com/598963. In
1308 // that case, postpone ActualDestroy() until after the drain.
1397 if (media_codec_ && codec_config_->codec_ == kCodecVP8) { 1309 if (media_codec_ && codec_config_->codec_ == kCodecVP8) {
1398 // Clear pending_bitstream_records_. 1310 // Clear |pending_bitstream_records_|.
1399 while (!pending_bitstream_records_.empty()) 1311 while (!pending_bitstream_records_.empty())
1400 pending_bitstream_records_.pop(); 1312 pending_bitstream_records_.pop();
1401 1313
1402 // Postpone ActualDestroy after the drain.
1403 StartCodecDrain(DRAIN_FOR_DESTROY); 1314 StartCodecDrain(DRAIN_FOR_DESTROY);
1404 } else { 1315 } else {
1405 ActualDestroy(); 1316 ActualDestroy();
1406 } 1317 }
1407 } 1318 }
1408 1319
1409 void AndroidVideoDecodeAccelerator::ActualDestroy() { 1320 void AndroidVideoDecodeAccelerator::ActualDestroy() {
1410 DVLOG(1) << __FUNCTION__; 1321 DVLOG(1) << __FUNCTION__;
1411 DCHECK(thread_checker_.CalledOnValidThread()); 1322 DCHECK(thread_checker_.CalledOnValidThread());
1412 1323
1413 if (!on_destroying_surface_cb_.is_null()) { 1324 if (!on_destroying_surface_cb_.is_null()) {
1414 AVDASurfaceTracker::GetInstance()->UnregisterOnDestroyingSurfaceCallback( 1325 AVDASurfaceTracker::GetInstance()->UnregisterOnDestroyingSurfaceCallback(
1415 on_destroying_surface_cb_); 1326 on_destroying_surface_cb_);
1416 } 1327 }
1417 1328
1418 if (strategy_)
1419 strategy_->EndCleanup();
1420
1421 // We no longer care about |surface_id|, in case we did before. It's okay 1329 // We no longer care about |surface_id|, in case we did before. It's okay
1422 // if we have no surface and/or weren't the owner or a waiter. 1330 // if we have no surface and/or weren't the owner or a waiter.
1423 g_avda_manager.Get().DeallocateSurface(config_.surface_id, this); 1331 g_avda_manager.Get().DeallocateSurface(config_.surface_id, this);
1424 1332
1425 // Note that async codec construction might still be in progress. In that 1333 // Note that async codec construction might still be in progress. In that
1426 // case, the codec will be deleted when it completes once we invalidate all 1334 // case, the codec will be deleted when it completes once we invalidate all
1427 // our weak refs. 1335 // our weak refs.
1428 weak_this_factory_.InvalidateWeakPtrs(); 1336 weak_this_factory_.InvalidateWeakPtrs();
1429 if (media_codec_) { 1337 if (media_codec_) {
1430 g_avda_manager.Get().StopTimer(this); 1338 g_avda_manager.Get().StopTimer(this);
1431 ReleaseMediaCodec(); 1339 ReleaseMediaCodec();
1432 } 1340 }
1341
1433 delete this; 1342 delete this;
1434 } 1343 }
1435 1344
1436 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( 1345 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread(
1437 const base::WeakPtr<Client>& decode_client, 1346 const base::WeakPtr<Client>& decode_client,
1438 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { 1347 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) {
1439 return false; 1348 return false;
1440 } 1349 }
1441 1350
1442 const gfx::Size& AndroidVideoDecodeAccelerator::GetSize() const { 1351 const gfx::Size& AndroidVideoDecodeAccelerator::GetSize() const {
1443 return size_; 1352 return size_;
1444 } 1353 }
1445 1354
1446 const base::ThreadChecker& AndroidVideoDecodeAccelerator::ThreadChecker()
1447 const {
1448 return thread_checker_;
1449 }
1450
1451 base::WeakPtr<gpu::gles2::GLES2Decoder> 1355 base::WeakPtr<gpu::gles2::GLES2Decoder>
1452 AndroidVideoDecodeAccelerator::GetGlDecoder() const { 1356 AndroidVideoDecodeAccelerator::GetGlDecoder() const {
1453 return get_gles2_decoder_cb_.Run(); 1357 return get_gles2_decoder_cb_.Run();
1454 } 1358 }
1455 1359
1456 gpu::gles2::TextureRef* AndroidVideoDecodeAccelerator::GetTextureForPicture(
1457 const PictureBuffer& picture_buffer) {
1458 auto gles_decoder = GetGlDecoder();
1459 RETURN_ON_FAILURE(this, gles_decoder, "Failed to get GL decoder",
1460 ILLEGAL_STATE, nullptr);
1461 RETURN_ON_FAILURE(this, gles_decoder->GetContextGroup(),
1462 "Null gles_decoder->GetContextGroup()", ILLEGAL_STATE,
1463 nullptr);
1464 gpu::gles2::TextureManager* texture_manager =
1465 gles_decoder->GetContextGroup()->texture_manager();
1466 RETURN_ON_FAILURE(this, texture_manager, "Null texture_manager",
1467 ILLEGAL_STATE, nullptr);
1468
1469 DCHECK_LE(1u, picture_buffer.internal_texture_ids().size());
1470 gpu::gles2::TextureRef* texture_ref =
1471 texture_manager->GetTexture(picture_buffer.internal_texture_ids()[0]);
1472 RETURN_ON_FAILURE(this, texture_manager, "Null texture_ref", ILLEGAL_STATE,
1473 nullptr);
1474
1475 return texture_ref;
1476 }
1477
1478 scoped_refptr<gl::SurfaceTexture>
1479 AndroidVideoDecodeAccelerator::CreateAttachedSurfaceTexture(
1480 GLuint* service_id) {
1481 GLuint texture_id;
1482 glGenTextures(1, &texture_id);
1483
1484 glActiveTexture(GL_TEXTURE0);
1485 glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_id);
1486 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1487 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1488 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1489 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1490
1491 auto gl_decoder = GetGlDecoder();
1492 gl_decoder->RestoreTextureUnitBindings(0);
1493 gl_decoder->RestoreActiveTexture();
1494 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
1495
1496 *service_id = texture_id;
1497 // Previously, to reduce context switching, we used to create an unattached
1498 // SurfaceTexture and attach it lazily in the compositor's context. But that
1499 // was flaky because SurfaceTexture#detachFromGLContext() is buggy on a lot of
1500 // devices. Now we attach it to the current context, which means we might have
1501 // to context switch later to call updateTexImage(). Fortunately, if virtual
1502 // contexts are in use, we won't have to context switch.
1503 return gl::SurfaceTexture::Create(texture_id);
1504 }
1505
1506 void AndroidVideoDecodeAccelerator::OnDestroyingSurface(int surface_id) { 1360 void AndroidVideoDecodeAccelerator::OnDestroyingSurface(int surface_id) {
1507 DCHECK(thread_checker_.CalledOnValidThread()); 1361 DCHECK(thread_checker_.CalledOnValidThread());
1508 TRACE_EVENT0("media", "AVDA::OnDestroyingSurface"); 1362 TRACE_EVENT0("media", "AVDA::OnDestroyingSurface");
1509 DVLOG(1) << __FUNCTION__ << " surface_id: " << surface_id; 1363 DVLOG(1) << __FUNCTION__ << " surface_id: " << surface_id;
1510 1364
1511 if (surface_id != config_.surface_id) 1365 if (surface_id != config_.surface_id)
1512 return; 1366 return;
1513 1367
1514 // If we're currently asynchronously configuring a codec, it will be destroyed 1368 // If we're currently asynchronously configuring a codec, it will be destroyed
1515 // when configuration completes and it notices that |state_| has changed to 1369 // when configuration completes and it notices that |state_| has changed to
1516 // SURFACE_DESTROYED. 1370 // SURFACE_DESTROYED.
1517 state_ = SURFACE_DESTROYED; 1371 state_ = SURFACE_DESTROYED;
1518 if (media_codec_) { 1372 if (media_codec_) {
1519 ReleaseMediaCodec(); 1373 ReleaseMediaCodec();
1520 strategy_->CodecChanged(media_codec_.get()); 1374 picture_buffer_manager_.CodecChanged(media_codec_.get());
1521 } 1375 }
1522 // If we're draining, signal completion now because the drain can no longer 1376 // If we're draining, signal completion now because the drain can no longer
1523 // proceed. 1377 // proceed.
1524 if (drain_type_ != DRAIN_TYPE_NONE) 1378 if (drain_type_ != DRAIN_TYPE_NONE)
1525 OnDrainCompleted(); 1379 OnDrainCompleted();
1526 } 1380 }
1527 1381
1528 void AndroidVideoDecodeAccelerator::OnFrameAvailable() {
1529 // Remember: this may be on any thread.
1530 DCHECK(strategy_);
1531 strategy_->OnFrameAvailable();
1532 }
1533
1534 void AndroidVideoDecodeAccelerator::PostError( 1382 void AndroidVideoDecodeAccelerator::PostError(
1535 const ::tracked_objects::Location& from_here, 1383 const ::tracked_objects::Location& from_here,
1536 VideoDecodeAccelerator::Error error) { 1384 VideoDecodeAccelerator::Error error) {
1537 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( 1385 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1538 from_here, 1386 from_here,
1539 base::Bind(&AndroidVideoDecodeAccelerator::NotifyError, 1387 base::Bind(&AndroidVideoDecodeAccelerator::NotifyError,
1540 weak_this_factory_.GetWeakPtr(), error, error_sequence_token_), 1388 weak_this_factory_.GetWeakPtr(), error, error_sequence_token_),
1541 (defer_errors_ ? ErrorPostingDelay : base::TimeDelta())); 1389 (defer_errors_ ? ErrorPostingDelay : base::TimeDelta()));
1542 state_ = ERROR; 1390 state_ = ERROR;
1543 } 1391 }
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
1686 // or not. 1534 // or not.
1687 if (!codec_config_->allow_autodetection_) { 1535 if (!codec_config_->allow_autodetection_) {
1688 media_codec_.reset(); 1536 media_codec_.reset();
1689 } else { 1537 } else {
1690 g_avda_manager.Get().ConstructionTaskRunner()->DeleteSoon( 1538 g_avda_manager.Get().ConstructionTaskRunner()->DeleteSoon(
1691 FROM_HERE, media_codec_.release()); 1539 FROM_HERE, media_codec_.release());
1692 } 1540 }
1693 } 1541 }
1694 1542
1695 // static 1543 // static
1696 bool AndroidVideoDecodeAccelerator::UseDeferredRenderingStrategy(
1697 const gpu::GpuPreferences& gpu_preferences) {
1698 return true;
1699 }
1700
1701 // static
1702 VideoDecodeAccelerator::Capabilities 1544 VideoDecodeAccelerator::Capabilities
1703 AndroidVideoDecodeAccelerator::GetCapabilities( 1545 AndroidVideoDecodeAccelerator::GetCapabilities(
1704 const gpu::GpuPreferences& gpu_preferences) { 1546 const gpu::GpuPreferences& gpu_preferences) {
1705 Capabilities capabilities; 1547 Capabilities capabilities;
1706 SupportedProfiles& profiles = capabilities.supported_profiles; 1548 SupportedProfiles& profiles = capabilities.supported_profiles;
1707 1549
1708 // Only support VP8 on Android versions where we don't have to synchronously 1550 // Only support VP8 on Android versions where we don't have to synchronously
1709 // tear down the MediaCodec on surface destruction because VP8 requires 1551 // tear down the MediaCodec on surface destruction because VP8 requires
1710 // us to completely drain the decoder before releasing it, which is difficult 1552 // us to completely drain the decoder before releasing it, which is difficult
1711 // and time consuming to do while the surface is being destroyed. 1553 // and time consuming to do while the surface is being destroyed.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1752 profile.min_resolution.SetSize(0, 0); 1594 profile.min_resolution.SetSize(0, 0);
1753 // Advertise support for 4k and let the MediaCodec fail when decoding if it 1595 // Advertise support for 4k and let the MediaCodec fail when decoding if it
1754 // doesn't support the resolution. It's assumed that consumers won't have 1596 // doesn't support the resolution. It's assumed that consumers won't have
1755 // software fallback for H264 on Android anyway. 1597 // software fallback for H264 on Android anyway.
1756 profile.max_resolution.SetSize(3840, 2160); 1598 profile.max_resolution.SetSize(3840, 2160);
1757 profiles.push_back(profile); 1599 profiles.push_back(profile);
1758 } 1600 }
1759 1601
1760 capabilities.flags = 1602 capabilities.flags =
1761 VideoDecodeAccelerator::Capabilities::SUPPORTS_DEFERRED_INITIALIZATION; 1603 VideoDecodeAccelerator::Capabilities::SUPPORTS_DEFERRED_INITIALIZATION;
1762 if (UseDeferredRenderingStrategy(gpu_preferences)) { 1604 capabilities.flags |=
1763 capabilities.flags |= VideoDecodeAccelerator::Capabilities:: 1605 VideoDecodeAccelerator::Capabilities::NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE;
1764 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE;
1765 1606
1766 // If we're using threaded texture mailboxes the COPY_REQUIRED flag must be 1607 // If we're using threaded texture mailboxes the COPY_REQUIRED flag must be
1767 // set on deferred strategy frames (http://crbug.com/582170), and 1608 // set on the video frames (http://crbug.com/582170), and SurfaceView output
1768 // SurfaceView output is disabled (http://crbug.com/582170). 1609 // is disabled (http://crbug.com/582170).
1769 if (gpu_preferences.enable_threaded_texture_mailboxes) { 1610 if (gpu_preferences.enable_threaded_texture_mailboxes) {
1770 capabilities.flags |= 1611 capabilities.flags |=
1771 media::VideoDecodeAccelerator::Capabilities::REQUIRES_TEXTURE_COPY; 1612 media::VideoDecodeAccelerator::Capabilities::REQUIRES_TEXTURE_COPY;
1772 } else if (media::MediaCodecUtil::IsSurfaceViewOutputSupported()) { 1613 } else if (media::MediaCodecUtil::IsSurfaceViewOutputSupported()) {
1773 capabilities.flags |= media::VideoDecodeAccelerator::Capabilities:: 1614 capabilities.flags |= media::VideoDecodeAccelerator::Capabilities::
1774 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; 1615 SUPPORTS_EXTERNAL_OUTPUT_SURFACE;
1775 }
1776 } 1616 }
1777 1617
1778 return capabilities; 1618 return capabilities;
1779 } 1619 }
1780 1620
1781 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden() 1621 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden()
1782 const { 1622 const {
1783 // Prevent MediaCodec from using its internal software decoders when we have 1623 // Prevent MediaCodec from using its internal software decoders when we have
1784 // more secure and up to date versions in the renderer process. 1624 // more secure and up to date versions in the renderer process.
1785 return !config_.is_encrypted && (codec_config_->codec_ == media::kCodecVP8 || 1625 return !config_.is_encrypted && (codec_config_->codec_ == media::kCodecVP8 ||
1786 codec_config_->codec_ == media::kCodecVP9); 1626 codec_config_->codec_ == media::kCodecVP9);
1787 } 1627 }
1788 1628
1789 } // namespace media 1629 } // namespace media
OLDNEW
« no previous file with comments | « media/gpu/android_video_decode_accelerator.h ('k') | media/gpu/android_video_decode_accelerator_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698