| 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 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 state_(WAITING_FOR_SURFACE), | 235 state_(WAITING_FOR_SURFACE), |
| 236 picturebuffers_requested_(false), | 236 picturebuffers_requested_(false), |
| 237 picture_buffer_manager_(this), | 237 picture_buffer_manager_(this), |
| 238 media_drm_bridge_cdm_context_(nullptr), | 238 media_drm_bridge_cdm_context_(nullptr), |
| 239 cdm_registration_id_(0), | 239 cdm_registration_id_(0), |
| 240 pending_input_buf_index_(-1), | 240 pending_input_buf_index_(-1), |
| 241 during_initialize_(false), | 241 during_initialize_(false), |
| 242 deferred_initialization_pending_(false), | 242 deferred_initialization_pending_(false), |
| 243 codec_needs_reset_(false), | 243 codec_needs_reset_(false), |
| 244 defer_surface_creation_(false), | 244 defer_surface_creation_(false), |
| 245 last_release_task_type_(TaskType::AUTO_CODEC), | |
| 246 weak_this_factory_(this) {} | 245 weak_this_factory_(this) {} |
| 247 | 246 |
| 248 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { | 247 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { |
| 249 DCHECK(thread_checker_.CalledOnValidThread()); | 248 DCHECK(thread_checker_.CalledOnValidThread()); |
| 250 GetManager()->StopTimer(this); | 249 GetManager()->StopTimer(this); |
| 251 codec_allocator_->StopThread(this); | 250 codec_allocator_->StopThread(this); |
| 252 | 251 |
| 253 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 252 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
| 254 if (!media_drm_bridge_cdm_context_) | 253 if (!media_drm_bridge_cdm_context_) |
| 255 return; | 254 return; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 282 return false; | 281 return false; |
| 283 } | 282 } |
| 284 | 283 |
| 285 DCHECK(client); | 284 DCHECK(client); |
| 286 client_ = client; | 285 client_ = client; |
| 287 config_ = config; | 286 config_ = config; |
| 288 codec_config_ = new CodecConfig(); | 287 codec_config_ = new CodecConfig(); |
| 289 codec_config_->codec = VideoCodecProfileToVideoCodec(config.profile); | 288 codec_config_->codec = VideoCodecProfileToVideoCodec(config.profile); |
| 290 codec_config_->initial_expected_coded_size = | 289 codec_config_->initial_expected_coded_size = |
| 291 config.initial_expected_coded_size; | 290 config.initial_expected_coded_size; |
| 291 incoming_bundle_ = new AVDASurfaceBundle(config_.surface_id); |
| 292 | 292 |
| 293 if (codec_config_->codec != kCodecVP8 && codec_config_->codec != kCodecVP9 && | 293 if (codec_config_->codec != kCodecVP8 && codec_config_->codec != kCodecVP9 && |
| 294 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) | 294 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) |
| 295 codec_config_->codec != kCodecHEVC && | 295 codec_config_->codec != kCodecHEVC && |
| 296 #endif | 296 #endif |
| 297 codec_config_->codec != kCodecH264) { | 297 codec_config_->codec != kCodecH264) { |
| 298 DLOG(ERROR) << "Unsupported profile: " << GetProfileName(config.profile); | 298 DLOG(ERROR) << "Unsupported profile: " << GetProfileName(config.profile); |
| 299 return false; | 299 return false; |
| 300 } | 300 } |
| 301 | 301 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 323 // SetSurface() can't be called before Initialize(), so we pick up our first | 323 // SetSurface() can't be called before Initialize(), so we pick up our first |
| 324 // surface ID from the codec configuration. | 324 // surface ID from the codec configuration. |
| 325 DCHECK(!pending_surface_id_); | 325 DCHECK(!pending_surface_id_); |
| 326 | 326 |
| 327 // We signaled that we support deferred initialization, so see if the client | 327 // We signaled that we support deferred initialization, so see if the client |
| 328 // does also. | 328 // does also. |
| 329 deferred_initialization_pending_ = config.is_deferred_initialization_allowed; | 329 deferred_initialization_pending_ = config.is_deferred_initialization_allowed; |
| 330 | 330 |
| 331 // If we're low on resources, we may decide to defer creation of the surface | 331 // If we're low on resources, we may decide to defer creation of the surface |
| 332 // until the codec is actually used. | 332 // until the codec is actually used. |
| 333 if (ShouldDeferSurfaceCreation(codec_allocator_, config_.surface_id, | 333 if (ShouldDeferSurfaceCreation(codec_allocator_, surface_id(), |
| 334 codec_config_->codec)) { | 334 codec_config_->codec)) { |
| 335 // We should never be here if a SurfaceView is required. | 335 // We should never be here if a SurfaceView is required. |
| 336 DCHECK_EQ(config_.surface_id, SurfaceManager::kNoSurfaceID); | 336 DCHECK_EQ(surface_id(), SurfaceManager::kNoSurfaceID); |
| 337 defer_surface_creation_ = true; | 337 defer_surface_creation_ = true; |
| 338 } | 338 } |
| 339 | 339 |
| 340 if (!codec_allocator_->StartThread(this)) { | 340 if (!codec_allocator_->StartThread(this)) { |
| 341 LOG(ERROR) << "Unable to start thread"; | 341 LOG(ERROR) << "Unable to start thread"; |
| 342 return false; | 342 return false; |
| 343 } | 343 } |
| 344 | 344 |
| 345 // For encrypted media, start by initializing the CDM. Otherwise, start with | 345 // For encrypted media, start by initializing the CDM. Otherwise, start with |
| 346 // the surface. | 346 // the surface. |
| 347 if (config_.is_encrypted()) { | 347 if (config_.is_encrypted()) { |
| 348 if (!deferred_initialization_pending_) { | 348 if (!deferred_initialization_pending_) { |
| 349 DLOG(ERROR) | 349 DLOG(ERROR) |
| 350 << "Deferred initialization must be used for encrypted streams"; | 350 << "Deferred initialization must be used for encrypted streams"; |
| 351 return false; | 351 return false; |
| 352 } | 352 } |
| 353 InitializeCdm(); | 353 InitializeCdm(); |
| 354 } else { | 354 } else { |
| 355 StartSurfaceCreation(); | 355 StartSurfaceCreation(); |
| 356 } | 356 } |
| 357 | 357 |
| 358 // Fail / complete / defer initialization. | 358 // Fail / complete / defer initialization. |
| 359 return state_ != ERROR; | 359 return state_ != ERROR; |
| 360 } | 360 } |
| 361 | 361 |
| 362 void AndroidVideoDecodeAccelerator::StartSurfaceCreation() { | 362 void AndroidVideoDecodeAccelerator::StartSurfaceCreation() { |
| 363 // We might be called during Initialize, during deferred initialization, or | 363 // We might be called during Initialize, during deferred initialization, or |
| 364 // afterwards (::Decode, for deferred surface init, UpdateSurface). | 364 // afterwards (::Decode, for deferred surface init, UpdateSurface). |
| 365 DCHECK(incoming_bundle_); |
| 365 | 366 |
| 366 // If surface creation is deferred, then do nothing except signal that init | 367 // If surface creation is deferred, then do nothing except signal that init |
| 367 // is complete, if needed. We might still fail to get a surface or codec, | 368 // is complete, if needed. We might still fail to get a surface or codec, |
| 368 // which would normally be an init error. Since we're deferring init until a | 369 // which would normally be an init error. Since we're deferring init until a |
| 369 // decode to save resources, though, we're signaling success now. If we're | 370 // decode to save resources, though, we're signaling success now. If we're |
| 370 // wrong, then decoding might fail when we might have been able to use a | 371 // wrong, then decoding might fail when we might have been able to use a |
| 371 // fallback renderer in WMPI if we failed init. | 372 // fallback renderer in WMPI if we failed init. |
| 372 if (defer_surface_creation_) { | 373 if (defer_surface_creation_) { |
| 373 if (deferred_initialization_pending_) | 374 if (deferred_initialization_pending_) |
| 374 NotifyInitializationSucceeded(); | 375 NotifyInitializationSucceeded(); |
| 375 | 376 |
| 376 return; | 377 return; |
| 377 } | 378 } |
| 378 | 379 |
| 379 if (!codec_allocator_->AllocateSurface(this, config_.surface_id)) { | 380 if (!codec_allocator_->AllocateSurface(this, incoming_bundle_->surface_id)) { |
| 380 // We have to wait for some other AVDA instance to free up the surface. | 381 // We have to wait for some other AVDA instance to free up the surface. |
| 381 // OnSurfaceAvailable will be called when it's available. | 382 // OnSurfaceAvailable will be called when it's available. |
| 382 // Note that if we aren't deferring init, then we'll signal success, and | 383 // Note that if we aren't deferring init, then we'll signal success, and |
| 383 // if we fail later then it will fail decoding instead. However, since | 384 // if we fail later then it will fail decoding instead. However, since |
| 384 // nobody that provides a SurfaceView requires sync init, it doesn't matter. | 385 // nobody that provides a SurfaceView requires sync init, it doesn't matter. |
| 385 state_ = WAITING_FOR_SURFACE; | 386 state_ = WAITING_FOR_SURFACE; |
| 386 return; | 387 return; |
| 387 } | 388 } |
| 388 | 389 |
| 389 // We now own the surface, so finish initialization. | 390 // We now own the surface, so finish initialization. |
| 390 InitializePictureBufferManager(); | 391 InitializePictureBufferManager(); |
| 391 } | 392 } |
| 392 | 393 |
| 393 void AndroidVideoDecodeAccelerator::OnSurfaceAvailable(bool success) { | 394 void AndroidVideoDecodeAccelerator::OnSurfaceAvailable(bool success) { |
| 394 DCHECK(!defer_surface_creation_); | 395 DCHECK(!defer_surface_creation_); |
| 395 DCHECK_EQ(state_, WAITING_FOR_SURFACE); | 396 DCHECK_EQ(state_, WAITING_FOR_SURFACE); |
| 397 DCHECK(incoming_bundle_); |
| 396 | 398 |
| 397 if (!success) { | 399 if (!success) { |
| 398 NOTIFY_ERROR(PLATFORM_FAILURE, "Surface is not available"); | 400 NOTIFY_ERROR(PLATFORM_FAILURE, "Surface is not available"); |
| 401 incoming_bundle_ = nullptr; |
| 399 return; | 402 return; |
| 400 } | 403 } |
| 401 | 404 |
| 402 InitializePictureBufferManager(); | 405 InitializePictureBufferManager(); |
| 403 } | 406 } |
| 404 | 407 |
| 405 void AndroidVideoDecodeAccelerator::InitializePictureBufferManager() { | 408 void AndroidVideoDecodeAccelerator::InitializePictureBufferManager() { |
| 406 DCHECK(!defer_surface_creation_); | 409 DCHECK(!defer_surface_creation_); |
| 410 DCHECK(incoming_bundle_); |
| 407 | 411 |
| 408 if (!make_context_current_cb_.Run()) { | 412 if (!make_context_current_cb_.Run()) { |
| 409 NOTIFY_ERROR(PLATFORM_FAILURE, | 413 NOTIFY_ERROR(PLATFORM_FAILURE, |
| 410 "Failed to make this decoder's GL context current"); | 414 "Failed to make this decoder's GL context current"); |
| 411 return; | 415 return; |
| 412 } | 416 } |
| 413 | 417 |
| 414 codec_config_->surface = | 418 // Move |incoming_bundle_| to |codec_config_|. Our caller must set up an |
| 415 picture_buffer_manager_.Initialize(config_.surface_id); | 419 // incoming bundle properly, since we don't want to accidentally overwrite |
| 416 codec_config_->surface_texture = picture_buffer_manager_.surface_texture(); | 420 // |surface_bundle| for a codec that's being released elsewhere. |
| 417 if (codec_config_->surface.IsEmpty()) { | 421 incoming_bundle_->surface = picture_buffer_manager_.Initialize(surface_id()); |
| 422 incoming_bundle_->surface_texture = picture_buffer_manager_.surface_texture(); |
| 423 if (incoming_bundle_->surface.IsEmpty()) { |
| 418 NOTIFY_ERROR(PLATFORM_FAILURE, "Codec surface is empty"); | 424 NOTIFY_ERROR(PLATFORM_FAILURE, "Codec surface is empty"); |
| 425 incoming_bundle_ = nullptr; |
| 419 return; | 426 return; |
| 420 } | 427 } |
| 421 | 428 |
| 422 // If we have a media codec, then setSurface. If that doesn't work, then we | 429 // If we have a media codec, then SetSurface. If that doesn't work, then we |
| 423 // do not try to allocate a new codec; we might not be at a keyframe, etc. | 430 // do not try to allocate a new codec; we might not be at a keyframe, etc. |
| 424 // If we get here with a codec, then we must setSurface. | 431 // If we get here with a codec, then we must setSurface. |
| 425 if (media_codec_) { | 432 if (media_codec_) { |
| 426 // TODO(liberato): fail on api check? | 433 // TODO(liberato): fail on api check? |
| 427 if (!media_codec_->SetSurface(codec_config_->surface.j_surface().obj())) { | 434 if (!media_codec_->SetSurface( |
| 435 incoming_bundle_->surface.j_surface().obj())) { |
| 428 NOTIFY_ERROR(PLATFORM_FAILURE, "MediaCodec failed to switch surfaces."); | 436 NOTIFY_ERROR(PLATFORM_FAILURE, "MediaCodec failed to switch surfaces."); |
| 437 // We're not going to use |incoming_bundle_|. |
| 438 } else { |
| 439 // We've switched surfaces, so replace |surface_bundle|. |
| 440 codec_config_->surface_bundle = incoming_bundle_; |
| 441 // We could be in WAITING_FOR_SURFACE, but we're not anymore. |
| 442 state_ = NO_ERROR; |
| 429 } | 443 } |
| 444 incoming_bundle_ = nullptr; |
| 430 return; | 445 return; |
| 431 } | 446 } |
| 432 | 447 |
| 448 // We're going to create a codec with |incoming_bundle_|. It might fail, but |
| 449 // either way, we're done with any previous bundle. Note that, since we |
| 450 // never get here after init (i.e., we never change surfaces without using |
| 451 // SetSurface), there shouldn't be any previous bundle. However, this is the |
| 452 // right thing to do even if we can switch. |
| 453 codec_config_->surface_bundle = incoming_bundle_; |
| 454 incoming_bundle_ = nullptr; |
| 455 |
| 433 // If the client doesn't support deferred initialization (WebRTC), then we | 456 // If the client doesn't support deferred initialization (WebRTC), then we |
| 434 // should complete it now and return a meaningful result. Note that it would | 457 // should complete it now and return a meaningful result. Note that it would |
| 435 // be nice if we didn't have to worry about starting codec configuration at | 458 // be nice if we didn't have to worry about starting codec configuration at |
| 436 // all (::Initialize or the wrapper can do it), but then they have to remember | 459 // all (::Initialize or the wrapper can do it), but then they have to remember |
| 437 // not to start codec config if we have to wait for the cdm. It's somewhat | 460 // not to start codec config if we have to wait for the cdm. It's somewhat |
| 438 // clearer for us to handle both cases. | 461 // clearer for us to handle both cases. |
| 439 // For this to be a case for sync configuration, we must be called from | 462 // For this to be a case for sync configuration, we must be called from |
| 440 // Initialize(), and the client must not want deferred init. Note that having | 463 // Initialize(), and the client must not want deferred init. Note that having |
| 441 // |deferred_initialization_pending_| false by itself isn't enough; if we're | 464 // |deferred_initialization_pending_| false by itself isn't enough; if we're |
| 442 // deferring surface creation, then we'll finish deferred init before asking | 465 // deferring surface creation, then we'll finish deferred init before asking |
| (...skipping 727 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1170 bitstreams_notified_in_advance_.clear(); | 1193 bitstreams_notified_in_advance_.clear(); |
| 1171 | 1194 |
| 1172 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_); | 1195 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_); |
| 1173 StartCodecDrain(DRAIN_FOR_RESET); | 1196 StartCodecDrain(DRAIN_FOR_RESET); |
| 1174 } | 1197 } |
| 1175 | 1198 |
| 1176 void AndroidVideoDecodeAccelerator::SetSurface(int32_t surface_id) { | 1199 void AndroidVideoDecodeAccelerator::SetSurface(int32_t surface_id) { |
| 1177 DVLOG(1) << __func__; | 1200 DVLOG(1) << __func__; |
| 1178 DCHECK(thread_checker_.CalledOnValidThread()); | 1201 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1179 | 1202 |
| 1180 if (surface_id == config_.surface_id) { | 1203 if (surface_id == this->surface_id()) { |
| 1181 pending_surface_id_.reset(); | 1204 pending_surface_id_.reset(); |
| 1182 return; | 1205 return; |
| 1183 } | 1206 } |
| 1184 | 1207 |
| 1185 // Surface changes never take effect immediately, they will be handled during | 1208 // Surface changes never take effect immediately, they will be handled during |
| 1186 // DequeOutput() once we get to a good switch point or immediately during an | 1209 // DequeOutput() once we get to a good switch point or immediately during an |
| 1187 // OnSurfaceDestroyed() call. | 1210 // OnSurfaceDestroyed() call. |
| 1188 pending_surface_id_ = surface_id; | 1211 pending_surface_id_ = surface_id; |
| 1189 } | 1212 } |
| 1190 | 1213 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1206 | 1229 |
| 1207 // Note that async codec construction might still be in progress. In that | 1230 // Note that async codec construction might still be in progress. In that |
| 1208 // case, the codec will be deleted when it completes once we invalidate all | 1231 // case, the codec will be deleted when it completes once we invalidate all |
| 1209 // our weak refs. | 1232 // our weak refs. |
| 1210 weak_this_factory_.InvalidateWeakPtrs(); | 1233 weak_this_factory_.InvalidateWeakPtrs(); |
| 1211 GetManager()->StopTimer(this); | 1234 GetManager()->StopTimer(this); |
| 1212 ReleaseCodec(); | 1235 ReleaseCodec(); |
| 1213 | 1236 |
| 1214 // We no longer care about |surface_id|, in case we did before. It's okay | 1237 // We no longer care about |surface_id|, in case we did before. It's okay |
| 1215 // if we have no surface and/or weren't the owner or a waiter. | 1238 // if we have no surface and/or weren't the owner or a waiter. |
| 1216 codec_allocator_->DeallocateSurface(this, config_.surface_id); | 1239 codec_allocator_->DeallocateSurface(this, surface_id()); |
| 1217 | |
| 1218 // Hop the SurfaceTexture release call through the task runner used last time | |
| 1219 // we released a codec. This ensures that we release the surface texture after | |
| 1220 // the codec it's attached to (if any) is released. It's not sufficient to use | |
| 1221 // |codec_config_->task_type| because that might have changed since we | |
| 1222 // released the codec this surface was attached to. | |
| 1223 if (codec_config_->surface_texture) { | |
| 1224 codec_allocator_->TaskRunnerFor(last_release_task_type_) | |
| 1225 ->PostTaskAndReply( | |
| 1226 FROM_HERE, base::Bind(&base::DoNothing), | |
| 1227 base::Bind(&gl::SurfaceTexture::ReleaseSurfaceTexture, | |
| 1228 codec_config_->surface_texture)); | |
| 1229 } | |
| 1230 | 1240 |
| 1231 delete this; | 1241 delete this; |
| 1232 } | 1242 } |
| 1233 | 1243 |
| 1234 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( | 1244 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( |
| 1235 const base::WeakPtr<Client>& decode_client, | 1245 const base::WeakPtr<Client>& decode_client, |
| 1236 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { | 1246 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { |
| 1237 return false; | 1247 return false; |
| 1238 } | 1248 } |
| 1239 | 1249 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1260 | 1270 |
| 1261 // If the API is available avoid having to restart the decoder in order to | 1271 // If the API is available avoid having to restart the decoder in order to |
| 1262 // leave fullscreen. If we don't clear the surface immediately during this | 1272 // leave fullscreen. If we don't clear the surface immediately during this |
| 1263 // callback, the MediaCodec will throw an error as the surface is destroyed. | 1273 // callback, the MediaCodec will throw an error as the surface is destroyed. |
| 1264 if (base::android::BuildInfo::GetInstance()->sdk_int() >= 23) { | 1274 if (base::android::BuildInfo::GetInstance()->sdk_int() >= 23) { |
| 1265 // Since we can't wait for a transition, we must invalidate all outstanding | 1275 // Since we can't wait for a transition, we must invalidate all outstanding |
| 1266 // picture buffers to avoid putting the GL system in a broken state. | 1276 // picture buffers to avoid putting the GL system in a broken state. |
| 1267 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_); | 1277 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_); |
| 1268 | 1278 |
| 1269 // Switch away from the surface being destroyed to a surface texture. | 1279 // Switch away from the surface being destroyed to a surface texture. |
| 1270 DCHECK_NE(config_.surface_id, SurfaceManager::kNoSurfaceID); | 1280 DCHECK_NE(surface_id(), SurfaceManager::kNoSurfaceID); |
| 1271 | 1281 |
| 1272 // The leaving fullscreen notification may come in before this point. | 1282 // The leaving fullscreen notification may come in before this point. |
| 1273 if (pending_surface_id_) | 1283 if (pending_surface_id_) |
| 1274 DCHECK_EQ(pending_surface_id_.value(), SurfaceManager::kNoSurfaceID); | 1284 DCHECK_EQ(pending_surface_id_.value(), SurfaceManager::kNoSurfaceID); |
| 1275 | 1285 |
| 1276 pending_surface_id_ = SurfaceManager::kNoSurfaceID; | 1286 pending_surface_id_ = SurfaceManager::kNoSurfaceID; |
| 1277 UpdateSurface(); | 1287 UpdateSurface(); |
| 1278 // Switching to a SurfaceTexture should never need to wait. If it does, | 1288 // Switching to a SurfaceTexture should never need to wait. If it does, |
| 1279 // then the codec might still be using the destroyed surface, which is bad. | 1289 // then the codec might still be using the destroyed surface, which is bad. |
| 1280 DCHECK_NE(state_, WAITING_FOR_SURFACE); | 1290 DCHECK_NE(state_, WAITING_FOR_SURFACE); |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1538 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden() | 1548 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden() |
| 1539 const { | 1549 const { |
| 1540 // Prevent MediaCodec from using its internal software decoders when we have | 1550 // Prevent MediaCodec from using its internal software decoders when we have |
| 1541 // more secure and up to date versions in the renderer process. | 1551 // more secure and up to date versions in the renderer process. |
| 1542 return !config_.is_encrypted() && (codec_config_->codec == kCodecVP8 || | 1552 return !config_.is_encrypted() && (codec_config_->codec == kCodecVP8 || |
| 1543 codec_config_->codec == kCodecVP9); | 1553 codec_config_->codec == kCodecVP9); |
| 1544 } | 1554 } |
| 1545 | 1555 |
| 1546 bool AndroidVideoDecodeAccelerator::UpdateSurface() { | 1556 bool AndroidVideoDecodeAccelerator::UpdateSurface() { |
| 1547 DCHECK(pending_surface_id_); | 1557 DCHECK(pending_surface_id_); |
| 1548 DCHECK_NE(config_.surface_id, pending_surface_id_.value()); | 1558 DCHECK_NE(surface_id(), pending_surface_id_.value()); |
| 1549 DCHECK(config_.surface_id == SurfaceManager::kNoSurfaceID || | 1559 DCHECK(surface_id() == SurfaceManager::kNoSurfaceID || |
| 1550 pending_surface_id_.value() == SurfaceManager::kNoSurfaceID); | 1560 pending_surface_id_.value() == SurfaceManager::kNoSurfaceID); |
| 1551 | 1561 |
| 1552 const int previous_surface_id = config_.surface_id; | 1562 const int previous_surface_id = surface_id(); |
| 1553 const int new_surface_id = pending_surface_id_.value(); | 1563 const int new_surface_id = pending_surface_id_.value(); |
| 1554 pending_surface_id_.reset(); | 1564 pending_surface_id_.reset(); |
| 1555 | 1565 |
| 1556 // Start surface creation. Note that if we're called via surfaceDestroyed, | 1566 // Start surface creation. Note that if we're called via surfaceDestroyed, |
| 1557 // then this must complete synchronously or it will DCHECK. Otherwise, we | 1567 // then this must complete synchronously or it will DCHECK. Otherwise, we |
| 1558 // might still be using the destroyed surface. We don't enforce this, but | 1568 // might still be using the destroyed surface. We don't enforce this, but |
| 1559 // it's worth remembering that there are cases where it's required. | 1569 // it's worth remembering that there are cases where it's required. |
| 1560 config_.surface_id = new_surface_id; | 1570 // Note that we don't re-use |surface_bundle|, since the codec is using it! |
| 1571 incoming_bundle_ = new AVDASurfaceBundle(new_surface_id); |
| 1561 StartSurfaceCreation(); | 1572 StartSurfaceCreation(); |
| 1562 if (state_ == ERROR) { | 1573 if (state_ == ERROR) { |
| 1563 // This might be called from OnSurfaceDestroyed(), so we have to release the | 1574 // This might be called from OnSurfaceDestroyed(), so we have to release the |
| 1564 // MediaCodec if we failed to switch the surface. We reset the surface ID | 1575 // MediaCodec if we failed to switch the surface. We reset the surface ID |
| 1565 // to the previous one, since failures never result in the codec using the | 1576 // to the previous one, since failures never result in the codec using the |
| 1566 // new surface. This is only guaranteed because of how OnCodecConfigured | 1577 // new surface. This is only guaranteed because of how OnCodecConfigured |
| 1567 // works. If it could fail after getting a codec, then this assumption | 1578 // works. If it could fail after getting a codec, then this assumption |
| 1568 // wouldn't be necessarily true anymore. | 1579 // wouldn't be necessarily true anymore. |
| 1569 // Also note that we might not have switched surfaces yet, which is also bad | 1580 // Also note that we might not have switched surfaces yet, which is also bad |
| 1570 // for OnSurfaceDestroyed, because of WAITING_FOR_SURFACE. Shouldn't | 1581 // for OnSurfaceDestroyed, because of WAITING_FOR_SURFACE. Shouldn't |
| 1571 // happen with SurfaceTexture, and OnSurfaceDestroyed checks for it. | 1582 // happen with SurfaceTexture, and OnSurfaceDestroyed checks for it. In |
| 1572 config_.surface_id = previous_surface_id; | 1583 // either case, we definitely should not still have an incoming bundle; it |
| 1584 // should have been dropped. |
| 1585 DCHECK(!incoming_bundle_); |
| 1573 ReleaseCodec(); | 1586 ReleaseCodec(); |
| 1587 // We no longer own the new surface. |
| 1574 codec_allocator_->DeallocateSurface(this, new_surface_id); | 1588 codec_allocator_->DeallocateSurface(this, new_surface_id); |
| 1575 } | 1589 } |
| 1576 | 1590 |
| 1577 // Regardless of whether we succeeded, we no longer own the previous surface. | 1591 // Regardless of whether we succeeded, we no longer own the previous surface. |
| 1592 // This is the only case where we start a new incoming bundle, and we maintain |
| 1593 // the property that |incoming_bundle_| is the one that we own, as documented |
| 1594 // for surface_id(). |
| 1595 // It would be nice if the outgoing surface bundle did this. |
| 1596 // TODO(liberato): It could, but the CVV implementation of AndroidOverlay |
| 1597 // will do it too when the bundle holding it is dropped. We'll do it this way |
| 1598 // until then, just to minimize changes. |
| 1578 codec_allocator_->DeallocateSurface(this, previous_surface_id); | 1599 codec_allocator_->DeallocateSurface(this, previous_surface_id); |
| 1579 | 1600 |
| 1580 return state_ != ERROR; | 1601 return state_ != ERROR; |
| 1581 } | 1602 } |
| 1582 | 1603 |
| 1583 void AndroidVideoDecodeAccelerator::ReleaseCodec() { | 1604 void AndroidVideoDecodeAccelerator::ReleaseCodec() { |
| 1584 if (!media_codec_) | 1605 if (!media_codec_) |
| 1585 return; | 1606 return; |
| 1586 | 1607 |
| 1587 picture_buffer_manager_.CodecChanged(nullptr); | 1608 picture_buffer_manager_.CodecChanged(nullptr); |
| 1588 codec_allocator_->ReleaseMediaCodec( | 1609 codec_allocator_->ReleaseMediaCodec(std::move(media_codec_), |
| 1589 std::move(media_codec_), codec_config_->task_type, config_.surface_id); | 1610 codec_config_->task_type, |
| 1590 last_release_task_type_ = codec_config_->task_type; | 1611 codec_config_->surface_bundle); |
| 1591 } | 1612 } |
| 1592 | 1613 |
| 1593 } // namespace media | 1614 } // namespace media |
| OLD | NEW |