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 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 22 matching lines...) Expand all Loading... | |
| 324 // SetSurface() can't be called before Initialize(), so we pick up our first | 324 // SetSurface() can't be called before Initialize(), so we pick up our first |
| 325 // surface ID from the codec configuration. | 325 // surface ID from the codec configuration. |
| 326 DCHECK(!pending_surface_id_); | 326 DCHECK(!pending_surface_id_); |
| 327 | 327 |
| 328 // We signaled that we support deferred initialization, so see if the client | 328 // We signaled that we support deferred initialization, so see if the client |
| 329 // does also. | 329 // does also. |
| 330 deferred_initialization_pending_ = config.is_deferred_initialization_allowed; | 330 deferred_initialization_pending_ = config.is_deferred_initialization_allowed; |
| 331 | 331 |
| 332 // If we're low on resources, we may decide to defer creation of the surface | 332 // If we're low on resources, we may decide to defer creation of the surface |
| 333 // until the codec is actually used. | 333 // until the codec is actually used. |
| 334 if (ShouldDeferSurfaceCreation(codec_allocator_, config_.surface_id, | 334 if (ShouldDeferSurfaceCreation(codec_allocator_, surface_id(), |
| 335 codec_config_->codec)) { | 335 codec_config_->codec)) { |
| 336 // We should never be here if a SurfaceView is required. | 336 // We should never be here if a SurfaceView is required. |
| 337 DCHECK_EQ(config_.surface_id, SurfaceManager::kNoSurfaceID); | 337 DCHECK_EQ(surface_id(), SurfaceManager::kNoSurfaceID); |
| 338 defer_surface_creation_ = true; | 338 defer_surface_creation_ = true; |
| 339 } | 339 } |
| 340 | 340 |
| 341 if (!codec_allocator_->StartThread(this)) { | 341 if (!codec_allocator_->StartThread(this)) { |
| 342 LOG(ERROR) << "Unable to start thread"; | 342 LOG(ERROR) << "Unable to start thread"; |
| 343 return false; | 343 return false; |
| 344 } | 344 } |
| 345 | 345 |
| 346 // For encrypted media, start by initializing the CDM. Otherwise, start with | 346 // For encrypted media, start by initializing the CDM. Otherwise, start with |
| 347 // the surface. | 347 // the surface. |
| 348 if (config_.is_encrypted()) { | 348 if (config_.is_encrypted()) { |
| 349 if (!deferred_initialization_pending_) { | 349 if (!deferred_initialization_pending_) { |
| 350 DLOG(ERROR) | 350 DLOG(ERROR) |
| 351 << "Deferred initialization must be used for encrypted streams"; | 351 << "Deferred initialization must be used for encrypted streams"; |
| 352 return false; | 352 return false; |
| 353 } | 353 } |
| 354 InitializeCdm(); | 354 InitializeCdm(); |
| 355 } else { | 355 } else { |
| 356 StartSurfaceCreation(); | 356 StartSurfaceCreation(); |
| 357 } | 357 } |
| 358 | 358 |
| 359 // Fail / complete / defer initialization. | 359 // Fail / complete / defer initialization. |
| 360 return state_ != ERROR; | 360 return state_ != ERROR; |
| 361 } | 361 } |
| 362 | 362 |
| 363 void AndroidVideoDecodeAccelerator::StartSurfaceCreation() { | 363 void AndroidVideoDecodeAccelerator::StartSurfaceCreation() { |
| 364 // We might be called during Initialize, during deferred initialization, or | 364 // We might be called during Initialize, during deferred initialization, or |
| 365 // afterwards (::Decode, for deferred surface init, UpdateSurface). | 365 // afterwards (::Decode, for deferred surface init, UpdateSurface). |
| 366 DCHECK(incoming_bundle_); | |
| 366 | 367 |
| 367 // If surface creation is deferred, then do nothing except signal that init | 368 // 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, | 369 // 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 | 370 // 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 | 371 // 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 | 372 // wrong, then decoding might fail when we might have been able to use a |
| 372 // fallback renderer in WMPI if we failed init. | 373 // fallback renderer in WMPI if we failed init. |
| 373 if (defer_surface_creation_) { | 374 if (defer_surface_creation_) { |
| 374 if (deferred_initialization_pending_) | 375 if (deferred_initialization_pending_) |
| 375 NotifyInitializationSucceeded(); | 376 NotifyInitializationSucceeded(); |
| 376 | 377 |
| 377 return; | 378 return; |
| 378 } | 379 } |
| 379 | 380 |
| 380 if (!codec_allocator_->AllocateSurface(this, config_.surface_id)) { | 381 if (!codec_allocator_->AllocateSurface(this, incoming_bundle_->surface_id)) { |
| 381 // We have to wait for some other AVDA instance to free up the surface. | 382 // We have to wait for some other AVDA instance to free up the surface. |
| 382 // OnSurfaceAvailable will be called when it's available. | 383 // OnSurfaceAvailable will be called when it's available. |
| 383 // Note that if we aren't deferring init, then we'll signal success, and | 384 // 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 | 385 // 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. | 386 // nobody that provides a SurfaceView requires sync init, it doesn't matter. |
| 386 state_ = WAITING_FOR_SURFACE; | 387 state_ = WAITING_FOR_SURFACE; |
| 387 return; | 388 return; |
| 388 } | 389 } |
| 389 | 390 |
| 390 // We now own the surface, so finish initialization. | 391 // We now own the surface, so finish initialization. |
| 391 InitializePictureBufferManager(); | 392 InitializePictureBufferManager(); |
| 392 } | 393 } |
| 393 | 394 |
| 394 void AndroidVideoDecodeAccelerator::OnSurfaceAvailable(bool success) { | 395 void AndroidVideoDecodeAccelerator::OnSurfaceAvailable(bool success) { |
| 395 DCHECK(!defer_surface_creation_); | 396 DCHECK(!defer_surface_creation_); |
| 396 DCHECK_EQ(state_, WAITING_FOR_SURFACE); | 397 DCHECK_EQ(state_, WAITING_FOR_SURFACE); |
| 398 DCHECK(incoming_bundle_); | |
| 397 | 399 |
| 398 if (!success) { | 400 if (!success) { |
| 399 NOTIFY_ERROR(PLATFORM_FAILURE, "Surface is not available"); | 401 NOTIFY_ERROR(PLATFORM_FAILURE, "Surface is not available"); |
| 402 incoming_bundle_ = nullptr; | |
| 400 return; | 403 return; |
| 401 } | 404 } |
| 402 | 405 |
| 403 InitializePictureBufferManager(); | 406 InitializePictureBufferManager(); |
| 404 } | 407 } |
| 405 | 408 |
| 406 void AndroidVideoDecodeAccelerator::InitializePictureBufferManager() { | 409 void AndroidVideoDecodeAccelerator::InitializePictureBufferManager() { |
| 407 DCHECK(!defer_surface_creation_); | 410 DCHECK(!defer_surface_creation_); |
| 411 DCHECK(incoming_bundle_); | |
| 408 | 412 |
| 409 if (!make_context_current_cb_.Run()) { | 413 if (!make_context_current_cb_.Run()) { |
| 410 NOTIFY_ERROR(PLATFORM_FAILURE, | 414 NOTIFY_ERROR(PLATFORM_FAILURE, |
| 411 "Failed to make this decoder's GL context current"); | 415 "Failed to make this decoder's GL context current"); |
| 412 return; | 416 return; |
| 413 } | 417 } |
| 414 | 418 |
| 415 codec_config_->surface = | 419 // Move |incoming_bundle_| to |codec_config_|. Our caller must set up an |
| 416 picture_buffer_manager_.Initialize(config_.surface_id); | 420 // incoming bundle properly, since we don't want to accidentally overwrite |
| 417 codec_config_->surface_texture = picture_buffer_manager_.surface_texture(); | 421 // |surface_bundle| for a codec that's being released elsewhere. |
| 418 if (codec_config_->surface.IsEmpty()) { | 422 incoming_bundle_->surface = picture_buffer_manager_.Initialize(surface_id()); |
| 423 incoming_bundle_->surface_texture = picture_buffer_manager_.surface_texture(); | |
| 424 if (incoming_bundle_->surface.IsEmpty()) { | |
| 419 NOTIFY_ERROR(PLATFORM_FAILURE, "Codec surface is empty"); | 425 NOTIFY_ERROR(PLATFORM_FAILURE, "Codec surface is empty"); |
| 426 incoming_bundle_ = nullptr; | |
| 420 return; | 427 return; |
| 421 } | 428 } |
| 422 | 429 |
| 423 // If we have a media codec, then setSurface. If that doesn't work, then we | 430 // 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. | 431 // 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. | 432 // If we get here with a codec, then we must setSurface. |
| 426 if (media_codec_) { | 433 if (media_codec_) { |
| 427 // TODO(liberato): fail on api check? | 434 // TODO(liberato): fail on api check? |
| 428 if (!media_codec_->SetSurface(codec_config_->surface.j_surface().obj())) { | 435 if (!media_codec_->SetSurface( |
| 436 incoming_bundle_->surface.j_surface().obj())) { | |
| 429 NOTIFY_ERROR(PLATFORM_FAILURE, "MediaCodec failed to switch surfaces."); | 437 NOTIFY_ERROR(PLATFORM_FAILURE, "MediaCodec failed to switch surfaces."); |
| 438 // We're not going to use |incoming_bundle_|. | |
| 439 } else { | |
| 440 // We've switched surfaces, so replace |surface_bundle|. | |
| 441 codec_config_->surface_bundle = incoming_bundle_; | |
| 442 state_ = NO_ERROR; | |
|
watk
2017/02/22 20:38:55
I don't think we should be changing state_ here?
liberato (no reviews please)
2017/02/23 18:18:46
it can be WAITING_FOR_SURFACE if it came through O
| |
| 430 } | 443 } |
| 444 incoming_bundle_ = nullptr; | |
| 431 return; | 445 return; |
| 432 } | 446 } |
| 433 | 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 | |
| 434 // If the client doesn't support deferred initialization (WebRTC), then we | 456 // 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 | 457 // 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 | 458 // 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 | 459 // 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 | 460 // not to start codec config if we have to wait for the cdm. It's somewhat |
| 439 // clearer for us to handle both cases. | 461 // clearer for us to handle both cases. |
| 440 // 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 |
| 441 // 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 |
| 442 // |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 |
| 443 // 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... | |
| 1171 bitstreams_notified_in_advance_.clear(); | 1193 bitstreams_notified_in_advance_.clear(); |
| 1172 | 1194 |
| 1173 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_); | 1195 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_); |
| 1174 StartCodecDrain(DRAIN_FOR_RESET); | 1196 StartCodecDrain(DRAIN_FOR_RESET); |
| 1175 } | 1197 } |
| 1176 | 1198 |
| 1177 void AndroidVideoDecodeAccelerator::SetSurface(int32_t surface_id) { | 1199 void AndroidVideoDecodeAccelerator::SetSurface(int32_t surface_id) { |
| 1178 DVLOG(1) << __func__; | 1200 DVLOG(1) << __func__; |
| 1179 DCHECK(thread_checker_.CalledOnValidThread()); | 1201 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1180 | 1202 |
| 1181 if (surface_id == config_.surface_id) { | 1203 if (surface_id == this->surface_id()) { |
|
watk
2017/02/22 20:38:55
remove this->
liberato (no reviews please)
2017/02/23 18:18:46
can't. |surface_id| shadows the method.
| |
| 1182 pending_surface_id_.reset(); | 1204 pending_surface_id_.reset(); |
| 1183 return; | 1205 return; |
| 1184 } | 1206 } |
| 1185 | 1207 |
| 1186 // Surface changes never take effect immediately, they will be handled during | 1208 // Surface changes never take effect immediately, they will be handled during |
| 1187 // 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 |
| 1188 // OnSurfaceDestroyed() call. | 1210 // OnSurfaceDestroyed() call. |
| 1189 pending_surface_id_ = surface_id; | 1211 pending_surface_id_ = surface_id; |
| 1190 } | 1212 } |
| 1191 | 1213 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1207 | 1229 |
| 1208 // 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 |
| 1209 // 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 |
| 1210 // our weak refs. | 1232 // our weak refs. |
| 1211 weak_this_factory_.InvalidateWeakPtrs(); | 1233 weak_this_factory_.InvalidateWeakPtrs(); |
| 1212 GetManager()->StopTimer(this); | 1234 GetManager()->StopTimer(this); |
| 1213 ReleaseCodec(); | 1235 ReleaseCodec(); |
| 1214 | 1236 |
| 1215 // 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 |
| 1216 // 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. |
| 1217 codec_allocator_->DeallocateSurface(this, config_.surface_id); | 1239 codec_allocator_->DeallocateSurface(this, surface_id()); |
|
watk
2017/02/22 20:38:55
If we have an incoming SurfaceBundle, we don't wan
liberato (no reviews please)
2017/02/23 18:18:46
having |incoming_bundle_| implies that there is no
| |
| 1218 | |
| 1219 // 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 | |
| 1221 // 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 | |
| 1223 // released the codec this surface was attached to. | |
| 1224 if (codec_config_->surface_texture) { | |
| 1225 codec_allocator_->TaskRunnerFor(last_release_task_type_) | |
| 1226 ->PostTaskAndReply( | |
| 1227 FROM_HERE, base::Bind(&base::DoNothing), | |
| 1228 base::Bind(&gl::SurfaceTexture::ReleaseSurfaceTexture, | |
| 1229 codec_config_->surface_texture)); | |
| 1230 } | |
| 1231 | 1240 |
| 1232 delete this; | 1241 delete this; |
| 1233 } | 1242 } |
| 1234 | 1243 |
| 1235 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( | 1244 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( |
| 1236 const base::WeakPtr<Client>& decode_client, | 1245 const base::WeakPtr<Client>& decode_client, |
| 1237 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { | 1246 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { |
| 1238 return false; | 1247 return false; |
| 1239 } | 1248 } |
| 1240 | 1249 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1261 | 1270 |
| 1262 // 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 |
| 1263 // 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 |
| 1264 // 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. |
| 1265 if (base::android::BuildInfo::GetInstance()->sdk_int() >= 23) { | 1274 if (base::android::BuildInfo::GetInstance()->sdk_int() >= 23) { |
| 1266 // 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 |
| 1267 // 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. |
| 1268 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_); | 1277 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_); |
| 1269 | 1278 |
| 1270 // Switch away from the surface being destroyed to a surface texture. | 1279 // Switch away from the surface being destroyed to a surface texture. |
| 1271 DCHECK_NE(config_.surface_id, SurfaceManager::kNoSurfaceID); | 1280 DCHECK_NE(surface_id(), SurfaceManager::kNoSurfaceID); |
| 1272 | 1281 |
| 1273 // The leaving fullscreen notification may come in before this point. | 1282 // The leaving fullscreen notification may come in before this point. |
| 1274 if (pending_surface_id_) | 1283 if (pending_surface_id_) |
| 1275 DCHECK_EQ(pending_surface_id_.value(), SurfaceManager::kNoSurfaceID); | 1284 DCHECK_EQ(pending_surface_id_.value(), SurfaceManager::kNoSurfaceID); |
| 1276 | 1285 |
| 1277 pending_surface_id_ = SurfaceManager::kNoSurfaceID; | 1286 pending_surface_id_ = SurfaceManager::kNoSurfaceID; |
| 1278 UpdateSurface(); | 1287 UpdateSurface(); |
| 1279 // 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, |
| 1280 // 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. |
| 1281 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... | |
| 1539 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden() | 1548 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden() |
| 1540 const { | 1549 const { |
| 1541 // Prevent MediaCodec from using its internal software decoders when we have | 1550 // Prevent MediaCodec from using its internal software decoders when we have |
| 1542 // more secure and up to date versions in the renderer process. | 1551 // more secure and up to date versions in the renderer process. |
| 1543 return !config_.is_encrypted() && (codec_config_->codec == kCodecVP8 || | 1552 return !config_.is_encrypted() && (codec_config_->codec == kCodecVP8 || |
| 1544 codec_config_->codec == kCodecVP9); | 1553 codec_config_->codec == kCodecVP9); |
| 1545 } | 1554 } |
| 1546 | 1555 |
| 1547 bool AndroidVideoDecodeAccelerator::UpdateSurface() { | 1556 bool AndroidVideoDecodeAccelerator::UpdateSurface() { |
| 1548 DCHECK(pending_surface_id_); | 1557 DCHECK(pending_surface_id_); |
| 1549 DCHECK_NE(config_.surface_id, pending_surface_id_.value()); | 1558 DCHECK_NE(surface_id(), pending_surface_id_.value()); |
| 1550 DCHECK(config_.surface_id == SurfaceManager::kNoSurfaceID || | 1559 DCHECK(surface_id() == SurfaceManager::kNoSurfaceID || |
| 1551 pending_surface_id_.value() == SurfaceManager::kNoSurfaceID); | 1560 pending_surface_id_.value() == SurfaceManager::kNoSurfaceID); |
| 1552 | 1561 |
| 1553 const int previous_surface_id = config_.surface_id; | 1562 const int previous_surface_id = surface_id(); |
| 1554 const int new_surface_id = pending_surface_id_.value(); | 1563 const int new_surface_id = pending_surface_id_.value(); |
| 1555 pending_surface_id_.reset(); | 1564 pending_surface_id_.reset(); |
| 1556 | 1565 |
| 1557 // Start surface creation. Note that if we're called via surfaceDestroyed, | 1566 // Start surface creation. Note that if we're called via surfaceDestroyed, |
| 1558 // then this must complete synchronously or it will DCHECK. Otherwise, we | 1567 // 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 | 1568 // 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. | 1569 // it's worth remembering that there are cases where it's required. |
| 1561 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); | |
| 1562 StartSurfaceCreation(); | 1572 StartSurfaceCreation(); |
| 1563 if (state_ == ERROR) { | 1573 if (state_ == ERROR) { |
| 1564 // 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 |
| 1565 // 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 |
| 1566 // 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 |
| 1567 // new surface. This is only guaranteed because of how OnCodecConfigured | 1577 // new surface. This is only guaranteed because of how OnCodecConfigured |
| 1568 // 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 |
| 1569 // wouldn't be necessarily true anymore. | 1579 // wouldn't be necessarily true anymore. |
| 1570 // 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 |
| 1571 // for OnSurfaceDestroyed, because of WAITING_FOR_SURFACE. Shouldn't | 1581 // for OnSurfaceDestroyed, because of WAITING_FOR_SURFACE. Shouldn't |
| 1572 // happen with SurfaceTexture, and OnSurfaceDestroyed checks for it. | 1582 // happen with SurfaceTexture, and OnSurfaceDestroyed checks for it. In |
| 1573 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_); | |
| 1574 ReleaseCodec(); | 1586 ReleaseCodec(); |
| 1587 // We no longer own the new surface. | |
| 1575 codec_allocator_->DeallocateSurface(this, new_surface_id); | 1588 codec_allocator_->DeallocateSurface(this, new_surface_id); |
| 1576 } | 1589 } |
| 1577 | 1590 |
| 1578 // 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 // It would be nice if the outgoing surface bundle did this. | |
| 1593 // TODO(liberato): It could, but the CVV implementation of AndroidOverlay | |
| 1594 // will do it too when the bundle holding it is dropped. We'll do it this way | |
| 1595 // until then, just to minimize changes. | |
| 1579 codec_allocator_->DeallocateSurface(this, previous_surface_id); | 1596 codec_allocator_->DeallocateSurface(this, previous_surface_id); |
| 1580 | 1597 |
| 1581 return state_ != ERROR; | 1598 return state_ != ERROR; |
| 1582 } | 1599 } |
| 1583 | 1600 |
| 1584 void AndroidVideoDecodeAccelerator::ReleaseCodec() { | 1601 void AndroidVideoDecodeAccelerator::ReleaseCodec() { |
| 1585 if (!media_codec_) | 1602 if (!media_codec_) |
| 1586 return; | 1603 return; |
| 1587 | 1604 |
| 1588 picture_buffer_manager_.CodecChanged(nullptr); | 1605 picture_buffer_manager_.CodecChanged(nullptr); |
| 1589 codec_allocator_->ReleaseMediaCodec( | 1606 codec_allocator_->ReleaseMediaCodec(std::move(media_codec_), |
| 1590 std::move(media_codec_), codec_config_->task_type, config_.surface_id); | 1607 codec_config_->task_type, |
| 1591 last_release_task_type_ = codec_config_->task_type; | 1608 codec_config_->surface_bundle); |
| 1592 } | 1609 } |
| 1593 | 1610 |
| 1594 } // namespace media | 1611 } // namespace media |
| OLD | NEW |