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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 105 | 105 |
| 106 constexpr base::TimeDelta NoWaitTimeOut = base::TimeDelta::FromMicroseconds(0); | 106 constexpr base::TimeDelta NoWaitTimeOut = base::TimeDelta::FromMicroseconds(0); |
| 107 | 107 |
| 108 constexpr base::TimeDelta IdleTimerTimeOut = base::TimeDelta::FromSeconds(1); | 108 constexpr base::TimeDelta IdleTimerTimeOut = base::TimeDelta::FromSeconds(1); |
| 109 | 109 |
| 110 // On low end devices (< KitKat is always low-end due to buggy MediaCodec), | 110 // On low end devices (< KitKat is always low-end due to buggy MediaCodec), |
| 111 // defer the surface creation until the codec is actually used if we know no | 111 // defer the surface creation until the codec is actually used if we know no |
| 112 // software fallback exists. | 112 // software fallback exists. |
| 113 bool ShouldDeferSurfaceCreation( | 113 bool ShouldDeferSurfaceCreation( |
| 114 AVDACodecAllocator* codec_allocator, | 114 AVDACodecAllocator* codec_allocator, |
| 115 int surface_id, | 115 const OverlayInfo& overlay_info, |
| 116 base::Optional<base::UnguessableToken> overlay_routing_token, | |
| 117 VideoCodec codec, | 116 VideoCodec codec, |
| 118 const AndroidVideoDecodeAccelerator::PlatformConfig& platform_config) { | 117 const AndroidVideoDecodeAccelerator::PlatformConfig& platform_config) { |
| 119 if (platform_config.force_deferred_surface_creation) | 118 if (platform_config.force_deferred_surface_creation) |
| 120 return true; | 119 return true; |
| 121 | 120 |
| 122 // TODO(liberato): We might still want to defer if we've got a routing | 121 // TODO(liberato): We might still want to defer if we've got a routing |
| 123 // token. It depends on whether we want to use it right away or not. | 122 // token. It depends on whether we want to use it right away or not. |
| 124 if (surface_id != SurfaceManager::kNoSurfaceID || overlay_routing_token) | 123 if (overlay_info.HasValidSurfaceId() || overlay_info.HasValidRoutingToken()) |
| 125 return false; | 124 return false; |
| 126 | 125 |
| 127 return codec == kCodecH264 && codec_allocator->IsAnyRegisteredAVDA() && | 126 return codec == kCodecH264 && codec_allocator->IsAnyRegisteredAVDA() && |
| 128 platform_config.sdk_int <= 18; | 127 platform_config.sdk_int <= 18; |
| 129 } | 128 } |
| 130 | 129 |
| 131 std::unique_ptr<AndroidOverlay> CreateContentVideoViewOverlay( | 130 std::unique_ptr<AndroidOverlay> CreateContentVideoViewOverlay( |
| 132 int32_t surface_id, | 131 int32_t surface_id, |
| 133 AndroidOverlayConfig config) { | 132 AndroidOverlayConfig config) { |
| 134 return base::MakeUnique<ContentVideoViewOverlay>(surface_id, | 133 return base::MakeUnique<ContentVideoViewOverlay>(surface_id, |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 351 // SetSurface() can't be called before Initialize(), so we pick up our first | 350 // SetSurface() can't be called before Initialize(), so we pick up our first |
| 352 // surface ID from the codec configuration. | 351 // surface ID from the codec configuration. |
| 353 DCHECK(!pending_surface_id_); | 352 DCHECK(!pending_surface_id_); |
| 354 | 353 |
| 355 // We signaled that we support deferred initialization, so see if the client | 354 // We signaled that we support deferred initialization, so see if the client |
| 356 // does also. | 355 // does also. |
| 357 deferred_initialization_pending_ = config.is_deferred_initialization_allowed; | 356 deferred_initialization_pending_ = config.is_deferred_initialization_allowed; |
| 358 | 357 |
| 359 // If we're low on resources, we may decide to defer creation of the surface | 358 // If we're low on resources, we may decide to defer creation of the surface |
| 360 // until the codec is actually used. | 359 // until the codec is actually used. |
| 361 if (ShouldDeferSurfaceCreation(codec_allocator_, config_.surface_id, | 360 if (ShouldDeferSurfaceCreation(codec_allocator_, config_.overlay_info, |
| 362 config_.overlay_routing_token, | |
| 363 codec_config_->codec, platform_config_)) { | 361 codec_config_->codec, platform_config_)) { |
| 364 // We should never be here if a SurfaceView is required. | 362 // We should never be here if a SurfaceView is required. |
| 365 // TODO(liberato): This really isn't true with AndroidOverlay. | 363 // TODO(liberato): This really isn't true with AndroidOverlay. |
| 366 DCHECK_EQ(config_.surface_id, SurfaceManager::kNoSurfaceID); | 364 DCHECK(!config_.overlay_info.HasValidSurfaceId()); |
| 367 defer_surface_creation_ = true; | 365 defer_surface_creation_ = true; |
| 368 } | 366 } |
| 369 | 367 |
| 370 if (!codec_allocator_->StartThread(this)) { | 368 if (!codec_allocator_->StartThread(this)) { |
| 371 LOG(ERROR) << "Unable to start thread"; | 369 LOG(ERROR) << "Unable to start thread"; |
| 372 return false; | 370 return false; |
| 373 } | 371 } |
| 374 | 372 |
| 375 // For encrypted media, start by initializing the CDM. Otherwise, start with | 373 // For encrypted media, start by initializing the CDM. Otherwise, start with |
| 376 // the surface. | 374 // the surface. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 408 // | 406 // |
| 409 // Also note that we might choose to defer surface creation for the sync path, | 407 // Also note that we might choose to defer surface creation for the sync path, |
| 410 // which won't get here. We'll exit above, successfully, during init, and | 408 // which won't get here. We'll exit above, successfully, during init, and |
| 411 // will fall through to the below when Decode calls us back. That's okay. | 409 // will fall through to the below when Decode calls us back. That's okay. |
| 412 // We only handle this case specially since |surface_chooser_| is allowed to | 410 // We only handle this case specially since |surface_chooser_| is allowed to |
| 413 // post callbacks to us. Here, we guarantee that the sync case is actually | 411 // post callbacks to us. Here, we guarantee that the sync case is actually |
| 414 // resolved synchronously. The only exception will be if we need to defer | 412 // resolved synchronously. The only exception will be if we need to defer |
| 415 // surface creation for other reasons, in which case the sync path with just | 413 // surface creation for other reasons, in which case the sync path with just |
| 416 // signal success optimistically. | 414 // signal success optimistically. |
| 417 if (during_initialize_ && !deferred_initialization_pending_) { | 415 if (during_initialize_ && !deferred_initialization_pending_) { |
| 418 DCHECK_EQ(config_.surface_id, SurfaceManager::kNoSurfaceID); | 416 DCHECK(!config_.overlay_info.HasValidSurfaceId()); |
| 419 DCHECK(!config_.overlay_routing_token); | 417 DCHECK(!config_.overlay_info.HasValidRoutingToken()); |
| 420 OnSurfaceTransition(nullptr); | 418 OnSurfaceTransition(nullptr); |
| 421 return; | 419 return; |
| 422 } | 420 } |
| 423 | 421 |
| 424 // If we have a surface, then notify |surface_chooser_| about it. | 422 // If we have a surface, then notify |surface_chooser_| about it. If we were |
| 423 // told not to use an overlay (kNoSurfaceID or a null routing token), then we | |
| 424 // leave the factory blank. | |
| 425 AndroidOverlayFactoryCB factory; | 425 AndroidOverlayFactoryCB factory; |
| 426 if (config_.surface_id != SurfaceManager::kNoSurfaceID) | 426 if (config_.overlay_info.HasValidSurfaceId()) { |
| 427 factory = base::Bind(&CreateContentVideoViewOverlay, config_.surface_id); | 427 factory = base::Bind(&CreateContentVideoViewOverlay, |
| 428 else if (config_.overlay_routing_token && overlay_factory_cb_) | 428 *config_.overlay_info.surface_id); |
| 429 factory = base::Bind(overlay_factory_cb_, *config_.overlay_routing_token); | 429 } else if (config_.overlay_info.HasValidRoutingToken() && |
| 430 overlay_factory_cb_) { | |
| 431 factory = | |
| 432 base::Bind(overlay_factory_cb_, **config_.overlay_info.routing_token); | |
| 433 } | |
| 430 | 434 |
| 431 // Notify |surface_chooser_| that we've started. This guarantees that we'll | 435 // Notify |surface_chooser_| that we've started. This guarantees that we'll |
| 432 // get a callback. It might not be a synchronous callback, but we're not in | 436 // get a callback. It might not be a synchronous callback, but we're not in |
| 433 // the synchronous case. It will be soon, though. For pre-M, we rely on the | 437 // the synchronous case. It will be soon, though. For pre-M, we rely on the |
| 434 // fact that |surface_chooser_| won't tell us to use a SurfaceTexture while | 438 // fact that |surface_chooser_| won't tell us to use a SurfaceTexture while |
| 435 // waiting for an overlay to become ready, for example. | 439 // waiting for an overlay to become ready, for example. |
| 436 surface_chooser_->Initialize( | 440 surface_chooser_->Initialize( |
| 437 base::Bind(&AndroidVideoDecodeAccelerator::OnSurfaceTransition, | 441 base::Bind(&AndroidVideoDecodeAccelerator::OnSurfaceTransition, |
| 438 weak_this_factory_.GetWeakPtr()), | 442 weak_this_factory_.GetWeakPtr()), |
| 439 base::Bind(&AndroidVideoDecodeAccelerator::OnSurfaceTransition, | 443 base::Bind(&AndroidVideoDecodeAccelerator::OnSurfaceTransition, |
| (...skipping 802 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1242 weak_this_factory_.GetWeakPtr(), bitstream_buffer_id)); | 1246 weak_this_factory_.GetWeakPtr(), bitstream_buffer_id)); |
| 1243 } | 1247 } |
| 1244 } | 1248 } |
| 1245 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 0); | 1249 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 0); |
| 1246 bitstreams_notified_in_advance_.clear(); | 1250 bitstreams_notified_in_advance_.clear(); |
| 1247 | 1251 |
| 1248 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_); | 1252 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_); |
| 1249 StartCodecDrain(DRAIN_FOR_RESET); | 1253 StartCodecDrain(DRAIN_FOR_RESET); |
| 1250 } | 1254 } |
| 1251 | 1255 |
| 1252 void AndroidVideoDecodeAccelerator::SetSurface( | 1256 void AndroidVideoDecodeAccelerator::SetOverlayInfo( |
| 1253 int32_t surface_id, | 1257 const OverlayInfo& overlay_info) { |
| 1254 const base::Optional<base::UnguessableToken>& routing_token) { | |
| 1255 DVLOG(1) << __func__; | 1258 DVLOG(1) << __func__; |
| 1256 DCHECK(thread_checker_.CalledOnValidThread()); | 1259 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1257 | 1260 |
| 1258 // It's possible that we'll receive a SetSurface before initializing the | 1261 // It's possible that we'll receive a SetSurface before initializing the |
|
watk
2017/05/25 18:09:36
"SetSurface"
liberato (no reviews please)
2017/05/25 21:26:56
Done.
| |
| 1259 // surface chooser. For example, if we defer surface creation, then we'll | 1262 // surface chooser. For example, if we defer surface creation, then we'll |
| 1260 // signal success to WMPI before initializing it. WMPI is free to change the | 1263 // signal success to WMPI before initializing it. WMPI is free to change the |
| 1261 // surface. In this case, just pretend that |surface_id| is the initial one. | 1264 // surface. In this case, just pretend that |surface_id| is the initial one. |
|
watk
2017/05/25 18:09:36
"surface_id"
liberato (no reviews please)
2017/05/25 21:26:56
done, reworked the comment a bit.
| |
| 1262 if (state_ == BEFORE_OVERLAY_INIT) { | 1265 if (state_ == BEFORE_OVERLAY_INIT) { |
| 1263 config_.surface_id = surface_id; | 1266 config_.overlay_info.MergeWith(overlay_info); |
| 1264 config_.overlay_routing_token = routing_token; | |
| 1265 return; | 1267 return; |
| 1266 } | 1268 } |
| 1267 | 1269 |
| 1270 int32_t surface_id = SurfaceManager::kNoSurfaceID; | |
| 1271 OverlayInfo::RoutingToken routing_token; | |
| 1272 | |
| 1273 // Note that these may be present, but still not OverlayInfo::HasValid...(), | |
| 1274 // since they may be set to kNoSurfaceID / no token. In those cases, we still | |
| 1275 // want to continue, and revoke the factory. | |
| 1276 if (overlay_info.surface_id) | |
| 1277 surface_id = *overlay_info.surface_id; | |
| 1278 else if (overlay_info.routing_token) | |
| 1279 routing_token = *overlay_info.routing_token; | |
| 1280 else | |
| 1281 return; | |
| 1282 | |
| 1268 AndroidOverlayFactoryCB factory; | 1283 AndroidOverlayFactoryCB factory; |
| 1269 if (routing_token && overlay_factory_cb_) { | 1284 if (routing_token && overlay_factory_cb_) |
| 1270 factory = base::Bind(overlay_factory_cb_, *routing_token); | 1285 factory = base::Bind(overlay_factory_cb_, *routing_token); |
| 1271 } else if (surface_id != SurfaceManager::kNoSurfaceID) { | 1286 else if (surface_id != SurfaceManager::kNoSurfaceID) |
| 1272 factory = base::Bind(&CreateContentVideoViewOverlay, surface_id); | 1287 factory = base::Bind(&CreateContentVideoViewOverlay, surface_id); |
| 1273 } | |
| 1274 | 1288 |
| 1275 surface_chooser_->ReplaceOverlayFactory(std::move(factory)); | 1289 surface_chooser_->ReplaceOverlayFactory(std::move(factory)); |
| 1276 } | 1290 } |
| 1277 | 1291 |
| 1278 void AndroidVideoDecodeAccelerator::Destroy() { | 1292 void AndroidVideoDecodeAccelerator::Destroy() { |
| 1279 DVLOG(1) << __func__; | 1293 DVLOG(1) << __func__; |
| 1280 DCHECK(thread_checker_.CalledOnValidThread()); | 1294 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1281 | 1295 |
| 1282 picture_buffer_manager_.Destroy(output_picture_buffers_); | 1296 picture_buffer_manager_.Destroy(output_picture_buffers_); |
| 1283 client_ = nullptr; | 1297 client_ = nullptr; |
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1692 codec_allocator_->ReleaseMediaCodec(std::move(media_codec_), | 1706 codec_allocator_->ReleaseMediaCodec(std::move(media_codec_), |
| 1693 codec_config_->surface_bundle); | 1707 codec_config_->surface_bundle); |
| 1694 } | 1708 } |
| 1695 | 1709 |
| 1696 void AndroidVideoDecodeAccelerator::ReleaseCodecAndBundle() { | 1710 void AndroidVideoDecodeAccelerator::ReleaseCodecAndBundle() { |
| 1697 ReleaseCodec(); | 1711 ReleaseCodec(); |
| 1698 codec_config_->surface_bundle = nullptr; | 1712 codec_config_->surface_bundle = nullptr; |
| 1699 } | 1713 } |
| 1700 | 1714 |
| 1701 } // namespace media | 1715 } // namespace media |
| OLD | NEW |