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

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

Issue 2692863011: Add ContentVideoViewOverlay to AVDA. (Closed)
Patch Set: keep |overlay| longer in UpdateSurface, comments Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/gpu/android_video_decode_accelerator.h" 5 #include "media/gpu/android_video_decode_accelerator.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <memory> 9 #include <memory>
10 10
(...skipping 17 matching lines...) Expand all
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698