OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 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/base/key_systems.h" | 5 #include "media/base/key_systems.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 | 10 |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 // for real key system names. Use is discouraged. | 162 // for real key system names. Use is discouraged. |
163 const char kExcludedPrefix[] = "x-"; | 163 const char kExcludedPrefix[] = "x-"; |
164 return base::StartsWith(key_system, kExcludedPrefix, | 164 return base::StartsWith(key_system, kExcludedPrefix, |
165 base::CompareCase::SENSITIVE); | 165 base::CompareCase::SENSITIVE); |
166 } | 166 } |
167 | 167 |
168 class KeySystemsImpl : public KeySystems { | 168 class KeySystemsImpl : public KeySystems { |
169 public: | 169 public: |
170 static KeySystemsImpl* GetInstance(); | 170 static KeySystemsImpl* GetInstance(); |
171 | 171 |
172 void UpdateIfNeeded(); | |
173 | |
174 std::string GetKeySystemNameForUMA(const std::string& key_system) const; | 172 std::string GetKeySystemNameForUMA(const std::string& key_system) const; |
175 | 173 |
176 bool UseAesDecryptor(const std::string& key_system) const; | 174 bool UseAesDecryptor(const std::string& key_system) const; |
177 | 175 |
178 #if BUILDFLAG(ENABLE_PEPPER_CDMS) | 176 #if BUILDFLAG(ENABLE_PEPPER_CDMS) |
179 std::string GetPepperType(const std::string& key_system) const; | 177 std::string GetPepperType(const std::string& key_system) const; |
180 #endif | 178 #endif |
181 | 179 |
182 // These two functions are for testing purpose only. | 180 // These two functions are for testing purpose only. |
183 void AddCodecMask(EmeMediaType media_type, | 181 void AddCodecMask(EmeMediaType media_type, |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 | 225 |
228 void RegisterMimeType(const std::string& mime_type, EmeCodec codecs_mask); | 226 void RegisterMimeType(const std::string& mime_type, EmeCodec codecs_mask); |
229 bool IsValidMimeTypeCodecsCombination(const std::string& mime_type, | 227 bool IsValidMimeTypeCodecsCombination(const std::string& mime_type, |
230 SupportedCodecs codecs_mask) const; | 228 SupportedCodecs codecs_mask) const; |
231 | 229 |
232 typedef base::hash_map<std::string, std::unique_ptr<KeySystemProperties>> | 230 typedef base::hash_map<std::string, std::unique_ptr<KeySystemProperties>> |
233 KeySystemPropertiesMap; | 231 KeySystemPropertiesMap; |
234 typedef base::hash_map<std::string, SupportedCodecs> MimeTypeCodecsMap; | 232 typedef base::hash_map<std::string, SupportedCodecs> MimeTypeCodecsMap; |
235 typedef base::hash_map<std::string, EmeCodec> CodecsMap; | 233 typedef base::hash_map<std::string, EmeCodec> CodecsMap; |
236 typedef base::hash_map<std::string, EmeInitDataType> InitDataTypesMap; | 234 typedef base::hash_map<std::string, EmeInitDataType> InitDataTypesMap; |
237 typedef base::hash_map<std::string, std::string> KeySystemNameForUMAMap; | |
238 | 235 |
239 // TODO(sandersd): Separate container enum from codec mask value. | 236 // TODO(sandersd): Separate container enum from codec mask value. |
240 // http://crbug.com/417440 | 237 // http://crbug.com/417440 |
241 // Potentially pass EmeMediaType and a container enum. | 238 // Potentially pass EmeMediaType and a container enum. |
242 SupportedCodecs GetCodecMaskForMimeType( | 239 SupportedCodecs GetCodecMaskForMimeType( |
243 const std::string& container_mime_type) const; | 240 const std::string& container_mime_type) const; |
244 EmeCodec GetCodecForString(const std::string& codec) const; | 241 EmeCodec GetCodecForString(const std::string& codec) const; |
245 | 242 |
246 // Map from key system string to KeySystemProperties instance. | 243 // Map from key system string to KeySystemProperties instance. |
247 KeySystemPropertiesMap key_system_properties_map_; | 244 KeySystemPropertiesMap key_system_properties_map_; |
248 | 245 |
249 // This member should only be modified by RegisterMimeType(). | 246 // This member should only be modified by RegisterMimeType(). |
250 MimeTypeCodecsMap mime_type_to_codec_mask_map_; | 247 MimeTypeCodecsMap mime_type_to_codec_mask_map_; |
251 CodecsMap codec_string_map_; | 248 CodecsMap codec_string_map_; |
252 KeySystemNameForUMAMap key_system_name_for_uma_map_; | |
253 | 249 |
254 SupportedCodecs audio_codec_mask_; | 250 SupportedCodecs audio_codec_mask_; |
255 SupportedCodecs video_codec_mask_; | 251 SupportedCodecs video_codec_mask_; |
256 | 252 |
257 // Makes sure all methods are called from the same thread. | 253 // Makes sure all methods are called from the same thread. |
258 base::ThreadChecker thread_checker_; | 254 base::ThreadChecker thread_checker_; |
259 | 255 |
260 DISALLOW_COPY_AND_ASSIGN(KeySystemsImpl); | 256 DISALLOW_COPY_AND_ASSIGN(KeySystemsImpl); |
261 }; | 257 }; |
262 | 258 |
263 KeySystemsImpl* KeySystemsImpl::GetInstance() { | 259 KeySystemsImpl* KeySystemsImpl::GetInstance() { |
264 static KeySystemsImpl* key_systems = new KeySystemsImpl(); | 260 static KeySystemsImpl* key_systems = new KeySystemsImpl(); |
265 key_systems->UpdateIfNeeded(); | |
266 return key_systems; | 261 return key_systems; |
267 } | 262 } |
268 | 263 |
269 // Because we use a thread-safe static, the key systems info must be populated | 264 // Because we use a thread-safe static, the key systems info must be populated |
270 // when the instance is constructed. | 265 // when the instance is constructed. |
271 KeySystemsImpl::KeySystemsImpl() | 266 KeySystemsImpl::KeySystemsImpl() |
272 : audio_codec_mask_(EME_CODEC_AUDIO_ALL), | 267 : audio_codec_mask_(EME_CODEC_AUDIO_ALL), |
273 video_codec_mask_(EME_CODEC_VIDEO_ALL) { | 268 video_codec_mask_(EME_CODEC_VIDEO_ALL) { |
274 for (size_t i = 0; i < arraysize(kCodecStrings); ++i) { | 269 for (size_t i = 0; i < arraysize(kCodecStrings); ++i) { |
275 const std::string& name = kCodecStrings[i].name; | 270 const std::string& name = kCodecStrings[i].name; |
276 DCHECK(!codec_string_map_.count(name)); | 271 DCHECK(!codec_string_map_.count(name)); |
277 codec_string_map_[name] = kCodecStrings[i].type; | 272 codec_string_map_[name] = kCodecStrings[i].type; |
278 } | 273 } |
279 for (size_t i = 0; i < arraysize(kMimeTypeToCodecMasks); ++i) { | 274 for (size_t i = 0; i < arraysize(kMimeTypeToCodecMasks); ++i) { |
280 RegisterMimeType(kMimeTypeToCodecMasks[i].name, | 275 RegisterMimeType(kMimeTypeToCodecMasks[i].name, |
281 kMimeTypeToCodecMasks[i].type); | 276 kMimeTypeToCodecMasks[i].type); |
282 } | 277 } |
283 | 278 |
284 InitializeUMAInfo(); | |
285 | |
286 // Always update supported key systems during construction. | 279 // Always update supported key systems during construction. |
287 UpdateSupportedKeySystems(); | 280 UpdateSupportedKeySystems(); |
288 } | 281 } |
289 | 282 |
290 KeySystemsImpl::~KeySystemsImpl() { | 283 KeySystemsImpl::~KeySystemsImpl() { |
291 } | 284 } |
292 | 285 |
293 SupportedCodecs KeySystemsImpl::GetCodecMaskForMimeType( | 286 SupportedCodecs KeySystemsImpl::GetCodecMaskForMimeType( |
294 const std::string& container_mime_type) const { | 287 const std::string& container_mime_type) const { |
295 MimeTypeCodecsMap::const_iterator iter = | 288 MimeTypeCodecsMap::const_iterator iter = |
296 mime_type_to_codec_mask_map_.find(container_mime_type); | 289 mime_type_to_codec_mask_map_.find(container_mime_type); |
297 if (iter == mime_type_to_codec_mask_map_.end()) | 290 if (iter == mime_type_to_codec_mask_map_.end()) |
298 return EME_CODEC_NONE; | 291 return EME_CODEC_NONE; |
299 | 292 |
300 DCHECK(IsValidMimeTypeCodecsCombination(container_mime_type, iter->second)); | 293 DCHECK(IsValidMimeTypeCodecsCombination(container_mime_type, iter->second)); |
301 return iter->second; | 294 return iter->second; |
302 } | 295 } |
303 | 296 |
304 EmeCodec KeySystemsImpl::GetCodecForString(const std::string& codec) const { | 297 EmeCodec KeySystemsImpl::GetCodecForString(const std::string& codec) const { |
305 CodecsMap::const_iterator iter = codec_string_map_.find(codec); | 298 CodecsMap::const_iterator iter = codec_string_map_.find(codec); |
306 if (iter != codec_string_map_.end()) | 299 if (iter != codec_string_map_.end()) |
307 return iter->second; | 300 return iter->second; |
308 return EME_CODEC_NONE; | 301 return EME_CODEC_NONE; |
309 } | 302 } |
310 | 303 |
311 void KeySystemsImpl::InitializeUMAInfo() { | |
312 DCHECK(thread_checker_.CalledOnValidThread()); | |
313 DCHECK(key_system_name_for_uma_map_.empty()); | |
314 | |
315 std::vector<KeySystemInfoForUMA> key_systems_info_for_uma; | |
316 if (GetMediaClient()) | |
317 GetMediaClient()->AddKeySystemsInfoForUMA(&key_systems_info_for_uma); | |
318 | |
319 for (const KeySystemInfoForUMA& info : key_systems_info_for_uma) { | |
320 key_system_name_for_uma_map_[info.key_system] = | |
321 info.key_system_name_for_uma; | |
322 } | |
323 | |
324 // Clear Key is always supported. | |
325 key_system_name_for_uma_map_[kClearKeyKeySystem] = | |
326 kClearKeyKeySystemNameForUMA; | |
327 } | |
328 | |
329 void KeySystemsImpl::UpdateIfNeeded() { | |
330 if (GetMediaClient() && GetMediaClient()->IsKeySystemsUpdateNeeded()) | |
331 UpdateSupportedKeySystems(); | |
332 } | |
333 | |
334 void KeySystemsImpl::UpdateSupportedKeySystems() { | 304 void KeySystemsImpl::UpdateSupportedKeySystems() { |
335 DCHECK(thread_checker_.CalledOnValidThread()); | 305 DCHECK(thread_checker_.CalledOnValidThread()); |
336 key_system_properties_map_.clear(); | 306 key_system_properties_map_.clear(); |
337 | 307 |
338 std::vector<std::unique_ptr<KeySystemProperties>> key_systems_properties; | 308 std::vector<std::unique_ptr<KeySystemProperties>> key_systems_properties; |
339 | 309 |
340 // Add key systems supported by the MediaClient implementation. | 310 // Add key systems supported by the MediaClient implementation. |
341 if (GetMediaClient()) | 311 if (GetMediaClient()) { |
342 GetMediaClient()->AddSupportedKeySystems(&key_systems_properties); | 312 GetMediaClient()->AddSupportedKeySystems(&key_systems_properties); |
| 313 } else { |
| 314 DVLOG(1) << __func__ << " No media client to provide key systems"; |
| 315 } |
343 | 316 |
344 // Clear Key is always supported. | 317 // Clear Key is always supported. |
345 key_systems_properties.emplace_back(new ClearKeyProperties()); | 318 key_systems_properties.emplace_back(new ClearKeyProperties()); |
346 | 319 |
347 AddSupportedKeySystems(&key_systems_properties); | 320 AddSupportedKeySystems(&key_systems_properties); |
348 } | 321 } |
349 | 322 |
350 // Returns whether distinctive identifiers and persistent state can be reliably | 323 // Returns whether distinctive identifiers and persistent state can be reliably |
351 // blocked for |properties| (and therefore be safely configurable). | 324 // blocked for |properties| (and therefore be safely configurable). |
352 static bool CanBlock(const KeySystemProperties& properties) { | 325 static bool CanBlock(const KeySystemProperties& properties) { |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
436 | 409 |
437 #if defined(OS_ANDROID) | 410 #if defined(OS_ANDROID) |
438 // Ensure that the renderer can access the decoders necessary to use the | 411 // Ensure that the renderer can access the decoders necessary to use the |
439 // key system. | 412 // key system. |
440 if (!properties->UseAesDecryptor() && !HasPlatformDecoderSupport()) { | 413 if (!properties->UseAesDecryptor() && !HasPlatformDecoderSupport()) { |
441 DLOG(WARNING) << properties->GetKeySystemName() << " not registered"; | 414 DLOG(WARNING) << properties->GetKeySystemName() << " not registered"; |
442 continue; | 415 continue; |
443 } | 416 } |
444 #endif // defined(OS_ANDROID) | 417 #endif // defined(OS_ANDROID) |
445 | 418 |
| 419 DVLOG(1) << __func__ |
| 420 << " Adding key system:" << properties->GetKeySystemName(); |
446 key_system_properties_map_[properties->GetKeySystemName()] = | 421 key_system_properties_map_[properties->GetKeySystemName()] = |
447 std::move(properties); | 422 std::move(properties); |
448 } | 423 } |
449 } | 424 } |
450 | 425 |
451 // Adds the MIME type with the codec mask after verifying the validity. | 426 // Adds the MIME type with the codec mask after verifying the validity. |
452 // Only this function should modify |mime_type_to_codec_mask_map_|. | 427 // Only this function should modify |mime_type_to_codec_mask_map_|. |
453 void KeySystemsImpl::RegisterMimeType(const std::string& mime_type, | 428 void KeySystemsImpl::RegisterMimeType(const std::string& mime_type, |
454 EmeCodec codecs_mask) { | 429 EmeCodec codecs_mask) { |
455 DCHECK(thread_checker_.CalledOnValidThread()); | 430 DCHECK(thread_checker_.CalledOnValidThread()); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
487 NOTREACHED(); | 462 NOTREACHED(); |
488 return false; | 463 return false; |
489 } | 464 } |
490 return key_system_iter->second->IsSupportedInitDataType(init_data_type); | 465 return key_system_iter->second->IsSupportedInitDataType(init_data_type); |
491 } | 466 } |
492 | 467 |
493 std::string KeySystemsImpl::GetKeySystemNameForUMA( | 468 std::string KeySystemsImpl::GetKeySystemNameForUMA( |
494 const std::string& key_system) const { | 469 const std::string& key_system) const { |
495 DCHECK(thread_checker_.CalledOnValidThread()); | 470 DCHECK(thread_checker_.CalledOnValidThread()); |
496 | 471 |
497 KeySystemNameForUMAMap::const_iterator iter = | 472 // Here we maintain a short list of known key systems to facilitate UMA |
498 key_system_name_for_uma_map_.find(key_system); | 473 // reporting. Mentioned key systems are not necessarily supported by |
499 if (iter == key_system_name_for_uma_map_.end()) | 474 // the current platform. |
500 return kUnknownKeySystemNameForUMA; | 475 if (key_system == kWidevineKeySystem) |
| 476 return kWidevineKeySystemNameForUMA; |
501 | 477 |
502 return iter->second; | 478 if (key_system == kClearKeyKeySystem) |
| 479 return kClearKeyKeySystemNameForUMA; |
| 480 |
| 481 return kUnknownKeySystemNameForUMA; |
503 } | 482 } |
504 | 483 |
505 bool KeySystemsImpl::UseAesDecryptor(const std::string& key_system) const { | 484 bool KeySystemsImpl::UseAesDecryptor(const std::string& key_system) const { |
506 DCHECK(thread_checker_.CalledOnValidThread()); | 485 DCHECK(thread_checker_.CalledOnValidThread()); |
507 | 486 |
508 KeySystemPropertiesMap::const_iterator key_system_iter = | 487 KeySystemPropertiesMap::const_iterator key_system_iter = |
509 key_system_properties_map_.find(key_system); | 488 key_system_properties_map_.find(key_system); |
510 if (key_system_iter == key_system_properties_map_.end()) { | 489 if (key_system_iter == key_system_properties_map_.end()) { |
511 DLOG(ERROR) << key_system << " is not a known system"; | 490 DLOG(ERROR) << key_system << " is not a known system"; |
512 return false; | 491 return false; |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
730 uint32_t mask) { | 709 uint32_t mask) { |
731 KeySystemsImpl::GetInstance()->AddCodecMask(media_type, codec, mask); | 710 KeySystemsImpl::GetInstance()->AddCodecMask(media_type, codec, mask); |
732 } | 711 } |
733 | 712 |
734 MEDIA_EXPORT void AddMimeTypeCodecMask(const std::string& mime_type, | 713 MEDIA_EXPORT void AddMimeTypeCodecMask(const std::string& mime_type, |
735 uint32_t mask) { | 714 uint32_t mask) { |
736 KeySystemsImpl::GetInstance()->AddMimeTypeCodecMask(mime_type, mask); | 715 KeySystemsImpl::GetInstance()->AddMimeTypeCodecMask(mime_type, mask); |
737 } | 716 } |
738 | 717 |
739 } // namespace media | 718 } // namespace media |
OLD | NEW |