webrtc_m130/video/buffered_frame_decryptor_unittest.cc

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

233 lines
9.0 KiB
C++
Raw Permalink Normal View History

Add BufferedFrameDecryptor to cleanly deal with receiving encrypted frames. This change introduces a new class BufferedFrameDecryptor that is responsible for decrypting received encrypted frames and passing them on to the RtpReferenceFinder. This decoupling refactoring was triggered by a new optimization also introduced in this patch to stash a small number of undecryptable frames if no frames have ever been decrypted. The goal of this optimization is to prevent re-fectching of key frames on low bandwidth networks simply because the key to decrypt them had not arrived yet. The optimization will stash 24 frames (about 1 second of video) in a ring buffer and will attempt to re-decrypt previously received frames on the first valid decryption. This allows the decoder to receive the key frame without having to request due to short key delivery latencies. In testing this is actually hit quite often and saves an entire RTT which can be up to 200ms on a bad network. As the scope of frame encryption increases in WebRTC and has more specialized optimizations that do not apply to the general flow it makes sense to move it to a more explicit bump in the stack protocol that is decoupled from the WebRTC main flow, similar to how SRTP is utilized with srtp_protect and srtp_unprotect. One advantage of this approach is the BufferedFrameDecryptor isn't even constructed if FrameEncryption is not in use. I have decided against merging the RtpReferenceFinder and EncryptedFrame stash because it introduced a lot of complexity around the mixed scenario where some of the frames in the stash are encrypted and others are not. In this case we would need to mark certain frames as decrypted which appeared to introduce more complexity than this simple decoupling. Bug: webrtc:10022 Change-Id: Iab74f7b7d25ef1cdd15c4a76b5daae1cfa24932c Reviewed-on: https://webrtc-review.googlesource.com/c/112221 Commit-Queue: Benjamin Wright <benwright@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25865}
2018-11-30 16:18:26 -08:00
/*
* 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 <map>
#include <memory>
#include <optional>
Add BufferedFrameDecryptor to cleanly deal with receiving encrypted frames. This change introduces a new class BufferedFrameDecryptor that is responsible for decrypting received encrypted frames and passing them on to the RtpReferenceFinder. This decoupling refactoring was triggered by a new optimization also introduced in this patch to stash a small number of undecryptable frames if no frames have ever been decrypted. The goal of this optimization is to prevent re-fectching of key frames on low bandwidth networks simply because the key to decrypt them had not arrived yet. The optimization will stash 24 frames (about 1 second of video) in a ring buffer and will attempt to re-decrypt previously received frames on the first valid decryption. This allows the decoder to receive the key frame without having to request due to short key delivery latencies. In testing this is actually hit quite often and saves an entire RTT which can be up to 200ms on a bad network. As the scope of frame encryption increases in WebRTC and has more specialized optimizations that do not apply to the general flow it makes sense to move it to a more explicit bump in the stack protocol that is decoupled from the WebRTC main flow, similar to how SRTP is utilized with srtp_protect and srtp_unprotect. One advantage of this approach is the BufferedFrameDecryptor isn't even constructed if FrameEncryption is not in use. I have decided against merging the RtpReferenceFinder and EncryptedFrame stash because it introduced a lot of complexity around the mixed scenario where some of the frames in the stash are encrypted and others are not. In this case we would need to mark certain frames as decrypted which appeared to introduce more complexity than this simple decoupling. Bug: webrtc:10022 Change-Id: Iab74f7b7d25ef1cdd15c4a76b5daae1cfa24932c Reviewed-on: https://webrtc-review.googlesource.com/c/112221 Commit-Queue: Benjamin Wright <benwright@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25865}
2018-11-30 16:18:26 -08:00
#include <vector>
#include "api/test/mock_frame_decryptor.h"
#include "modules/video_coding/packet_buffer.h"
#include "system_wrappers/include/clock.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/scoped_key_value_config.h"
Add BufferedFrameDecryptor to cleanly deal with receiving encrypted frames. This change introduces a new class BufferedFrameDecryptor that is responsible for decrypting received encrypted frames and passing them on to the RtpReferenceFinder. This decoupling refactoring was triggered by a new optimization also introduced in this patch to stash a small number of undecryptable frames if no frames have ever been decrypted. The goal of this optimization is to prevent re-fectching of key frames on low bandwidth networks simply because the key to decrypt them had not arrived yet. The optimization will stash 24 frames (about 1 second of video) in a ring buffer and will attempt to re-decrypt previously received frames on the first valid decryption. This allows the decoder to receive the key frame without having to request due to short key delivery latencies. In testing this is actually hit quite often and saves an entire RTT which can be up to 200ms on a bad network. As the scope of frame encryption increases in WebRTC and has more specialized optimizations that do not apply to the general flow it makes sense to move it to a more explicit bump in the stack protocol that is decoupled from the WebRTC main flow, similar to how SRTP is utilized with srtp_protect and srtp_unprotect. One advantage of this approach is the BufferedFrameDecryptor isn't even constructed if FrameEncryption is not in use. I have decided against merging the RtpReferenceFinder and EncryptedFrame stash because it introduced a lot of complexity around the mixed scenario where some of the frames in the stash are encrypted and others are not. In this case we would need to mark certain frames as decrypted which appeared to introduce more complexity than this simple decoupling. Bug: webrtc:10022 Change-Id: Iab74f7b7d25ef1cdd15c4a76b5daae1cfa24932c Reviewed-on: https://webrtc-review.googlesource.com/c/112221 Commit-Queue: Benjamin Wright <benwright@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25865}
2018-11-30 16:18:26 -08:00
using ::testing::Return;
namespace webrtc {
namespace {
Reland "Refactor FrameDecryptorInterface::Decrypt to use new API." This reverts commit 7dd83e2bf73a7f1746c5ee976939bf52e19fa8be. Reason for revert: This wasn't the cause of the break. Original change's description: > Revert "Refactor FrameDecryptorInterface::Decrypt to use new API." > > This reverts commit 642aa81f7d5cc55d5b99e2abc51327eed9d40195. > > Reason for revert: Speculative revert. The chromium roll is failing: > https://ci.chromium.org/p/chromium/builders/try/linux-rel/64388 > But I can't figure out exactly what is failing, this looks suspecious. > > Original change's description: > > Refactor FrameDecryptorInterface::Decrypt to use new API. > > > > This change refactors the FrameDecryptorInterface to use the new API. The new > > API surface simply moves bytes_written to the return type and implements a > > simple Status type. > > > > Bug: webrtc:10512 > > Change-Id: I622c5d344d58e618853c94c2f691cf7c8fb73a36 > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/131460 > > Reviewed-by: Steve Anton <steveanton@webrtc.org> > > Reviewed-by: Fredrik Solenberg <solenberg@webrtc.org> > > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org> > > Reviewed-by: Stefan Holmer <stefan@webrtc.org> > > Commit-Queue: Benjamin Wright <benwright@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#27497} > > TBR=brandtr@webrtc.org,steveanton@webrtc.org,solenberg@webrtc.org,ossu@webrtc.org,stefan@webrtc.org,benwright@webrtc.org > > Change-Id: Ia9ec70263762c34671af13f0d519e636eb8473cd > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Bug: webrtc:10512 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/132013 > Reviewed-by: Henrik Boström <hbos@webrtc.org> > Commit-Queue: Henrik Boström <hbos@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#27510} TBR=brandtr@webrtc.org,steveanton@webrtc.org,solenberg@webrtc.org,hbos@webrtc.org,ossu@webrtc.org,stefan@webrtc.org,benwright@webrtc.org Change-Id: I8e4b7965cf1d1a1554c3b46e6245f5ad0d2dcbb4 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:10512 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/131982 Reviewed-by: Benjamin Wright <benwright@webrtc.org> Commit-Queue: Benjamin Wright <benwright@webrtc.org> Cr-Commit-Position: refs/heads/master@{#27529}
2019-04-09 20:08:41 +00:00
FrameDecryptorInterface::Result DecryptSuccess() {
return FrameDecryptorInterface::Result(FrameDecryptorInterface::Status::kOk,
0);
}
FrameDecryptorInterface::Result DecryptFail() {
return FrameDecryptorInterface::Result(
FrameDecryptorInterface::Status::kFailedToDecrypt, 0);
}
Add BufferedFrameDecryptor to cleanly deal with receiving encrypted frames. This change introduces a new class BufferedFrameDecryptor that is responsible for decrypting received encrypted frames and passing them on to the RtpReferenceFinder. This decoupling refactoring was triggered by a new optimization also introduced in this patch to stash a small number of undecryptable frames if no frames have ever been decrypted. The goal of this optimization is to prevent re-fectching of key frames on low bandwidth networks simply because the key to decrypt them had not arrived yet. The optimization will stash 24 frames (about 1 second of video) in a ring buffer and will attempt to re-decrypt previously received frames on the first valid decryption. This allows the decoder to receive the key frame without having to request due to short key delivery latencies. In testing this is actually hit quite often and saves an entire RTT which can be up to 200ms on a bad network. As the scope of frame encryption increases in WebRTC and has more specialized optimizations that do not apply to the general flow it makes sense to move it to a more explicit bump in the stack protocol that is decoupled from the WebRTC main flow, similar to how SRTP is utilized with srtp_protect and srtp_unprotect. One advantage of this approach is the BufferedFrameDecryptor isn't even constructed if FrameEncryption is not in use. I have decided against merging the RtpReferenceFinder and EncryptedFrame stash because it introduced a lot of complexity around the mixed scenario where some of the frames in the stash are encrypted and others are not. In this case we would need to mark certain frames as decrypted which appeared to introduce more complexity than this simple decoupling. Bug: webrtc:10022 Change-Id: Iab74f7b7d25ef1cdd15c4a76b5daae1cfa24932c Reviewed-on: https://webrtc-review.googlesource.com/c/112221 Commit-Queue: Benjamin Wright <benwright@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25865}
2018-11-30 16:18:26 -08:00
} // namespace
class BufferedFrameDecryptorTest : public ::testing::Test,
public OnDecryptedFrameCallback,
public OnDecryptionStatusChangeCallback {
Add BufferedFrameDecryptor to cleanly deal with receiving encrypted frames. This change introduces a new class BufferedFrameDecryptor that is responsible for decrypting received encrypted frames and passing them on to the RtpReferenceFinder. This decoupling refactoring was triggered by a new optimization also introduced in this patch to stash a small number of undecryptable frames if no frames have ever been decrypted. The goal of this optimization is to prevent re-fectching of key frames on low bandwidth networks simply because the key to decrypt them had not arrived yet. The optimization will stash 24 frames (about 1 second of video) in a ring buffer and will attempt to re-decrypt previously received frames on the first valid decryption. This allows the decoder to receive the key frame without having to request due to short key delivery latencies. In testing this is actually hit quite often and saves an entire RTT which can be up to 200ms on a bad network. As the scope of frame encryption increases in WebRTC and has more specialized optimizations that do not apply to the general flow it makes sense to move it to a more explicit bump in the stack protocol that is decoupled from the WebRTC main flow, similar to how SRTP is utilized with srtp_protect and srtp_unprotect. One advantage of this approach is the BufferedFrameDecryptor isn't even constructed if FrameEncryption is not in use. I have decided against merging the RtpReferenceFinder and EncryptedFrame stash because it introduced a lot of complexity around the mixed scenario where some of the frames in the stash are encrypted and others are not. In this case we would need to mark certain frames as decrypted which appeared to introduce more complexity than this simple decoupling. Bug: webrtc:10022 Change-Id: Iab74f7b7d25ef1cdd15c4a76b5daae1cfa24932c Reviewed-on: https://webrtc-review.googlesource.com/c/112221 Commit-Queue: Benjamin Wright <benwright@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25865}
2018-11-30 16:18:26 -08:00
public:
// Implements the OnDecryptedFrameCallbackInterface
void OnDecryptedFrame(std::unique_ptr<RtpFrameObject> frame) override {
Add BufferedFrameDecryptor to cleanly deal with receiving encrypted frames. This change introduces a new class BufferedFrameDecryptor that is responsible for decrypting received encrypted frames and passing them on to the RtpReferenceFinder. This decoupling refactoring was triggered by a new optimization also introduced in this patch to stash a small number of undecryptable frames if no frames have ever been decrypted. The goal of this optimization is to prevent re-fectching of key frames on low bandwidth networks simply because the key to decrypt them had not arrived yet. The optimization will stash 24 frames (about 1 second of video) in a ring buffer and will attempt to re-decrypt previously received frames on the first valid decryption. This allows the decoder to receive the key frame without having to request due to short key delivery latencies. In testing this is actually hit quite often and saves an entire RTT which can be up to 200ms on a bad network. As the scope of frame encryption increases in WebRTC and has more specialized optimizations that do not apply to the general flow it makes sense to move it to a more explicit bump in the stack protocol that is decoupled from the WebRTC main flow, similar to how SRTP is utilized with srtp_protect and srtp_unprotect. One advantage of this approach is the BufferedFrameDecryptor isn't even constructed if FrameEncryption is not in use. I have decided against merging the RtpReferenceFinder and EncryptedFrame stash because it introduced a lot of complexity around the mixed scenario where some of the frames in the stash are encrypted and others are not. In this case we would need to mark certain frames as decrypted which appeared to introduce more complexity than this simple decoupling. Bug: webrtc:10022 Change-Id: Iab74f7b7d25ef1cdd15c4a76b5daae1cfa24932c Reviewed-on: https://webrtc-review.googlesource.com/c/112221 Commit-Queue: Benjamin Wright <benwright@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25865}
2018-11-30 16:18:26 -08:00
decrypted_frame_call_count_++;
}
Reland "Refactor FrameDecryptorInterface::Decrypt to use new API." This reverts commit 7dd83e2bf73a7f1746c5ee976939bf52e19fa8be. Reason for revert: This wasn't the cause of the break. Original change's description: > Revert "Refactor FrameDecryptorInterface::Decrypt to use new API." > > This reverts commit 642aa81f7d5cc55d5b99e2abc51327eed9d40195. > > Reason for revert: Speculative revert. The chromium roll is failing: > https://ci.chromium.org/p/chromium/builders/try/linux-rel/64388 > But I can't figure out exactly what is failing, this looks suspecious. > > Original change's description: > > Refactor FrameDecryptorInterface::Decrypt to use new API. > > > > This change refactors the FrameDecryptorInterface to use the new API. The new > > API surface simply moves bytes_written to the return type and implements a > > simple Status type. > > > > Bug: webrtc:10512 > > Change-Id: I622c5d344d58e618853c94c2f691cf7c8fb73a36 > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/131460 > > Reviewed-by: Steve Anton <steveanton@webrtc.org> > > Reviewed-by: Fredrik Solenberg <solenberg@webrtc.org> > > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org> > > Reviewed-by: Stefan Holmer <stefan@webrtc.org> > > Commit-Queue: Benjamin Wright <benwright@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#27497} > > TBR=brandtr@webrtc.org,steveanton@webrtc.org,solenberg@webrtc.org,ossu@webrtc.org,stefan@webrtc.org,benwright@webrtc.org > > Change-Id: Ia9ec70263762c34671af13f0d519e636eb8473cd > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Bug: webrtc:10512 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/132013 > Reviewed-by: Henrik Boström <hbos@webrtc.org> > Commit-Queue: Henrik Boström <hbos@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#27510} TBR=brandtr@webrtc.org,steveanton@webrtc.org,solenberg@webrtc.org,hbos@webrtc.org,ossu@webrtc.org,stefan@webrtc.org,benwright@webrtc.org Change-Id: I8e4b7965cf1d1a1554c3b46e6245f5ad0d2dcbb4 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:10512 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/131982 Reviewed-by: Benjamin Wright <benwright@webrtc.org> Commit-Queue: Benjamin Wright <benwright@webrtc.org> Cr-Commit-Position: refs/heads/master@{#27529}
2019-04-09 20:08:41 +00:00
void OnDecryptionStatusChange(FrameDecryptorInterface::Status status) {
++decryption_status_change_count_;
}
Add BufferedFrameDecryptor to cleanly deal with receiving encrypted frames. This change introduces a new class BufferedFrameDecryptor that is responsible for decrypting received encrypted frames and passing them on to the RtpReferenceFinder. This decoupling refactoring was triggered by a new optimization also introduced in this patch to stash a small number of undecryptable frames if no frames have ever been decrypted. The goal of this optimization is to prevent re-fectching of key frames on low bandwidth networks simply because the key to decrypt them had not arrived yet. The optimization will stash 24 frames (about 1 second of video) in a ring buffer and will attempt to re-decrypt previously received frames on the first valid decryption. This allows the decoder to receive the key frame without having to request due to short key delivery latencies. In testing this is actually hit quite often and saves an entire RTT which can be up to 200ms on a bad network. As the scope of frame encryption increases in WebRTC and has more specialized optimizations that do not apply to the general flow it makes sense to move it to a more explicit bump in the stack protocol that is decoupled from the WebRTC main flow, similar to how SRTP is utilized with srtp_protect and srtp_unprotect. One advantage of this approach is the BufferedFrameDecryptor isn't even constructed if FrameEncryption is not in use. I have decided against merging the RtpReferenceFinder and EncryptedFrame stash because it introduced a lot of complexity around the mixed scenario where some of the frames in the stash are encrypted and others are not. In this case we would need to mark certain frames as decrypted which appeared to introduce more complexity than this simple decoupling. Bug: webrtc:10022 Change-Id: Iab74f7b7d25ef1cdd15c4a76b5daae1cfa24932c Reviewed-on: https://webrtc-review.googlesource.com/c/112221 Commit-Queue: Benjamin Wright <benwright@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25865}
2018-11-30 16:18:26 -08:00
// Returns a new fake RtpFrameObject it abstracts the difficult construction
// of the RtpFrameObject to simplify testing.
std::unique_ptr<RtpFrameObject> CreateRtpFrameObject(bool key_frame) {
Add BufferedFrameDecryptor to cleanly deal with receiving encrypted frames. This change introduces a new class BufferedFrameDecryptor that is responsible for decrypting received encrypted frames and passing them on to the RtpReferenceFinder. This decoupling refactoring was triggered by a new optimization also introduced in this patch to stash a small number of undecryptable frames if no frames have ever been decrypted. The goal of this optimization is to prevent re-fectching of key frames on low bandwidth networks simply because the key to decrypt them had not arrived yet. The optimization will stash 24 frames (about 1 second of video) in a ring buffer and will attempt to re-decrypt previously received frames on the first valid decryption. This allows the decoder to receive the key frame without having to request due to short key delivery latencies. In testing this is actually hit quite often and saves an entire RTT which can be up to 200ms on a bad network. As the scope of frame encryption increases in WebRTC and has more specialized optimizations that do not apply to the general flow it makes sense to move it to a more explicit bump in the stack protocol that is decoupled from the WebRTC main flow, similar to how SRTP is utilized with srtp_protect and srtp_unprotect. One advantage of this approach is the BufferedFrameDecryptor isn't even constructed if FrameEncryption is not in use. I have decided against merging the RtpReferenceFinder and EncryptedFrame stash because it introduced a lot of complexity around the mixed scenario where some of the frames in the stash are encrypted and others are not. In this case we would need to mark certain frames as decrypted which appeared to introduce more complexity than this simple decoupling. Bug: webrtc:10022 Change-Id: Iab74f7b7d25ef1cdd15c4a76b5daae1cfa24932c Reviewed-on: https://webrtc-review.googlesource.com/c/112221 Commit-Queue: Benjamin Wright <benwright@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25865}
2018-11-30 16:18:26 -08:00
seq_num_++;
RTPVideoHeader rtp_video_header;
rtp_video_header.generic.emplace();
Add BufferedFrameDecryptor to cleanly deal with receiving encrypted frames. This change introduces a new class BufferedFrameDecryptor that is responsible for decrypting received encrypted frames and passing them on to the RtpReferenceFinder. This decoupling refactoring was triggered by a new optimization also introduced in this patch to stash a small number of undecryptable frames if no frames have ever been decrypted. The goal of this optimization is to prevent re-fectching of key frames on low bandwidth networks simply because the key to decrypt them had not arrived yet. The optimization will stash 24 frames (about 1 second of video) in a ring buffer and will attempt to re-decrypt previously received frames on the first valid decryption. This allows the decoder to receive the key frame without having to request due to short key delivery latencies. In testing this is actually hit quite often and saves an entire RTT which can be up to 200ms on a bad network. As the scope of frame encryption increases in WebRTC and has more specialized optimizations that do not apply to the general flow it makes sense to move it to a more explicit bump in the stack protocol that is decoupled from the WebRTC main flow, similar to how SRTP is utilized with srtp_protect and srtp_unprotect. One advantage of this approach is the BufferedFrameDecryptor isn't even constructed if FrameEncryption is not in use. I have decided against merging the RtpReferenceFinder and EncryptedFrame stash because it introduced a lot of complexity around the mixed scenario where some of the frames in the stash are encrypted and others are not. In this case we would need to mark certain frames as decrypted which appeared to introduce more complexity than this simple decoupling. Bug: webrtc:10022 Change-Id: Iab74f7b7d25ef1cdd15c4a76b5daae1cfa24932c Reviewed-on: https://webrtc-review.googlesource.com/c/112221 Commit-Queue: Benjamin Wright <benwright@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25865}
2018-11-30 16:18:26 -08:00
// clang-format off
return std::make_unique<RtpFrameObject>(
seq_num_,
seq_num_,
/*markerBit=*/true,
/*times_nacked=*/0,
/*first_packet_received_time=*/0,
/*last_packet_received_time=*/0,
/*rtp_timestamp=*/0,
/*ntp_time_ms=*/0,
VideoSendTiming(),
/*payload_type=*/0,
kVideoCodecGeneric,
kVideoRotation_0,
VideoContentType::UNSPECIFIED,
rtp_video_header,
/*color_space=*/std::nullopt,
/*frame_instrumentation_data=*/std::nullopt,
RtpPacketInfos(),
EncodedImageBuffer::Create(/*size=*/0));
// clang-format on
Add BufferedFrameDecryptor to cleanly deal with receiving encrypted frames. This change introduces a new class BufferedFrameDecryptor that is responsible for decrypting received encrypted frames and passing them on to the RtpReferenceFinder. This decoupling refactoring was triggered by a new optimization also introduced in this patch to stash a small number of undecryptable frames if no frames have ever been decrypted. The goal of this optimization is to prevent re-fectching of key frames on low bandwidth networks simply because the key to decrypt them had not arrived yet. The optimization will stash 24 frames (about 1 second of video) in a ring buffer and will attempt to re-decrypt previously received frames on the first valid decryption. This allows the decoder to receive the key frame without having to request due to short key delivery latencies. In testing this is actually hit quite often and saves an entire RTT which can be up to 200ms on a bad network. As the scope of frame encryption increases in WebRTC and has more specialized optimizations that do not apply to the general flow it makes sense to move it to a more explicit bump in the stack protocol that is decoupled from the WebRTC main flow, similar to how SRTP is utilized with srtp_protect and srtp_unprotect. One advantage of this approach is the BufferedFrameDecryptor isn't even constructed if FrameEncryption is not in use. I have decided against merging the RtpReferenceFinder and EncryptedFrame stash because it introduced a lot of complexity around the mixed scenario where some of the frames in the stash are encrypted and others are not. In this case we would need to mark certain frames as decrypted which appeared to introduce more complexity than this simple decoupling. Bug: webrtc:10022 Change-Id: Iab74f7b7d25ef1cdd15c4a76b5daae1cfa24932c Reviewed-on: https://webrtc-review.googlesource.com/c/112221 Commit-Queue: Benjamin Wright <benwright@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25865}
2018-11-30 16:18:26 -08:00
}
protected:
BufferedFrameDecryptorTest() {
Add BufferedFrameDecryptor to cleanly deal with receiving encrypted frames. This change introduces a new class BufferedFrameDecryptor that is responsible for decrypting received encrypted frames and passing them on to the RtpReferenceFinder. This decoupling refactoring was triggered by a new optimization also introduced in this patch to stash a small number of undecryptable frames if no frames have ever been decrypted. The goal of this optimization is to prevent re-fectching of key frames on low bandwidth networks simply because the key to decrypt them had not arrived yet. The optimization will stash 24 frames (about 1 second of video) in a ring buffer and will attempt to re-decrypt previously received frames on the first valid decryption. This allows the decoder to receive the key frame without having to request due to short key delivery latencies. In testing this is actually hit quite often and saves an entire RTT which can be up to 200ms on a bad network. As the scope of frame encryption increases in WebRTC and has more specialized optimizations that do not apply to the general flow it makes sense to move it to a more explicit bump in the stack protocol that is decoupled from the WebRTC main flow, similar to how SRTP is utilized with srtp_protect and srtp_unprotect. One advantage of this approach is the BufferedFrameDecryptor isn't even constructed if FrameEncryption is not in use. I have decided against merging the RtpReferenceFinder and EncryptedFrame stash because it introduced a lot of complexity around the mixed scenario where some of the frames in the stash are encrypted and others are not. In this case we would need to mark certain frames as decrypted which appeared to introduce more complexity than this simple decoupling. Bug: webrtc:10022 Change-Id: Iab74f7b7d25ef1cdd15c4a76b5daae1cfa24932c Reviewed-on: https://webrtc-review.googlesource.com/c/112221 Commit-Queue: Benjamin Wright <benwright@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25865}
2018-11-30 16:18:26 -08:00
fake_packet_data_ = std::vector<uint8_t>(100);
decrypted_frame_call_count_ = 0;
decryption_status_change_count_ = 0;
Add BufferedFrameDecryptor to cleanly deal with receiving encrypted frames. This change introduces a new class BufferedFrameDecryptor that is responsible for decrypting received encrypted frames and passing them on to the RtpReferenceFinder. This decoupling refactoring was triggered by a new optimization also introduced in this patch to stash a small number of undecryptable frames if no frames have ever been decrypted. The goal of this optimization is to prevent re-fectching of key frames on low bandwidth networks simply because the key to decrypt them had not arrived yet. The optimization will stash 24 frames (about 1 second of video) in a ring buffer and will attempt to re-decrypt previously received frames on the first valid decryption. This allows the decoder to receive the key frame without having to request due to short key delivery latencies. In testing this is actually hit quite often and saves an entire RTT which can be up to 200ms on a bad network. As the scope of frame encryption increases in WebRTC and has more specialized optimizations that do not apply to the general flow it makes sense to move it to a more explicit bump in the stack protocol that is decoupled from the WebRTC main flow, similar to how SRTP is utilized with srtp_protect and srtp_unprotect. One advantage of this approach is the BufferedFrameDecryptor isn't even constructed if FrameEncryption is not in use. I have decided against merging the RtpReferenceFinder and EncryptedFrame stash because it introduced a lot of complexity around the mixed scenario where some of the frames in the stash are encrypted and others are not. In this case we would need to mark certain frames as decrypted which appeared to introduce more complexity than this simple decoupling. Bug: webrtc:10022 Change-Id: Iab74f7b7d25ef1cdd15c4a76b5daae1cfa24932c Reviewed-on: https://webrtc-review.googlesource.com/c/112221 Commit-Queue: Benjamin Wright <benwright@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25865}
2018-11-30 16:18:26 -08:00
seq_num_ = 0;
mock_frame_decryptor_ = rtc::make_ref_counted<MockFrameDecryptor>();
buffered_frame_decryptor_ =
std::make_unique<BufferedFrameDecryptor>(this, this, field_trials_);
buffered_frame_decryptor_->SetFrameDecryptor(mock_frame_decryptor_);
Add BufferedFrameDecryptor to cleanly deal with receiving encrypted frames. This change introduces a new class BufferedFrameDecryptor that is responsible for decrypting received encrypted frames and passing them on to the RtpReferenceFinder. This decoupling refactoring was triggered by a new optimization also introduced in this patch to stash a small number of undecryptable frames if no frames have ever been decrypted. The goal of this optimization is to prevent re-fectching of key frames on low bandwidth networks simply because the key to decrypt them had not arrived yet. The optimization will stash 24 frames (about 1 second of video) in a ring buffer and will attempt to re-decrypt previously received frames on the first valid decryption. This allows the decoder to receive the key frame without having to request due to short key delivery latencies. In testing this is actually hit quite often and saves an entire RTT which can be up to 200ms on a bad network. As the scope of frame encryption increases in WebRTC and has more specialized optimizations that do not apply to the general flow it makes sense to move it to a more explicit bump in the stack protocol that is decoupled from the WebRTC main flow, similar to how SRTP is utilized with srtp_protect and srtp_unprotect. One advantage of this approach is the BufferedFrameDecryptor isn't even constructed if FrameEncryption is not in use. I have decided against merging the RtpReferenceFinder and EncryptedFrame stash because it introduced a lot of complexity around the mixed scenario where some of the frames in the stash are encrypted and others are not. In this case we would need to mark certain frames as decrypted which appeared to introduce more complexity than this simple decoupling. Bug: webrtc:10022 Change-Id: Iab74f7b7d25ef1cdd15c4a76b5daae1cfa24932c Reviewed-on: https://webrtc-review.googlesource.com/c/112221 Commit-Queue: Benjamin Wright <benwright@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25865}
2018-11-30 16:18:26 -08:00
}
static const size_t kMaxStashedFrames;
test::ScopedKeyValueConfig field_trials_;
Add BufferedFrameDecryptor to cleanly deal with receiving encrypted frames. This change introduces a new class BufferedFrameDecryptor that is responsible for decrypting received encrypted frames and passing them on to the RtpReferenceFinder. This decoupling refactoring was triggered by a new optimization also introduced in this patch to stash a small number of undecryptable frames if no frames have ever been decrypted. The goal of this optimization is to prevent re-fectching of key frames on low bandwidth networks simply because the key to decrypt them had not arrived yet. The optimization will stash 24 frames (about 1 second of video) in a ring buffer and will attempt to re-decrypt previously received frames on the first valid decryption. This allows the decoder to receive the key frame without having to request due to short key delivery latencies. In testing this is actually hit quite often and saves an entire RTT which can be up to 200ms on a bad network. As the scope of frame encryption increases in WebRTC and has more specialized optimizations that do not apply to the general flow it makes sense to move it to a more explicit bump in the stack protocol that is decoupled from the WebRTC main flow, similar to how SRTP is utilized with srtp_protect and srtp_unprotect. One advantage of this approach is the BufferedFrameDecryptor isn't even constructed if FrameEncryption is not in use. I have decided against merging the RtpReferenceFinder and EncryptedFrame stash because it introduced a lot of complexity around the mixed scenario where some of the frames in the stash are encrypted and others are not. In this case we would need to mark certain frames as decrypted which appeared to introduce more complexity than this simple decoupling. Bug: webrtc:10022 Change-Id: Iab74f7b7d25ef1cdd15c4a76b5daae1cfa24932c Reviewed-on: https://webrtc-review.googlesource.com/c/112221 Commit-Queue: Benjamin Wright <benwright@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25865}
2018-11-30 16:18:26 -08:00
std::vector<uint8_t> fake_packet_data_;
rtc::scoped_refptr<MockFrameDecryptor> mock_frame_decryptor_;
std::unique_ptr<BufferedFrameDecryptor> buffered_frame_decryptor_;
size_t decrypted_frame_call_count_;
size_t decryption_status_change_count_ = 0;
Add BufferedFrameDecryptor to cleanly deal with receiving encrypted frames. This change introduces a new class BufferedFrameDecryptor that is responsible for decrypting received encrypted frames and passing them on to the RtpReferenceFinder. This decoupling refactoring was triggered by a new optimization also introduced in this patch to stash a small number of undecryptable frames if no frames have ever been decrypted. The goal of this optimization is to prevent re-fectching of key frames on low bandwidth networks simply because the key to decrypt them had not arrived yet. The optimization will stash 24 frames (about 1 second of video) in a ring buffer and will attempt to re-decrypt previously received frames on the first valid decryption. This allows the decoder to receive the key frame without having to request due to short key delivery latencies. In testing this is actually hit quite often and saves an entire RTT which can be up to 200ms on a bad network. As the scope of frame encryption increases in WebRTC and has more specialized optimizations that do not apply to the general flow it makes sense to move it to a more explicit bump in the stack protocol that is decoupled from the WebRTC main flow, similar to how SRTP is utilized with srtp_protect and srtp_unprotect. One advantage of this approach is the BufferedFrameDecryptor isn't even constructed if FrameEncryption is not in use. I have decided against merging the RtpReferenceFinder and EncryptedFrame stash because it introduced a lot of complexity around the mixed scenario where some of the frames in the stash are encrypted and others are not. In this case we would need to mark certain frames as decrypted which appeared to introduce more complexity than this simple decoupling. Bug: webrtc:10022 Change-Id: Iab74f7b7d25ef1cdd15c4a76b5daae1cfa24932c Reviewed-on: https://webrtc-review.googlesource.com/c/112221 Commit-Queue: Benjamin Wright <benwright@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25865}
2018-11-30 16:18:26 -08:00
uint16_t seq_num_;
};
const size_t BufferedFrameDecryptorTest::kMaxStashedFrames = 24;
// Callback should always be triggered on a successful decryption.
TEST_F(BufferedFrameDecryptorTest, CallbackCalledOnSuccessfulDecryption) {
Reland "Refactor FrameDecryptorInterface::Decrypt to use new API." This reverts commit 7dd83e2bf73a7f1746c5ee976939bf52e19fa8be. Reason for revert: This wasn't the cause of the break. Original change's description: > Revert "Refactor FrameDecryptorInterface::Decrypt to use new API." > > This reverts commit 642aa81f7d5cc55d5b99e2abc51327eed9d40195. > > Reason for revert: Speculative revert. The chromium roll is failing: > https://ci.chromium.org/p/chromium/builders/try/linux-rel/64388 > But I can't figure out exactly what is failing, this looks suspecious. > > Original change's description: > > Refactor FrameDecryptorInterface::Decrypt to use new API. > > > > This change refactors the FrameDecryptorInterface to use the new API. The new > > API surface simply moves bytes_written to the return type and implements a > > simple Status type. > > > > Bug: webrtc:10512 > > Change-Id: I622c5d344d58e618853c94c2f691cf7c8fb73a36 > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/131460 > > Reviewed-by: Steve Anton <steveanton@webrtc.org> > > Reviewed-by: Fredrik Solenberg <solenberg@webrtc.org> > > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org> > > Reviewed-by: Stefan Holmer <stefan@webrtc.org> > > Commit-Queue: Benjamin Wright <benwright@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#27497} > > TBR=brandtr@webrtc.org,steveanton@webrtc.org,solenberg@webrtc.org,ossu@webrtc.org,stefan@webrtc.org,benwright@webrtc.org > > Change-Id: Ia9ec70263762c34671af13f0d519e636eb8473cd > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Bug: webrtc:10512 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/132013 > Reviewed-by: Henrik Boström <hbos@webrtc.org> > Commit-Queue: Henrik Boström <hbos@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#27510} TBR=brandtr@webrtc.org,steveanton@webrtc.org,solenberg@webrtc.org,hbos@webrtc.org,ossu@webrtc.org,stefan@webrtc.org,benwright@webrtc.org Change-Id: I8e4b7965cf1d1a1554c3b46e6245f5ad0d2dcbb4 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:10512 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/131982 Reviewed-by: Benjamin Wright <benwright@webrtc.org> Commit-Queue: Benjamin Wright <benwright@webrtc.org> Cr-Commit-Position: refs/heads/master@{#27529}
2019-04-09 20:08:41 +00:00
EXPECT_CALL(*mock_frame_decryptor_, Decrypt)
.Times(1)
.WillOnce(Return(DecryptSuccess()));
Add BufferedFrameDecryptor to cleanly deal with receiving encrypted frames. This change introduces a new class BufferedFrameDecryptor that is responsible for decrypting received encrypted frames and passing them on to the RtpReferenceFinder. This decoupling refactoring was triggered by a new optimization also introduced in this patch to stash a small number of undecryptable frames if no frames have ever been decrypted. The goal of this optimization is to prevent re-fectching of key frames on low bandwidth networks simply because the key to decrypt them had not arrived yet. The optimization will stash 24 frames (about 1 second of video) in a ring buffer and will attempt to re-decrypt previously received frames on the first valid decryption. This allows the decoder to receive the key frame without having to request due to short key delivery latencies. In testing this is actually hit quite often and saves an entire RTT which can be up to 200ms on a bad network. As the scope of frame encryption increases in WebRTC and has more specialized optimizations that do not apply to the general flow it makes sense to move it to a more explicit bump in the stack protocol that is decoupled from the WebRTC main flow, similar to how SRTP is utilized with srtp_protect and srtp_unprotect. One advantage of this approach is the BufferedFrameDecryptor isn't even constructed if FrameEncryption is not in use. I have decided against merging the RtpReferenceFinder and EncryptedFrame stash because it introduced a lot of complexity around the mixed scenario where some of the frames in the stash are encrypted and others are not. In this case we would need to mark certain frames as decrypted which appeared to introduce more complexity than this simple decoupling. Bug: webrtc:10022 Change-Id: Iab74f7b7d25ef1cdd15c4a76b5daae1cfa24932c Reviewed-on: https://webrtc-review.googlesource.com/c/112221 Commit-Queue: Benjamin Wright <benwright@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25865}
2018-11-30 16:18:26 -08:00
EXPECT_CALL(*mock_frame_decryptor_, GetMaxPlaintextByteSize)
.Times(1)
.WillOnce(Return(0));
buffered_frame_decryptor_->ManageEncryptedFrame(CreateRtpFrameObject(true));
EXPECT_EQ(decrypted_frame_call_count_, static_cast<size_t>(1));
EXPECT_EQ(decryption_status_change_count_, static_cast<size_t>(1));
Add BufferedFrameDecryptor to cleanly deal with receiving encrypted frames. This change introduces a new class BufferedFrameDecryptor that is responsible for decrypting received encrypted frames and passing them on to the RtpReferenceFinder. This decoupling refactoring was triggered by a new optimization also introduced in this patch to stash a small number of undecryptable frames if no frames have ever been decrypted. The goal of this optimization is to prevent re-fectching of key frames on low bandwidth networks simply because the key to decrypt them had not arrived yet. The optimization will stash 24 frames (about 1 second of video) in a ring buffer and will attempt to re-decrypt previously received frames on the first valid decryption. This allows the decoder to receive the key frame without having to request due to short key delivery latencies. In testing this is actually hit quite often and saves an entire RTT which can be up to 200ms on a bad network. As the scope of frame encryption increases in WebRTC and has more specialized optimizations that do not apply to the general flow it makes sense to move it to a more explicit bump in the stack protocol that is decoupled from the WebRTC main flow, similar to how SRTP is utilized with srtp_protect and srtp_unprotect. One advantage of this approach is the BufferedFrameDecryptor isn't even constructed if FrameEncryption is not in use. I have decided against merging the RtpReferenceFinder and EncryptedFrame stash because it introduced a lot of complexity around the mixed scenario where some of the frames in the stash are encrypted and others are not. In this case we would need to mark certain frames as decrypted which appeared to introduce more complexity than this simple decoupling. Bug: webrtc:10022 Change-Id: Iab74f7b7d25ef1cdd15c4a76b5daae1cfa24932c Reviewed-on: https://webrtc-review.googlesource.com/c/112221 Commit-Queue: Benjamin Wright <benwright@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25865}
2018-11-30 16:18:26 -08:00
}
// An initial fail to decrypt should not trigger the callback.
TEST_F(BufferedFrameDecryptorTest, CallbackNotCalledOnFailedDecryption) {
Reland "Refactor FrameDecryptorInterface::Decrypt to use new API." This reverts commit 7dd83e2bf73a7f1746c5ee976939bf52e19fa8be. Reason for revert: This wasn't the cause of the break. Original change's description: > Revert "Refactor FrameDecryptorInterface::Decrypt to use new API." > > This reverts commit 642aa81f7d5cc55d5b99e2abc51327eed9d40195. > > Reason for revert: Speculative revert. The chromium roll is failing: > https://ci.chromium.org/p/chromium/builders/try/linux-rel/64388 > But I can't figure out exactly what is failing, this looks suspecious. > > Original change's description: > > Refactor FrameDecryptorInterface::Decrypt to use new API. > > > > This change refactors the FrameDecryptorInterface to use the new API. The new > > API surface simply moves bytes_written to the return type and implements a > > simple Status type. > > > > Bug: webrtc:10512 > > Change-Id: I622c5d344d58e618853c94c2f691cf7c8fb73a36 > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/131460 > > Reviewed-by: Steve Anton <steveanton@webrtc.org> > > Reviewed-by: Fredrik Solenberg <solenberg@webrtc.org> > > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org> > > Reviewed-by: Stefan Holmer <stefan@webrtc.org> > > Commit-Queue: Benjamin Wright <benwright@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#27497} > > TBR=brandtr@webrtc.org,steveanton@webrtc.org,solenberg@webrtc.org,ossu@webrtc.org,stefan@webrtc.org,benwright@webrtc.org > > Change-Id: Ia9ec70263762c34671af13f0d519e636eb8473cd > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Bug: webrtc:10512 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/132013 > Reviewed-by: Henrik Boström <hbos@webrtc.org> > Commit-Queue: Henrik Boström <hbos@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#27510} TBR=brandtr@webrtc.org,steveanton@webrtc.org,solenberg@webrtc.org,hbos@webrtc.org,ossu@webrtc.org,stefan@webrtc.org,benwright@webrtc.org Change-Id: I8e4b7965cf1d1a1554c3b46e6245f5ad0d2dcbb4 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:10512 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/131982 Reviewed-by: Benjamin Wright <benwright@webrtc.org> Commit-Queue: Benjamin Wright <benwright@webrtc.org> Cr-Commit-Position: refs/heads/master@{#27529}
2019-04-09 20:08:41 +00:00
EXPECT_CALL(*mock_frame_decryptor_, Decrypt)
.Times(1)
.WillOnce(Return(DecryptFail()));
Add BufferedFrameDecryptor to cleanly deal with receiving encrypted frames. This change introduces a new class BufferedFrameDecryptor that is responsible for decrypting received encrypted frames and passing them on to the RtpReferenceFinder. This decoupling refactoring was triggered by a new optimization also introduced in this patch to stash a small number of undecryptable frames if no frames have ever been decrypted. The goal of this optimization is to prevent re-fectching of key frames on low bandwidth networks simply because the key to decrypt them had not arrived yet. The optimization will stash 24 frames (about 1 second of video) in a ring buffer and will attempt to re-decrypt previously received frames on the first valid decryption. This allows the decoder to receive the key frame without having to request due to short key delivery latencies. In testing this is actually hit quite often and saves an entire RTT which can be up to 200ms on a bad network. As the scope of frame encryption increases in WebRTC and has more specialized optimizations that do not apply to the general flow it makes sense to move it to a more explicit bump in the stack protocol that is decoupled from the WebRTC main flow, similar to how SRTP is utilized with srtp_protect and srtp_unprotect. One advantage of this approach is the BufferedFrameDecryptor isn't even constructed if FrameEncryption is not in use. I have decided against merging the RtpReferenceFinder and EncryptedFrame stash because it introduced a lot of complexity around the mixed scenario where some of the frames in the stash are encrypted and others are not. In this case we would need to mark certain frames as decrypted which appeared to introduce more complexity than this simple decoupling. Bug: webrtc:10022 Change-Id: Iab74f7b7d25ef1cdd15c4a76b5daae1cfa24932c Reviewed-on: https://webrtc-review.googlesource.com/c/112221 Commit-Queue: Benjamin Wright <benwright@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25865}
2018-11-30 16:18:26 -08:00
EXPECT_CALL(*mock_frame_decryptor_, GetMaxPlaintextByteSize)
.Times(1)
.WillOnce(Return(0));
buffered_frame_decryptor_->ManageEncryptedFrame(CreateRtpFrameObject(true));
EXPECT_EQ(decrypted_frame_call_count_, static_cast<size_t>(0));
EXPECT_EQ(decryption_status_change_count_, static_cast<size_t>(1));
Add BufferedFrameDecryptor to cleanly deal with receiving encrypted frames. This change introduces a new class BufferedFrameDecryptor that is responsible for decrypting received encrypted frames and passing them on to the RtpReferenceFinder. This decoupling refactoring was triggered by a new optimization also introduced in this patch to stash a small number of undecryptable frames if no frames have ever been decrypted. The goal of this optimization is to prevent re-fectching of key frames on low bandwidth networks simply because the key to decrypt them had not arrived yet. The optimization will stash 24 frames (about 1 second of video) in a ring buffer and will attempt to re-decrypt previously received frames on the first valid decryption. This allows the decoder to receive the key frame without having to request due to short key delivery latencies. In testing this is actually hit quite often and saves an entire RTT which can be up to 200ms on a bad network. As the scope of frame encryption increases in WebRTC and has more specialized optimizations that do not apply to the general flow it makes sense to move it to a more explicit bump in the stack protocol that is decoupled from the WebRTC main flow, similar to how SRTP is utilized with srtp_protect and srtp_unprotect. One advantage of this approach is the BufferedFrameDecryptor isn't even constructed if FrameEncryption is not in use. I have decided against merging the RtpReferenceFinder and EncryptedFrame stash because it introduced a lot of complexity around the mixed scenario where some of the frames in the stash are encrypted and others are not. In this case we would need to mark certain frames as decrypted which appeared to introduce more complexity than this simple decoupling. Bug: webrtc:10022 Change-Id: Iab74f7b7d25ef1cdd15c4a76b5daae1cfa24932c Reviewed-on: https://webrtc-review.googlesource.com/c/112221 Commit-Queue: Benjamin Wright <benwright@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25865}
2018-11-30 16:18:26 -08:00
}
// Initial failures should be stored and retried after the first successful
// decryption.
TEST_F(BufferedFrameDecryptorTest, DelayedCallbackOnBufferedFrames) {
EXPECT_CALL(*mock_frame_decryptor_, Decrypt)
.Times(3)
Reland "Refactor FrameDecryptorInterface::Decrypt to use new API." This reverts commit 7dd83e2bf73a7f1746c5ee976939bf52e19fa8be. Reason for revert: This wasn't the cause of the break. Original change's description: > Revert "Refactor FrameDecryptorInterface::Decrypt to use new API." > > This reverts commit 642aa81f7d5cc55d5b99e2abc51327eed9d40195. > > Reason for revert: Speculative revert. The chromium roll is failing: > https://ci.chromium.org/p/chromium/builders/try/linux-rel/64388 > But I can't figure out exactly what is failing, this looks suspecious. > > Original change's description: > > Refactor FrameDecryptorInterface::Decrypt to use new API. > > > > This change refactors the FrameDecryptorInterface to use the new API. The new > > API surface simply moves bytes_written to the return type and implements a > > simple Status type. > > > > Bug: webrtc:10512 > > Change-Id: I622c5d344d58e618853c94c2f691cf7c8fb73a36 > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/131460 > > Reviewed-by: Steve Anton <steveanton@webrtc.org> > > Reviewed-by: Fredrik Solenberg <solenberg@webrtc.org> > > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org> > > Reviewed-by: Stefan Holmer <stefan@webrtc.org> > > Commit-Queue: Benjamin Wright <benwright@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#27497} > > TBR=brandtr@webrtc.org,steveanton@webrtc.org,solenberg@webrtc.org,ossu@webrtc.org,stefan@webrtc.org,benwright@webrtc.org > > Change-Id: Ia9ec70263762c34671af13f0d519e636eb8473cd > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Bug: webrtc:10512 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/132013 > Reviewed-by: Henrik Boström <hbos@webrtc.org> > Commit-Queue: Henrik Boström <hbos@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#27510} TBR=brandtr@webrtc.org,steveanton@webrtc.org,solenberg@webrtc.org,hbos@webrtc.org,ossu@webrtc.org,stefan@webrtc.org,benwright@webrtc.org Change-Id: I8e4b7965cf1d1a1554c3b46e6245f5ad0d2dcbb4 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:10512 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/131982 Reviewed-by: Benjamin Wright <benwright@webrtc.org> Commit-Queue: Benjamin Wright <benwright@webrtc.org> Cr-Commit-Position: refs/heads/master@{#27529}
2019-04-09 20:08:41 +00:00
.WillOnce(Return(DecryptFail()))
.WillOnce(Return(DecryptSuccess()))
.WillOnce(Return(DecryptSuccess()));
Add BufferedFrameDecryptor to cleanly deal with receiving encrypted frames. This change introduces a new class BufferedFrameDecryptor that is responsible for decrypting received encrypted frames and passing them on to the RtpReferenceFinder. This decoupling refactoring was triggered by a new optimization also introduced in this patch to stash a small number of undecryptable frames if no frames have ever been decrypted. The goal of this optimization is to prevent re-fectching of key frames on low bandwidth networks simply because the key to decrypt them had not arrived yet. The optimization will stash 24 frames (about 1 second of video) in a ring buffer and will attempt to re-decrypt previously received frames on the first valid decryption. This allows the decoder to receive the key frame without having to request due to short key delivery latencies. In testing this is actually hit quite often and saves an entire RTT which can be up to 200ms on a bad network. As the scope of frame encryption increases in WebRTC and has more specialized optimizations that do not apply to the general flow it makes sense to move it to a more explicit bump in the stack protocol that is decoupled from the WebRTC main flow, similar to how SRTP is utilized with srtp_protect and srtp_unprotect. One advantage of this approach is the BufferedFrameDecryptor isn't even constructed if FrameEncryption is not in use. I have decided against merging the RtpReferenceFinder and EncryptedFrame stash because it introduced a lot of complexity around the mixed scenario where some of the frames in the stash are encrypted and others are not. In this case we would need to mark certain frames as decrypted which appeared to introduce more complexity than this simple decoupling. Bug: webrtc:10022 Change-Id: Iab74f7b7d25ef1cdd15c4a76b5daae1cfa24932c Reviewed-on: https://webrtc-review.googlesource.com/c/112221 Commit-Queue: Benjamin Wright <benwright@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25865}
2018-11-30 16:18:26 -08:00
EXPECT_CALL(*mock_frame_decryptor_, GetMaxPlaintextByteSize)
.Times(3)
.WillRepeatedly(Return(0));
// The first decrypt will fail stashing the first frame.
buffered_frame_decryptor_->ManageEncryptedFrame(CreateRtpFrameObject(true));
EXPECT_EQ(decrypted_frame_call_count_, static_cast<size_t>(0));
EXPECT_EQ(decryption_status_change_count_, static_cast<size_t>(1));
Add BufferedFrameDecryptor to cleanly deal with receiving encrypted frames. This change introduces a new class BufferedFrameDecryptor that is responsible for decrypting received encrypted frames and passing them on to the RtpReferenceFinder. This decoupling refactoring was triggered by a new optimization also introduced in this patch to stash a small number of undecryptable frames if no frames have ever been decrypted. The goal of this optimization is to prevent re-fectching of key frames on low bandwidth networks simply because the key to decrypt them had not arrived yet. The optimization will stash 24 frames (about 1 second of video) in a ring buffer and will attempt to re-decrypt previously received frames on the first valid decryption. This allows the decoder to receive the key frame without having to request due to short key delivery latencies. In testing this is actually hit quite often and saves an entire RTT which can be up to 200ms on a bad network. As the scope of frame encryption increases in WebRTC and has more specialized optimizations that do not apply to the general flow it makes sense to move it to a more explicit bump in the stack protocol that is decoupled from the WebRTC main flow, similar to how SRTP is utilized with srtp_protect and srtp_unprotect. One advantage of this approach is the BufferedFrameDecryptor isn't even constructed if FrameEncryption is not in use. I have decided against merging the RtpReferenceFinder and EncryptedFrame stash because it introduced a lot of complexity around the mixed scenario where some of the frames in the stash are encrypted and others are not. In this case we would need to mark certain frames as decrypted which appeared to introduce more complexity than this simple decoupling. Bug: webrtc:10022 Change-Id: Iab74f7b7d25ef1cdd15c4a76b5daae1cfa24932c Reviewed-on: https://webrtc-review.googlesource.com/c/112221 Commit-Queue: Benjamin Wright <benwright@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25865}
2018-11-30 16:18:26 -08:00
// The second call will succeed playing back both frames.
buffered_frame_decryptor_->ManageEncryptedFrame(CreateRtpFrameObject(false));
EXPECT_EQ(decrypted_frame_call_count_, static_cast<size_t>(2));
EXPECT_EQ(decryption_status_change_count_, static_cast<size_t>(2));
Add BufferedFrameDecryptor to cleanly deal with receiving encrypted frames. This change introduces a new class BufferedFrameDecryptor that is responsible for decrypting received encrypted frames and passing them on to the RtpReferenceFinder. This decoupling refactoring was triggered by a new optimization also introduced in this patch to stash a small number of undecryptable frames if no frames have ever been decrypted. The goal of this optimization is to prevent re-fectching of key frames on low bandwidth networks simply because the key to decrypt them had not arrived yet. The optimization will stash 24 frames (about 1 second of video) in a ring buffer and will attempt to re-decrypt previously received frames on the first valid decryption. This allows the decoder to receive the key frame without having to request due to short key delivery latencies. In testing this is actually hit quite often and saves an entire RTT which can be up to 200ms on a bad network. As the scope of frame encryption increases in WebRTC and has more specialized optimizations that do not apply to the general flow it makes sense to move it to a more explicit bump in the stack protocol that is decoupled from the WebRTC main flow, similar to how SRTP is utilized with srtp_protect and srtp_unprotect. One advantage of this approach is the BufferedFrameDecryptor isn't even constructed if FrameEncryption is not in use. I have decided against merging the RtpReferenceFinder and EncryptedFrame stash because it introduced a lot of complexity around the mixed scenario where some of the frames in the stash are encrypted and others are not. In this case we would need to mark certain frames as decrypted which appeared to introduce more complexity than this simple decoupling. Bug: webrtc:10022 Change-Id: Iab74f7b7d25ef1cdd15c4a76b5daae1cfa24932c Reviewed-on: https://webrtc-review.googlesource.com/c/112221 Commit-Queue: Benjamin Wright <benwright@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25865}
2018-11-30 16:18:26 -08:00
}
// Subsequent failure to decrypts after the first successful decryption should
// fail to decryptk
TEST_F(BufferedFrameDecryptorTest, FTDDiscardedAfterFirstSuccess) {
EXPECT_CALL(*mock_frame_decryptor_, Decrypt)
.Times(4)
Reland "Refactor FrameDecryptorInterface::Decrypt to use new API." This reverts commit 7dd83e2bf73a7f1746c5ee976939bf52e19fa8be. Reason for revert: This wasn't the cause of the break. Original change's description: > Revert "Refactor FrameDecryptorInterface::Decrypt to use new API." > > This reverts commit 642aa81f7d5cc55d5b99e2abc51327eed9d40195. > > Reason for revert: Speculative revert. The chromium roll is failing: > https://ci.chromium.org/p/chromium/builders/try/linux-rel/64388 > But I can't figure out exactly what is failing, this looks suspecious. > > Original change's description: > > Refactor FrameDecryptorInterface::Decrypt to use new API. > > > > This change refactors the FrameDecryptorInterface to use the new API. The new > > API surface simply moves bytes_written to the return type and implements a > > simple Status type. > > > > Bug: webrtc:10512 > > Change-Id: I622c5d344d58e618853c94c2f691cf7c8fb73a36 > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/131460 > > Reviewed-by: Steve Anton <steveanton@webrtc.org> > > Reviewed-by: Fredrik Solenberg <solenberg@webrtc.org> > > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org> > > Reviewed-by: Stefan Holmer <stefan@webrtc.org> > > Commit-Queue: Benjamin Wright <benwright@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#27497} > > TBR=brandtr@webrtc.org,steveanton@webrtc.org,solenberg@webrtc.org,ossu@webrtc.org,stefan@webrtc.org,benwright@webrtc.org > > Change-Id: Ia9ec70263762c34671af13f0d519e636eb8473cd > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Bug: webrtc:10512 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/132013 > Reviewed-by: Henrik Boström <hbos@webrtc.org> > Commit-Queue: Henrik Boström <hbos@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#27510} TBR=brandtr@webrtc.org,steveanton@webrtc.org,solenberg@webrtc.org,hbos@webrtc.org,ossu@webrtc.org,stefan@webrtc.org,benwright@webrtc.org Change-Id: I8e4b7965cf1d1a1554c3b46e6245f5ad0d2dcbb4 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:10512 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/131982 Reviewed-by: Benjamin Wright <benwright@webrtc.org> Commit-Queue: Benjamin Wright <benwright@webrtc.org> Cr-Commit-Position: refs/heads/master@{#27529}
2019-04-09 20:08:41 +00:00
.WillOnce(Return(DecryptFail()))
.WillOnce(Return(DecryptSuccess()))
.WillOnce(Return(DecryptSuccess()))
.WillOnce(Return(DecryptFail()));
Add BufferedFrameDecryptor to cleanly deal with receiving encrypted frames. This change introduces a new class BufferedFrameDecryptor that is responsible for decrypting received encrypted frames and passing them on to the RtpReferenceFinder. This decoupling refactoring was triggered by a new optimization also introduced in this patch to stash a small number of undecryptable frames if no frames have ever been decrypted. The goal of this optimization is to prevent re-fectching of key frames on low bandwidth networks simply because the key to decrypt them had not arrived yet. The optimization will stash 24 frames (about 1 second of video) in a ring buffer and will attempt to re-decrypt previously received frames on the first valid decryption. This allows the decoder to receive the key frame without having to request due to short key delivery latencies. In testing this is actually hit quite often and saves an entire RTT which can be up to 200ms on a bad network. As the scope of frame encryption increases in WebRTC and has more specialized optimizations that do not apply to the general flow it makes sense to move it to a more explicit bump in the stack protocol that is decoupled from the WebRTC main flow, similar to how SRTP is utilized with srtp_protect and srtp_unprotect. One advantage of this approach is the BufferedFrameDecryptor isn't even constructed if FrameEncryption is not in use. I have decided against merging the RtpReferenceFinder and EncryptedFrame stash because it introduced a lot of complexity around the mixed scenario where some of the frames in the stash are encrypted and others are not. In this case we would need to mark certain frames as decrypted which appeared to introduce more complexity than this simple decoupling. Bug: webrtc:10022 Change-Id: Iab74f7b7d25ef1cdd15c4a76b5daae1cfa24932c Reviewed-on: https://webrtc-review.googlesource.com/c/112221 Commit-Queue: Benjamin Wright <benwright@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25865}
2018-11-30 16:18:26 -08:00
EXPECT_CALL(*mock_frame_decryptor_, GetMaxPlaintextByteSize)
.Times(4)
.WillRepeatedly(Return(0));
// The first decrypt will fail stashing the first frame.
buffered_frame_decryptor_->ManageEncryptedFrame(CreateRtpFrameObject(true));
EXPECT_EQ(decrypted_frame_call_count_, static_cast<size_t>(0));
EXPECT_EQ(decryption_status_change_count_, static_cast<size_t>(1));
Add BufferedFrameDecryptor to cleanly deal with receiving encrypted frames. This change introduces a new class BufferedFrameDecryptor that is responsible for decrypting received encrypted frames and passing them on to the RtpReferenceFinder. This decoupling refactoring was triggered by a new optimization also introduced in this patch to stash a small number of undecryptable frames if no frames have ever been decrypted. The goal of this optimization is to prevent re-fectching of key frames on low bandwidth networks simply because the key to decrypt them had not arrived yet. The optimization will stash 24 frames (about 1 second of video) in a ring buffer and will attempt to re-decrypt previously received frames on the first valid decryption. This allows the decoder to receive the key frame without having to request due to short key delivery latencies. In testing this is actually hit quite often and saves an entire RTT which can be up to 200ms on a bad network. As the scope of frame encryption increases in WebRTC and has more specialized optimizations that do not apply to the general flow it makes sense to move it to a more explicit bump in the stack protocol that is decoupled from the WebRTC main flow, similar to how SRTP is utilized with srtp_protect and srtp_unprotect. One advantage of this approach is the BufferedFrameDecryptor isn't even constructed if FrameEncryption is not in use. I have decided against merging the RtpReferenceFinder and EncryptedFrame stash because it introduced a lot of complexity around the mixed scenario where some of the frames in the stash are encrypted and others are not. In this case we would need to mark certain frames as decrypted which appeared to introduce more complexity than this simple decoupling. Bug: webrtc:10022 Change-Id: Iab74f7b7d25ef1cdd15c4a76b5daae1cfa24932c Reviewed-on: https://webrtc-review.googlesource.com/c/112221 Commit-Queue: Benjamin Wright <benwright@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25865}
2018-11-30 16:18:26 -08:00
// The second call will succeed playing back both frames.
buffered_frame_decryptor_->ManageEncryptedFrame(CreateRtpFrameObject(false));
EXPECT_EQ(decrypted_frame_call_count_, static_cast<size_t>(2));
EXPECT_EQ(decryption_status_change_count_, static_cast<size_t>(2));
Add BufferedFrameDecryptor to cleanly deal with receiving encrypted frames. This change introduces a new class BufferedFrameDecryptor that is responsible for decrypting received encrypted frames and passing them on to the RtpReferenceFinder. This decoupling refactoring was triggered by a new optimization also introduced in this patch to stash a small number of undecryptable frames if no frames have ever been decrypted. The goal of this optimization is to prevent re-fectching of key frames on low bandwidth networks simply because the key to decrypt them had not arrived yet. The optimization will stash 24 frames (about 1 second of video) in a ring buffer and will attempt to re-decrypt previously received frames on the first valid decryption. This allows the decoder to receive the key frame without having to request due to short key delivery latencies. In testing this is actually hit quite often and saves an entire RTT which can be up to 200ms on a bad network. As the scope of frame encryption increases in WebRTC and has more specialized optimizations that do not apply to the general flow it makes sense to move it to a more explicit bump in the stack protocol that is decoupled from the WebRTC main flow, similar to how SRTP is utilized with srtp_protect and srtp_unprotect. One advantage of this approach is the BufferedFrameDecryptor isn't even constructed if FrameEncryption is not in use. I have decided against merging the RtpReferenceFinder and EncryptedFrame stash because it introduced a lot of complexity around the mixed scenario where some of the frames in the stash are encrypted and others are not. In this case we would need to mark certain frames as decrypted which appeared to introduce more complexity than this simple decoupling. Bug: webrtc:10022 Change-Id: Iab74f7b7d25ef1cdd15c4a76b5daae1cfa24932c Reviewed-on: https://webrtc-review.googlesource.com/c/112221 Commit-Queue: Benjamin Wright <benwright@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25865}
2018-11-30 16:18:26 -08:00
// A new failure call will not result in an additional decrypted frame
// callback.
buffered_frame_decryptor_->ManageEncryptedFrame(CreateRtpFrameObject(true));
EXPECT_EQ(decrypted_frame_call_count_, static_cast<size_t>(2));
EXPECT_EQ(decryption_status_change_count_, static_cast<size_t>(3));
Add BufferedFrameDecryptor to cleanly deal with receiving encrypted frames. This change introduces a new class BufferedFrameDecryptor that is responsible for decrypting received encrypted frames and passing them on to the RtpReferenceFinder. This decoupling refactoring was triggered by a new optimization also introduced in this patch to stash a small number of undecryptable frames if no frames have ever been decrypted. The goal of this optimization is to prevent re-fectching of key frames on low bandwidth networks simply because the key to decrypt them had not arrived yet. The optimization will stash 24 frames (about 1 second of video) in a ring buffer and will attempt to re-decrypt previously received frames on the first valid decryption. This allows the decoder to receive the key frame without having to request due to short key delivery latencies. In testing this is actually hit quite often and saves an entire RTT which can be up to 200ms on a bad network. As the scope of frame encryption increases in WebRTC and has more specialized optimizations that do not apply to the general flow it makes sense to move it to a more explicit bump in the stack protocol that is decoupled from the WebRTC main flow, similar to how SRTP is utilized with srtp_protect and srtp_unprotect. One advantage of this approach is the BufferedFrameDecryptor isn't even constructed if FrameEncryption is not in use. I have decided against merging the RtpReferenceFinder and EncryptedFrame stash because it introduced a lot of complexity around the mixed scenario where some of the frames in the stash are encrypted and others are not. In this case we would need to mark certain frames as decrypted which appeared to introduce more complexity than this simple decoupling. Bug: webrtc:10022 Change-Id: Iab74f7b7d25ef1cdd15c4a76b5daae1cfa24932c Reviewed-on: https://webrtc-review.googlesource.com/c/112221 Commit-Queue: Benjamin Wright <benwright@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25865}
2018-11-30 16:18:26 -08:00
}
// Validate that the maximum number of stashed frames cannot be exceeded even if
// more than its maximum arrives before the first successful decryption.
TEST_F(BufferedFrameDecryptorTest, MaximumNumberOfFramesStored) {
const size_t failed_to_decrypt_count = kMaxStashedFrames * 2;
EXPECT_CALL(*mock_frame_decryptor_, Decrypt)
.Times(failed_to_decrypt_count)
Reland "Refactor FrameDecryptorInterface::Decrypt to use new API." This reverts commit 7dd83e2bf73a7f1746c5ee976939bf52e19fa8be. Reason for revert: This wasn't the cause of the break. Original change's description: > Revert "Refactor FrameDecryptorInterface::Decrypt to use new API." > > This reverts commit 642aa81f7d5cc55d5b99e2abc51327eed9d40195. > > Reason for revert: Speculative revert. The chromium roll is failing: > https://ci.chromium.org/p/chromium/builders/try/linux-rel/64388 > But I can't figure out exactly what is failing, this looks suspecious. > > Original change's description: > > Refactor FrameDecryptorInterface::Decrypt to use new API. > > > > This change refactors the FrameDecryptorInterface to use the new API. The new > > API surface simply moves bytes_written to the return type and implements a > > simple Status type. > > > > Bug: webrtc:10512 > > Change-Id: I622c5d344d58e618853c94c2f691cf7c8fb73a36 > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/131460 > > Reviewed-by: Steve Anton <steveanton@webrtc.org> > > Reviewed-by: Fredrik Solenberg <solenberg@webrtc.org> > > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org> > > Reviewed-by: Stefan Holmer <stefan@webrtc.org> > > Commit-Queue: Benjamin Wright <benwright@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#27497} > > TBR=brandtr@webrtc.org,steveanton@webrtc.org,solenberg@webrtc.org,ossu@webrtc.org,stefan@webrtc.org,benwright@webrtc.org > > Change-Id: Ia9ec70263762c34671af13f0d519e636eb8473cd > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Bug: webrtc:10512 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/132013 > Reviewed-by: Henrik Boström <hbos@webrtc.org> > Commit-Queue: Henrik Boström <hbos@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#27510} TBR=brandtr@webrtc.org,steveanton@webrtc.org,solenberg@webrtc.org,hbos@webrtc.org,ossu@webrtc.org,stefan@webrtc.org,benwright@webrtc.org Change-Id: I8e4b7965cf1d1a1554c3b46e6245f5ad0d2dcbb4 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:10512 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/131982 Reviewed-by: Benjamin Wright <benwright@webrtc.org> Commit-Queue: Benjamin Wright <benwright@webrtc.org> Cr-Commit-Position: refs/heads/master@{#27529}
2019-04-09 20:08:41 +00:00
.WillRepeatedly(Return(DecryptFail()));
Add BufferedFrameDecryptor to cleanly deal with receiving encrypted frames. This change introduces a new class BufferedFrameDecryptor that is responsible for decrypting received encrypted frames and passing them on to the RtpReferenceFinder. This decoupling refactoring was triggered by a new optimization also introduced in this patch to stash a small number of undecryptable frames if no frames have ever been decrypted. The goal of this optimization is to prevent re-fectching of key frames on low bandwidth networks simply because the key to decrypt them had not arrived yet. The optimization will stash 24 frames (about 1 second of video) in a ring buffer and will attempt to re-decrypt previously received frames on the first valid decryption. This allows the decoder to receive the key frame without having to request due to short key delivery latencies. In testing this is actually hit quite often and saves an entire RTT which can be up to 200ms on a bad network. As the scope of frame encryption increases in WebRTC and has more specialized optimizations that do not apply to the general flow it makes sense to move it to a more explicit bump in the stack protocol that is decoupled from the WebRTC main flow, similar to how SRTP is utilized with srtp_protect and srtp_unprotect. One advantage of this approach is the BufferedFrameDecryptor isn't even constructed if FrameEncryption is not in use. I have decided against merging the RtpReferenceFinder and EncryptedFrame stash because it introduced a lot of complexity around the mixed scenario where some of the frames in the stash are encrypted and others are not. In this case we would need to mark certain frames as decrypted which appeared to introduce more complexity than this simple decoupling. Bug: webrtc:10022 Change-Id: Iab74f7b7d25ef1cdd15c4a76b5daae1cfa24932c Reviewed-on: https://webrtc-review.googlesource.com/c/112221 Commit-Queue: Benjamin Wright <benwright@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25865}
2018-11-30 16:18:26 -08:00
EXPECT_CALL(*mock_frame_decryptor_, GetMaxPlaintextByteSize)
.WillRepeatedly(Return(0));
for (size_t i = 0; i < failed_to_decrypt_count; ++i) {
buffered_frame_decryptor_->ManageEncryptedFrame(CreateRtpFrameObject(true));
}
EXPECT_EQ(decrypted_frame_call_count_, static_cast<size_t>(0));
EXPECT_EQ(decryption_status_change_count_, static_cast<size_t>(1));
Add BufferedFrameDecryptor to cleanly deal with receiving encrypted frames. This change introduces a new class BufferedFrameDecryptor that is responsible for decrypting received encrypted frames and passing them on to the RtpReferenceFinder. This decoupling refactoring was triggered by a new optimization also introduced in this patch to stash a small number of undecryptable frames if no frames have ever been decrypted. The goal of this optimization is to prevent re-fectching of key frames on low bandwidth networks simply because the key to decrypt them had not arrived yet. The optimization will stash 24 frames (about 1 second of video) in a ring buffer and will attempt to re-decrypt previously received frames on the first valid decryption. This allows the decoder to receive the key frame without having to request due to short key delivery latencies. In testing this is actually hit quite often and saves an entire RTT which can be up to 200ms on a bad network. As the scope of frame encryption increases in WebRTC and has more specialized optimizations that do not apply to the general flow it makes sense to move it to a more explicit bump in the stack protocol that is decoupled from the WebRTC main flow, similar to how SRTP is utilized with srtp_protect and srtp_unprotect. One advantage of this approach is the BufferedFrameDecryptor isn't even constructed if FrameEncryption is not in use. I have decided against merging the RtpReferenceFinder and EncryptedFrame stash because it introduced a lot of complexity around the mixed scenario where some of the frames in the stash are encrypted and others are not. In this case we would need to mark certain frames as decrypted which appeared to introduce more complexity than this simple decoupling. Bug: webrtc:10022 Change-Id: Iab74f7b7d25ef1cdd15c4a76b5daae1cfa24932c Reviewed-on: https://webrtc-review.googlesource.com/c/112221 Commit-Queue: Benjamin Wright <benwright@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25865}
2018-11-30 16:18:26 -08:00
EXPECT_CALL(*mock_frame_decryptor_, Decrypt)
.Times(kMaxStashedFrames + 1)
Reland "Refactor FrameDecryptorInterface::Decrypt to use new API." This reverts commit 7dd83e2bf73a7f1746c5ee976939bf52e19fa8be. Reason for revert: This wasn't the cause of the break. Original change's description: > Revert "Refactor FrameDecryptorInterface::Decrypt to use new API." > > This reverts commit 642aa81f7d5cc55d5b99e2abc51327eed9d40195. > > Reason for revert: Speculative revert. The chromium roll is failing: > https://ci.chromium.org/p/chromium/builders/try/linux-rel/64388 > But I can't figure out exactly what is failing, this looks suspecious. > > Original change's description: > > Refactor FrameDecryptorInterface::Decrypt to use new API. > > > > This change refactors the FrameDecryptorInterface to use the new API. The new > > API surface simply moves bytes_written to the return type and implements a > > simple Status type. > > > > Bug: webrtc:10512 > > Change-Id: I622c5d344d58e618853c94c2f691cf7c8fb73a36 > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/131460 > > Reviewed-by: Steve Anton <steveanton@webrtc.org> > > Reviewed-by: Fredrik Solenberg <solenberg@webrtc.org> > > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org> > > Reviewed-by: Stefan Holmer <stefan@webrtc.org> > > Commit-Queue: Benjamin Wright <benwright@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#27497} > > TBR=brandtr@webrtc.org,steveanton@webrtc.org,solenberg@webrtc.org,ossu@webrtc.org,stefan@webrtc.org,benwright@webrtc.org > > Change-Id: Ia9ec70263762c34671af13f0d519e636eb8473cd > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Bug: webrtc:10512 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/132013 > Reviewed-by: Henrik Boström <hbos@webrtc.org> > Commit-Queue: Henrik Boström <hbos@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#27510} TBR=brandtr@webrtc.org,steveanton@webrtc.org,solenberg@webrtc.org,hbos@webrtc.org,ossu@webrtc.org,stefan@webrtc.org,benwright@webrtc.org Change-Id: I8e4b7965cf1d1a1554c3b46e6245f5ad0d2dcbb4 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:10512 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/131982 Reviewed-by: Benjamin Wright <benwright@webrtc.org> Commit-Queue: Benjamin Wright <benwright@webrtc.org> Cr-Commit-Position: refs/heads/master@{#27529}
2019-04-09 20:08:41 +00:00
.WillRepeatedly(Return(DecryptSuccess()));
Add BufferedFrameDecryptor to cleanly deal with receiving encrypted frames. This change introduces a new class BufferedFrameDecryptor that is responsible for decrypting received encrypted frames and passing them on to the RtpReferenceFinder. This decoupling refactoring was triggered by a new optimization also introduced in this patch to stash a small number of undecryptable frames if no frames have ever been decrypted. The goal of this optimization is to prevent re-fectching of key frames on low bandwidth networks simply because the key to decrypt them had not arrived yet. The optimization will stash 24 frames (about 1 second of video) in a ring buffer and will attempt to re-decrypt previously received frames on the first valid decryption. This allows the decoder to receive the key frame without having to request due to short key delivery latencies. In testing this is actually hit quite often and saves an entire RTT which can be up to 200ms on a bad network. As the scope of frame encryption increases in WebRTC and has more specialized optimizations that do not apply to the general flow it makes sense to move it to a more explicit bump in the stack protocol that is decoupled from the WebRTC main flow, similar to how SRTP is utilized with srtp_protect and srtp_unprotect. One advantage of this approach is the BufferedFrameDecryptor isn't even constructed if FrameEncryption is not in use. I have decided against merging the RtpReferenceFinder and EncryptedFrame stash because it introduced a lot of complexity around the mixed scenario where some of the frames in the stash are encrypted and others are not. In this case we would need to mark certain frames as decrypted which appeared to introduce more complexity than this simple decoupling. Bug: webrtc:10022 Change-Id: Iab74f7b7d25ef1cdd15c4a76b5daae1cfa24932c Reviewed-on: https://webrtc-review.googlesource.com/c/112221 Commit-Queue: Benjamin Wright <benwright@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25865}
2018-11-30 16:18:26 -08:00
buffered_frame_decryptor_->ManageEncryptedFrame(CreateRtpFrameObject(true));
EXPECT_EQ(decrypted_frame_call_count_, kMaxStashedFrames + 1);
EXPECT_EQ(decryption_status_change_count_, static_cast<size_t>(2));
Add BufferedFrameDecryptor to cleanly deal with receiving encrypted frames. This change introduces a new class BufferedFrameDecryptor that is responsible for decrypting received encrypted frames and passing them on to the RtpReferenceFinder. This decoupling refactoring was triggered by a new optimization also introduced in this patch to stash a small number of undecryptable frames if no frames have ever been decrypted. The goal of this optimization is to prevent re-fectching of key frames on low bandwidth networks simply because the key to decrypt them had not arrived yet. The optimization will stash 24 frames (about 1 second of video) in a ring buffer and will attempt to re-decrypt previously received frames on the first valid decryption. This allows the decoder to receive the key frame without having to request due to short key delivery latencies. In testing this is actually hit quite often and saves an entire RTT which can be up to 200ms on a bad network. As the scope of frame encryption increases in WebRTC and has more specialized optimizations that do not apply to the general flow it makes sense to move it to a more explicit bump in the stack protocol that is decoupled from the WebRTC main flow, similar to how SRTP is utilized with srtp_protect and srtp_unprotect. One advantage of this approach is the BufferedFrameDecryptor isn't even constructed if FrameEncryption is not in use. I have decided against merging the RtpReferenceFinder and EncryptedFrame stash because it introduced a lot of complexity around the mixed scenario where some of the frames in the stash are encrypted and others are not. In this case we would need to mark certain frames as decrypted which appeared to introduce more complexity than this simple decoupling. Bug: webrtc:10022 Change-Id: Iab74f7b7d25ef1cdd15c4a76b5daae1cfa24932c Reviewed-on: https://webrtc-review.googlesource.com/c/112221 Commit-Queue: Benjamin Wright <benwright@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25865}
2018-11-30 16:18:26 -08:00
}
// Verifies if a BufferedFrameDecryptor is attached but has no FrameDecryptor
// attached it will still store frames up to the frame max.
TEST_F(BufferedFrameDecryptorTest, FramesStoredIfDecryptorNull) {
buffered_frame_decryptor_->SetFrameDecryptor(nullptr);
for (size_t i = 0; i < (2 * kMaxStashedFrames); ++i) {
buffered_frame_decryptor_->ManageEncryptedFrame(CreateRtpFrameObject(true));
}
EXPECT_CALL(*mock_frame_decryptor_, Decrypt)
.Times(kMaxStashedFrames + 1)
Reland "Refactor FrameDecryptorInterface::Decrypt to use new API." This reverts commit 7dd83e2bf73a7f1746c5ee976939bf52e19fa8be. Reason for revert: This wasn't the cause of the break. Original change's description: > Revert "Refactor FrameDecryptorInterface::Decrypt to use new API." > > This reverts commit 642aa81f7d5cc55d5b99e2abc51327eed9d40195. > > Reason for revert: Speculative revert. The chromium roll is failing: > https://ci.chromium.org/p/chromium/builders/try/linux-rel/64388 > But I can't figure out exactly what is failing, this looks suspecious. > > Original change's description: > > Refactor FrameDecryptorInterface::Decrypt to use new API. > > > > This change refactors the FrameDecryptorInterface to use the new API. The new > > API surface simply moves bytes_written to the return type and implements a > > simple Status type. > > > > Bug: webrtc:10512 > > Change-Id: I622c5d344d58e618853c94c2f691cf7c8fb73a36 > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/131460 > > Reviewed-by: Steve Anton <steveanton@webrtc.org> > > Reviewed-by: Fredrik Solenberg <solenberg@webrtc.org> > > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org> > > Reviewed-by: Stefan Holmer <stefan@webrtc.org> > > Commit-Queue: Benjamin Wright <benwright@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#27497} > > TBR=brandtr@webrtc.org,steveanton@webrtc.org,solenberg@webrtc.org,ossu@webrtc.org,stefan@webrtc.org,benwright@webrtc.org > > Change-Id: Ia9ec70263762c34671af13f0d519e636eb8473cd > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Bug: webrtc:10512 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/132013 > Reviewed-by: Henrik Boström <hbos@webrtc.org> > Commit-Queue: Henrik Boström <hbos@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#27510} TBR=brandtr@webrtc.org,steveanton@webrtc.org,solenberg@webrtc.org,hbos@webrtc.org,ossu@webrtc.org,stefan@webrtc.org,benwright@webrtc.org Change-Id: I8e4b7965cf1d1a1554c3b46e6245f5ad0d2dcbb4 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:10512 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/131982 Reviewed-by: Benjamin Wright <benwright@webrtc.org> Commit-Queue: Benjamin Wright <benwright@webrtc.org> Cr-Commit-Position: refs/heads/master@{#27529}
2019-04-09 20:08:41 +00:00
.WillRepeatedly(Return(DecryptSuccess()));
EXPECT_CALL(*mock_frame_decryptor_, GetMaxPlaintextByteSize)
.WillRepeatedly(Return(0));
// Attach the frame decryptor at a later point after frames have arrived.
buffered_frame_decryptor_->SetFrameDecryptor(mock_frame_decryptor_);
// Next frame should trigger kMaxStashedFrame decryptions.
buffered_frame_decryptor_->ManageEncryptedFrame(CreateRtpFrameObject(true));
EXPECT_EQ(decrypted_frame_call_count_, kMaxStashedFrames + 1);
}
Add BufferedFrameDecryptor to cleanly deal with receiving encrypted frames. This change introduces a new class BufferedFrameDecryptor that is responsible for decrypting received encrypted frames and passing them on to the RtpReferenceFinder. This decoupling refactoring was triggered by a new optimization also introduced in this patch to stash a small number of undecryptable frames if no frames have ever been decrypted. The goal of this optimization is to prevent re-fectching of key frames on low bandwidth networks simply because the key to decrypt them had not arrived yet. The optimization will stash 24 frames (about 1 second of video) in a ring buffer and will attempt to re-decrypt previously received frames on the first valid decryption. This allows the decoder to receive the key frame without having to request due to short key delivery latencies. In testing this is actually hit quite often and saves an entire RTT which can be up to 200ms on a bad network. As the scope of frame encryption increases in WebRTC and has more specialized optimizations that do not apply to the general flow it makes sense to move it to a more explicit bump in the stack protocol that is decoupled from the WebRTC main flow, similar to how SRTP is utilized with srtp_protect and srtp_unprotect. One advantage of this approach is the BufferedFrameDecryptor isn't even constructed if FrameEncryption is not in use. I have decided against merging the RtpReferenceFinder and EncryptedFrame stash because it introduced a lot of complexity around the mixed scenario where some of the frames in the stash are encrypted and others are not. In this case we would need to mark certain frames as decrypted which appeared to introduce more complexity than this simple decoupling. Bug: webrtc:10022 Change-Id: Iab74f7b7d25ef1cdd15c4a76b5daae1cfa24932c Reviewed-on: https://webrtc-review.googlesource.com/c/112221 Commit-Queue: Benjamin Wright <benwright@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25865}
2018-11-30 16:18:26 -08:00
} // namespace webrtc