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 17 matching lines...) Expand all Loading... | |
28 #include "gpu/ipc/service/gpu_channel.h" | 28 #include "gpu/ipc/service/gpu_channel.h" |
29 #include "media/base/android/media_codec_bridge_impl.h" | 29 #include "media/base/android/media_codec_bridge_impl.h" |
30 #include "media/base/android/media_codec_util.h" | 30 #include "media/base/android/media_codec_util.h" |
31 #include "media/base/bind_to_current_loop.h" | 31 #include "media/base/bind_to_current_loop.h" |
32 #include "media/base/bitstream_buffer.h" | 32 #include "media/base/bitstream_buffer.h" |
33 #include "media/base/limits.h" | 33 #include "media/base/limits.h" |
34 #include "media/base/media.h" | 34 #include "media/base/media.h" |
35 #include "media/base/timestamp_constants.h" | 35 #include "media/base/timestamp_constants.h" |
36 #include "media/base/video_decoder_config.h" | 36 #include "media/base/video_decoder_config.h" |
37 #include "media/gpu/avda_picture_buffer_manager.h" | 37 #include "media/gpu/avda_picture_buffer_manager.h" |
38 #include "media/gpu/content_video_view_overlay.h" | |
38 #include "media/gpu/shared_memory_region.h" | 39 #include "media/gpu/shared_memory_region.h" |
39 #include "media/video/picture.h" | 40 #include "media/video/picture.h" |
40 #include "ui/gl/android/scoped_java_surface.h" | 41 #include "ui/gl/android/scoped_java_surface.h" |
41 #include "ui/gl/android/surface_texture.h" | 42 #include "ui/gl/android/surface_texture.h" |
42 #include "ui/gl/gl_bindings.h" | 43 #include "ui/gl/gl_bindings.h" |
43 | 44 |
44 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 45 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
45 #include "media/mojo/services/mojo_cdm_service.h" | 46 #include "media/mojo/services/mojo_cdm_service.h" |
46 #endif | 47 #endif |
47 | 48 |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
357 } | 358 } |
358 | 359 |
359 // Fail / complete / defer initialization. | 360 // Fail / complete / defer initialization. |
360 return state_ != ERROR; | 361 return state_ != ERROR; |
361 } | 362 } |
362 | 363 |
363 void AndroidVideoDecodeAccelerator::StartSurfaceCreation() { | 364 void AndroidVideoDecodeAccelerator::StartSurfaceCreation() { |
364 // We might be called during Initialize, during deferred initialization, or | 365 // We might be called during Initialize, during deferred initialization, or |
365 // afterwards (::Decode, for deferred surface init, UpdateSurface). | 366 // afterwards (::Decode, for deferred surface init, UpdateSurface). |
366 | 367 |
368 // Whoever calls us should release any overlay we had. | |
369 DCHECK(!codec_config_->overlay); | |
370 // Note that we don't enforce that for any SurfaceTexture or its Surface, | |
liberato (no reviews please)
2017/02/17 18:34:38
watk: do you agree with this reasoning? i believe
watk
2017/02/17 22:40:36
I don't know to be honest. I'm pretty confused :(
liberato (no reviews please)
2017/03/07 21:30:25
i think that this is now okay, since surface bundl
| |
371 // since there might be a codec that's using them. They'll get cleared | |
372 // later, in InitializePictureBufferManager. | |
373 | |
367 // If surface creation is deferred, then do nothing except signal that init | 374 // If surface creation is deferred, then do nothing except signal that init |
368 // is complete, if needed. We might still fail to get a surface or codec, | 375 // is complete, if needed. We might still fail to get a surface or codec, |
369 // which would normally be an init error. Since we're deferring init until a | 376 // which would normally be an init error. Since we're deferring init until a |
370 // decode to save resources, though, we're signaling success now. If we're | 377 // decode to save resources, though, we're signaling success now. If we're |
371 // wrong, then decoding might fail when we might have been able to use a | 378 // wrong, then decoding might fail when we might have been able to use a |
372 // fallback renderer in WMPI if we failed init. | 379 // fallback renderer in WMPI if we failed init. |
373 if (defer_surface_creation_) { | 380 if (defer_surface_creation_) { |
374 if (deferred_initialization_pending_) | 381 if (deferred_initialization_pending_) |
375 NotifyInitializationSucceeded(); | 382 NotifyInitializationSucceeded(); |
376 | 383 |
377 return; | 384 return; |
378 } | 385 } |
379 | 386 |
380 if (!codec_allocator_->AllocateSurface(this, config_.surface_id)) { | 387 if (config_.surface_id != SurfaceManager::kNoSurfaceID) { |
388 // Create the overlay. Note that it will never call us back immedaitely. | |
watk
2017/02/17 22:40:36
immediately
liberato (no reviews please)
2017/03/07 21:30:25
Done.
| |
389 // It will post when the surface is available. | |
390 AndroidOverlay::Config overlay_config; | |
391 // We use weak ptrs here since |overlay| can outlive us, if we send it for | |
392 // async codec config. | |
393 overlay_config.ready_cb = | |
394 base::Bind(&AndroidVideoDecodeAccelerator::OnSurfaceAvailable, | |
395 weak_this_factory_.GetWeakPtr()); | |
396 overlay_config.destroyed_cb = | |
397 base::Bind(&AndroidVideoDecodeAccelerator::OnSurfaceDestroyed, | |
398 weak_this_factory_.GetWeakPtr()); | |
399 codec_config_->overlay = base::MakeUnique<ContentVideoViewOverlay>( | |
400 codec_allocator_, config_.surface_id, overlay_config); | |
381 // We have to wait for some other AVDA instance to free up the surface. | 401 // We have to wait for some other AVDA instance to free up the surface. |
382 // OnSurfaceAvailable will be called when it's available. | 402 // OnSurfaceAvailable will be called when it's available. |
383 // Note that if we aren't deferring init, then we'll signal success, and | 403 // Note that if we aren't deferring init, then we'll signal success, and |
384 // if we fail later then it will fail decoding instead. However, since | 404 // if we fail later then it will fail decoding instead. However, since |
385 // nobody that provides a SurfaceView requires sync init, it doesn't matter. | 405 // nobody that provides a SurfaceView requires sync init, it doesn't matter. |
386 state_ = WAITING_FOR_SURFACE; | 406 state_ = WAITING_FOR_SURFACE; |
387 return; | 407 return; |
388 } | 408 } |
389 | 409 |
390 // We now own the surface, so finish initialization. | 410 // We're creating a SurfaceTexture. |
391 InitializePictureBufferManager(); | 411 InitializePictureBufferManager(); |
392 } | 412 } |
393 | 413 |
394 void AndroidVideoDecodeAccelerator::OnSurfaceAvailable(bool success) { | 414 void AndroidVideoDecodeAccelerator::OnSurfaceAvailable() { |
395 DCHECK(!defer_surface_creation_); | 415 DCHECK(!defer_surface_creation_); |
396 DCHECK_EQ(state_, WAITING_FOR_SURFACE); | 416 DCHECK_EQ(state_, WAITING_FOR_SURFACE); |
397 | 417 |
398 if (!success) { | 418 // TODO(liberato): We could short-circuit the AndroidOverlay callback to call |
watk
2017/02/17 22:40:36
Remove TODO? I don't think we need a comment here
liberato (no reviews please)
2017/03/07 21:30:25
Done.
| |
399 NOTIFY_ERROR(PLATFORM_FAILURE, "Surface is not available"); | 419 // InitializePictureBufferManager, but it's somewhat clearer this way. We |
400 return; | 420 // also get to keep the WAITING_FOR_SURFACE DCHECK, whcih isn't always true |
401 } | 421 // in InitializePictureBufferManager. |
402 | 422 |
403 InitializePictureBufferManager(); | 423 InitializePictureBufferManager(); |
404 } | 424 } |
405 | 425 |
406 void AndroidVideoDecodeAccelerator::InitializePictureBufferManager() { | 426 void AndroidVideoDecodeAccelerator::InitializePictureBufferManager() { |
407 DCHECK(!defer_surface_creation_); | 427 DCHECK(!defer_surface_creation_); |
408 | 428 |
409 if (!make_context_current_cb_.Run()) { | 429 if (!make_context_current_cb_.Run()) { |
410 NOTIFY_ERROR(PLATFORM_FAILURE, | 430 NOTIFY_ERROR(PLATFORM_FAILURE, |
411 "Failed to make this decoder's GL context current"); | 431 "Failed to make this decoder's GL context current"); |
412 return; | 432 return; |
413 } | 433 } |
414 | 434 |
415 codec_config_->surface = | 435 // TODO(liberato): it doesn't make sense anymore for the PictureBufferManager |
416 picture_buffer_manager_.Initialize(config_.surface_id); | 436 // to create the surface texture. |
417 codec_config_->surface_texture = picture_buffer_manager_.surface_texture(); | 437 if (codec_config_->overlay) { |
418 if (codec_config_->surface.IsEmpty()) { | 438 picture_buffer_manager_.InitializeForOverlay(); |
419 NOTIFY_ERROR(PLATFORM_FAILURE, "Codec surface is empty"); | 439 // Note that we might want to do this after SetSurface, or on return, or |
liberato (no reviews please)
2017/02/17 18:34:38
hrm, this also exists in the current code. i'm pr
watk
2017/02/17 22:40:36
Yeah +1 to already exists.
liberato (no reviews please)
2017/03/07 21:30:25
surface bundle should fix this.
| |
420 return; | 440 // something like that. There might still be a MediaCodec that's using |
441 // them now. Perhaps put them into local vars? | |
442 codec_config_->surface_texture_surface = gl::ScopedJavaSurface(); | |
443 codec_config_->surface_texture = nullptr; | |
watk
2017/02/17 22:40:36
This seems broken? Before this change. I think it
liberato (no reviews please)
2017/03/07 21:30:25
it did this before, too. it used to be that AVDA:
| |
444 } else { | |
445 codec_config_->surface_texture_surface = | |
446 picture_buffer_manager_.InitializeForSurfaceTexture(); | |
447 codec_config_->surface_texture = picture_buffer_manager_.surface_texture(); | |
421 } | 448 } |
422 | 449 |
423 // If we have a media codec, then setSurface. If that doesn't work, then we | 450 // If we have a media codec, then SetSurface. If that doesn't work, then we |
424 // do not try to allocate a new codec; we might not be at a keyframe, etc. | 451 // do not try to allocate a new codec; we might not be at a keyframe, etc. |
425 // If we get here with a codec, then we must setSurface. | 452 // If we get here with a codec, then we must setSurface. |
426 if (media_codec_) { | 453 if (media_codec_) { |
427 // TODO(liberato): fail on api check? | 454 // TODO(liberato): fail on api check? |
428 if (!media_codec_->SetSurface(codec_config_->surface.j_surface().obj())) { | 455 if (!media_codec_->SetSurface(codec_config_->j_surface().obj())) { |
429 NOTIFY_ERROR(PLATFORM_FAILURE, "MediaCodec failed to switch surfaces."); | 456 NOTIFY_ERROR(PLATFORM_FAILURE, "MediaCodec failed to switch surfaces."); |
457 } else { | |
458 state_ = NO_ERROR; | |
430 } | 459 } |
431 return; | 460 return; |
432 } | 461 } |
433 | 462 |
434 // If the client doesn't support deferred initialization (WebRTC), then we | 463 // If the client doesn't support deferred initialization (WebRTC), then we |
435 // should complete it now and return a meaningful result. Note that it would | 464 // should complete it now and return a meaningful result. Note that it would |
436 // be nice if we didn't have to worry about starting codec configuration at | 465 // be nice if we didn't have to worry about starting codec configuration at |
437 // all (::Initialize or the wrapper can do it), but then they have to remember | 466 // all (::Initialize or the wrapper can do it), but then they have to remember |
438 // not to start codec config if we have to wait for the cdm. It's somewhat | 467 // not to start codec config if we have to wait for the cdm. It's somewhat |
439 // clearer for us to handle both cases. | 468 // clearer for us to handle both cases. |
(...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
943 | 972 |
944 DCHECK_NE(state_, WAITING_FOR_CODEC); | 973 DCHECK_NE(state_, WAITING_FOR_CODEC); |
945 state_ = WAITING_FOR_CODEC; | 974 state_ = WAITING_FOR_CODEC; |
946 | 975 |
947 ReleaseCodec(); | 976 ReleaseCodec(); |
948 | 977 |
949 base::Optional<TaskType> task_type = | 978 base::Optional<TaskType> task_type = |
950 codec_allocator_->TaskTypeForAllocation(); | 979 codec_allocator_->TaskTypeForAllocation(); |
951 if (!task_type) { | 980 if (!task_type) { |
952 // If there is no free thread, then just fail. | 981 // If there is no free thread, then just fail. |
953 OnCodecConfigured(nullptr); | 982 OnCodecConfigured(nullptr, nullptr); |
954 return; | 983 return; |
955 } | 984 } |
956 | 985 |
957 // If autodetection is disallowed, fall back to Chrome's software decoders | 986 // If autodetection is disallowed, fall back to Chrome's software decoders |
958 // instead of using the software decoders provided by MediaCodec. | 987 // instead of using the software decoders provided by MediaCodec. |
959 if (task_type == TaskType::SW_CODEC && | 988 if (task_type == TaskType::SW_CODEC && |
960 IsMediaCodecSoftwareDecodingForbidden()) { | 989 IsMediaCodecSoftwareDecodingForbidden()) { |
961 OnCodecConfigured(nullptr); | 990 OnCodecConfigured(nullptr, nullptr); |
962 return; | 991 return; |
963 } | 992 } |
964 | 993 |
965 codec_config_->task_type = task_type.value(); | 994 codec_config_->task_type = task_type.value(); |
966 codec_allocator_->CreateMediaCodecAsync(weak_this_factory_.GetWeakPtr(), | 995 codec_allocator_->CreateMediaCodecAsync(weak_this_factory_.GetWeakPtr(), |
967 codec_config_); | 996 codec_config_); |
968 } | 997 } |
969 | 998 |
970 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecSynchronously() { | 999 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecSynchronously() { |
971 DCHECK(thread_checker_.CalledOnValidThread()); | 1000 DCHECK(thread_checker_.CalledOnValidThread()); |
972 DCHECK(!media_codec_); | 1001 DCHECK(!media_codec_); |
973 DCHECK_NE(state_, WAITING_FOR_CODEC); | 1002 DCHECK_NE(state_, WAITING_FOR_CODEC); |
974 state_ = WAITING_FOR_CODEC; | 1003 state_ = WAITING_FOR_CODEC; |
975 | 1004 |
976 base::Optional<TaskType> task_type = | 1005 base::Optional<TaskType> task_type = |
977 codec_allocator_->TaskTypeForAllocation(); | 1006 codec_allocator_->TaskTypeForAllocation(); |
978 if (!task_type) { | 1007 if (!task_type) { |
979 // If there is no free thread, then just fail. | 1008 // If there is no free thread, then just fail. |
980 OnCodecConfigured(nullptr); | 1009 OnCodecConfigured(nullptr, nullptr); |
981 return; | 1010 return; |
982 } | 1011 } |
983 | 1012 |
984 codec_config_->task_type = task_type.value(); | 1013 codec_config_->task_type = task_type.value(); |
985 std::unique_ptr<VideoCodecBridge> media_codec = | 1014 std::unique_ptr<VideoCodecBridge> media_codec = |
986 codec_allocator_->CreateMediaCodecSync(codec_config_); | 1015 codec_allocator_->CreateMediaCodecSync(codec_config_); |
987 // Note that |media_codec| might be null, which will NotifyError. | 1016 // Note that |media_codec| might be null, which will NotifyError. |
988 OnCodecConfigured(std::move(media_codec)); | 1017 OnCodecConfigured(codec_config_, std::move(media_codec)); |
989 } | 1018 } |
990 | 1019 |
991 void AndroidVideoDecodeAccelerator::OnCodecConfigured( | 1020 void AndroidVideoDecodeAccelerator::OnCodecConfigured( |
1021 scoped_refptr<CodecConfig> codec_config, | |
992 std::unique_ptr<VideoCodecBridge> media_codec) { | 1022 std::unique_ptr<VideoCodecBridge> media_codec) { |
993 DCHECK(thread_checker_.CalledOnValidThread()); | 1023 DCHECK(thread_checker_.CalledOnValidThread()); |
994 DCHECK(state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED); | 1024 DCHECK(state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED); |
1025 // We don't use |codec_config|. It's present only in case the callback | |
1026 // fails, so that |overlay| will be dropped on the right thread if it's the | |
1027 // last reference. | |
995 | 1028 |
996 // If we are supposed to notify that initialization is complete, then do so | 1029 // If we are supposed to notify that initialization is complete, then do so |
997 // before returning. Otherwise, this is a reconfiguration. | 1030 // before returning. Otherwise, this is a reconfiguration. |
998 | 1031 |
999 // If |state_| changed to SURFACE_DESTROYED while we were configuring a codec, | 1032 // If |state_| changed to SURFACE_DESTROYED while we were configuring a codec, |
1000 // then the codec is already invalid so we return early and drop it. | 1033 // then the codec is already invalid so we return early and drop it. |
1001 // TODO(liberato): We're going to drop the codec when |media_codec| goes out | 1034 // TODO(liberato): We're going to drop the codec when |media_codec| goes out |
1002 // of scope, on this thread. We really should post it to the proper thread | 1035 // of scope, on this thread. We really should post it to the proper thread |
1003 // to avoid potentially hanging. | 1036 // to avoid potentially hanging. |
1004 if (state_ == SURFACE_DESTROYED) { | 1037 if (state_ == SURFACE_DESTROYED) { |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1129 // Flush the codec if possible, or create a new one if not. | 1162 // Flush the codec if possible, or create a new one if not. |
1130 if (!MediaCodecUtil::CodecNeedsFlushWorkaround(media_codec_.get())) { | 1163 if (!MediaCodecUtil::CodecNeedsFlushWorkaround(media_codec_.get())) { |
1131 DVLOG(3) << __func__ << " Flushing MediaCodec."; | 1164 DVLOG(3) << __func__ << " Flushing MediaCodec."; |
1132 media_codec_->Flush(); | 1165 media_codec_->Flush(); |
1133 // Since we just flushed all the output buffers, make sure that nothing is | 1166 // Since we just flushed all the output buffers, make sure that nothing is |
1134 // using them. | 1167 // using them. |
1135 picture_buffer_manager_.CodecChanged(media_codec_.get()); | 1168 picture_buffer_manager_.CodecChanged(media_codec_.get()); |
1136 } else { | 1169 } else { |
1137 DVLOG(3) << __func__ << " Deleting the MediaCodec and creating a new one."; | 1170 DVLOG(3) << __func__ << " Deleting the MediaCodec and creating a new one."; |
1138 GetManager()->StopTimer(this); | 1171 GetManager()->StopTimer(this); |
1172 // Note that this will release the codec, then allocate a new one. It will | |
1173 // not wait for the old one to finish up with the surface, which is bad. | |
1174 // It works (usually) because it ends up allocating the codec on the same | |
1175 // thread as is used to release the old one, so it's serialized anyway. | |
1139 ConfigureMediaCodecAsynchronously(); | 1176 ConfigureMediaCodecAsynchronously(); |
1140 } | 1177 } |
1141 } | 1178 } |
1142 | 1179 |
1143 void AndroidVideoDecodeAccelerator::Reset() { | 1180 void AndroidVideoDecodeAccelerator::Reset() { |
1144 DVLOG(1) << __func__; | 1181 DVLOG(1) << __func__; |
1145 DCHECK(thread_checker_.CalledOnValidThread()); | 1182 DCHECK(thread_checker_.CalledOnValidThread()); |
1146 TRACE_EVENT0("media", "AVDA::Reset"); | 1183 TRACE_EVENT0("media", "AVDA::Reset"); |
1147 | 1184 |
1148 if (defer_surface_creation_) { | 1185 if (defer_surface_creation_) { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1205 DVLOG(1) << __func__; | 1242 DVLOG(1) << __func__; |
1206 DCHECK(thread_checker_.CalledOnValidThread()); | 1243 DCHECK(thread_checker_.CalledOnValidThread()); |
1207 | 1244 |
1208 // Note that async codec construction might still be in progress. In that | 1245 // Note that async codec construction might still be in progress. In that |
1209 // case, the codec will be deleted when it completes once we invalidate all | 1246 // case, the codec will be deleted when it completes once we invalidate all |
1210 // our weak refs. | 1247 // our weak refs. |
1211 weak_this_factory_.InvalidateWeakPtrs(); | 1248 weak_this_factory_.InvalidateWeakPtrs(); |
1212 GetManager()->StopTimer(this); | 1249 GetManager()->StopTimer(this); |
1213 ReleaseCodec(); | 1250 ReleaseCodec(); |
1214 | 1251 |
1215 // We no longer care about |surface_id|, in case we did before. It's okay | 1252 // If we own |surface_id|, then we'll delete it when |codec_config_| goes |
1216 // if we have no surface and/or weren't the owner or a waiter. | 1253 // out of scope. That might be after an in-progress async config completes. |
1217 codec_allocator_->DeallocateSurface(this, config_.surface_id); | |
1218 | 1254 |
1219 // Hop the SurfaceTexture release call through the task runner used last time | 1255 // Hop the SurfaceTexture release call through the task runner used last time |
1220 // we released a codec. This ensures that we release the surface texture after | 1256 // we released a codec. This ensures that we release the surface texture after |
1221 // the codec it's attached to (if any) is released. It's not sufficient to use | 1257 // the codec it's attached to (if any) is released. It's not sufficient to use |
1222 // |codec_config_->task_type| because that might have changed since we | 1258 // |codec_config_->task_type| because that might have changed since we |
1223 // released the codec this surface was attached to. | 1259 // released the codec this surface was attached to. |
1224 if (codec_config_->surface_texture) { | 1260 if (codec_config_->surface_texture) { |
1225 codec_allocator_->TaskRunnerFor(last_release_task_type_) | 1261 codec_allocator_->TaskRunnerFor(last_release_task_type_) |
1226 ->PostTaskAndReply( | 1262 ->PostTaskAndReply( |
1227 FROM_HERE, base::Bind(&base::DoNothing), | 1263 FROM_HERE, base::Bind(&base::DoNothing), |
(...skipping 17 matching lines...) Expand all Loading... | |
1245 base::WeakPtr<gpu::gles2::GLES2Decoder> | 1281 base::WeakPtr<gpu::gles2::GLES2Decoder> |
1246 AndroidVideoDecodeAccelerator::GetGlDecoder() const { | 1282 AndroidVideoDecodeAccelerator::GetGlDecoder() const { |
1247 return get_gles2_decoder_cb_.Run(); | 1283 return get_gles2_decoder_cb_.Run(); |
1248 } | 1284 } |
1249 | 1285 |
1250 void AndroidVideoDecodeAccelerator::OnSurfaceDestroyed() { | 1286 void AndroidVideoDecodeAccelerator::OnSurfaceDestroyed() { |
1251 DVLOG(1) << __func__; | 1287 DVLOG(1) << __func__; |
1252 TRACE_EVENT0("media", "AVDA::OnSurfaceDestroyed"); | 1288 TRACE_EVENT0("media", "AVDA::OnSurfaceDestroyed"); |
1253 DCHECK(thread_checker_.CalledOnValidThread()); | 1289 DCHECK(thread_checker_.CalledOnValidThread()); |
1254 | 1290 |
1255 // We cannot get here if we're before surface allocation, since we transition | 1291 // If we're notified that the overlay is destroyed while we're waiting for a |
1256 // to WAITING_FOR_CODEC (or NO_ERROR, if sync) when we get the surface without | 1292 // surface from it, then we could just switch back to SurfaceTexture. For |
1257 // posting. If we do ever lose the surface before starting codec allocation, | 1293 // now, we just fail. |
1258 // then we could just update the config to use a SurfaceTexture and return | 1294 if (state_ == WAITING_FOR_SURFACE) { |
1259 // without changing state. | 1295 NOTIFY_ERROR(PLATFORM_FAILURE, "Surface is not available"); |
1260 DCHECK_NE(state_, WAITING_FOR_SURFACE); | 1296 return; |
1297 } | |
1261 | 1298 |
1262 // If the API is available avoid having to restart the decoder in order to | 1299 // If the API is available avoid having to restart the decoder in order to |
1263 // leave fullscreen. If we don't clear the surface immediately during this | 1300 // leave fullscreen. If we don't clear the surface immediately during this |
1264 // callback, the MediaCodec will throw an error as the surface is destroyed. | 1301 // callback, the MediaCodec will throw an error as the surface is destroyed. |
1265 if (base::android::BuildInfo::GetInstance()->sdk_int() >= 23) { | 1302 if (base::android::BuildInfo::GetInstance()->sdk_int() >= 23) { |
1266 // Since we can't wait for a transition, we must invalidate all outstanding | 1303 // Since we can't wait for a transition, we must invalidate all outstanding |
1267 // picture buffers to avoid putting the GL system in a broken state. | 1304 // picture buffers to avoid putting the GL system in a broken state. |
1268 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_); | 1305 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_); |
1269 | 1306 |
1270 // Switch away from the surface being destroyed to a surface texture. | 1307 // Switch away from the surface being destroyed to a surface texture. |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1551 pending_surface_id_.value() == SurfaceManager::kNoSurfaceID); | 1588 pending_surface_id_.value() == SurfaceManager::kNoSurfaceID); |
1552 | 1589 |
1553 const int previous_surface_id = config_.surface_id; | 1590 const int previous_surface_id = config_.surface_id; |
1554 const int new_surface_id = pending_surface_id_.value(); | 1591 const int new_surface_id = pending_surface_id_.value(); |
1555 pending_surface_id_.reset(); | 1592 pending_surface_id_.reset(); |
1556 | 1593 |
1557 // Start surface creation. Note that if we're called via surfaceDestroyed, | 1594 // Start surface creation. Note that if we're called via surfaceDestroyed, |
1558 // then this must complete synchronously or it will DCHECK. Otherwise, we | 1595 // then this must complete synchronously or it will DCHECK. Otherwise, we |
1559 // might still be using the destroyed surface. We don't enforce this, but | 1596 // might still be using the destroyed surface. We don't enforce this, but |
1560 // it's worth remembering that there are cases where it's required. | 1597 // it's worth remembering that there are cases where it's required. |
1598 | |
1599 // Regardless of whether we succeed, we will no longer own the previous | |
1600 // surface, if any, when we return. |previous_overlay| will be dropped then. | |
1601 std::unique_ptr<AndroidOverlay> previous_overlay = | |
1602 std::move(codec_config_->overlay); | |
1603 | |
1561 config_.surface_id = new_surface_id; | 1604 config_.surface_id = new_surface_id; |
1562 StartSurfaceCreation(); | 1605 StartSurfaceCreation(); |
1563 if (state_ == ERROR) { | 1606 if (state_ == ERROR) { |
1564 // This might be called from OnSurfaceDestroyed(), so we have to release the | 1607 // This might be called from OnSurfaceDestroyed(), so we have to release the |
1565 // MediaCodec if we failed to switch the surface. We reset the surface ID | 1608 // MediaCodec if we failed to switch the surface. We reset the surface ID |
1566 // to the previous one, since failures never result in the codec using the | 1609 // to the previous one, since failures never result in the codec using the |
1567 // new surface. This is only guaranteed because of how OnCodecConfigured | 1610 // new surface. This is only guaranteed because of how OnCodecConfigured |
1568 // works. If it could fail after getting a codec, then this assumption | 1611 // works. If it could fail after getting a codec, then this assumption |
1569 // wouldn't be necessarily true anymore. | 1612 // wouldn't be necessarily true anymore. |
1570 // Also note that we might not have switched surfaces yet, which is also bad | 1613 // Also note that we might not have switched surfaces yet, which is also bad |
1571 // for OnSurfaceDestroyed, because of WAITING_FOR_SURFACE. Shouldn't | 1614 // for OnSurfaceDestroyed, because of WAITING_FOR_SURFACE. Shouldn't |
1572 // happen with SurfaceTexture, and OnSurfaceDestroyed checks for it. | 1615 // happen with SurfaceTexture, and OnSurfaceDestroyed checks for it. |
1573 config_.surface_id = previous_surface_id; | 1616 config_.surface_id = previous_surface_id; |
1574 ReleaseCodec(); | 1617 ReleaseCodec(); |
1575 codec_allocator_->DeallocateSurface(this, new_surface_id); | 1618 // For CVV, this is the right thing to do, since dropping |overlay| doesn't |
1619 // really destroy the surface. However, for DS, we'll want to post it in | |
1620 // ReleaseCodec in this case since the codec is still using it. | |
1621 codec_config_->overlay = nullptr; | |
1576 } | 1622 } |
1577 | 1623 |
1578 // Regardless of whether we succeeded, we no longer own the previous surface. | |
1579 codec_allocator_->DeallocateSurface(this, previous_surface_id); | |
1580 | |
1581 return state_ != ERROR; | 1624 return state_ != ERROR; |
1582 } | 1625 } |
1583 | 1626 |
1584 void AndroidVideoDecodeAccelerator::ReleaseCodec() { | 1627 void AndroidVideoDecodeAccelerator::ReleaseCodec() { |
1585 if (!media_codec_) | 1628 if (!media_codec_) |
1586 return; | 1629 return; |
1587 | 1630 |
1588 picture_buffer_manager_.CodecChanged(nullptr); | 1631 picture_buffer_manager_.CodecChanged(nullptr); |
1589 codec_allocator_->ReleaseMediaCodec( | 1632 codec_allocator_->ReleaseMediaCodec( |
1590 std::move(media_codec_), codec_config_->task_type, config_.surface_id); | 1633 std::move(media_codec_), codec_config_->task_type, config_.surface_id); |
1591 last_release_task_type_ = codec_config_->task_type; | 1634 last_release_task_type_ = codec_config_->task_type; |
1592 } | 1635 } |
1593 | 1636 |
1594 } // namespace media | 1637 } // namespace media |
OLD | NEW |