Clean up decoders when stopping video receive stream.
This updates VideoReceiveStream2::Stop() to symmetrically tear down state that's built up in VideoReceiveStream2::Start(). Bug: webrtc:11993, webrtc:14486 Change-Id: I41f4feea5584e5baaeed2143432136f8b9761321 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/272537 Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org> Reviewed-by: Danil Chapovalov <danilchap@webrtc.org> Cr-Commit-Position: refs/heads/main@{#38244}
This commit is contained in:
142
modules/video_coding/video_receiver2_unittest.cc
Normal file
142
modules/video_coding/video_receiver2_unittest.cc
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 "modules/video_coding/video_receiver2.h"
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "api/test/mock_video_decoder.h"
|
||||
#include "api/units/timestamp.h"
|
||||
#include "api/video/encoded_frame.h"
|
||||
#include "common_video/test/utilities.h"
|
||||
#include "modules/video_coding/decoder_database.h"
|
||||
#include "modules/video_coding/timing/timing.h"
|
||||
#include "system_wrappers/include/clock.h"
|
||||
#include "test/gmock.h"
|
||||
#include "test/gtest.h"
|
||||
#include "test/scoped_key_value_config.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace {
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::NiceMock;
|
||||
using ::testing::Return;
|
||||
|
||||
class MockVCMReceiveCallback : public VCMReceiveCallback {
|
||||
public:
|
||||
MockVCMReceiveCallback() = default;
|
||||
|
||||
MOCK_METHOD(
|
||||
int32_t,
|
||||
FrameToRender,
|
||||
(VideoFrame&, absl::optional<uint8_t>, TimeDelta, VideoContentType),
|
||||
(override));
|
||||
MOCK_METHOD(void, OnIncomingPayloadType, (int), (override));
|
||||
MOCK_METHOD(void, OnDecoderImplementationName, (const char*), (override));
|
||||
};
|
||||
|
||||
class TestEncodedFrame : public EncodedFrame {
|
||||
public:
|
||||
explicit TestEncodedFrame(int payload_type) {
|
||||
_payloadType = payload_type;
|
||||
SetPacketInfos(CreatePacketInfos(3));
|
||||
}
|
||||
|
||||
void SetReceivedTime(webrtc::Timestamp received_time) {
|
||||
received_time_ = received_time;
|
||||
}
|
||||
|
||||
int64_t ReceivedTime() const override { return received_time_.ms(); }
|
||||
|
||||
int64_t RenderTime() const override { return _renderTimeMs; }
|
||||
|
||||
private:
|
||||
webrtc::Timestamp received_time_ = webrtc::Timestamp::Millis(0);
|
||||
};
|
||||
|
||||
class VideoReceiver2Test : public ::testing::Test {
|
||||
protected:
|
||||
VideoReceiver2Test() {
|
||||
receiver_.RegisterReceiveCallback(&receive_callback_);
|
||||
}
|
||||
|
||||
void RegisterReceiveCodecSettings(
|
||||
int payload_type,
|
||||
VideoCodecType codec_type = kVideoCodecVP8) {
|
||||
VideoDecoder::Settings settings;
|
||||
settings.set_codec_type(codec_type);
|
||||
settings.set_max_render_resolution({10, 10});
|
||||
settings.set_number_of_cores(4);
|
||||
receiver_.RegisterReceiveCodec(payload_type, settings);
|
||||
}
|
||||
|
||||
test::ScopedKeyValueConfig field_trials_;
|
||||
SimulatedClock clock_{Timestamp::Millis(1337)};
|
||||
VCMTiming timing_{&clock_, field_trials_};
|
||||
NiceMock<MockVCMReceiveCallback> receive_callback_;
|
||||
VideoReceiver2 receiver_{&clock_, &timing_, field_trials_};
|
||||
};
|
||||
|
||||
TEST_F(VideoReceiver2Test, RegisterExternalDecoder) {
|
||||
constexpr int kPayloadType = 1;
|
||||
ASSERT_FALSE(receiver_.IsExternalDecoderRegistered(kPayloadType));
|
||||
|
||||
// Register a decoder, check for correctness, then unregister and check again.
|
||||
auto decoder = std::make_unique<NiceMock<MockVideoDecoder>>();
|
||||
bool decoder_deleted = false;
|
||||
EXPECT_CALL(*decoder, Destruct).WillOnce([&decoder_deleted] {
|
||||
decoder_deleted = true;
|
||||
});
|
||||
receiver_.RegisterExternalDecoder(std::move(decoder), kPayloadType);
|
||||
EXPECT_TRUE(receiver_.IsExternalDecoderRegistered(kPayloadType));
|
||||
receiver_.RegisterExternalDecoder(nullptr, kPayloadType);
|
||||
EXPECT_TRUE(decoder_deleted);
|
||||
EXPECT_FALSE(receiver_.IsExternalDecoderRegistered(kPayloadType));
|
||||
}
|
||||
|
||||
TEST_F(VideoReceiver2Test, RegisterReceiveCodecs) {
|
||||
constexpr int kPayloadType = 1;
|
||||
|
||||
RegisterReceiveCodecSettings(kPayloadType);
|
||||
|
||||
TestEncodedFrame frame(kPayloadType);
|
||||
|
||||
// A decoder has not been registered yet, so an attempt to decode should fail.
|
||||
EXPECT_EQ(receiver_.Decode(&frame), VCM_NO_CODEC_REGISTERED);
|
||||
|
||||
// Register a decoder that will accept the Decode operation.
|
||||
auto decoder = std::make_unique<NiceMock<MockVideoDecoder>>();
|
||||
EXPECT_CALL(*decoder, RegisterDecodeCompleteCallback)
|
||||
.WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
|
||||
EXPECT_CALL(*decoder, Decode).WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
|
||||
EXPECT_CALL(*decoder, Release).WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
|
||||
|
||||
// Register the decoder. Note that this moves ownership of the mock object
|
||||
// to the `receiver_`.
|
||||
receiver_.RegisterExternalDecoder(std::move(decoder), kPayloadType);
|
||||
EXPECT_TRUE(receiver_.IsExternalDecoderRegistered(kPayloadType));
|
||||
|
||||
EXPECT_CALL(receive_callback_, OnIncomingPayloadType(kPayloadType));
|
||||
EXPECT_CALL(receive_callback_, OnDecoderImplementationName);
|
||||
|
||||
// Call `Decode`. This triggers the above call expectations.
|
||||
EXPECT_EQ(receiver_.Decode(&frame), VCM_OK);
|
||||
|
||||
// Unregister the decoder and verify.
|
||||
receiver_.RegisterExternalDecoder(nullptr, kPayloadType);
|
||||
EXPECT_FALSE(receiver_.IsExternalDecoderRegistered(kPayloadType));
|
||||
|
||||
receiver_.DeregisterReceiveCodec(kPayloadType);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace webrtc
|
||||
Reference in New Issue
Block a user