diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/libwebrtc/video/buffered_frame_decryptor.cc | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/libwebrtc/video/buffered_frame_decryptor.cc')
-rw-r--r-- | third_party/libwebrtc/video/buffered_frame_decryptor.cc | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/third_party/libwebrtc/video/buffered_frame_decryptor.cc b/third_party/libwebrtc/video/buffered_frame_decryptor.cc new file mode 100644 index 0000000000..24cbaf8265 --- /dev/null +++ b/third_party/libwebrtc/video/buffered_frame_decryptor.cc @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "video/buffered_frame_decryptor.h" + +#include <utility> +#include <vector> + +#include "modules/rtp_rtcp/source/rtp_descriptor_authentication.h" +#include "modules/video_coding/frame_object.h" +#include "rtc_base/logging.h" +#include "system_wrappers/include/field_trial.h" + +namespace webrtc { + +BufferedFrameDecryptor::BufferedFrameDecryptor( + OnDecryptedFrameCallback* decrypted_frame_callback, + OnDecryptionStatusChangeCallback* decryption_status_change_callback, + const FieldTrialsView& field_trials) + : generic_descriptor_auth_experiment_( + !field_trials.IsDisabled("WebRTC-GenericDescriptorAuth")), + decrypted_frame_callback_(decrypted_frame_callback), + decryption_status_change_callback_(decryption_status_change_callback) {} + +BufferedFrameDecryptor::~BufferedFrameDecryptor() {} + +void BufferedFrameDecryptor::SetFrameDecryptor( + rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor) { + frame_decryptor_ = std::move(frame_decryptor); +} + +void BufferedFrameDecryptor::ManageEncryptedFrame( + std::unique_ptr<RtpFrameObject> encrypted_frame) { + switch (DecryptFrame(encrypted_frame.get())) { + case FrameDecision::kStash: + if (stashed_frames_.size() >= kMaxStashedFrames) { + RTC_LOG(LS_WARNING) << "Encrypted frame stash full poping oldest item."; + stashed_frames_.pop_front(); + } + stashed_frames_.push_back(std::move(encrypted_frame)); + break; + case FrameDecision::kDecrypted: + RetryStashedFrames(); + decrypted_frame_callback_->OnDecryptedFrame(std::move(encrypted_frame)); + break; + case FrameDecision::kDrop: + break; + } +} + +BufferedFrameDecryptor::FrameDecision BufferedFrameDecryptor::DecryptFrame( + RtpFrameObject* frame) { + // Optionally attempt to decrypt the raw video frame if it was provided. + if (frame_decryptor_ == nullptr) { + RTC_LOG(LS_INFO) << "Frame decryption required but not attached to this " + "stream. Stashing frame."; + return FrameDecision::kStash; + } + // Retrieve the maximum possible size of the decrypted payload. + const size_t max_plaintext_byte_size = + frame_decryptor_->GetMaxPlaintextByteSize(cricket::MEDIA_TYPE_VIDEO, + frame->size()); + RTC_CHECK_LE(max_plaintext_byte_size, frame->size()); + // Place the decrypted frame inline into the existing frame. + rtc::ArrayView<uint8_t> inline_decrypted_bitstream(frame->mutable_data(), + max_plaintext_byte_size); + + // Enable authenticating the header if the field trial isn't disabled. + std::vector<uint8_t> additional_data; + if (generic_descriptor_auth_experiment_) { + additional_data = RtpDescriptorAuthentication(frame->GetRtpVideoHeader()); + } + + // Attempt to decrypt the video frame. + const FrameDecryptorInterface::Result decrypt_result = + frame_decryptor_->Decrypt(cricket::MEDIA_TYPE_VIDEO, /*csrcs=*/{}, + additional_data, *frame, + inline_decrypted_bitstream); + // Optionally call the callback if there was a change in status + if (decrypt_result.status != last_status_) { + last_status_ = decrypt_result.status; + decryption_status_change_callback_->OnDecryptionStatusChange( + decrypt_result.status); + } + + if (!decrypt_result.IsOk()) { + // Only stash frames if we have never decrypted a frame before. + return first_frame_decrypted_ ? FrameDecision::kDrop + : FrameDecision::kStash; + } + RTC_CHECK_LE(decrypt_result.bytes_written, max_plaintext_byte_size); + // Update the frame to contain just the written bytes. + frame->set_size(decrypt_result.bytes_written); + + // Indicate that all future fail to decrypt frames should be dropped. + if (!first_frame_decrypted_) { + first_frame_decrypted_ = true; + } + + return FrameDecision::kDecrypted; +} + +void BufferedFrameDecryptor::RetryStashedFrames() { + if (!stashed_frames_.empty()) { + RTC_LOG(LS_INFO) << "Retrying stashed encrypted frames. Count: " + << stashed_frames_.size(); + } + for (auto& frame : stashed_frames_) { + if (DecryptFrame(frame.get()) == FrameDecision::kDecrypted) { + decrypted_frame_callback_->OnDecryptedFrame(std::move(frame)); + } + } + stashed_frames_.clear(); +} + +} // namespace webrtc |