diff --git a/libwvdrmengine/cdm/core/include/crypto_session.h b/libwvdrmengine/cdm/core/include/crypto_session.h index 747c9ec5..ee891692 100644 --- a/libwvdrmengine/cdm/core/include/crypto_session.h +++ b/libwvdrmengine/cdm/core/include/crypto_session.h @@ -300,7 +300,7 @@ class CryptoSession { CdmResponseType GetSystemIdInternal(uint32_t* system_id); CdmResponseType GenerateRsaSignature(const std::string& message, std::string* signature); - bool GetMaxSubsampleRegionSize(size_t* max); + size_t GetMaxSubsampleRegionSize(); bool SetDestinationBufferType(); @@ -429,6 +429,7 @@ class CryptoSession { static std::atomic request_id_index_source_; uint32_t api_version_; + size_t max_subsample_region_size_; // Stores the most recent error code returned from a call to // OEMCrypto_DecryptCENC. This is used to reduce the total number of diff --git a/libwvdrmengine/cdm/core/src/crypto_session.cpp b/libwvdrmengine/cdm/core/src/crypto_session.cpp index 49266886..ede25310 100644 --- a/libwvdrmengine/cdm/core/src/crypto_session.cpp +++ b/libwvdrmengine/cdm/core/src/crypto_session.cpp @@ -80,7 +80,7 @@ static_assert(ArraySize(kMaxSubsampleRegionSizes) == "The kMaxSubsampleRegionSizes table needs to be updated to " "reflect the supported range of resource rating tiers."); -constexpr size_t kDefaultMaximumChunkSize = 100 * KiB; +constexpr size_t kDefaultMaxSubsampleRegionSize = kMaxSubsampleRegionSizes[0]; // This maps a few common OEMCryptoResult to CdmResponseType. Many mappings // are not universal but are OEMCrypto method specific. Those will be @@ -217,7 +217,8 @@ CryptoSession::CryptoSession(metrics::CryptoMetrics* metrics) requested_security_level_(kLevelDefault), usage_support_type_(kUnknownUsageSupport), usage_table_header_(nullptr), - api_version_(0) { + api_version_(0), + max_subsample_region_size_(0) { assert(metrics); Init(); life_span_.Start(); @@ -1331,14 +1332,28 @@ CdmResponseType CryptoSession::GenerateRsaSignature(const std::string& message, "OEMCrypto_GenerateRSASignature"); } -bool CryptoSession::GetMaxSubsampleRegionSize(size_t* max) { - uint32_t tier = 0; - if (!GetResourceRatingTier(&tier)) return false; - // Subtract RESOURCE_RATING_TIER_MIN to get a 0-based index into the table. - const uint32_t index = tier - RESOURCE_RATING_TIER_MIN; - if (index >= ArraySize(kMaxSubsampleRegionSizes)) return false; - *max = kMaxSubsampleRegionSizes[index]; - return true; +size_t CryptoSession::GetMaxSubsampleRegionSize() { + // If we haven't cached the answer yet, fetch it from OEMCrypto. + if (max_subsample_region_size_ == 0) { + uint32_t tier = 0; + if (GetResourceRatingTier(&tier)) { + // Subtract RESOURCE_RATING_TIER_MIN to get a 0-based index into the + // table. + const uint32_t index = tier - RESOURCE_RATING_TIER_MIN; + if (index < ArraySize(kMaxSubsampleRegionSizes)) { + max_subsample_region_size_ = kMaxSubsampleRegionSizes[index]; + } + } + + // If something went wrong, use the default. + if (max_subsample_region_size_ == 0) { + LOGW("Unable to get maximum subsample region size. Defaulting to %zu.", + kDefaultMaxSubsampleRegionSize); + max_subsample_region_size_ = kDefaultMaxSubsampleRegionSize; + } + } + + return max_subsample_region_size_; } CdmResponseType CryptoSession::Decrypt( @@ -2723,12 +2738,7 @@ OEMCryptoResult CryptoSession::DecryptSample( OEMCryptoResult CryptoSession::LegacyDecrypt( const OEMCrypto_SampleDescription& sample, CdmCipherMode cipher_mode, const OEMCrypto_CENCEncryptPatternDesc& pattern) { - size_t max_chunk_size; - if (!GetMaxSubsampleRegionSize(&max_chunk_size)) { - LOGW("Unable to get maximum subsample region size. Defaulting to 100 KiB."); - max_chunk_size = kDefaultMaximumChunkSize; - } - + const size_t max_chunk_size = GetMaxSubsampleRegionSize(); OEMCryptoResult sts = OEMCrypto_ERROR_NOT_IMPLEMENTED; // We can be sure this is only called with one subsample containing one