buffered_frame_decryptor.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /*
  2. * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
  3. *
  4. * Use of this source code is governed by a BSD-style license
  5. * that can be found in the LICENSE file in the root of the source
  6. * tree. An additional intellectual property rights grant can be found
  7. * in the file PATENTS. All contributing project authors may
  8. * be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #ifndef VIDEO_BUFFERED_FRAME_DECRYPTOR_H_
  11. #define VIDEO_BUFFERED_FRAME_DECRYPTOR_H_
  12. #include <deque>
  13. #include <memory>
  14. #include "api/crypto/crypto_options.h"
  15. #include "api/crypto/frame_decryptor_interface.h"
  16. #include "modules/video_coding/frame_object.h"
  17. namespace webrtc {
  18. // This callback is provided during the construction of the
  19. // BufferedFrameDecryptor and is called each time a frame is sucessfully
  20. // decrypted by the buffer.
  21. class OnDecryptedFrameCallback {
  22. public:
  23. virtual ~OnDecryptedFrameCallback() = default;
  24. // Called each time a decrypted frame is returned.
  25. virtual void OnDecryptedFrame(
  26. std::unique_ptr<video_coding::RtpFrameObject> frame) = 0;
  27. };
  28. // This callback is called each time there is a status change in the decryption
  29. // stream. For example going from a none state to a first decryption or going
  30. // frome a decryptable state to a non decryptable state.
  31. class OnDecryptionStatusChangeCallback {
  32. public:
  33. virtual ~OnDecryptionStatusChangeCallback() = default;
  34. // Called each time the decryption stream status changes. This call is
  35. // blocking so the caller must relinquish the callback quickly. This status
  36. // must match what is specified in the FrameDecryptorInterface file. Notably
  37. // 0 must indicate success and any positive integer is a failure.
  38. virtual void OnDecryptionStatusChange(
  39. FrameDecryptorInterface::Status status) = 0;
  40. };
  41. // The BufferedFrameDecryptor is responsible for deciding when to pass
  42. // decrypted received frames onto the OnDecryptedFrameCallback. Frames can be
  43. // delayed when frame encryption is enabled but the key hasn't arrived yet. In
  44. // this case we stash about 1 second of encrypted frames instead of dropping
  45. // them to prevent re-requesting the key frame. This optimization is
  46. // particularly important on low bandwidth networks. Note stashing is only ever
  47. // done if we have never sucessfully decrypted a frame before. After the first
  48. // successful decryption payloads will never be stashed.
  49. class BufferedFrameDecryptor final {
  50. public:
  51. // Constructs a new BufferedFrameDecryptor that can hold
  52. explicit BufferedFrameDecryptor(
  53. OnDecryptedFrameCallback* decrypted_frame_callback,
  54. OnDecryptionStatusChangeCallback* decryption_status_change_callback);
  55. ~BufferedFrameDecryptor();
  56. // This object cannot be copied.
  57. BufferedFrameDecryptor(const BufferedFrameDecryptor&) = delete;
  58. BufferedFrameDecryptor& operator=(const BufferedFrameDecryptor&) = delete;
  59. // Sets a new frame decryptor as the decryptor for the buffered frame
  60. // decryptor. This allows the decryptor to be switched out without resetting
  61. // the video stream.
  62. void SetFrameDecryptor(
  63. rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor);
  64. // Determines whether the frame should be stashed, dropped or handed off to
  65. // the OnDecryptedFrameCallback.
  66. void ManageEncryptedFrame(
  67. std::unique_ptr<video_coding::RtpFrameObject> encrypted_frame);
  68. private:
  69. // Represents what should be done with a given frame.
  70. enum class FrameDecision { kStash, kDecrypted, kDrop };
  71. // Attempts to decrypt the frame, if it fails and no prior frames have been
  72. // decrypted it will return kStash. Otherwise fail to decrypts will return
  73. // kDrop. Successful decryptions will always return kDecrypted.
  74. FrameDecision DecryptFrame(video_coding::RtpFrameObject* frame);
  75. // Retries all the stashed frames this is triggered each time a kDecrypted
  76. // event occurs.
  77. void RetryStashedFrames();
  78. static const size_t kMaxStashedFrames = 24;
  79. const bool generic_descriptor_auth_experiment_;
  80. bool first_frame_decrypted_ = false;
  81. FrameDecryptorInterface::Status last_status_ =
  82. FrameDecryptorInterface::Status::kUnknown;
  83. rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor_;
  84. OnDecryptedFrameCallback* const decrypted_frame_callback_;
  85. OnDecryptionStatusChangeCallback* const decryption_status_change_callback_;
  86. std::deque<std::unique_ptr<video_coding::RtpFrameObject>> stashed_frames_;
  87. };
  88. } // namespace webrtc
  89. #endif // VIDEO_BUFFERED_FRAME_DECRYPTOR_H_