OLD | NEW |
---|---|
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 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
162 if (timer_avda_instances_.empty()) | 162 if (timer_avda_instances_.empty()) |
163 io_timer_.Stop(); | 163 io_timer_.Stop(); |
164 } | 164 } |
165 | 165 |
166 // |avda| would like to use |surface_id|. If it is not busy, then mark it | 166 // |avda| would like to use |surface_id|. If it is not busy, then mark it |
167 // as busy and return true. If it is busy, then replace any existing waiter, | 167 // as busy and return true. If it is busy, then replace any existing waiter, |
168 // make |avda| the current waiter, and return false. Any existing waiter | 168 // make |avda| the current waiter, and return false. Any existing waiter |
169 // is assumed to be on the way out, so we fail its allocation request. | 169 // is assumed to be on the way out, so we fail its allocation request. |
170 bool AllocateSurface(int surface_id, AndroidVideoDecodeAccelerator* avda) { | 170 bool AllocateSurface(int surface_id, AndroidVideoDecodeAccelerator* avda) { |
171 // Nobody has to wait for no surface. | 171 // Nobody has to wait for no surface. |
172 if (surface_id == AndroidVideoDecodeAccelerator::Config::kNoSurfaceID) | 172 if (surface_id == SurfaceManager::kNoSurfaceID) |
173 return true; | 173 return true; |
174 | 174 |
175 auto iter = surface_waiter_map_.find(surface_id); | 175 auto iter = surface_waiter_map_.find(surface_id); |
176 if (iter == surface_waiter_map_.end()) { | 176 if (iter == surface_waiter_map_.end()) { |
177 // SurfaceView isn't allocated. Succeed. | 177 // SurfaceView isn't allocated. Succeed. |
178 surface_waiter_map_[surface_id].owner = avda; | 178 surface_waiter_map_[surface_id].owner = avda; |
179 return true; | 179 return true; |
180 } | 180 } |
181 | 181 |
182 // SurfaceView is already allocated. | 182 // SurfaceView is already allocated. |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
218 // Promote |waiter| to be the owner. | 218 // Promote |waiter| to be the owner. |
219 iter->second.owner = waiter; | 219 iter->second.owner = waiter; |
220 iter->second.waiter = nullptr; | 220 iter->second.waiter = nullptr; |
221 waiter->OnSurfaceAvailable(true); | 221 waiter->OnSurfaceAvailable(true); |
222 } | 222 } |
223 | 223 |
224 // On low end devices (< KitKat is always low-end due to buggy MediaCodec), | 224 // On low end devices (< KitKat is always low-end due to buggy MediaCodec), |
225 // defer the surface creation until the codec is actually used if we know no | 225 // defer the surface creation until the codec is actually used if we know no |
226 // software fallback exists. | 226 // software fallback exists. |
227 bool ShouldDeferSurfaceCreation(int surface_id, VideoCodec codec) { | 227 bool ShouldDeferSurfaceCreation(int surface_id, VideoCodec codec) { |
228 return surface_id == AndroidVideoDecodeAccelerator::Config::kNoSurfaceID && | 228 return surface_id == SurfaceManager::kNoSurfaceID && codec == kCodecH264 && |
229 codec == kCodecH264 && | |
230 g_avda_codec_allocator.Get().IsAnyRegisteredAVDA() && | 229 g_avda_codec_allocator.Get().IsAnyRegisteredAVDA() && |
231 (base::android::BuildInfo::GetInstance()->sdk_int() <= 18 || | 230 (base::android::BuildInfo::GetInstance()->sdk_int() <= 18 || |
232 base::SysInfo::IsLowEndDevice()); | 231 base::SysInfo::IsLowEndDevice()); |
233 } | 232 } |
234 | 233 |
235 private: | 234 private: |
236 friend struct base::DefaultLazyInstanceTraits<AVDAManager>; | 235 friend struct base::DefaultLazyInstanceTraits<AVDAManager>; |
237 | 236 |
238 AVDAManager() {} | 237 AVDAManager() {} |
239 ~AVDAManager() { NOTREACHED(); } | 238 ~AVDAManager() { NOTREACHED(); } |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
312 picture_buffer_manager_(this), | 311 picture_buffer_manager_(this), |
313 drain_type_(DRAIN_TYPE_NONE), | 312 drain_type_(DRAIN_TYPE_NONE), |
314 media_drm_bridge_cdm_context_(nullptr), | 313 media_drm_bridge_cdm_context_(nullptr), |
315 cdm_registration_id_(0), | 314 cdm_registration_id_(0), |
316 pending_input_buf_index_(-1), | 315 pending_input_buf_index_(-1), |
317 error_sequence_token_(0), | 316 error_sequence_token_(0), |
318 defer_errors_(false), | 317 defer_errors_(false), |
319 deferred_initialization_pending_(false), | 318 deferred_initialization_pending_(false), |
320 codec_needs_reset_(false), | 319 codec_needs_reset_(false), |
321 defer_surface_creation_(false), | 320 defer_surface_creation_(false), |
321 surface_id_(SurfaceManager::kNoSurfaceID), | |
322 weak_this_factory_(this) {} | 322 weak_this_factory_(this) {} |
323 | 323 |
324 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { | 324 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { |
325 DCHECK(thread_checker_.CalledOnValidThread()); | 325 DCHECK(thread_checker_.CalledOnValidThread()); |
326 g_avda_manager.Get().StopTimer(this); | 326 g_avda_manager.Get().StopTimer(this); |
327 g_avda_codec_allocator.Get().StopThread(this); | 327 g_avda_codec_allocator.Get().StopThread(this); |
328 | 328 |
329 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 329 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
330 if (!media_drm_bridge_cdm_context_) | 330 if (!media_drm_bridge_cdm_context_) |
331 return; | 331 return; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
390 << " is not hardware accelerated"; | 390 << " is not hardware accelerated"; |
391 return false; | 391 return false; |
392 } | 392 } |
393 | 393 |
394 auto gles_decoder = get_gles2_decoder_cb_.Run(); | 394 auto gles_decoder = get_gles2_decoder_cb_.Run(); |
395 if (!gles_decoder) { | 395 if (!gles_decoder) { |
396 DLOG(ERROR) << "Failed to get gles2 decoder instance."; | 396 DLOG(ERROR) << "Failed to get gles2 decoder instance."; |
397 return false; | 397 return false; |
398 } | 398 } |
399 | 399 |
400 // If SetSurface() was called before initialize, pick up the surface. | |
401 if (pending_surface_id_) { | |
402 surface_id_ = pending_surface_id_.value(); | |
403 pending_surface_id_.reset(); | |
404 } | |
405 | |
400 // If we're low on resources, we may decide to defer creation of the surface | 406 // If we're low on resources, we may decide to defer creation of the surface |
401 // until the codec is actually used. | 407 // until the codec is actually used. |
402 if (g_avda_manager.Get().ShouldDeferSurfaceCreation(config_.surface_id, | 408 if (g_avda_manager.Get().ShouldDeferSurfaceCreation(surface_id_, |
403 codec_config_->codec_)) { | 409 codec_config_->codec_)) { |
404 DCHECK(!deferred_initialization_pending_); | 410 DCHECK(!deferred_initialization_pending_); |
405 | 411 |
406 // We should never be here if a SurfaceView is required. | 412 // We should never be here if a SurfaceView is required. |
407 DCHECK_EQ(config_.surface_id, Config::kNoSurfaceID); | 413 DCHECK_EQ(surface_id_, SurfaceManager::kNoSurfaceID); |
408 DCHECK(g_avda_manager.Get().AllocateSurface(config_.surface_id, this)); | 414 DCHECK(g_avda_manager.Get().AllocateSurface(surface_id_, this)); |
409 | 415 |
410 defer_surface_creation_ = true; | 416 defer_surface_creation_ = true; |
411 NotifyInitializationComplete(true); | 417 NotifyInitializationComplete(true); |
412 return true; | 418 return true; |
413 } | 419 } |
414 | 420 |
415 // We signaled that we support deferred initialization, so see if the client | 421 // We signaled that we support deferred initialization, so see if the client |
416 // does also. | 422 // does also. |
417 deferred_initialization_pending_ = config.is_deferred_initialization_allowed; | 423 deferred_initialization_pending_ = config.is_deferred_initialization_allowed; |
418 if (config_.is_encrypted && !deferred_initialization_pending_) { | 424 if (config_.is_encrypted && !deferred_initialization_pending_) { |
419 DLOG(ERROR) << "Deferred initialization must be used for encrypted streams"; | 425 DLOG(ERROR) << "Deferred initialization must be used for encrypted streams"; |
420 return false; | 426 return false; |
421 } | 427 } |
422 | 428 |
423 if (g_avda_manager.Get().AllocateSurface(config_.surface_id, this)) { | 429 if (g_avda_manager.Get().AllocateSurface(surface_id_, this)) { |
424 // We have successfully owned the surface, so finish initialization now. | 430 // We have successfully owned the surface, so finish initialization now. |
425 return InitializePictureBufferManager(); | 431 return InitializePictureBufferManager(); |
426 } | 432 } |
427 | 433 |
428 // We have to wait for some other AVDA instance to free up the surface. | 434 // We have to wait for some other AVDA instance to free up the surface. |
429 // OnSurfaceAvailable will be called when it's available. | 435 // OnSurfaceAvailable will be called when it's available. |
430 return true; | 436 return true; |
431 } | 437 } |
432 | 438 |
433 void AndroidVideoDecodeAccelerator::OnSurfaceAvailable(bool success) { | 439 void AndroidVideoDecodeAccelerator::OnSurfaceAvailable(bool success) { |
434 DCHECK(deferred_initialization_pending_); | 440 DCHECK(deferred_initialization_pending_); |
435 DCHECK(!defer_surface_creation_); | 441 DCHECK(!defer_surface_creation_); |
436 | 442 |
437 if (!success || !InitializePictureBufferManager()) { | 443 if (!success || !InitializePictureBufferManager()) { |
438 NotifyInitializationComplete(false); | 444 NotifyInitializationComplete(false); |
439 deferred_initialization_pending_ = false; | 445 deferred_initialization_pending_ = false; |
440 } | 446 } |
441 } | 447 } |
442 | 448 |
443 bool AndroidVideoDecodeAccelerator::InitializePictureBufferManager() { | 449 bool AndroidVideoDecodeAccelerator::InitializePictureBufferManager() { |
444 if (!make_context_current_cb_.Run()) { | 450 if (!make_context_current_cb_.Run()) { |
445 LOG(ERROR) << "Failed to make this decoder's GL context current."; | 451 LOG(ERROR) << "Failed to make this decoder's GL context current."; |
446 return false; | 452 return false; |
447 } | 453 } |
448 | 454 |
449 codec_config_->surface_ = | 455 codec_config_->surface_ = picture_buffer_manager_.Initialize(surface_id_); |
450 picture_buffer_manager_.Initialize(config_.surface_id); | |
451 if (codec_config_->surface_.IsEmpty()) | 456 if (codec_config_->surface_.IsEmpty()) |
452 return false; | 457 return false; |
453 | 458 |
454 on_destroying_surface_cb_ = | 459 on_destroying_surface_cb_ = |
455 base::Bind(&AndroidVideoDecodeAccelerator::OnDestroyingSurface, | 460 base::Bind(&AndroidVideoDecodeAccelerator::OnDestroyingSurface, |
456 weak_this_factory_.GetWeakPtr()); | 461 weak_this_factory_.GetWeakPtr()); |
457 AVDASurfaceTracker::GetInstance()->RegisterOnDestroyingSurfaceCallback( | 462 AVDASurfaceTracker::GetInstance()->RegisterOnDestroyingSurfaceCallback( |
458 on_destroying_surface_cb_); | 463 on_destroying_surface_cb_); |
459 | 464 |
460 if (!g_avda_codec_allocator.Get().StartThread(this)) | 465 if (!g_avda_codec_allocator.Get().StartThread(this)) |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
647 if (picturebuffers_requested_ && output_picture_buffers_.empty() && | 652 if (picturebuffers_requested_ && output_picture_buffers_.empty() && |
648 !IsDrainingForResetOrDestroy()) { | 653 !IsDrainingForResetOrDestroy()) { |
649 return false; | 654 return false; |
650 } | 655 } |
651 if (!output_picture_buffers_.empty() && free_picture_ids_.empty() && | 656 if (!output_picture_buffers_.empty() && free_picture_ids_.empty() && |
652 !IsDrainingForResetOrDestroy()) { | 657 !IsDrainingForResetOrDestroy()) { |
653 // Don't have any picture buffer to send. Need to wait. | 658 // Don't have any picture buffer to send. Need to wait. |
654 return false; | 659 return false; |
655 } | 660 } |
656 | 661 |
662 // If we're waiting to switch surfaces pause output release until we have all | |
663 // picture buffers returned. This is so we can ensure the right flags are set | |
664 // on the picture buffers returned to the client. | |
665 if (pending_surface_id_) { | |
666 DCHECK_GE(base::android::BuildInfo::GetInstance()->sdk_int(), 23); | |
watk
2016/11/08 22:59:03
Feels like this DCHECK belongs in SetSurface(). i.
DaleCurtis
2016/11/08 23:50:11
Moved to the codec bridge.
| |
667 if (picture_buffer_manager_.ArePicturesOutstanding()) | |
668 return false; | |
669 if (!UpdateSurface()) | |
670 return false; | |
671 } | |
672 | |
657 bool eos = false; | 673 bool eos = false; |
658 base::TimeDelta presentation_timestamp; | 674 base::TimeDelta presentation_timestamp; |
659 int32_t buf_index = 0; | 675 int32_t buf_index = 0; |
660 do { | 676 do { |
661 size_t offset = 0; | 677 size_t offset = 0; |
662 size_t size = 0; | 678 size_t size = 0; |
663 | 679 |
664 TRACE_EVENT_BEGIN0("media", "AVDA::DequeueOutput"); | 680 TRACE_EVENT_BEGIN0("media", "AVDA::DequeueOutput"); |
665 MediaCodecStatus status = media_codec_->DequeueOutputBuffer( | 681 MediaCodecStatus status = media_codec_->DequeueOutputBuffer( |
666 NoWaitTimeOut, &buf_index, &offset, &size, &presentation_timestamp, | 682 NoWaitTimeOut, &buf_index, &offset, &size, &presentation_timestamp, |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
880 pending_bitstream_records_.size()); | 896 pending_bitstream_records_.size()); |
881 | 897 |
882 DoIOTask(true); | 898 DoIOTask(true); |
883 } | 899 } |
884 | 900 |
885 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() { | 901 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() { |
886 if (client_) { | 902 if (client_) { |
887 client_->ProvidePictureBuffers( | 903 client_->ProvidePictureBuffers( |
888 kNumPictureBuffers, PIXEL_FORMAT_UNKNOWN, 1, | 904 kNumPictureBuffers, PIXEL_FORMAT_UNKNOWN, 1, |
889 picture_buffer_manager_.GetPictureBufferSize(), | 905 picture_buffer_manager_.GetPictureBufferSize(), |
890 picture_buffer_manager_.GetTextureTarget()); | 906 AVDAPictureBufferManager::kTextureTarget); |
891 } | 907 } |
892 } | 908 } |
893 | 909 |
894 void AndroidVideoDecodeAccelerator::AssignPictureBuffers( | 910 void AndroidVideoDecodeAccelerator::AssignPictureBuffers( |
895 const std::vector<PictureBuffer>& buffers) { | 911 const std::vector<PictureBuffer>& buffers) { |
896 DCHECK(thread_checker_.CalledOnValidThread()); | 912 DCHECK(thread_checker_.CalledOnValidThread()); |
897 DCHECK(output_picture_buffers_.empty()); | 913 DCHECK(output_picture_buffers_.empty()); |
898 DCHECK(free_picture_ids_.empty()); | 914 DCHECK(free_picture_ids_.empty()); |
899 | 915 |
900 if (buffers.size() < kNumPictureBuffers) { | 916 if (buffers.size() < kNumPictureBuffers) { |
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1234 // Postpone ResetCodecState() after the drain. | 1250 // Postpone ResetCodecState() after the drain. |
1235 StartCodecDrain(DRAIN_FOR_RESET); | 1251 StartCodecDrain(DRAIN_FOR_RESET); |
1236 } else { | 1252 } else { |
1237 ResetCodecState(); | 1253 ResetCodecState(); |
1238 base::ThreadTaskRunnerHandle::Get()->PostTask( | 1254 base::ThreadTaskRunnerHandle::Get()->PostTask( |
1239 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, | 1255 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, |
1240 weak_this_factory_.GetWeakPtr())); | 1256 weak_this_factory_.GetWeakPtr())); |
1241 } | 1257 } |
1242 } | 1258 } |
1243 | 1259 |
1260 void AndroidVideoDecodeAccelerator::SetSurface(int32_t surface_id) { | |
1261 if (surface_id == surface_id_) { | |
1262 pending_surface_id_.reset(); | |
1263 return; | |
1264 } | |
1265 | |
1266 // Surface changes never take affect immediately, they will be handled during | |
watk
2016/11/08 22:59:03
s/affect/effect/
DaleCurtis
2016/11/08 23:50:11
Done.
| |
1267 // DequeOutput() once we get to a good switch point or immediately during an | |
1268 // OnDestroyingSurface() call. | |
1269 pending_surface_id_ = surface_id; | |
1270 } | |
1271 | |
1244 void AndroidVideoDecodeAccelerator::Destroy() { | 1272 void AndroidVideoDecodeAccelerator::Destroy() { |
1245 DVLOG(1) << __FUNCTION__; | 1273 DVLOG(1) << __FUNCTION__; |
1246 DCHECK(thread_checker_.CalledOnValidThread()); | 1274 DCHECK(thread_checker_.CalledOnValidThread()); |
1247 | 1275 |
1248 picture_buffer_manager_.Destroy(output_picture_buffers_); | 1276 picture_buffer_manager_.Destroy(output_picture_buffers_); |
1249 | 1277 |
1250 client_ = nullptr; | 1278 client_ = nullptr; |
1251 | 1279 |
1252 // Some VP8 files require a complete MediaCodec drain before we can call | 1280 // Some VP8 files require a complete MediaCodec drain before we can call |
1253 // MediaCodec.flush() or MediaCodec.release(). http://crbug.com/598963. In | 1281 // MediaCodec.flush() or MediaCodec.release(). http://crbug.com/598963. In |
(...skipping 13 matching lines...) Expand all Loading... | |
1267 DVLOG(1) << __FUNCTION__; | 1295 DVLOG(1) << __FUNCTION__; |
1268 DCHECK(thread_checker_.CalledOnValidThread()); | 1296 DCHECK(thread_checker_.CalledOnValidThread()); |
1269 | 1297 |
1270 if (!on_destroying_surface_cb_.is_null()) { | 1298 if (!on_destroying_surface_cb_.is_null()) { |
1271 AVDASurfaceTracker::GetInstance()->UnregisterOnDestroyingSurfaceCallback( | 1299 AVDASurfaceTracker::GetInstance()->UnregisterOnDestroyingSurfaceCallback( |
1272 on_destroying_surface_cb_); | 1300 on_destroying_surface_cb_); |
1273 } | 1301 } |
1274 | 1302 |
1275 // We no longer care about |surface_id|, in case we did before. It's okay | 1303 // We no longer care about |surface_id|, in case we did before. It's okay |
1276 // if we have no surface and/or weren't the owner or a waiter. | 1304 // if we have no surface and/or weren't the owner or a waiter. |
1277 g_avda_manager.Get().DeallocateSurface(config_.surface_id, this); | 1305 g_avda_manager.Get().DeallocateSurface(surface_id_, this); |
1278 | 1306 |
1279 // Note that async codec construction might still be in progress. In that | 1307 // Note that async codec construction might still be in progress. In that |
1280 // case, the codec will be deleted when it completes once we invalidate all | 1308 // case, the codec will be deleted when it completes once we invalidate all |
1281 // our weak refs. | 1309 // our weak refs. |
1282 weak_this_factory_.InvalidateWeakPtrs(); | 1310 weak_this_factory_.InvalidateWeakPtrs(); |
1283 if (media_codec_) { | 1311 if (media_codec_) { |
1284 g_avda_manager.Get().StopTimer(this); | 1312 g_avda_manager.Get().StopTimer(this); |
1285 ReleaseMediaCodec(); | 1313 ReleaseMediaCodec(); |
1286 } | 1314 } |
1287 | 1315 |
(...skipping 13 matching lines...) Expand all Loading... | |
1301 base::WeakPtr<gpu::gles2::GLES2Decoder> | 1329 base::WeakPtr<gpu::gles2::GLES2Decoder> |
1302 AndroidVideoDecodeAccelerator::GetGlDecoder() const { | 1330 AndroidVideoDecodeAccelerator::GetGlDecoder() const { |
1303 return get_gles2_decoder_cb_.Run(); | 1331 return get_gles2_decoder_cb_.Run(); |
1304 } | 1332 } |
1305 | 1333 |
1306 void AndroidVideoDecodeAccelerator::OnDestroyingSurface(int surface_id) { | 1334 void AndroidVideoDecodeAccelerator::OnDestroyingSurface(int surface_id) { |
1307 DCHECK(thread_checker_.CalledOnValidThread()); | 1335 DCHECK(thread_checker_.CalledOnValidThread()); |
1308 TRACE_EVENT0("media", "AVDA::OnDestroyingSurface"); | 1336 TRACE_EVENT0("media", "AVDA::OnDestroyingSurface"); |
1309 DVLOG(1) << __FUNCTION__ << " surface_id: " << surface_id; | 1337 DVLOG(1) << __FUNCTION__ << " surface_id: " << surface_id; |
1310 | 1338 |
1311 if (surface_id != config_.surface_id) | 1339 if (surface_id != surface_id_) |
1312 return; | 1340 return; |
1313 | 1341 |
1342 // If the API is available avoid having to restart the decoder in order to | |
1343 // leave full screen. If we don't clear the surface immediately during this | |
watk
2016/11/08 22:59:03
s/full screen/fullscreen for consistency
DaleCurtis
2016/11/08 23:50:10
Done.
| |
1344 // callback, the MediaCodec will throw an error as the surface is destroyed. | |
1345 if (base::android::BuildInfo::GetInstance()->sdk_int() >= 23) { | |
1346 // Since we can't wait for a transition, we must invalidate all outstanding | |
1347 // picture buffers to avoid putting the GL system in a broken state. | |
1348 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_); | |
1349 | |
1350 // Switch away from the surface being destroyed to a surface texture. | |
1351 DCHECK_NE(surface_id_, SurfaceManager::kNoSurfaceID); | |
1352 | |
1353 // The leaving full screen notification may come in before this point. | |
watk
2016/11/08 22:59:03
s/full screen/fullscreen
DaleCurtis
2016/11/08 23:50:11
Done.
| |
1354 if (pending_surface_id_) | |
1355 DCHECK_EQ(pending_surface_id_.value(), SurfaceManager::kNoSurfaceID); | |
1356 | |
1357 pending_surface_id_ = SurfaceManager::kNoSurfaceID; | |
1358 UpdateSurface(); | |
1359 return; | |
1360 } | |
1361 | |
1314 // If we're currently asynchronously configuring a codec, it will be destroyed | 1362 // If we're currently asynchronously configuring a codec, it will be destroyed |
1315 // when configuration completes and it notices that |state_| has changed to | 1363 // when configuration completes and it notices that |state_| has changed to |
1316 // SURFACE_DESTROYED. | 1364 // SURFACE_DESTROYED. |
1317 state_ = SURFACE_DESTROYED; | 1365 state_ = SURFACE_DESTROYED; |
1318 if (media_codec_) { | 1366 if (media_codec_) { |
1319 ReleaseMediaCodec(); | 1367 ReleaseMediaCodec(); |
1320 picture_buffer_manager_.CodecChanged(media_codec_.get()); | 1368 picture_buffer_manager_.CodecChanged(media_codec_.get()); |
1321 } | 1369 } |
1322 // If we're draining, signal completion now because the drain can no longer | 1370 // If we're draining, signal completion now because the drain can no longer |
1323 // proceed. | 1371 // proceed. |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1577 } | 1625 } |
1578 | 1626 |
1579 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden() | 1627 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden() |
1580 const { | 1628 const { |
1581 // Prevent MediaCodec from using its internal software decoders when we have | 1629 // Prevent MediaCodec from using its internal software decoders when we have |
1582 // more secure and up to date versions in the renderer process. | 1630 // more secure and up to date versions in the renderer process. |
1583 return !config_.is_encrypted && (codec_config_->codec_ == kCodecVP8 || | 1631 return !config_.is_encrypted && (codec_config_->codec_ == kCodecVP8 || |
1584 codec_config_->codec_ == kCodecVP9); | 1632 codec_config_->codec_ == kCodecVP9); |
1585 } | 1633 } |
1586 | 1634 |
1635 bool AndroidVideoDecodeAccelerator::UpdateSurface() { | |
1636 DCHECK_GE(base::android::BuildInfo::GetInstance()->sdk_int(), 23); | |
1637 DCHECK(pending_surface_id_); | |
1638 DCHECK_NE(surface_id_, pending_surface_id_.value()); | |
1639 | |
1640 // Ensure the current context is active when switching surfaces; we may need | |
1641 // to create a new texture. | |
1642 if (!make_context_current_cb_.Run()) { | |
1643 POST_ERROR(PLATFORM_FAILURE, | |
1644 "Failed to make this decoder's GL context current when " | |
1645 "switching surfaces."); | |
1646 return false; | |
1647 } | |
1648 | |
1649 surface_id_ = pending_surface_id_.value(); | |
1650 codec_config_->surface_ = | |
1651 picture_buffer_manager_.Initialize(pending_surface_id_.value()); | |
1652 if (codec_config_->surface_.IsEmpty()) { | |
1653 POST_ERROR(PLATFORM_FAILURE, "An error occurred while switching surfaces."); | |
1654 return false; | |
1655 } | |
1656 | |
1657 if (media_codec_) | |
1658 media_codec_->SetSurface(codec_config_->surface_.j_surface().obj()); | |
1659 pending_surface_id_.reset(); | |
1660 return true; | |
1661 } | |
1662 | |
1587 } // namespace media | 1663 } // namespace media |
OLD | NEW |