blob: be6ff9ae9cfb0f04ead77761d8d668d50dafbc05 [file] [log] [blame]
Benjamin Wright00765292018-11-30 16:18:26 -08001/*
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
11#ifndef VIDEO_BUFFERED_FRAME_DECRYPTOR_H_
12#define VIDEO_BUFFERED_FRAME_DECRYPTOR_H_
13
14#include <deque>
15#include <memory>
16
17#include "api/crypto/cryptooptions.h"
18#include "api/crypto/framedecryptorinterface.h"
19#include "modules/include/module_common_types.h"
20#include "modules/video_coding/frame_object.h"
21
22namespace webrtc {
23
24// This callback is provided during the construction of the
25// BufferedFrameDecryptor and is called each time a frame is sucessfully
26// decrypted by the buffer.
27class OnDecryptedFrameCallback {
28 public:
29 virtual ~OnDecryptedFrameCallback() = default;
30 // Called each time a decrypted frame is returned.
31 virtual void OnDecryptedFrame(
32 std::unique_ptr<video_coding::RtpFrameObject> frame) = 0;
33};
34
35// The BufferedFrameDecryptor is responsible for deciding when to pass
36// decrypted received frames onto the OnDecryptedFrameCallback. Frames can be
37// delayed when frame encryption is enabled but the key hasn't arrived yet. In
38// this case we stash about 1 second of encrypted frames instead of dropping
39// them to prevent re-requesting the key frame. This optimization is
40// particularly important on low bandwidth networks. Note stashing is only ever
41// done if we have never sucessfully decrypted a frame before. After the first
42// successful decryption payloads will never be stashed.
43class BufferedFrameDecryptor final {
44 public:
45 // Constructs a new BufferedFrameDecryptor that can hold
46 explicit BufferedFrameDecryptor(
47 OnDecryptedFrameCallback* decrypted_frame_callback,
48 rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor);
49 ~BufferedFrameDecryptor();
50 // This object cannot be copied.
51 BufferedFrameDecryptor(const BufferedFrameDecryptor&) = delete;
52 BufferedFrameDecryptor& operator=(const BufferedFrameDecryptor&) = delete;
53 // Determines whether the frame should be stashed, dropped or handed off to
54 // the OnDecryptedFrameCallback.
55 void ManageEncryptedFrame(
56 std::unique_ptr<video_coding::RtpFrameObject> encrypted_frame);
57
58 private:
59 // Represents what should be done with a given frame.
60 enum class FrameDecision { kStash, kDecrypted, kDrop };
61
62 // Attempts to decrypt the frame, if it fails and no prior frames have been
63 // decrypted it will return kStash. Otherwise fail to decrypts will return
64 // kDrop. Successful decryptions will always return kDecrypted.
65 FrameDecision DecryptFrame(video_coding::RtpFrameObject* frame);
66 // Retries all the stashed frames this is triggered each time a kDecrypted
67 // event occurs.
68 void RetryStashedFrames();
69
70 static const size_t kMaxStashedFrames = 24;
71
72 bool first_frame_decrypted_ = false;
73 const rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor_;
74 OnDecryptedFrameCallback* const decrypted_frame_callback_;
75 std::deque<std::unique_ptr<video_coding::RtpFrameObject>> stashed_frames_;
76};
77
78} // namespace webrtc
79
80#endif // VIDEO_BUFFERED_FRAME_DECRYPTOR_H_