| 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 "content/browser/media/android/browser_media_player_manager.h" | 5 #include "content/browser/media/android/browser_media_player_manager.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "content/browser/android/content_view_core_impl.h" | 8 #include "content/browser/android/content_view_core_impl.h" |
| 9 #include "content/browser/media/android/browser_demuxer_android.h" | 9 #include "content/browser/media/android/browser_demuxer_android.h" |
| 10 #include "content/browser/media/android/media_resource_getter_impl.h" | 10 #include "content/browser/media/android/media_resource_getter_impl.h" |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 #include "media/base/android/media_player_bridge.h" | 26 #include "media/base/android/media_player_bridge.h" |
| 27 #include "media/base/android/media_source_player.h" | 27 #include "media/base/android/media_source_player.h" |
| 28 #include "media/base/media_switches.h" | 28 #include "media/base/media_switches.h" |
| 29 | 29 |
| 30 using media::MediaDrmBridge; | 30 using media::MediaDrmBridge; |
| 31 using media::MediaPlayerAndroid; | 31 using media::MediaPlayerAndroid; |
| 32 using media::MediaPlayerBridge; | 32 using media::MediaPlayerBridge; |
| 33 using media::MediaPlayerManager; | 33 using media::MediaPlayerManager; |
| 34 using media::MediaSourcePlayer; | 34 using media::MediaSourcePlayer; |
| 35 | 35 |
| 36 namespace content { |
| 37 |
| 36 // Threshold on the number of media players per renderer before we start | 38 // Threshold on the number of media players per renderer before we start |
| 37 // attempting to release inactive media players. | 39 // attempting to release inactive media players. |
| 38 static const int kMediaPlayerThreshold = 1; | 40 const int kMediaPlayerThreshold = 1; |
| 39 | 41 |
| 40 // Maximum sizes for various EME message parameters. These are checks to | 42 // Maximum lengths for various EME API parameters. These are checks to |
| 41 // prevent unnecessarily large messages from being passed around, and the sizes | 43 // prevent unnecessarily large parameters from being passed around, and the |
| 42 // are somewhat arbitrary as the EME specification doesn't specify any limits. | 44 // lengths are somewhat arbitrary as the EME spec doesn't specify any limits. |
| 43 static const size_t kEmeUuidSize = 16; | 45 const size_t kMaxInitDataLength = 64 * 1024; // 64 KB |
| 44 static const size_t kEmeInitDataMaximum = 64 * 1024; // 64 KB | 46 const size_t kMaxSessionResponseLength = 64 * 1024; // 64 KB |
| 45 static const size_t kEmeResponseMaximum = 64 * 1024; // 64 KB | 47 const size_t kMaxKeySystemLength = 256; |
| 46 | |
| 47 namespace content { | |
| 48 | 48 |
| 49 static BrowserMediaPlayerManager::Factory g_factory = NULL; | 49 static BrowserMediaPlayerManager::Factory g_factory = NULL; |
| 50 | 50 |
| 51 // static | 51 // static |
| 52 void BrowserMediaPlayerManager::RegisterFactory(Factory factory) { | 52 void BrowserMediaPlayerManager::RegisterFactory(Factory factory) { |
| 53 g_factory = factory; | 53 g_factory = factory; |
| 54 } | 54 } |
| 55 | 55 |
| 56 // static | 56 // static |
| 57 BrowserMediaPlayerManager* BrowserMediaPlayerManager::Create( | 57 BrowserMediaPlayerManager* BrowserMediaPlayerManager::Create( |
| (...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 566 fullscreen_player_is_released_ = true; | 566 fullscreen_player_is_released_ = true; |
| 567 } | 567 } |
| 568 | 568 |
| 569 void BrowserMediaPlayerManager::OnDestroyPlayer(int player_id) { | 569 void BrowserMediaPlayerManager::OnDestroyPlayer(int player_id) { |
| 570 RemovePlayer(player_id); | 570 RemovePlayer(player_id); |
| 571 if (fullscreen_player_id_ == player_id) | 571 if (fullscreen_player_id_ == player_id) |
| 572 fullscreen_player_id_ = -1; | 572 fullscreen_player_id_ = -1; |
| 573 } | 573 } |
| 574 | 574 |
| 575 void BrowserMediaPlayerManager::OnInitializeCdm(int cdm_id, | 575 void BrowserMediaPlayerManager::OnInitializeCdm(int cdm_id, |
| 576 const std::vector<uint8>& uuid, | 576 const std::string& key_system, |
| 577 const GURL& frame_url) { | 577 const GURL& frame_url) { |
| 578 if (uuid.size() != kEmeUuidSize) { | 578 if (key_system.size() > kMaxKeySystemLength) { |
| 579 // This failure will be discovered and reported by OnCreateSession() | 579 // This failure will be discovered and reported by OnCreateSession() |
| 580 // as GetDrmBridge() will return null. | 580 // as GetDrmBridge() will return null. |
| 581 NOTREACHED() << "Invalid UUID for ID: " << cdm_id; | 581 NOTREACHED() << "Invalid key system: " << key_system; |
| 582 return; | 582 return; |
| 583 } | 583 } |
| 584 | 584 |
| 585 AddDrmBridge(cdm_id, uuid, frame_url); | 585 if (!MediaDrmBridge::IsKeySystemSupportedWithType(key_system, "")) { |
| 586 NOTREACHED() << "Unsupported key system: " << key_system; |
| 587 return; |
| 588 } |
| 589 |
| 590 AddDrmBridge(cdm_id, key_system, frame_url); |
| 586 // In EME v0.1b MediaKeys lives in the media element. So the |cdm_id| | 591 // In EME v0.1b MediaKeys lives in the media element. So the |cdm_id| |
| 587 // is the same as the |player_id|. | 592 // is the same as the |player_id|. |
| 588 OnSetMediaKeys(cdm_id, cdm_id); | 593 OnSetMediaKeys(cdm_id, cdm_id); |
| 589 } | 594 } |
| 590 | 595 |
| 591 void BrowserMediaPlayerManager::OnCreateSession( | 596 void BrowserMediaPlayerManager::OnCreateSession( |
| 592 int cdm_id, | 597 int cdm_id, |
| 593 uint32 session_id, | 598 uint32 session_id, |
| 594 CdmHostMsg_CreateSession_ContentType content_type, | 599 CdmHostMsg_CreateSession_ContentType content_type, |
| 595 const std::vector<uint8>& init_data) { | 600 const std::vector<uint8>& init_data) { |
| 596 if (init_data.size() > kEmeInitDataMaximum) { | 601 if (init_data.size() > kMaxInitDataLength) { |
| 597 LOG(WARNING) << "InitData for ID: " << cdm_id | 602 LOG(WARNING) << "InitData for ID: " << cdm_id |
| 598 << " too long: " << init_data.size(); | 603 << " too long: " << init_data.size(); |
| 599 OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0); | 604 OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0); |
| 600 return; | 605 return; |
| 601 } | 606 } |
| 602 | 607 |
| 603 // Convert the session content type into a MIME type. "audio" and "video" | 608 // Convert the session content type into a MIME type. "audio" and "video" |
| 604 // don't matter, so using "video" for the MIME type. | 609 // don't matter, so using "video" for the MIME type. |
| 605 // Ref: | 610 // Ref: |
| 606 // https://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/encrypte
d-media.html#dom-createsession | 611 // https://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/encrypte
d-media.html#dom-createsession |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 655 int cdm_id, | 660 int cdm_id, |
| 656 uint32 session_id, | 661 uint32 session_id, |
| 657 const std::vector<uint8>& response) { | 662 const std::vector<uint8>& response) { |
| 658 MediaDrmBridge* drm_bridge = GetDrmBridge(cdm_id); | 663 MediaDrmBridge* drm_bridge = GetDrmBridge(cdm_id); |
| 659 if (!drm_bridge) { | 664 if (!drm_bridge) { |
| 660 DLOG(WARNING) << "No MediaDrmBridge for ID: " << cdm_id << " found"; | 665 DLOG(WARNING) << "No MediaDrmBridge for ID: " << cdm_id << " found"; |
| 661 OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0); | 666 OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0); |
| 662 return; | 667 return; |
| 663 } | 668 } |
| 664 | 669 |
| 665 if (response.size() > kEmeResponseMaximum) { | 670 if (response.size() > kMaxSessionResponseLength) { |
| 666 LOG(WARNING) << "Response for ID: " << cdm_id | 671 LOG(WARNING) << "Response for ID: " << cdm_id |
| 667 << " too long: " << response.size(); | 672 << " too long: " << response.size(); |
| 668 OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0); | 673 OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0); |
| 669 return; | 674 return; |
| 670 } | 675 } |
| 671 | 676 |
| 672 drm_bridge->UpdateSession(session_id, &response[0], response.size()); | 677 drm_bridge->UpdateSession(session_id, &response[0], response.size()); |
| 673 // In EME v0.1b MediaKeys lives in the media element. So the |cdm_id| | 678 // In EME v0.1b MediaKeys lives in the media element. So the |cdm_id| |
| 674 // is the same as the |player_id|. | 679 // is the same as the |player_id|. |
| 675 // TODO(xhwang): Separate |cdm_id| and |player_id|. | 680 // TODO(xhwang): Separate |cdm_id| and |player_id|. |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 744 Send(new MediaPlayerMsg_DisconnectedFromRemoteDevice( | 749 Send(new MediaPlayerMsg_DisconnectedFromRemoteDevice( |
| 745 routing_id(), player->player_id())); | 750 routing_id(), player->player_id())); |
| 746 } | 751 } |
| 747 break; | 752 break; |
| 748 } | 753 } |
| 749 } | 754 } |
| 750 return scoped_ptr<media::MediaPlayerAndroid>(previous_player); | 755 return scoped_ptr<media::MediaPlayerAndroid>(previous_player); |
| 751 } | 756 } |
| 752 | 757 |
| 753 void BrowserMediaPlayerManager::AddDrmBridge(int cdm_id, | 758 void BrowserMediaPlayerManager::AddDrmBridge(int cdm_id, |
| 754 const std::vector<uint8>& uuid, | 759 const std::string& key_system, |
| 755 const GURL& frame_url) { | 760 const GURL& frame_url) { |
| 756 DCHECK(!GetDrmBridge(cdm_id)); | 761 DCHECK(!GetDrmBridge(cdm_id)); |
| 757 | 762 |
| 758 scoped_ptr<MediaDrmBridge> drm_bridge( | 763 scoped_ptr<MediaDrmBridge> drm_bridge( |
| 759 MediaDrmBridge::Create(cdm_id, uuid, frame_url, this)); | 764 MediaDrmBridge::Create(cdm_id, key_system, frame_url, this)); |
| 760 if (!drm_bridge) { | 765 if (!drm_bridge) { |
| 761 // This failure will be discovered and reported by OnCreateSession() | 766 // This failure will be discovered and reported by OnCreateSession() |
| 762 // as GetDrmBridge() will return null. | 767 // as GetDrmBridge() will return null. |
| 763 DVLOG(1) << "failed to create drm bridge."; | 768 DVLOG(1) << "failed to create drm bridge."; |
| 764 return; | 769 return; |
| 765 } | 770 } |
| 766 | 771 |
| 767 // TODO(xhwang/ddorwin): Pass the security level from key system. | 772 // TODO(xhwang/ddorwin): Pass the security level from key system. |
| 768 MediaDrmBridge::SecurityLevel security_level = | 773 MediaDrmBridge::SecurityLevel security_level = |
| 769 MediaDrmBridge::SECURITY_LEVEL_3; | 774 MediaDrmBridge::SECURITY_LEVEL_3; |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 879 if (player && player->IsSurfaceInUse()) | 884 if (player && player->IsSurfaceInUse()) |
| 880 return; | 885 return; |
| 881 ExternalVideoSurfaceContainer* surface_container = | 886 ExternalVideoSurfaceContainer* surface_container = |
| 882 ExternalVideoSurfaceContainer::FromWebContents(web_contents_); | 887 ExternalVideoSurfaceContainer::FromWebContents(web_contents_); |
| 883 if (surface_container) | 888 if (surface_container) |
| 884 surface_container->ReleaseExternalVideoSurface(player_id); | 889 surface_container->ReleaseExternalVideoSurface(player_id); |
| 885 #endif // defined(VIDEO_HOLE) | 890 #endif // defined(VIDEO_HOLE) |
| 886 } | 891 } |
| 887 | 892 |
| 888 } // namespace content | 893 } // namespace content |
| OLD | NEW |