vaapi_video_decoder_delegate.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. // Copyright 2019 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_GPU_VAAPI_VAAPI_VIDEO_DECODER_DELEGATE_H_
  5. #define MEDIA_GPU_VAAPI_VAAPI_VIDEO_DECODER_DELEGATE_H_
  6. #include <map>
  7. #include <memory>
  8. #include <string>
  9. #include <vector>
  10. #include "base/callback.h"
  11. #include "base/callback_helpers.h"
  12. #include "base/memory/raw_ptr.h"
  13. #include "base/memory/scoped_refptr.h"
  14. #include "base/memory/weak_ptr.h"
  15. #include "base/sequence_checker.h"
  16. #include "base/time/time.h"
  17. #include "build/chromeos_buildflags.h"
  18. #include "media/base/decryptor.h"
  19. #include "media/base/encryption_scheme.h"
  20. #include "media/base/subsample_entry.h"
  21. #include "third_party/libva_protected_content/va_protected_content.h"
  22. #if BUILDFLAG(IS_CHROMEOS_ASH)
  23. namespace chromeos {
  24. class ChromeOsCdmContext;
  25. } // namespace chromeos
  26. #endif // BUILDFLAG(IS_CHROMEOS_ASH)
  27. namespace media {
  28. class CdmContext;
  29. template <class T>
  30. class DecodeSurfaceHandler;
  31. class DecryptConfig;
  32. class VaapiWrapper;
  33. class VASurface;
  34. // The common part of each AcceleratedVideoDecoder's Accelerator for VA-API.
  35. // This class allows clients to reset VaapiWrapper in case of a profile change.
  36. // DecodeSurfaceHandler must stay alive for the lifetime of this class.
  37. // This also handles all of the shared functionality relating to protected
  38. // sessions in VA-API.
  39. class VaapiVideoDecoderDelegate {
  40. public:
  41. // Callback when using protected mode to indicate that if waiting, the
  42. // decoder should resume again. If |success| is false, then decoding should
  43. // fail.
  44. using ProtectedSessionUpdateCB = base::RepeatingCallback<void(bool success)>;
  45. VaapiVideoDecoderDelegate(
  46. DecodeSurfaceHandler<VASurface>* const vaapi_dec,
  47. scoped_refptr<VaapiWrapper> vaapi_wrapper,
  48. ProtectedSessionUpdateCB on_protected_session_update_cb,
  49. CdmContext* cdm_context,
  50. EncryptionScheme encryption_scheme = EncryptionScheme::kUnencrypted);
  51. virtual ~VaapiVideoDecoderDelegate();
  52. void set_vaapi_wrapper(scoped_refptr<VaapiWrapper> vaapi_wrapper);
  53. virtual void OnVAContextDestructionSoon();
  54. VaapiVideoDecoderDelegate(const VaapiVideoDecoderDelegate&) = delete;
  55. VaapiVideoDecoderDelegate& operator=(const VaapiVideoDecoderDelegate&) =
  56. delete;
  57. // Should be called when kTryAgain is returned from decoding to determine if
  58. // we should try to recover the session by sending a kDecodeStateLost message
  59. // up through the WaitingCB in the decoder. Returns true if we should send the
  60. // kDecodeStateLost message.
  61. bool HasInitiatedProtectedRecovery();
  62. protected:
  63. // Sets the |decrypt_config| currently active for this stream. Returns true if
  64. // that config is compatible with the existing one (for example, you can't
  65. // change encryption schemes midstream).
  66. bool SetDecryptConfig(std::unique_ptr<DecryptConfig> decrypt_config);
  67. enum class ProtectedSessionState {
  68. kNotCreated,
  69. kInProcess,
  70. kCreated,
  71. kNeedsRecovery,
  72. kFailed
  73. };
  74. // Ensures we have a protected session setup and attached to the active
  75. // |vaapi_wrapper_| we are using. We are in the corresponding state returned
  76. // when this call returns. |full_sample| indicates if we are using full sample
  77. // encryption or not and must remain consistent for a session. If everything
  78. // is setup for a protected session, it will fill in the |crypto_params|.
  79. // |segments| must retain its memory until the frame is submitted.
  80. // |subsamples| is for the current slice. |size| is the size of the slice
  81. // data. This should be called if IsEncrypted() is true even if the current
  82. // data is not encrypted (i.e. |subsamples| is empty).
  83. #if BUILDFLAG(IS_CHROMEOS_ASH)
  84. ProtectedSessionState SetupDecryptDecode(
  85. bool full_sample,
  86. size_t size,
  87. VAEncryptionParameters* crypto_params,
  88. std::vector<VAEncryptionSegmentInfo>* segments,
  89. const std::vector<SubsampleEntry>& subsamples);
  90. #endif // BUILDFLAG(IS_CHROMEOS_ASH)
  91. // Returns true if we are handling encrypted content, in which case
  92. // SetupDecryptDecode() should be called for every slice. This is specifically
  93. // for Intel platforms.
  94. bool IsEncryptedSession() const {
  95. return (encryption_scheme_ != EncryptionScheme::kUnencrypted) &&
  96. !transcryption_;
  97. }
  98. // Returns true if we are handling transcrypted content. This is specifically
  99. // for AMD platforms that normalize encrypted content with the TEE rather than
  100. // passing all the parameters into libva.
  101. bool IsTranscrypted() const { return transcryption_; }
  102. // Should be called by subclasses if a failure occurs during actual decoding.
  103. // This will check if we are using protected mode and it's in a state that
  104. // can be recovered which should resolve the error. If this method returns
  105. // true, then the caller should return kTryAgain from the accelerator to kick
  106. // off the rest of the recovery process.
  107. bool NeedsProtectedSessionRecovery();
  108. // Should be invoked by subclasses if they successfully decoded protected
  109. // video. This is so we can reset our tracker to indicate we successfully
  110. // recovered from protected session loss. It is fine to call this method on
  111. // every successful protected decode.
  112. void ProtectedDecodedSucceeded();
  113. // Returns the key_id string for the current DecryptConfig.
  114. std::string GetDecryptKeyId() const;
  115. // Both owned by caller.
  116. const raw_ptr<DecodeSurfaceHandler<VASurface>> vaapi_dec_;
  117. scoped_refptr<VaapiWrapper> vaapi_wrapper_;
  118. SEQUENCE_CHECKER(sequence_checker_);
  119. private:
  120. void OnGetHwConfigData(bool success, const std::vector<uint8_t>& config_data);
  121. void OnGetHwKeyData(const std::string& key_id,
  122. Decryptor::Status status,
  123. const std::vector<uint8_t>& key_data);
  124. void RecoverProtectedSession();
  125. // All members below pertain to protected content playback.
  126. ProtectedSessionUpdateCB on_protected_session_update_cb_;
  127. EncryptionScheme encryption_scheme_;
  128. #if BUILDFLAG(IS_CHROMEOS_ASH)
  129. chromeos::ChromeOsCdmContext* chromeos_cdm_context_{nullptr}; // Not owned.
  130. EncryptionScheme last_used_encryption_scheme_{EncryptionScheme::kUnencrypted};
  131. #endif // BUILDFLAG(IS_CHROMEOS_ASH)
  132. ProtectedSessionState protected_session_state_;
  133. std::unique_ptr<DecryptConfig> decrypt_config_;
  134. std::vector<uint8_t> hw_identifier_;
  135. std::map<std::string, std::vector<uint8_t>> hw_key_data_map_;
  136. base::TimeTicks last_key_retrieval_time_;
  137. // This will only be true on AMD platforms where we support encrypted content
  138. // and the content is encrypted.
  139. bool transcryption_ = false;
  140. // This gets set to true if we indicated we should try to recover from
  141. // protected session loss. We use this so that we don't go into a loop where
  142. // we repeatedly retry recovery over and over.
  143. bool performing_recovery_;
  144. base::WeakPtrFactory<VaapiVideoDecoderDelegate> weak_factory_{this};
  145. };
  146. } // namespace media
  147. #endif // MEDIA_GPU_VAAPI_VAAPI_VIDEO_DECODER_DELEGATE_H_