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