Chromium Code Reviews| 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 |