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

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

Issue 2508053002: media: Do a TimedWait() for video surface teardown in AVDA (Closed)
Patch Set: Created 4 years, 1 month 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
11 #include "base/android/build_info.h" 11 #include "base/android/build_info.h"
12 #include "base/auto_reset.h" 12 #include "base/auto_reset.h"
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/bind_helpers.h" 14 #include "base/bind_helpers.h"
15 #include "base/callback_helpers.h" 15 #include "base/callback_helpers.h"
16 #include "base/command_line.h" 16 #include "base/command_line.h"
17 #include "base/lazy_instance.h" 17 #include "base/lazy_instance.h"
18 #include "base/logging.h" 18 #include "base/logging.h"
19 #include "base/memory/ref_counted.h"
19 #include "base/message_loop/message_loop.h" 20 #include "base/message_loop/message_loop.h"
20 #include "base/metrics/histogram.h" 21 #include "base/metrics/histogram.h"
21 #include "base/sys_info.h" 22 #include "base/sys_info.h"
22 #include "base/task_runner_util.h" 23 #include "base/task_runner_util.h"
23 #include "base/threading/thread.h" 24 #include "base/threading/thread.h"
24 #include "base/threading/thread_checker.h" 25 #include "base/threading/thread_checker.h"
25 #include "base/threading/thread_task_runner_handle.h" 26 #include "base/threading/thread_task_runner_handle.h"
26 #include "base/trace_event/trace_event.h" 27 #include "base/trace_event/trace_event.h"
27 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" 28 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
28 #include "gpu/command_buffer/service/mailbox_manager.h" 29 #include "gpu/command_buffer/service/mailbox_manager.h"
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 // pictures have been fed to saturate any internal buffering). This is 100 // pictures have been fed to saturate any internal buffering). This is
100 // speculative and it's unclear that this would be a win (nor that there's a 101 // speculative and it's unclear that this would be a win (nor that there's a
101 // reasonably device-agnostic way to fill in the "believes" above). 102 // reasonably device-agnostic way to fill in the "believes" above).
102 constexpr base::TimeDelta DecodePollDelay = 103 constexpr base::TimeDelta DecodePollDelay =
103 base::TimeDelta::FromMilliseconds(10); 104 base::TimeDelta::FromMilliseconds(10);
104 105
105 constexpr base::TimeDelta NoWaitTimeOut = base::TimeDelta::FromMicroseconds(0); 106 constexpr base::TimeDelta NoWaitTimeOut = base::TimeDelta::FromMicroseconds(0);
106 107
107 constexpr base::TimeDelta IdleTimerTimeOut = base::TimeDelta::FromSeconds(1); 108 constexpr base::TimeDelta IdleTimerTimeOut = base::TimeDelta::FromSeconds(1);
108 109
110 // Time between when we notice an error, and when we actually notify somebody.
111 // This is to prevent codec errors caused by SurfaceView fullscreen transitions
112 // from breaking the pipeline, if we're about to be reset anyway.
113 constexpr base::TimeDelta ErrorPostingDelay = base::TimeDelta::FromSeconds(2);
114
115 // On low end devices (< KitKat is always low-end due to buggy MediaCodec),
116 // defer the surface creation until the codec is actually used if we know no
117 // software fallback exists.
118 bool ShouldDeferSurfaceCreation(int surface_id, VideoCodec codec) {
119 return surface_id == SurfaceManager::kNoSurfaceID && codec == kCodecH264 &&
120 AVDACodecAllocator::Get().IsAnyRegisteredAVDA() &&
121 (base::android::BuildInfo::GetInstance()->sdk_int() <= 18 ||
122 base::SysInfo::IsLowEndDevice());
123 }
124
109 } // namespace 125 } // namespace
110 126
111 static base::LazyInstance<AVDACodecAllocator>::Leaky g_avda_codec_allocator =
112 LAZY_INSTANCE_INITIALIZER;
113
114 // AVDAManager manages shared resources for a number of AVDA instances. 127 // AVDAManager manages shared resources for a number of AVDA instances.
115 // Its responsibilities include: 128 // Its responsibilities include:
116 // - Starting and stopping a shared "construction" thread for instantiating and 129 // - Starting and stopping a shared "construction" thread for instantiating and
117 // releasing MediaCodecs. 130 // releasing MediaCodecs.
118 // - 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
119 // stop using it. 132 // stop using it.
120 // - 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
121 // DoIOTask(). 134 // DoIOTask().
122 // - Tracking the allocation of surfaces to AVDAs and delivering callbacks when 135 // - Tracking the allocation of surfaces to AVDAs and delivering callbacks when
123 // surfaces are released. 136 // surfaces are released.
(...skipping 27 matching lines...) Expand all
151 if (timer_running_) { 164 if (timer_running_) {
152 pending_erase_.insert(avda); 165 pending_erase_.insert(avda);
153 return; 166 return;
154 } 167 }
155 168
156 timer_avda_instances_.erase(avda); 169 timer_avda_instances_.erase(avda);
157 if (timer_avda_instances_.empty()) 170 if (timer_avda_instances_.empty())
158 io_timer_.Stop(); 171 io_timer_.Stop();
159 } 172 }
160 173
161 // |avda| would like to use |surface_id|. If it is not busy, then mark it
162 // as busy and return true. If it is busy, then replace any existing waiter,
163 // make |avda| the current waiter, and return false. Any existing waiter
164 // is assumed to be on the way out, so we fail its allocation request.
165 bool AllocateSurface(int surface_id, AndroidVideoDecodeAccelerator* avda) {
166 // Nobody has to wait for no surface.
167 if (surface_id == SurfaceManager::kNoSurfaceID)
168 return true;
169
170 auto iter = surface_waiter_map_.find(surface_id);
171 if (iter == surface_waiter_map_.end()) {
172 // SurfaceView isn't allocated. Succeed.
173 surface_waiter_map_[surface_id].owner = avda;
174 return true;
175 }
176
177 // SurfaceView is already allocated.
178 if (iter->second.waiter) {
179 // Some other AVDA is waiting. |avda| will replace it, so notify it
180 // that it will fail.
181 iter->second.waiter->OnSurfaceAvailable(false);
182 iter->second.waiter = nullptr;
183 }
184
185 // |avda| is now waiting.
186 iter->second.waiter = avda;
187 return false;
188 }
189
190 // Clear any waiting request for |surface_id| by |avda|. It is okay if
191 // |waiter| is not waiting and/or isn't the owner of |surface_id|.
192 void DeallocateSurface(int surface_id, AndroidVideoDecodeAccelerator* avda) {
193 SurfaceWaiterMap::iterator iter = surface_waiter_map_.find(surface_id);
194 if (iter == surface_waiter_map_.end())
195 return;
196
197 // If |avda| was waiting, then remove it without OnSurfaceAvailable.
198 if (iter->second.waiter == avda)
199 iter->second.waiter = nullptr;
200
201 // If |avda| is the owner, then let the waiter have it.
202 if (iter->second.owner != avda)
203 return;
204
205 AndroidVideoDecodeAccelerator* waiter = iter->second.waiter;
206 if (!waiter) {
207 // No waiter -- remove the record and return explicitly since |iter| is
208 // no longer valid.
209 surface_waiter_map_.erase(iter);
210 return;
211 }
212
213 // Promote |waiter| to be the owner.
214 iter->second.owner = waiter;
215 iter->second.waiter = nullptr;
216 waiter->OnSurfaceAvailable(true);
217 }
218
219 // On low end devices (< KitKat is always low-end due to buggy MediaCodec),
220 // defer the surface creation until the codec is actually used if we know no
221 // software fallback exists.
222 bool ShouldDeferSurfaceCreation(int surface_id, VideoCodec codec) {
223 return surface_id == SurfaceManager::kNoSurfaceID && codec == kCodecH264 &&
224 g_avda_codec_allocator.Get().IsAnyRegisteredAVDA() &&
225 (base::android::BuildInfo::GetInstance()->sdk_int() <= 18 ||
226 base::SysInfo::IsLowEndDevice());
227 }
228
229 private: 174 private:
230 friend struct base::DefaultLazyInstanceTraits<AVDAManager>; 175 friend struct base::DefaultLazyInstanceTraits<AVDAManager>;
231 176
232 AVDAManager() {} 177 AVDAManager() {}
233 ~AVDAManager() { NOTREACHED(); } 178 ~AVDAManager() { NOTREACHED(); }
234 179
235 void RunTimer() { 180 void RunTimer() {
236 { 181 {
237 // Call out to all AVDA instances, some of which may attempt to remove 182 // Call out to all AVDA instances, some of which may attempt to remove
238 // themselves from the list during this operation; those removals will be 183 // themselves from the list during this operation; those removals will be
239 // deferred until after all iterations are complete. 184 // deferred until after all iterations are complete.
240 base::AutoReset<bool> scoper(&timer_running_, true); 185 base::AutoReset<bool> scoper(&timer_running_, true);
241 for (auto* avda : timer_avda_instances_) 186 for (auto* avda : timer_avda_instances_)
242 avda->DoIOTask(false); 187 avda->DoIOTask(false);
243 } 188 }
244 189
245 // Take care of any deferred erasures. 190 // Take care of any deferred erasures.
246 for (auto* avda : pending_erase_) 191 for (auto* avda : pending_erase_)
247 StopTimer(avda); 192 StopTimer(avda);
248 pending_erase_.clear(); 193 pending_erase_.clear();
249 194
250 // TODO(dalecurtis): We may want to consider chunking this if task execution 195 // TODO(dalecurtis): We may want to consider chunking this if task execution
251 // takes too long for the combined timer. 196 // takes too long for the combined timer.
252 } 197 }
253 198
254 // All AVDA instances that would like us to poll DoIOTask. 199 // All AVDA instances that would like us to poll DoIOTask.
255 std::set<AndroidVideoDecodeAccelerator*> timer_avda_instances_; 200 std::set<AndroidVideoDecodeAccelerator*> timer_avda_instances_;
256 201
257 struct OwnerRecord {
258 AndroidVideoDecodeAccelerator* owner = nullptr;
259 AndroidVideoDecodeAccelerator* waiter = nullptr;
260 };
261 // [surface id] = OwnerRecord for that surface.
262 using SurfaceWaiterMap = std::map<int, OwnerRecord>;
263 SurfaceWaiterMap surface_waiter_map_;
264
265 // Since we can't delete while iterating when using a set, defer erasure until 202 // Since we can't delete while iterating when using a set, defer erasure until
266 // after iteration complete. 203 // after iteration complete.
267 bool timer_running_ = false; 204 bool timer_running_ = false;
268 std::set<AndroidVideoDecodeAccelerator*> pending_erase_; 205 std::set<AndroidVideoDecodeAccelerator*> pending_erase_;
269 206
270 // Repeating timer responsible for draining pending IO to the codecs. 207 // Repeating timer responsible for draining pending IO to the codecs.
271 base::RepeatingTimer io_timer_; 208 base::RepeatingTimer io_timer_;
272 209
273 base::ThreadChecker thread_checker_; 210 base::ThreadChecker thread_checker_;
274 211
275 DISALLOW_COPY_AND_ASSIGN(AVDAManager); 212 DISALLOW_COPY_AND_ASSIGN(AVDAManager);
276 }; 213 };
277 214
278 static base::LazyInstance<AVDAManager>::Leaky g_avda_manager = 215 static base::LazyInstance<AVDAManager>::Leaky g_avda_manager =
279 LAZY_INSTANCE_INITIALIZER; 216 LAZY_INSTANCE_INITIALIZER;
280 217
281 AndroidVideoDecodeAccelerator::CodecConfig::CodecConfig() {}
282
283 AndroidVideoDecodeAccelerator::CodecConfig::~CodecConfig() {}
284
285 AndroidVideoDecodeAccelerator::BitstreamRecord::BitstreamRecord( 218 AndroidVideoDecodeAccelerator::BitstreamRecord::BitstreamRecord(
286 const BitstreamBuffer& bitstream_buffer) 219 const BitstreamBuffer& bitstream_buffer)
287 : buffer(bitstream_buffer) { 220 : buffer(bitstream_buffer) {
288 if (buffer.id() != -1) 221 if (buffer.id() != -1)
289 memory.reset(new SharedMemoryRegion(buffer, true)); 222 memory.reset(new SharedMemoryRegion(buffer, true));
290 } 223 }
291 224
292 AndroidVideoDecodeAccelerator::BitstreamRecord::BitstreamRecord( 225 AndroidVideoDecodeAccelerator::BitstreamRecord::BitstreamRecord(
293 BitstreamRecord&& other) 226 BitstreamRecord&& other)
294 : buffer(std::move(other.buffer)), memory(std::move(other.memory)) {} 227 : buffer(std::move(other.buffer)), memory(std::move(other.memory)) {}
(...skipping 14 matching lines...) Expand all
309 cdm_registration_id_(0), 242 cdm_registration_id_(0),
310 pending_input_buf_index_(-1), 243 pending_input_buf_index_(-1),
311 deferred_initialization_pending_(false), 244 deferred_initialization_pending_(false),
312 codec_needs_reset_(false), 245 codec_needs_reset_(false),
313 defer_surface_creation_(false), 246 defer_surface_creation_(false),
314 weak_this_factory_(this) {} 247 weak_this_factory_(this) {}
315 248
316 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { 249 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() {
317 DCHECK(thread_checker_.CalledOnValidThread()); 250 DCHECK(thread_checker_.CalledOnValidThread());
318 g_avda_manager.Get().StopTimer(this); 251 g_avda_manager.Get().StopTimer(this);
319 g_avda_codec_allocator.Get().StopThread(this); 252 AVDACodecAllocator::Get().StopThread(this);
320 253
321 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) 254 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
322 if (!media_drm_bridge_cdm_context_) 255 if (!media_drm_bridge_cdm_context_)
323 return; 256 return;
324 257
325 DCHECK(cdm_registration_id_); 258 DCHECK(cdm_registration_id_);
326 259
327 // Cancel previously registered callback (if any). 260 // Cancel previously registered callback (if any).
328 media_drm_bridge_cdm_context_->SetMediaCryptoReadyCB( 261 media_drm_bridge_cdm_context_->SetMediaCryptoReadyCB(
329 MediaDrmBridgeCdmContext::MediaCryptoReadyCB()); 262 MediaDrmBridgeCdmContext::MediaCryptoReadyCB());
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 DLOG(ERROR) << "Failed to get gles2 decoder instance."; 321 DLOG(ERROR) << "Failed to get gles2 decoder instance.";
389 return false; 322 return false;
390 } 323 }
391 324
392 // SetSurface() can't be called before Initialize(), so we pick up our first 325 // SetSurface() can't be called before Initialize(), so we pick up our first
393 // surface ID from the codec configuration. 326 // surface ID from the codec configuration.
394 DCHECK(!pending_surface_id_); 327 DCHECK(!pending_surface_id_);
395 328
396 // If we're low on resources, we may decide to defer creation of the surface 329 // If we're low on resources, we may decide to defer creation of the surface
397 // until the codec is actually used. 330 // until the codec is actually used.
398 if (g_avda_manager.Get().ShouldDeferSurfaceCreation(config_.surface_id, 331 if (ShouldDeferSurfaceCreation(config_.surface_id, codec_config_->codec_)) {
399 codec_config_->codec_)) {
400 DCHECK(!deferred_initialization_pending_); 332 DCHECK(!deferred_initialization_pending_);
401
402 // We should never be here if a SurfaceView is required. 333 // We should never be here if a SurfaceView is required.
403 DCHECK_EQ(config_.surface_id, SurfaceManager::kNoSurfaceID); 334 DCHECK_EQ(config_.surface_id, SurfaceManager::kNoSurfaceID);
404 DCHECK(g_avda_manager.Get().AllocateSurface(config_.surface_id, this));
liberato (no reviews please) 2016/11/17 07:28:19 where did this go?
watk 2016/11/17 20:37:05 Ah, I added a unit test that mostly obseletes this
405
406 defer_surface_creation_ = true; 335 defer_surface_creation_ = true;
407 NotifyInitializationComplete(true); 336 NotifyInitializationComplete(true);
408 return true; 337 return true;
409 } 338 }
410 339
411 // We signaled that we support deferred initialization, so see if the client 340 // We signaled that we support deferred initialization, so see if the client
412 // does also. 341 // does also.
413 deferred_initialization_pending_ = config.is_deferred_initialization_allowed; 342 deferred_initialization_pending_ = config.is_deferred_initialization_allowed;
414 if (config_.is_encrypted && !deferred_initialization_pending_) { 343 if (config_.is_encrypted && !deferred_initialization_pending_) {
415 DLOG(ERROR) << "Deferred initialization must be used for encrypted streams"; 344 DLOG(ERROR) << "Deferred initialization must be used for encrypted streams";
416 return false; 345 return false;
417 } 346 }
418 347
419 if (g_avda_manager.Get().AllocateSurface(config_.surface_id, this)) { 348 if (AVDACodecAllocator::Get().AllocateSurface(this, config_.surface_id)) {
420 // We have successfully owned the surface, so finish initialization now. 349 // We now own the surface, so finish initialization.
421 return InitializePictureBufferManager(); 350 return InitializePictureBufferManager();
422 } 351 }
423 352
424 // We have to wait for some other AVDA instance to free up the surface. 353 // We have to wait for some other AVDA instance to free up the surface.
425 // OnSurfaceAvailable will be called when it's available. 354 // OnSurfaceAvailable will be called when it's available.
426 return true; 355 return true;
427 } 356 }
428 357
429 void AndroidVideoDecodeAccelerator::OnSurfaceAvailable(bool success) { 358 void AndroidVideoDecodeAccelerator::OnSurfaceAvailable(bool success) {
430 DCHECK(deferred_initialization_pending_); 359 DCHECK(deferred_initialization_pending_);
431 DCHECK(!defer_surface_creation_); 360 DCHECK(!defer_surface_creation_);
432 361
433 if (!success || !InitializePictureBufferManager()) { 362 if (!success || !InitializePictureBufferManager()) {
434 NotifyInitializationComplete(false); 363 NotifyInitializationComplete(false);
435 deferred_initialization_pending_ = false; 364 deferred_initialization_pending_ = false;
436 } 365 }
437 } 366 }
438 367
439 bool AndroidVideoDecodeAccelerator::InitializePictureBufferManager() { 368 bool AndroidVideoDecodeAccelerator::InitializePictureBufferManager() {
440 if (!make_context_current_cb_.Run()) { 369 if (!make_context_current_cb_.Run()) {
441 LOG(ERROR) << "Failed to make this decoder's GL context current."; 370 LOG(ERROR) << "Failed to make this decoder's GL context current.";
442 return false; 371 return false;
443 } 372 }
444 373
445 codec_config_->surface_ = 374 codec_config_->surface_ =
446 picture_buffer_manager_.Initialize(config_.surface_id); 375 picture_buffer_manager_.Initialize(config_.surface_id);
447 if (codec_config_->surface_.IsEmpty()) 376 if (codec_config_->surface_.IsEmpty())
448 return false; 377 return false;
449 378
450 on_destroying_surface_cb_ = 379 if (!AVDACodecAllocator::Get().StartThread(this))
451 base::Bind(&AndroidVideoDecodeAccelerator::OnDestroyingSurface,
452 weak_this_factory_.GetWeakPtr());
453 AVDASurfaceTracker::GetInstance()->RegisterOnDestroyingSurfaceCallback(
454 on_destroying_surface_cb_);
455
456 if (!g_avda_codec_allocator.Get().StartThread(this))
457 return false; 380 return false;
458 381
459 // If we are encrypted, then we aren't able to create the codec yet. 382 // If we are encrypted, then we aren't able to create the codec yet.
460 if (config_.is_encrypted) { 383 if (config_.is_encrypted) {
461 InitializeCdm(); 384 InitializeCdm();
462 return true; 385 return true;
463 } 386 }
464 387
465 if (deferred_initialization_pending_ || defer_surface_creation_) { 388 if (deferred_initialization_pending_ || defer_surface_creation_) {
466 defer_surface_creation_ = false; 389 defer_surface_creation_ = false;
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after
950 873
951 if (state_ == SURFACE_DESTROYED || defer_surface_creation_) 874 if (state_ == SURFACE_DESTROYED || defer_surface_creation_)
952 NotifyFlushDone(); 875 NotifyFlushDone();
953 else 876 else
954 StartCodecDrain(DRAIN_FOR_FLUSH); 877 StartCodecDrain(DRAIN_FOR_FLUSH);
955 } 878 }
956 879
957 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() { 880 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() {
958 DCHECK(thread_checker_.CalledOnValidThread()); 881 DCHECK(thread_checker_.CalledOnValidThread());
959 882
960 // It's probably okay just to return here, since the codec will be configured
961 // asynchronously. It's unclear that any state for the new request could
962 // be different, unless somebody modifies |codec_config_| while we're already
963 // waiting for a codec. One shouldn't do that for thread safety.
964 DCHECK_NE(state_, WAITING_FOR_CODEC); 883 DCHECK_NE(state_, WAITING_FOR_CODEC);
965
966 state_ = WAITING_FOR_CODEC; 884 state_ = WAITING_FOR_CODEC;
967 885
968 // Tell the picture buffer manager that we're changing codecs. The codec
969 // itself could be used normally, since we don't replace it until we're back
970 // on the main thread. However, if we're using an output surface, then the
971 // incoming codec might access that surface while the main thread is drawing.
972 // Telling the manager to forget the codec avoids this.
973 if (media_codec_) { 886 if (media_codec_) {
974 ReleaseMediaCodec(); 887 AVDACodecAllocator::Get().ReleaseMediaCodec(
888 std::move(media_codec_), codec_config_->task_type_, config_.surface_id);
975 picture_buffer_manager_.CodecChanged(nullptr); 889 picture_buffer_manager_.CodecChanged(nullptr);
976 } 890 }
977 891
978 codec_config_->task_type_ = 892 codec_config_->task_type_ = AVDACodecAllocator::Get().TaskTypeForAllocation();
979 g_avda_codec_allocator.Get().TaskTypeForAllocation(); 893 if (codec_config_->task_type_ == TaskType::FAILED_CODEC) {
980 if (codec_config_->task_type_ == AVDACodecAllocator::TaskType::FAILED_CODEC) {
981 // If there is no free thread, then just fail. 894 // If there is no free thread, then just fail.
982 OnCodecConfigured(nullptr); 895 OnCodecConfigured(nullptr);
983 return; 896 return;
984 } 897 }
985 898
986 // If autodetection is disallowed, fall back to Chrome's software decoders 899 // If autodetection is disallowed, fall back to Chrome's software decoders
987 // instead of using the software decoders provided by MediaCodec. 900 // instead of using the software decoders provided by MediaCodec.
988 if (codec_config_->task_type_ == AVDACodecAllocator::TaskType::SW_CODEC && 901 if (codec_config_->task_type_ == TaskType::SW_CODEC &&
989 IsMediaCodecSoftwareDecodingForbidden()) { 902 IsMediaCodecSoftwareDecodingForbidden()) {
990 OnCodecConfigured(nullptr); 903 OnCodecConfigured(nullptr);
991 return; 904 return;
992 } 905 }
993 906
994 base::PostTaskAndReplyWithResult( 907 AVDACodecAllocator::Get().CreateMediaCodecAsync(
995 g_avda_codec_allocator.Get() 908 weak_this_factory_.GetWeakPtr(), codec_config_);
996 .TaskRunnerFor(codec_config_->task_type_)
997 .get(),
998 FROM_HERE,
999 base::Bind(&AndroidVideoDecodeAccelerator::ConfigureMediaCodecOnAnyThread,
1000 codec_config_),
1001 base::Bind(&AndroidVideoDecodeAccelerator::OnCodecConfigured,
1002 weak_this_factory_.GetWeakPtr()));
1003 } 909 }
1004 910
1005 bool AndroidVideoDecodeAccelerator::ConfigureMediaCodecSynchronously() { 911 bool AndroidVideoDecodeAccelerator::ConfigureMediaCodecSynchronously() {
1006 state_ = WAITING_FOR_CODEC; 912 state_ = WAITING_FOR_CODEC;
1007 913
1008 ReleaseMediaCodec(); 914 codec_config_->task_type_ = AVDACodecAllocator::Get().TaskTypeForAllocation();
1009 915 if (codec_config_->task_type_ == TaskType::FAILED_CODEC) {
1010 codec_config_->task_type_ =
1011 g_avda_codec_allocator.Get().TaskTypeForAllocation();
1012 if (codec_config_->task_type_ == AVDACodecAllocator::TaskType::FAILED_CODEC) {
1013 OnCodecConfigured(nullptr); 916 OnCodecConfigured(nullptr);
1014 return false; 917 return false;
1015 } 918 }
1016 919
1017 std::unique_ptr<VideoCodecBridge> media_codec = 920 std::unique_ptr<VideoCodecBridge> media_codec =
1018 ConfigureMediaCodecOnAnyThread(codec_config_); 921 AVDACodecAllocator::Get().CreateMediaCodecSync(codec_config_);
1019 OnCodecConfigured(std::move(media_codec)); 922 OnCodecConfigured(std::move(media_codec));
1020 return !!media_codec_; 923 return !!media_codec_;
1021 } 924 }
1022 925
1023 std::unique_ptr<VideoCodecBridge>
1024 AndroidVideoDecodeAccelerator::ConfigureMediaCodecOnAnyThread(
1025 scoped_refptr<CodecConfig> codec_config) {
1026 TRACE_EVENT0("media", "AVDA::ConfigureMediaCodec");
1027
1028 jobject media_crypto = codec_config->media_crypto_
1029 ? codec_config->media_crypto_->obj()
1030 : nullptr;
1031
1032 // |needs_protected_surface_| implies encrypted stream.
1033 DCHECK(!codec_config->needs_protected_surface_ || media_crypto);
1034
1035 const bool require_software_codec =
1036 codec_config->task_type_ == AVDACodecAllocator::TaskType::SW_CODEC;
1037
1038 std::unique_ptr<VideoCodecBridge> codec(VideoCodecBridge::CreateDecoder(
1039 codec_config->codec_, codec_config->needs_protected_surface_,
1040 codec_config->initial_expected_coded_size_,
1041 codec_config->surface_.j_surface().obj(), media_crypto,
1042 codec_config->csd0_, codec_config->csd1_, true, require_software_codec));
1043
1044 return codec;
1045 }
1046
1047 void AndroidVideoDecodeAccelerator::OnCodecConfigured( 926 void AndroidVideoDecodeAccelerator::OnCodecConfigured(
1048 std::unique_ptr<VideoCodecBridge> media_codec) { 927 std::unique_ptr<VideoCodecBridge> media_codec) {
1049 DCHECK(thread_checker_.CalledOnValidThread()); 928 DCHECK(thread_checker_.CalledOnValidThread());
1050 DCHECK(state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED); 929 DCHECK(state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED);
1051 930
1052 // If we are supposed to notify that initialization is complete, then do so 931 // If we are supposed to notify that initialization is complete, then do so
1053 // now. Otherwise, this is a reconfiguration. 932 // now. Otherwise, this is a reconfiguration.
1054 if (deferred_initialization_pending_) { 933 if (deferred_initialization_pending_) {
1055 // Losing the output surface is not considered an error state, so notify 934 // Losing the output surface is not considered an error state, so notify
1056 // success. The client will destroy this soon. 935 // success. The client will destroy this soon.
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
1226 StartCodecDrain(DRAIN_FOR_RESET); 1105 StartCodecDrain(DRAIN_FOR_RESET);
1227 } else { 1106 } else {
1228 ResetCodecState(); 1107 ResetCodecState();
1229 base::ThreadTaskRunnerHandle::Get()->PostTask( 1108 base::ThreadTaskRunnerHandle::Get()->PostTask(
1230 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, 1109 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone,
1231 weak_this_factory_.GetWeakPtr())); 1110 weak_this_factory_.GetWeakPtr()));
1232 } 1111 }
1233 } 1112 }
1234 1113
1235 void AndroidVideoDecodeAccelerator::SetSurface(int32_t surface_id) { 1114 void AndroidVideoDecodeAccelerator::SetSurface(int32_t surface_id) {
1115 DVLOG(1) << __func__;
1116 DCHECK(thread_checker_.CalledOnValidThread());
1117
1236 if (surface_id == config_.surface_id) { 1118 if (surface_id == config_.surface_id) {
1237 pending_surface_id_.reset(); 1119 pending_surface_id_.reset();
1238 return; 1120 return;
1239 } 1121 }
1240 1122
1241 // Surface changes never take effect immediately, they will be handled during 1123 // Surface changes never take effect immediately, they will be handled during
1242 // DequeOutput() once we get to a good switch point or immediately during an 1124 // DequeOutput() once we get to a good switch point or immediately during an
1243 // OnDestroyingSurface() call. 1125 // OnSurfaceDestroyed() call.
1244 pending_surface_id_ = surface_id; 1126 pending_surface_id_ = surface_id;
1245 } 1127 }
1246 1128
1247 void AndroidVideoDecodeAccelerator::Destroy() { 1129 void AndroidVideoDecodeAccelerator::Destroy() {
1248 DVLOG(1) << __FUNCTION__; 1130 DVLOG(1) << __FUNCTION__;
1249 DCHECK(thread_checker_.CalledOnValidThread()); 1131 DCHECK(thread_checker_.CalledOnValidThread());
1250 1132
1251 picture_buffer_manager_.Destroy(output_picture_buffers_); 1133 picture_buffer_manager_.Destroy(output_picture_buffers_);
1252 1134
1253 client_ = nullptr; 1135 client_ = nullptr;
1254 1136
1255 // Some VP8 files require a complete MediaCodec drain before we can call 1137 // Some VP8 files require a complete MediaCodec drain before we can call
1256 // MediaCodec.flush() or MediaCodec.release(). http://crbug.com/598963. In 1138 // MediaCodec.flush() or MediaCodec.release(). http://crbug.com/598963. In
1257 // that case, postpone ActualDestroy() until after the drain. 1139 // that case, postpone ActualDestroy() until after the drain.
1258 if (media_codec_ && codec_config_->codec_ == kCodecVP8) { 1140 if (media_codec_ && codec_config_->codec_ == kCodecVP8) {
1259 // Clear |pending_bitstream_records_|. 1141 // Clear |pending_bitstream_records_|.
1260 while (!pending_bitstream_records_.empty()) 1142 while (!pending_bitstream_records_.empty())
1261 pending_bitstream_records_.pop(); 1143 pending_bitstream_records_.pop();
1262 1144
1263 StartCodecDrain(DRAIN_FOR_DESTROY); 1145 StartCodecDrain(DRAIN_FOR_DESTROY);
1264 } else { 1146 } else {
1265 ActualDestroy(); 1147 ActualDestroy();
1266 } 1148 }
1267 } 1149 }
1268 1150
1269 void AndroidVideoDecodeAccelerator::ActualDestroy() { 1151 void AndroidVideoDecodeAccelerator::ActualDestroy() {
1270 DVLOG(1) << __FUNCTION__; 1152 DVLOG(1) << __FUNCTION__;
1271 DCHECK(thread_checker_.CalledOnValidThread()); 1153 DCHECK(thread_checker_.CalledOnValidThread());
1272 1154
1273 if (!on_destroying_surface_cb_.is_null()) {
1274 AVDASurfaceTracker::GetInstance()->UnregisterOnDestroyingSurfaceCallback(
1275 on_destroying_surface_cb_);
1276 }
1277
1278 // We no longer care about |surface_id|, in case we did before. It's okay 1155 // We no longer care about |surface_id|, in case we did before. It's okay
1279 // if we have no surface and/or weren't the owner or a waiter. 1156 // if we have no surface and/or weren't the owner or a waiter.
1280 g_avda_manager.Get().DeallocateSurface(config_.surface_id, this); 1157 AVDACodecAllocator::Get().DeallocateSurface(this, config_.surface_id);
1281 1158
1282 // Note that async codec construction might still be in progress. In that 1159 // Note that async codec construction might still be in progress. In that
1283 // case, the codec will be deleted when it completes once we invalidate all 1160 // case, the codec will be deleted when it completes once we invalidate all
1284 // our weak refs. 1161 // our weak refs.
1285 weak_this_factory_.InvalidateWeakPtrs(); 1162 weak_this_factory_.InvalidateWeakPtrs();
1163 g_avda_manager.Get().StopTimer(this);
liberato (no reviews please) 2016/11/17 07:28:19 hrm, that seems like an improvement.
1286 if (media_codec_) { 1164 if (media_codec_) {
1287 g_avda_manager.Get().StopTimer(this); 1165 AVDACodecAllocator::Get().ReleaseMediaCodec(
1288 ReleaseMediaCodec(); 1166 std::move(media_codec_), codec_config_->task_type_, config_.surface_id);
1289 } 1167 }
1290 1168
1291 delete this; 1169 delete this;
1292 } 1170 }
1293 1171
1294 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( 1172 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread(
1295 const base::WeakPtr<Client>& decode_client, 1173 const base::WeakPtr<Client>& decode_client,
1296 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { 1174 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) {
1297 return false; 1175 return false;
1298 } 1176 }
1299 1177
1300 const gfx::Size& AndroidVideoDecodeAccelerator::GetSize() const { 1178 const gfx::Size& AndroidVideoDecodeAccelerator::GetSize() const {
1301 return size_; 1179 return size_;
1302 } 1180 }
1303 1181
1304 base::WeakPtr<gpu::gles2::GLES2Decoder> 1182 base::WeakPtr<gpu::gles2::GLES2Decoder>
1305 AndroidVideoDecodeAccelerator::GetGlDecoder() const { 1183 AndroidVideoDecodeAccelerator::GetGlDecoder() const {
1306 return get_gles2_decoder_cb_.Run(); 1184 return get_gles2_decoder_cb_.Run();
1307 } 1185 }
1308 1186
1309 void AndroidVideoDecodeAccelerator::OnDestroyingSurface(int surface_id) { 1187 void AndroidVideoDecodeAccelerator::OnSurfaceDestroyed() {
1188 DVLOG(1) << __func__;
1189 TRACE_EVENT0("media", "AVDA::OnSurfaceDestroyed");
1310 DCHECK(thread_checker_.CalledOnValidThread()); 1190 DCHECK(thread_checker_.CalledOnValidThread());
1311 TRACE_EVENT0("media", "AVDA::OnDestroyingSurface");
1312 DVLOG(1) << __FUNCTION__ << " surface_id: " << surface_id;
1313
1314 if (surface_id != config_.surface_id)
1315 return;
1316 1191
1317 // If the API is available avoid having to restart the decoder in order to 1192 // If the API is available avoid having to restart the decoder in order to
1318 // leave fullscreen. If we don't clear the surface immediately during this 1193 // leave fullscreen. If we don't clear the surface immediately during this
1319 // callback, the MediaCodec will throw an error as the surface is destroyed. 1194 // callback, the MediaCodec will throw an error as the surface is destroyed.
1320 if (base::android::BuildInfo::GetInstance()->sdk_int() >= 23) { 1195 if (base::android::BuildInfo::GetInstance()->sdk_int() >= 23) {
1321 // Since we can't wait for a transition, we must invalidate all outstanding 1196 // Since we can't wait for a transition, we must invalidate all outstanding
1322 // picture buffers to avoid putting the GL system in a broken state. 1197 // picture buffers to avoid putting the GL system in a broken state.
1323 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_); 1198 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_);
1324 1199
1325 // Switch away from the surface being destroyed to a surface texture. 1200 // Switch away from the surface being destroyed to a surface texture.
1326 DCHECK_NE(config_.surface_id, SurfaceManager::kNoSurfaceID); 1201 DCHECK_NE(config_.surface_id, SurfaceManager::kNoSurfaceID);
1327 1202
1328 // The leaving fullscreen notification may come in before this point. 1203 // The leaving fullscreen notification may come in before this point.
1329 if (pending_surface_id_) 1204 if (pending_surface_id_)
1330 DCHECK_EQ(pending_surface_id_.value(), SurfaceManager::kNoSurfaceID); 1205 DCHECK_EQ(pending_surface_id_.value(), SurfaceManager::kNoSurfaceID);
1331 1206
1332 pending_surface_id_ = SurfaceManager::kNoSurfaceID; 1207 pending_surface_id_ = SurfaceManager::kNoSurfaceID;
1333 UpdateSurface(); 1208 UpdateSurface();
1334 return; 1209 return;
1335 } 1210 }
1336 1211
1337 // If we're currently asynchronously configuring a codec, it will be destroyed 1212 // If we're currently asynchronously configuring a codec, it will be destroyed
1338 // when configuration completes and it notices that |state_| has changed to 1213 // when configuration completes and it notices that |state_| has changed to
1339 // SURFACE_DESTROYED. 1214 // SURFACE_DESTROYED.
1340 state_ = SURFACE_DESTROYED; 1215 state_ = SURFACE_DESTROYED;
1341 if (media_codec_) { 1216 if (media_codec_) {
1342 ReleaseMediaCodec(); 1217 AVDACodecAllocator::Get().ReleaseMediaCodec(
1218 std::move(media_codec_), codec_config_->task_type_, config_.surface_id);
1343 picture_buffer_manager_.CodecChanged(media_codec_.get()); 1219 picture_buffer_manager_.CodecChanged(media_codec_.get());
1344 } 1220 }
1221
1345 // If we're draining, signal completion now because the drain can no longer 1222 // If we're draining, signal completion now because the drain can no longer
1346 // proceed. 1223 // proceed.
1347 if (drain_type_ != DRAIN_TYPE_NONE) 1224 if (drain_type_ != DRAIN_TYPE_NONE)
1348 OnDrainCompleted(); 1225 OnDrainCompleted();
1349 } 1226 }
1350 1227
1351 void AndroidVideoDecodeAccelerator::InitializeCdm() { 1228 void AndroidVideoDecodeAccelerator::InitializeCdm() {
1352 DVLOG(2) << __FUNCTION__ << ": " << config_.cdm_id; 1229 DVLOG(2) << __FUNCTION__ << ": " << config_.cdm_id;
1353 1230
1354 #if !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) 1231 #if !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
1465 } else { 1342 } else {
1466 most_recent_work_ = now; 1343 most_recent_work_ = now;
1467 } 1344 }
1468 1345
1469 if (should_be_running) 1346 if (should_be_running)
1470 g_avda_manager.Get().StartTimer(this); 1347 g_avda_manager.Get().StartTimer(this);
1471 else 1348 else
1472 g_avda_manager.Get().StopTimer(this); 1349 g_avda_manager.Get().StopTimer(this);
1473 } 1350 }
1474 1351
1475 void AndroidVideoDecodeAccelerator::ReleaseMediaCodec() {
1476 if (!media_codec_)
1477 return;
1478
1479 // Post it to the same thread as was used to allocate it, and it'll get freed
1480 // if that thread isn't hung waiting on mediaserver. We can't release it
1481 // on this thread since it might hang up.
1482 g_avda_codec_allocator.Get()
1483 .TaskRunnerFor(codec_config_->task_type_)
1484 ->DeleteSoon(FROM_HERE, media_codec_.release());
1485 }
1486
1487 // static 1352 // static
1488 VideoDecodeAccelerator::Capabilities 1353 VideoDecodeAccelerator::Capabilities
1489 AndroidVideoDecodeAccelerator::GetCapabilities( 1354 AndroidVideoDecodeAccelerator::GetCapabilities(
1490 const gpu::GpuPreferences& gpu_preferences) { 1355 const gpu::GpuPreferences& gpu_preferences) {
1491 Capabilities capabilities; 1356 Capabilities capabilities;
1492 SupportedProfiles& profiles = capabilities.supported_profiles; 1357 SupportedProfiles& profiles = capabilities.supported_profiles;
1493 1358
1494 if (MediaCodecUtil::IsVp8DecoderAvailable()) { 1359 if (MediaCodecUtil::IsVp8DecoderAvailable()) {
1495 SupportedProfile profile; 1360 SupportedProfile profile;
1496 profile.profile = VP8PROFILE_ANY; 1361 profile.profile = VP8PROFILE_ANY;
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1587 // Prevent MediaCodec from using its internal software decoders when we have 1452 // Prevent MediaCodec from using its internal software decoders when we have
1588 // more secure and up to date versions in the renderer process. 1453 // more secure and up to date versions in the renderer process.
1589 return !config_.is_encrypted && (codec_config_->codec_ == kCodecVP8 || 1454 return !config_.is_encrypted && (codec_config_->codec_ == kCodecVP8 ||
1590 codec_config_->codec_ == kCodecVP9); 1455 codec_config_->codec_ == kCodecVP9);
1591 } 1456 }
1592 1457
1593 bool AndroidVideoDecodeAccelerator::UpdateSurface() { 1458 bool AndroidVideoDecodeAccelerator::UpdateSurface() {
1594 DCHECK(pending_surface_id_); 1459 DCHECK(pending_surface_id_);
1595 DCHECK_NE(config_.surface_id, pending_surface_id_.value()); 1460 DCHECK_NE(config_.surface_id, pending_surface_id_.value());
1596 1461
1462 // Deallocate our current surface.
1463 AVDACodecAllocator::Get().DeallocateSurface(this, config_.surface_id);
liberato (no reviews please) 2016/11/17 07:28:19 one of these has to be "no surface", i think. wor
watk 2016/11/17 20:37:05 sg will do
1464 config_.surface_id = pending_surface_id_.value();
1465 pending_surface_id_.reset();
1466
1467 // TODO(watk): Fix this so we can wait for the new surface to be allocated.
1468 if (!AVDACodecAllocator::Get().AllocateSurface(this, config_.surface_id)) {
1469 NOTIFY_ERROR(PLATFORM_FAILURE, "Failed to allocate the new surface");
1470 return false;
1471 }
1472
1597 // Ensure the current context is active when switching surfaces; we may need 1473 // Ensure the current context is active when switching surfaces; we may need
1598 // to create a new texture. 1474 // to create a new texture.
1599 if (!make_context_current_cb_.Run()) { 1475 if (!make_context_current_cb_.Run()) {
1600 NOTIFY_ERROR(PLATFORM_FAILURE, 1476 NOTIFY_ERROR(PLATFORM_FAILURE,
1601 "Failed to make this decoder's GL context current when " 1477 "Failed to make this decoder's GL context current when "
1602 "switching surfaces."); 1478 "switching surfaces.");
1603 return false; 1479 return false;
1604 } 1480 }
1605 1481
1606 config_.surface_id = pending_surface_id_.value();
1607 codec_config_->surface_ = 1482 codec_config_->surface_ =
1608 picture_buffer_manager_.Initialize(pending_surface_id_.value()); 1483 picture_buffer_manager_.Initialize(config_.surface_id);
1609 if (codec_config_->surface_.IsEmpty()) { 1484 if (codec_config_->surface_.IsEmpty()) {
1610 NOTIFY_ERROR(PLATFORM_FAILURE, "Failed to switch surfaces."); 1485 NOTIFY_ERROR(PLATFORM_FAILURE, "Failed to switch surfaces.");
1611 return false; 1486 return false;
1612 } 1487 }
1613 1488
1614 if (media_codec_ && 1489 if (media_codec_ &&
1615 !media_codec_->SetSurface(codec_config_->surface_.j_surface().obj())) { 1490 !media_codec_->SetSurface(codec_config_->surface_.j_surface().obj())) {
1616 NOTIFY_ERROR(PLATFORM_FAILURE, "MediaCodec failed to switch surfaces."); 1491 NOTIFY_ERROR(PLATFORM_FAILURE, "MediaCodec failed to switch surfaces.");
1617 return false; 1492 return false;
1618 } 1493 }
1619 1494
1620 pending_surface_id_.reset();
1621 return true; 1495 return true;
1622 } 1496 }
1623 1497
1624 } // namespace media 1498 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698