blob: 2293a24a693b400016409bc6786dd09fdb220bbc [file] [log] [blame]
/*
* Copyright (c) 2015 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 <memory>
#include "webrtc/call/video_config.h"
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
#include "webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h"
#include "webrtc/modules/video_coding/include/video_codec_interface.h"
#include "webrtc/test/gmock.h"
#include "webrtc/test/gtest.h"
#include "webrtc/video/payload_router.h"
using ::testing::_;
using ::testing::AnyNumber;
using ::testing::NiceMock;
using ::testing::Return;
namespace webrtc {
TEST(PayloadRouterTest, SendOnOneModule) {
NiceMock<MockRtpRtcp> rtp;
std::vector<RtpRtcp*> modules(1, &rtp);
std::vector<VideoStream> streams(1);
uint8_t payload = 'a';
int8_t payload_type = 96;
EncodedImage encoded_image;
encoded_image._timeStamp = 1;
encoded_image.capture_time_ms_ = 2;
encoded_image._frameType = kVideoFrameKey;
encoded_image._buffer = &payload;
encoded_image._length = 1;
PayloadRouter payload_router(modules, payload_type);
EXPECT_CALL(rtp, SendOutgoingData(encoded_image._frameType, payload_type,
encoded_image._timeStamp,
encoded_image.capture_time_ms_, &payload,
encoded_image._length, nullptr, _, _))
.Times(0);
EXPECT_NE(
EncodedImageCallback::Result::OK,
payload_router.OnEncodedImage(encoded_image, nullptr, nullptr).error);
payload_router.SetActive(true);
EXPECT_CALL(rtp, SendOutgoingData(encoded_image._frameType, payload_type,
encoded_image._timeStamp,
encoded_image.capture_time_ms_, &payload,
encoded_image._length, nullptr, _, _))
.Times(1)
.WillOnce(Return(true));
EXPECT_EQ(
EncodedImageCallback::Result::OK,
payload_router.OnEncodedImage(encoded_image, nullptr, nullptr).error);
payload_router.SetActive(false);
EXPECT_CALL(rtp, SendOutgoingData(encoded_image._frameType, payload_type,
encoded_image._timeStamp,
encoded_image.capture_time_ms_, &payload,
encoded_image._length, nullptr, _, _))
.Times(0);
EXPECT_NE(
EncodedImageCallback::Result::OK,
payload_router.OnEncodedImage(encoded_image, nullptr, nullptr).error);
payload_router.SetActive(true);
EXPECT_CALL(rtp, SendOutgoingData(encoded_image._frameType, payload_type,
encoded_image._timeStamp,
encoded_image.capture_time_ms_, &payload,
encoded_image._length, nullptr, _, _))
.Times(1)
.WillOnce(Return(true));
EXPECT_EQ(
EncodedImageCallback::Result::OK,
payload_router.OnEncodedImage(encoded_image, nullptr, nullptr).error);
}
TEST(PayloadRouterTest, SendSimulcast) {
NiceMock<MockRtpRtcp> rtp_1;
NiceMock<MockRtpRtcp> rtp_2;
std::vector<RtpRtcp*> modules;
modules.push_back(&rtp_1);
modules.push_back(&rtp_2);
std::vector<VideoStream> streams(2);
int8_t payload_type = 96;
uint8_t payload = 'a';
EncodedImage encoded_image;
encoded_image._timeStamp = 1;
encoded_image.capture_time_ms_ = 2;
encoded_image._frameType = kVideoFrameKey;
encoded_image._buffer = &payload;
encoded_image._length = 1;
PayloadRouter payload_router(modules, payload_type);
CodecSpecificInfo codec_info_1;
memset(&codec_info_1, 0, sizeof(CodecSpecificInfo));
codec_info_1.codecType = kVideoCodecVP8;
codec_info_1.codecSpecific.VP8.simulcastIdx = 0;
payload_router.SetActive(true);
EXPECT_CALL(rtp_1, SendOutgoingData(encoded_image._frameType, payload_type,
encoded_image._timeStamp,
encoded_image.capture_time_ms_, &payload,
encoded_image._length, nullptr, _, _))
.Times(1)
.WillOnce(Return(true));
EXPECT_CALL(rtp_2, SendOutgoingData(_, _, _, _, _, _, _, _, _)).Times(0);
EXPECT_EQ(EncodedImageCallback::Result::OK,
payload_router.OnEncodedImage(encoded_image, &codec_info_1, nullptr)
.error);
CodecSpecificInfo codec_info_2;
memset(&codec_info_2, 0, sizeof(CodecSpecificInfo));
codec_info_2.codecType = kVideoCodecVP8;
codec_info_2.codecSpecific.VP8.simulcastIdx = 1;
EXPECT_CALL(rtp_2, SendOutgoingData(encoded_image._frameType, payload_type,
encoded_image._timeStamp,
encoded_image.capture_time_ms_, &payload,
encoded_image._length, nullptr, _, _))
.Times(1)
.WillOnce(Return(true));
EXPECT_CALL(rtp_1, SendOutgoingData(_, _, _, _, _, _, _, _, _))
.Times(0);
EXPECT_EQ(EncodedImageCallback::Result::OK,
payload_router.OnEncodedImage(encoded_image, &codec_info_2, nullptr)
.error);
// Inactive.
payload_router.SetActive(false);
EXPECT_CALL(rtp_1, SendOutgoingData(_, _, _, _, _, _, _, _, _))
.Times(0);
EXPECT_CALL(rtp_2, SendOutgoingData(_, _, _, _, _, _, _, _, _))
.Times(0);
EXPECT_NE(EncodedImageCallback::Result::OK,
payload_router.OnEncodedImage(encoded_image, &codec_info_1, nullptr)
.error);
EXPECT_NE(EncodedImageCallback::Result::OK,
payload_router.OnEncodedImage(encoded_image, &codec_info_2, nullptr)
.error);
}
TEST(PayloadRouterTest, SimulcastTargetBitrate) {
NiceMock<MockRtpRtcp> rtp_1;
NiceMock<MockRtpRtcp> rtp_2;
std::vector<RtpRtcp*> modules;
modules.push_back(&rtp_1);
modules.push_back(&rtp_2);
PayloadRouter payload_router(modules, 42);
payload_router.SetActive(true);
BitrateAllocation bitrate;
bitrate.SetBitrate(0, 0, 10000);
bitrate.SetBitrate(0, 1, 20000);
bitrate.SetBitrate(1, 0, 40000);
bitrate.SetBitrate(1, 1, 80000);
BitrateAllocation layer0_bitrate;
layer0_bitrate.SetBitrate(0, 0, 10000);
layer0_bitrate.SetBitrate(0, 1, 20000);
BitrateAllocation layer1_bitrate;
layer1_bitrate.SetBitrate(0, 0, 40000);
layer1_bitrate.SetBitrate(0, 1, 80000);
EXPECT_CALL(rtp_1, SetVideoBitrateAllocation(layer0_bitrate)).Times(1);
EXPECT_CALL(rtp_2, SetVideoBitrateAllocation(layer1_bitrate)).Times(1);
payload_router.OnBitrateAllocationUpdated(bitrate);
}
TEST(PayloadRouterTest, SimulcastTargetBitrateWithInactiveStream) {
// Set up two active rtp modules.
NiceMock<MockRtpRtcp> rtp_1;
NiceMock<MockRtpRtcp> rtp_2;
std::vector<RtpRtcp*> modules;
modules.push_back(&rtp_1);
modules.push_back(&rtp_2);
PayloadRouter payload_router(modules, 42);
payload_router.SetActive(true);
// Create bitrate allocation with bitrate only for the first stream.
BitrateAllocation bitrate;
bitrate.SetBitrate(0, 0, 10000);
bitrate.SetBitrate(0, 1, 20000);
// Expect only the first rtp module to be asked to send a TargetBitrate
// message. (No target bitrate with 0bps sent from the second one.)
EXPECT_CALL(rtp_1, SetVideoBitrateAllocation(bitrate)).Times(1);
EXPECT_CALL(rtp_2, SetVideoBitrateAllocation(_)).Times(0);
payload_router.OnBitrateAllocationUpdated(bitrate);
}
TEST(PayloadRouterTest, SvcTargetBitrate) {
NiceMock<MockRtpRtcp> rtp_1;
std::vector<RtpRtcp*> modules;
modules.push_back(&rtp_1);
PayloadRouter payload_router(modules, 42);
payload_router.SetActive(true);
BitrateAllocation bitrate;
bitrate.SetBitrate(0, 0, 10000);
bitrate.SetBitrate(0, 1, 20000);
bitrate.SetBitrate(1, 0, 40000);
bitrate.SetBitrate(1, 1, 80000);
EXPECT_CALL(rtp_1, SetVideoBitrateAllocation(bitrate)).Times(1);
payload_router.OnBitrateAllocationUpdated(bitrate);
}
} // namespace webrtc