media_foundation_cdm.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef MEDIA_CDM_WIN_MEDIA_FOUNDATION_CDM_H_
  5. #define MEDIA_CDM_WIN_MEDIA_FOUNDATION_CDM_H_
  6. #include <mfcontentdecryptionmodule.h>
  7. #include <wrl.h>
  8. #include <map>
  9. #include <memory>
  10. #include <string>
  11. #include <vector>
  12. #include "base/memory/scoped_refptr.h"
  13. #include "base/memory/weak_ptr.h"
  14. #include "media/base/cdm_context.h"
  15. #include "media/base/content_decryption_module.h"
  16. #include "media/base/media_export.h"
  17. #include "media/cdm/cdm_document_service.h"
  18. namespace media {
  19. // Key to the client token. The same value is also used in MediaFoundation CDMs.
  20. // Do NOT change this value!
  21. DEFINE_PROPERTYKEY(EME_CONTENTDECRYPTIONMODULE_CLIENT_TOKEN,
  22. 0xa4abc308,
  23. 0xd249,
  24. 0x4150,
  25. 0x90,
  26. 0x37,
  27. 0xc9,
  28. 0x97,
  29. 0xf8,
  30. 0xcf,
  31. 0x8d,
  32. 0x0f,
  33. PID_FIRST_USABLE);
  34. class MediaFoundationCdmSession;
  35. // A CDM implementation based on Media Foundation IMFContentDecryptionModule on
  36. // Windows.
  37. class MEDIA_EXPORT MediaFoundationCdm final : public ContentDecryptionModule,
  38. public CdmContext {
  39. public:
  40. // Checks whether MediaFoundationCdm is available based on OS version. Further
  41. // checks need to be made to determine the usability and the capabilities.
  42. static bool IsAvailable();
  43. // Callback to create an IMFContentDecryptionModule. If failed,
  44. // IMFContentDecryptionModule must be null.
  45. using CreateMFCdmCB = base::RepeatingCallback<
  46. void(HRESULT&, Microsoft::WRL::ComPtr<IMFContentDecryptionModule>&)>;
  47. // Callback for `IsTypeSupportedCB` below.
  48. using IsTypeSupportedResultCB = base::OnceCallback<void(bool is_supported)>;
  49. // Callback to IMFMediaFoundataionCdmFactory's IsTypeSupported.
  50. using IsTypeSupportedCB =
  51. base::RepeatingCallback<void(const std::string& content_type,
  52. IsTypeSupportedResultCB)>;
  53. // Callback to MediaFoundationCdmFactory::StoreClientToken
  54. using StoreClientTokenCB =
  55. base::RepeatingCallback<void(const std::vector<uint8_t>&)>;
  56. using CdmEventCB = base::RepeatingCallback<void(CdmEvent)>;
  57. // Constructs `MediaFoundationCdm`. Note that `Initialize()` must be called
  58. // before calling any other methods.
  59. // TODO(xhwang): Use a helper to reduce the number of callbacks.
  60. MediaFoundationCdm(
  61. const std::string& uma_prefix,
  62. const CreateMFCdmCB& create_mf_cdm_cb,
  63. const IsTypeSupportedCB& is_type_supported_cb,
  64. const StoreClientTokenCB& store_client_token_cb,
  65. const CdmEventCB& cdm_event_cb,
  66. const SessionMessageCB& session_message_cb,
  67. const SessionClosedCB& session_closed_cb,
  68. const SessionKeysChangeCB& session_keys_change_cb,
  69. const SessionExpirationUpdateCB& session_expiration_update_cb);
  70. MediaFoundationCdm(const MediaFoundationCdm&) = delete;
  71. MediaFoundationCdm& operator=(const MediaFoundationCdm&) = delete;
  72. // Initializes `this` and returns whether the initialization succeeds. Must
  73. // be called before any other methods.
  74. HRESULT Initialize();
  75. // ContentDecryptionModule implementation.
  76. void SetServerCertificate(const std::vector<uint8_t>& certificate,
  77. std::unique_ptr<SimpleCdmPromise> promise) override;
  78. void GetStatusForPolicy(
  79. HdcpVersion min_hdcp_version,
  80. std::unique_ptr<KeyStatusCdmPromise> promise) override;
  81. void CreateSessionAndGenerateRequest(
  82. CdmSessionType session_type,
  83. EmeInitDataType init_data_type,
  84. const std::vector<uint8_t>& init_data,
  85. std::unique_ptr<NewSessionCdmPromise> promise) override;
  86. void LoadSession(CdmSessionType session_type,
  87. const std::string& session_id,
  88. std::unique_ptr<NewSessionCdmPromise> promise) override;
  89. void UpdateSession(const std::string& session_id,
  90. const std::vector<uint8_t>& response,
  91. std::unique_ptr<SimpleCdmPromise> promise) override;
  92. void CloseSession(const std::string& session_id,
  93. std::unique_ptr<SimpleCdmPromise> promise) override;
  94. void RemoveSession(const std::string& session_id,
  95. std::unique_ptr<SimpleCdmPromise> promise) override;
  96. CdmContext* GetCdmContext() override;
  97. // CdmContext implementation.
  98. bool RequiresMediaFoundationRenderer() override;
  99. scoped_refptr<MediaFoundationCdmProxy> GetMediaFoundationCdmProxy() override;
  100. private:
  101. ~MediaFoundationCdm() override;
  102. // Returns whether the |session_id| is accepted by the |this|.
  103. bool OnSessionId(int session_token,
  104. std::unique_ptr<NewSessionCdmPromise> promise,
  105. const std::string& session_id);
  106. MediaFoundationCdmSession* GetSession(const std::string& session_id);
  107. void CloseSessionInternal(const std::string& session_id,
  108. CdmSessionClosedReason reason,
  109. std::unique_ptr<SimpleCdmPromise> promise);
  110. // Called when hardware context reset happens.
  111. void OnHardwareContextReset();
  112. // Called when CdmEvent happens.
  113. void OnCdmEvent(CdmEvent event);
  114. // Called when IsTypeSupported() result is available.
  115. void OnIsTypeSupportedResult(std::unique_ptr<KeyStatusCdmPromise> promise,
  116. bool is_supported);
  117. void StoreClientTokenIfNeeded();
  118. // Prefix for UMA reported in `this` and the `sessions_`.
  119. const std::string uma_prefix_;
  120. // Callback to create `mf_cdm_`.
  121. CreateMFCdmCB create_mf_cdm_cb_;
  122. // Callback to MFCdmFactory's IsTypeSupported().
  123. IsTypeSupportedCB is_type_supported_cb_;
  124. // Callback to MFCdmFactory's StoreClientToken().
  125. StoreClientTokenCB store_client_token_cb_;
  126. // Callback to report fatal errors.
  127. CdmEventCB cdm_event_cb_;
  128. // Callbacks for firing session events.
  129. SessionMessageCB session_message_cb_;
  130. SessionClosedCB session_closed_cb_;
  131. SessionKeysChangeCB session_keys_change_cb_;
  132. SessionExpirationUpdateCB session_expiration_update_cb_;
  133. Microsoft::WRL::ComPtr<IMFContentDecryptionModule> mf_cdm_;
  134. // Used to generate unique tokens for identifying pending sessions before
  135. // session ID is available.
  136. int next_session_token_ = 0;
  137. // Session token to session map for sessions waiting for session ID.
  138. std::map<int, std::unique_ptr<MediaFoundationCdmSession>> pending_sessions_;
  139. // Session ID to session map.
  140. std::map<std::string, std::unique_ptr<MediaFoundationCdmSession>> sessions_;
  141. scoped_refptr<MediaFoundationCdmProxy> cdm_proxy_;
  142. // Copy of the last client token we stored.
  143. std::vector<uint8_t> cached_client_token_;
  144. // This must be the last member.
  145. base::WeakPtrFactory<MediaFoundationCdm> weak_factory_{this};
  146. };
  147. } // namespace media
  148. #endif // MEDIA_CDM_WIN_MEDIA_FOUNDATION_CDM_H_