webrtc_m130/video/video_send_stream_tests.cc

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

3620 lines
127 KiB
C++
Raw Normal View History

/*
* Copyright (c) 2013 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 <algorithm> // max
#include <memory>
#include <vector>
#include "call/call.h"
#include "call/rtp_transport_controller_send.h"
#include "common_video/include/frame_callback.h"
#include "common_video/include/video_frame.h"
#include "modules/pacing/alr_detector.h"
#include "modules/rtp_rtcp/include/rtp_header_parser.h"
#include "modules/rtp_rtcp/include/rtp_rtcp.h"
#include "modules/rtp_rtcp/source/rtcp_sender.h"
#include "modules/rtp_rtcp/source/rtp_format_vp9.h"
#include "modules/video_coding/codecs/vp8/include/vp8.h"
#include "modules/video_coding/codecs/vp9/include/vp9.h"
#include "rtc_base/bind.h"
#include "rtc_base/checks.h"
#include "rtc_base/criticalsection.h"
#include "rtc_base/event.h"
#include "rtc_base/logging.h"
#include "rtc_base/platform_thread.h"
#include "rtc_base/rate_limiter.h"
#include "rtc_base/timeutils.h"
#include "system_wrappers/include/sleep.h"
#include "test/call_test.h"
#include "test/configurable_frame_size_encoder.h"
#include "test/fake_texture_frame.h"
#include "test/field_trial.h"
#include "test/frame_generator.h"
#include "test/frame_generator_capturer.h"
#include "test/frame_utils.h"
#include "test/gtest.h"
#include "test/null_transport.h"
#include "test/rtcp_packet_parser.h"
#include "test/testsupport/perf_test.h"
#include "video/send_statistics_proxy.h"
#include "video/transport_adapter.h"
#include "call/video_send_stream.h"
namespace webrtc {
enum VideoFormat { kGeneric, kVP8, };
void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
const std::vector<VideoFrame>& frames2);
VideoFrame CreateVideoFrame(int width, int height, uint8_t data);
class VideoSendStreamTest : public test::CallTest {
protected:
void TestNackRetransmission(uint32_t retransmit_ssrc,
uint8_t retransmit_payload_type);
void TestPacketFragmentationSize(VideoFormat format, bool with_fec);
void TestVp9NonFlexMode(uint8_t num_temporal_layers,
uint8_t num_spatial_layers);
void TestRequestSourceRotateVideo(bool support_orientation_ext);
};
TEST_F(VideoSendStreamTest, CanStartStartedStream) {
task_queue_.SendTask([this]() {
CreateSenderCall(Call::Config(event_log_.get()));
test::NullTransport transport;
CreateSendConfig(1, 0, 0, &transport);
CreateVideoStreams();
video_send_stream_->Start();
video_send_stream_->Start();
DestroyStreams();
DestroyCalls();
});
}
TEST_F(VideoSendStreamTest, CanStopStoppedStream) {
task_queue_.SendTask([this]() {
CreateSenderCall(Call::Config(event_log_.get()));
test::NullTransport transport;
CreateSendConfig(1, 0, 0, &transport);
CreateVideoStreams();
video_send_stream_->Stop();
video_send_stream_->Stop();
DestroyStreams();
DestroyCalls();
});
}
TEST_F(VideoSendStreamTest, SupportsCName) {
static std::string kCName = "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo=";
class CNameObserver : public test::SendTest {
public:
CNameObserver() : SendTest(kDefaultTimeoutMs) {}
private:
Action OnSendRtcp(const uint8_t* packet, size_t length) override {
test::RtcpPacketParser parser;
EXPECT_TRUE(parser.Parse(packet, length));
if (parser.sdes()->num_packets() > 0) {
EXPECT_EQ(1u, parser.sdes()->chunks().size());
EXPECT_EQ(kCName, parser.sdes()->chunks()[0].cname);
observation_complete_.Set();
}
return SEND_PACKET;
}
void ModifyVideoConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) override {
send_config->rtp.c_name = kCName;
}
void PerformTest() override {
EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP with CNAME.";
}
} test;
RunBaseTest(&test);
}
TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) {
class AbsoluteSendTimeObserver : public test::SendTest {
public:
AbsoluteSendTimeObserver() : SendTest(kDefaultTimeoutMs) {
EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
kRtpExtensionAbsoluteSendTime, test::kAbsSendTimeExtensionId));
}
Action OnSendRtp(const uint8_t* packet, size_t length) override {
RTPHeader header;
EXPECT_TRUE(parser_->Parse(packet, length, &header));
EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
EXPECT_EQ(header.extension.transmissionTimeOffset, 0);
if (header.extension.absoluteSendTime != 0) {
// Wait for at least one packet with a non-zero send time. The send time
// is a 16-bit value derived from the system clock, and it is valid
// for a packet to have a zero send time. To tell that from an
// unpopulated value we'll wait for a packet with non-zero send time.
observation_complete_.Set();
} else {
RTC_LOG(LS_WARNING)
<< "Got a packet with zero absoluteSendTime, waiting"
" for another packet...";
}
return SEND_PACKET;
}
void ModifyVideoConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) override {
send_config->rtp.extensions.clear();
send_config->rtp.extensions.push_back(RtpExtension(
RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
}
void PerformTest() override {
EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
}
} test;
RunBaseTest(&test);
}
TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
static const int kEncodeDelayMs = 5;
class TransmissionTimeOffsetObserver : public test::SendTest {
public:
TransmissionTimeOffsetObserver()
: SendTest(kDefaultTimeoutMs),
encoder_(Clock::GetRealTimeClock(), kEncodeDelayMs) {
EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
kRtpExtensionTransmissionTimeOffset, test::kTOffsetExtensionId));
}
private:
Action OnSendRtp(const uint8_t* packet, size_t length) override {
RTPHeader header;
EXPECT_TRUE(parser_->Parse(packet, length, &header));
EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
EXPECT_GT(header.extension.transmissionTimeOffset, 0);
EXPECT_EQ(header.extension.absoluteSendTime, 0u);
observation_complete_.Set();
return SEND_PACKET;
}
void ModifyVideoConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) override {
send_config->encoder_settings.encoder = &encoder_;
send_config->rtp.extensions.clear();
send_config->rtp.extensions.push_back(RtpExtension(
RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
}
void PerformTest() override {
EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
}
test::DelayedEncoder encoder_;
} test;
RunBaseTest(&test);
}
TEST_F(VideoSendStreamTest, SupportsTransportWideSequenceNumbers) {
static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
class TransportWideSequenceNumberObserver : public test::SendTest {
public:
TransportWideSequenceNumberObserver()
: SendTest(kDefaultTimeoutMs), encoder_(Clock::GetRealTimeClock()) {
EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
kRtpExtensionTransportSequenceNumber, kExtensionId));
}
private:
Action OnSendRtp(const uint8_t* packet, size_t length) override {
RTPHeader header;
EXPECT_TRUE(parser_->Parse(packet, length, &header));
EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
observation_complete_.Set();
return SEND_PACKET;
}
void ModifyVideoConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) override {
send_config->encoder_settings.encoder = &encoder_;
}
void PerformTest() override {
EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
}
test::FakeEncoder encoder_;
} test;
RunBaseTest(&test);
}
TEST_F(VideoSendStreamTest, SupportsVideoRotation) {
class VideoRotationObserver : public test::SendTest {
public:
VideoRotationObserver() : SendTest(kDefaultTimeoutMs) {
EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
kRtpExtensionVideoRotation, test::kVideoRotationExtensionId));
}
Action OnSendRtp(const uint8_t* packet, size_t length) override {
RTPHeader header;
EXPECT_TRUE(parser_->Parse(packet, length, &header));
// Only the last packet of the frame is required to have the extension.
if (!header.markerBit)
return SEND_PACKET;
EXPECT_TRUE(header.extension.hasVideoRotation);
EXPECT_EQ(kVideoRotation_90, header.extension.videoRotation);
observation_complete_.Set();
return SEND_PACKET;
}
void ModifyVideoConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) override {
send_config->rtp.extensions.clear();
send_config->rtp.extensions.push_back(RtpExtension(
RtpExtension::kVideoRotationUri, test::kVideoRotationExtensionId));
}
void OnFrameGeneratorCapturerCreated(
test::FrameGeneratorCapturer* frame_generator_capturer) override {
frame_generator_capturer->SetFakeRotation(kVideoRotation_90);
}
void PerformTest() override {
EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
}
} test;
RunBaseTest(&test);
}
TEST_F(VideoSendStreamTest, SupportsVideoContentType) {
class VideoContentTypeObserver : public test::SendTest {
public:
VideoContentTypeObserver() : SendTest(kDefaultTimeoutMs) {
EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
kRtpExtensionVideoContentType, test::kVideoContentTypeExtensionId));
}
Action OnSendRtp(const uint8_t* packet, size_t length) override {
RTPHeader header;
EXPECT_TRUE(parser_->Parse(packet, length, &header));
// Only the last packet of the frame must have extension.
if (!header.markerBit)
return SEND_PACKET;
EXPECT_TRUE(header.extension.hasVideoContentType);
EXPECT_TRUE(videocontenttypehelpers::IsScreenshare(
header.extension.videoContentType));
observation_complete_.Set();
return SEND_PACKET;
}
void ModifyVideoConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) override {
send_config->rtp.extensions.clear();
send_config->rtp.extensions.push_back(
RtpExtension(RtpExtension::kVideoContentTypeUri,
test::kVideoContentTypeExtensionId));
encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
}
void PerformTest() override {
EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
}
} test;
RunBaseTest(&test);
}
TEST_F(VideoSendStreamTest, SupportsVideoTimingFrames) {
class VideoTimingObserver : public test::SendTest {
public:
VideoTimingObserver() : SendTest(kDefaultTimeoutMs) {
EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
kRtpExtensionVideoTiming, test::kVideoTimingExtensionId));
}
Action OnSendRtp(const uint8_t* packet, size_t length) override {
RTPHeader header;
EXPECT_TRUE(parser_->Parse(packet, length, &header));
// Only the last packet of the frame must have extension.
if (!header.markerBit)
return SEND_PACKET;
EXPECT_TRUE(header.extension.has_video_timing);
observation_complete_.Set();
return SEND_PACKET;
}
void ModifyVideoConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) override {
send_config->rtp.extensions.clear();
send_config->rtp.extensions.push_back(RtpExtension(
RtpExtension::kVideoTimingUri, test::kVideoTimingExtensionId));
}
void PerformTest() override {
EXPECT_TRUE(Wait()) << "Timed out while waiting for timing frames.";
}
} test;
RunBaseTest(&test);
}
class FakeReceiveStatistics : public ReceiveStatisticsProvider {
public:
FakeReceiveStatistics(uint32_t send_ssrc,
uint32_t last_sequence_number,
uint32_t cumulative_lost,
uint8_t fraction_lost) {
stat_.SetMediaSsrc(send_ssrc);
stat_.SetExtHighestSeqNum(last_sequence_number);
stat_.SetCumulativeLost(cumulative_lost);
stat_.SetFractionLost(fraction_lost);
}
std::vector<rtcp::ReportBlock> RtcpReportBlocks(size_t max_blocks) override {
EXPECT_GE(max_blocks, 1u);
return {stat_};
}
private:
rtcp::ReportBlock stat_;
};
class UlpfecObserver : public test::EndToEndTest {
public:
UlpfecObserver(bool header_extensions_enabled,
bool use_nack,
bool expect_red,
bool expect_ulpfec,
const std::string& codec,
VideoEncoder* encoder)
: EndToEndTest(kTimeoutMs),
encoder_(encoder),
Reland of Don't send FEC for H.264 with NACK enabled. (patchset #1 id:1 of https://codereview.webrtc.org/1692783005/ ) Reason for revert: Disabling tests on memcheck that time out due to using real VP8 encoders. Original issue's description: > Revert of Don't send FEC for H.264 with NACK enabled. (patchset #5 id:80001 of https://codereview.webrtc.org/1687303002/ ) > > Reason for revert: > Broke the VerifyHistogramStatsWithRed test on the Windows DrMemory Full bot and Linux Memcheck bot. Please fix the test and reland. > > Original issue's description: > > Don't send FEC for H.264 with NACK enabled. > > > > The H.264 does not contain picture IDs and are not sufficient to > > determine that a packet may be skipped. This causes retransmission > > requests for FEC that are currently dropped by the sender (since they > > should be redundant). > > > > The receiver is then unable to continue without having the packet gap > > filled (unlike VP8/VP9 which moves on since it has a consecutive stream > > of picture IDs). > > > > Even if FEC retransmission did work it's a huge waste of bandwidth, > > since it just adds additional overhead that has to be unconditionally > > transmitted. This bandwidth is better used to send higher-quality > > frames. > > > > BUG=webrtc:5264 > > R=stefan@webrtc.org > > > > Committed: https://crrev.com/25558ad819b4df41ba51537e26a77480ace1e525 > > Cr-Commit-Position: refs/heads/master@{#11601} > > TBR=stefan@webrtc.org,pbos@webrtc.org > # Skipping CQ checks because original CL landed less than 1 days ago. > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:5264 > > Committed: https://crrev.com/29ffdc1a15e31bd81e806ff135c2100d811714f0 > Cr-Commit-Position: refs/heads/master@{#11607} TBR=stefan@webrtc.org,deadbeef@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=webrtc:5264 Review URL: https://codereview.webrtc.org/1697093002 . Cr-Commit-Position: refs/heads/master@{#11621}
2016-02-15 11:27:15 +01:00
payload_name_(codec),
use_nack_(use_nack),
expect_red_(expect_red),
expect_ulpfec_(expect_ulpfec),
sent_media_(false),
sent_ulpfec_(false),
header_extensions_enabled_(header_extensions_enabled) {}
// Some of the test cases are expected to time out and thus we are using
// a shorter timeout window than the default here.
static constexpr size_t kTimeoutMs = 10000;
private:
Action OnSendRtp(const uint8_t* packet, size_t length) override {
RTPHeader header;
EXPECT_TRUE(parser_->Parse(packet, length, &header));
int encapsulated_payload_type = -1;
if (header.payloadType == VideoSendStreamTest::kRedPayloadType) {
Reland of Don't send FEC for H.264 with NACK enabled. (patchset #1 id:1 of https://codereview.webrtc.org/1692783005/ ) Reason for revert: Disabling tests on memcheck that time out due to using real VP8 encoders. Original issue's description: > Revert of Don't send FEC for H.264 with NACK enabled. (patchset #5 id:80001 of https://codereview.webrtc.org/1687303002/ ) > > Reason for revert: > Broke the VerifyHistogramStatsWithRed test on the Windows DrMemory Full bot and Linux Memcheck bot. Please fix the test and reland. > > Original issue's description: > > Don't send FEC for H.264 with NACK enabled. > > > > The H.264 does not contain picture IDs and are not sufficient to > > determine that a packet may be skipped. This causes retransmission > > requests for FEC that are currently dropped by the sender (since they > > should be redundant). > > > > The receiver is then unable to continue without having the packet gap > > filled (unlike VP8/VP9 which moves on since it has a consecutive stream > > of picture IDs). > > > > Even if FEC retransmission did work it's a huge waste of bandwidth, > > since it just adds additional overhead that has to be unconditionally > > transmitted. This bandwidth is better used to send higher-quality > > frames. > > > > BUG=webrtc:5264 > > R=stefan@webrtc.org > > > > Committed: https://crrev.com/25558ad819b4df41ba51537e26a77480ace1e525 > > Cr-Commit-Position: refs/heads/master@{#11601} > > TBR=stefan@webrtc.org,pbos@webrtc.org > # Skipping CQ checks because original CL landed less than 1 days ago. > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:5264 > > Committed: https://crrev.com/29ffdc1a15e31bd81e806ff135c2100d811714f0 > Cr-Commit-Position: refs/heads/master@{#11607} TBR=stefan@webrtc.org,deadbeef@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=webrtc:5264 Review URL: https://codereview.webrtc.org/1697093002 . Cr-Commit-Position: refs/heads/master@{#11621}
2016-02-15 11:27:15 +01:00
EXPECT_TRUE(expect_red_);
encapsulated_payload_type = static_cast<int>(packet[header.headerLength]);
if (encapsulated_payload_type !=
Reland of Don't send FEC for H.264 with NACK enabled. (patchset #1 id:1 of https://codereview.webrtc.org/1692783005/ ) Reason for revert: Disabling tests on memcheck that time out due to using real VP8 encoders. Original issue's description: > Revert of Don't send FEC for H.264 with NACK enabled. (patchset #5 id:80001 of https://codereview.webrtc.org/1687303002/ ) > > Reason for revert: > Broke the VerifyHistogramStatsWithRed test on the Windows DrMemory Full bot and Linux Memcheck bot. Please fix the test and reland. > > Original issue's description: > > Don't send FEC for H.264 with NACK enabled. > > > > The H.264 does not contain picture IDs and are not sufficient to > > determine that a packet may be skipped. This causes retransmission > > requests for FEC that are currently dropped by the sender (since they > > should be redundant). > > > > The receiver is then unable to continue without having the packet gap > > filled (unlike VP8/VP9 which moves on since it has a consecutive stream > > of picture IDs). > > > > Even if FEC retransmission did work it's a huge waste of bandwidth, > > since it just adds additional overhead that has to be unconditionally > > transmitted. This bandwidth is better used to send higher-quality > > frames. > > > > BUG=webrtc:5264 > > R=stefan@webrtc.org > > > > Committed: https://crrev.com/25558ad819b4df41ba51537e26a77480ace1e525 > > Cr-Commit-Position: refs/heads/master@{#11601} > > TBR=stefan@webrtc.org,pbos@webrtc.org > # Skipping CQ checks because original CL landed less than 1 days ago. > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:5264 > > Committed: https://crrev.com/29ffdc1a15e31bd81e806ff135c2100d811714f0 > Cr-Commit-Position: refs/heads/master@{#11607} TBR=stefan@webrtc.org,deadbeef@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=webrtc:5264 Review URL: https://codereview.webrtc.org/1697093002 . Cr-Commit-Position: refs/heads/master@{#11621}
2016-02-15 11:27:15 +01:00
VideoSendStreamTest::kFakeVideoSendPayloadType) {
EXPECT_EQ(VideoSendStreamTest::kUlpfecPayloadType,
encapsulated_payload_type);
Reland of Don't send FEC for H.264 with NACK enabled. (patchset #1 id:1 of https://codereview.webrtc.org/1692783005/ ) Reason for revert: Disabling tests on memcheck that time out due to using real VP8 encoders. Original issue's description: > Revert of Don't send FEC for H.264 with NACK enabled. (patchset #5 id:80001 of https://codereview.webrtc.org/1687303002/ ) > > Reason for revert: > Broke the VerifyHistogramStatsWithRed test on the Windows DrMemory Full bot and Linux Memcheck bot. Please fix the test and reland. > > Original issue's description: > > Don't send FEC for H.264 with NACK enabled. > > > > The H.264 does not contain picture IDs and are not sufficient to > > determine that a packet may be skipped. This causes retransmission > > requests for FEC that are currently dropped by the sender (since they > > should be redundant). > > > > The receiver is then unable to continue without having the packet gap > > filled (unlike VP8/VP9 which moves on since it has a consecutive stream > > of picture IDs). > > > > Even if FEC retransmission did work it's a huge waste of bandwidth, > > since it just adds additional overhead that has to be unconditionally > > transmitted. This bandwidth is better used to send higher-quality > > frames. > > > > BUG=webrtc:5264 > > R=stefan@webrtc.org > > > > Committed: https://crrev.com/25558ad819b4df41ba51537e26a77480ace1e525 > > Cr-Commit-Position: refs/heads/master@{#11601} > > TBR=stefan@webrtc.org,pbos@webrtc.org > # Skipping CQ checks because original CL landed less than 1 days ago. > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:5264 > > Committed: https://crrev.com/29ffdc1a15e31bd81e806ff135c2100d811714f0 > Cr-Commit-Position: refs/heads/master@{#11607} TBR=stefan@webrtc.org,deadbeef@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=webrtc:5264 Review URL: https://codereview.webrtc.org/1697093002 . Cr-Commit-Position: refs/heads/master@{#11621}
2016-02-15 11:27:15 +01:00
}
} else {
EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
header.payloadType);
Reland of Don't send FEC for H.264 with NACK enabled. (patchset #1 id:1 of https://codereview.webrtc.org/1692783005/ ) Reason for revert: Disabling tests on memcheck that time out due to using real VP8 encoders. Original issue's description: > Revert of Don't send FEC for H.264 with NACK enabled. (patchset #5 id:80001 of https://codereview.webrtc.org/1687303002/ ) > > Reason for revert: > Broke the VerifyHistogramStatsWithRed test on the Windows DrMemory Full bot and Linux Memcheck bot. Please fix the test and reland. > > Original issue's description: > > Don't send FEC for H.264 with NACK enabled. > > > > The H.264 does not contain picture IDs and are not sufficient to > > determine that a packet may be skipped. This causes retransmission > > requests for FEC that are currently dropped by the sender (since they > > should be redundant). > > > > The receiver is then unable to continue without having the packet gap > > filled (unlike VP8/VP9 which moves on since it has a consecutive stream > > of picture IDs). > > > > Even if FEC retransmission did work it's a huge waste of bandwidth, > > since it just adds additional overhead that has to be unconditionally > > transmitted. This bandwidth is better used to send higher-quality > > frames. > > > > BUG=webrtc:5264 > > R=stefan@webrtc.org > > > > Committed: https://crrev.com/25558ad819b4df41ba51537e26a77480ace1e525 > > Cr-Commit-Position: refs/heads/master@{#11601} > > TBR=stefan@webrtc.org,pbos@webrtc.org > # Skipping CQ checks because original CL landed less than 1 days ago. > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:5264 > > Committed: https://crrev.com/29ffdc1a15e31bd81e806ff135c2100d811714f0 > Cr-Commit-Position: refs/heads/master@{#11607} TBR=stefan@webrtc.org,deadbeef@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=webrtc:5264 Review URL: https://codereview.webrtc.org/1697093002 . Cr-Commit-Position: refs/heads/master@{#11621}
2016-02-15 11:27:15 +01:00
if (static_cast<size_t>(header.headerLength + header.paddingLength) <
length) {
// Not padding-only, media received outside of RED.
EXPECT_FALSE(expect_red_);
sent_media_ = true;
Reland of Don't send FEC for H.264 with NACK enabled. (patchset #1 id:1 of https://codereview.webrtc.org/1692783005/ ) Reason for revert: Disabling tests on memcheck that time out due to using real VP8 encoders. Original issue's description: > Revert of Don't send FEC for H.264 with NACK enabled. (patchset #5 id:80001 of https://codereview.webrtc.org/1687303002/ ) > > Reason for revert: > Broke the VerifyHistogramStatsWithRed test on the Windows DrMemory Full bot and Linux Memcheck bot. Please fix the test and reland. > > Original issue's description: > > Don't send FEC for H.264 with NACK enabled. > > > > The H.264 does not contain picture IDs and are not sufficient to > > determine that a packet may be skipped. This causes retransmission > > requests for FEC that are currently dropped by the sender (since they > > should be redundant). > > > > The receiver is then unable to continue without having the packet gap > > filled (unlike VP8/VP9 which moves on since it has a consecutive stream > > of picture IDs). > > > > Even if FEC retransmission did work it's a huge waste of bandwidth, > > since it just adds additional overhead that has to be unconditionally > > transmitted. This bandwidth is better used to send higher-quality > > frames. > > > > BUG=webrtc:5264 > > R=stefan@webrtc.org > > > > Committed: https://crrev.com/25558ad819b4df41ba51537e26a77480ace1e525 > > Cr-Commit-Position: refs/heads/master@{#11601} > > TBR=stefan@webrtc.org,pbos@webrtc.org > # Skipping CQ checks because original CL landed less than 1 days ago. > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:5264 > > Committed: https://crrev.com/29ffdc1a15e31bd81e806ff135c2100d811714f0 > Cr-Commit-Position: refs/heads/master@{#11607} TBR=stefan@webrtc.org,deadbeef@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=webrtc:5264 Review URL: https://codereview.webrtc.org/1697093002 . Cr-Commit-Position: refs/heads/master@{#11621}
2016-02-15 11:27:15 +01:00
}
}
if (header_extensions_enabled_) {
EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
uint32_t kHalf24BitsSpace = 0xFFFFFF / 2;
if (header.extension.absoluteSendTime <= kHalf24BitsSpace &&
prev_header_.extension.absoluteSendTime > kHalf24BitsSpace) {
// 24 bits wrap.
EXPECT_GT(prev_header_.extension.absoluteSendTime,
header.extension.absoluteSendTime);
} else {
EXPECT_GE(header.extension.absoluteSendTime,
prev_header_.extension.absoluteSendTime);
}
EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
uint16_t seq_num_diff = header.extension.transportSequenceNumber -
prev_header_.extension.transportSequenceNumber;
EXPECT_EQ(1, seq_num_diff);
}
if (encapsulated_payload_type != -1) {
if (encapsulated_payload_type ==
VideoSendStreamTest::kUlpfecPayloadType) {
EXPECT_TRUE(expect_ulpfec_);
sent_ulpfec_ = true;
} else {
sent_media_ = true;
}
}
if (sent_media_ && sent_ulpfec_) {
observation_complete_.Set();
Reland of Don't send FEC for H.264 with NACK enabled. (patchset #1 id:1 of https://codereview.webrtc.org/1692783005/ ) Reason for revert: Disabling tests on memcheck that time out due to using real VP8 encoders. Original issue's description: > Revert of Don't send FEC for H.264 with NACK enabled. (patchset #5 id:80001 of https://codereview.webrtc.org/1687303002/ ) > > Reason for revert: > Broke the VerifyHistogramStatsWithRed test on the Windows DrMemory Full bot and Linux Memcheck bot. Please fix the test and reland. > > Original issue's description: > > Don't send FEC for H.264 with NACK enabled. > > > > The H.264 does not contain picture IDs and are not sufficient to > > determine that a packet may be skipped. This causes retransmission > > requests for FEC that are currently dropped by the sender (since they > > should be redundant). > > > > The receiver is then unable to continue without having the packet gap > > filled (unlike VP8/VP9 which moves on since it has a consecutive stream > > of picture IDs). > > > > Even if FEC retransmission did work it's a huge waste of bandwidth, > > since it just adds additional overhead that has to be unconditionally > > transmitted. This bandwidth is better used to send higher-quality > > frames. > > > > BUG=webrtc:5264 > > R=stefan@webrtc.org > > > > Committed: https://crrev.com/25558ad819b4df41ba51537e26a77480ace1e525 > > Cr-Commit-Position: refs/heads/master@{#11601} > > TBR=stefan@webrtc.org,pbos@webrtc.org > # Skipping CQ checks because original CL landed less than 1 days ago. > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:5264 > > Committed: https://crrev.com/29ffdc1a15e31bd81e806ff135c2100d811714f0 > Cr-Commit-Position: refs/heads/master@{#11607} TBR=stefan@webrtc.org,deadbeef@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=webrtc:5264 Review URL: https://codereview.webrtc.org/1697093002 . Cr-Commit-Position: refs/heads/master@{#11621}
2016-02-15 11:27:15 +01:00
}
prev_header_ = header;
return SEND_PACKET;
}
test::PacketTransport* CreateSendTransport(
test::SingleThreadedTaskQueueForTesting* task_queue,
Call* sender_call) override {
Reland of Don't send FEC for H.264 with NACK enabled. (patchset #1 id:1 of https://codereview.webrtc.org/1692783005/ ) Reason for revert: Disabling tests on memcheck that time out due to using real VP8 encoders. Original issue's description: > Revert of Don't send FEC for H.264 with NACK enabled. (patchset #5 id:80001 of https://codereview.webrtc.org/1687303002/ ) > > Reason for revert: > Broke the VerifyHistogramStatsWithRed test on the Windows DrMemory Full bot and Linux Memcheck bot. Please fix the test and reland. > > Original issue's description: > > Don't send FEC for H.264 with NACK enabled. > > > > The H.264 does not contain picture IDs and are not sufficient to > > determine that a packet may be skipped. This causes retransmission > > requests for FEC that are currently dropped by the sender (since they > > should be redundant). > > > > The receiver is then unable to continue without having the packet gap > > filled (unlike VP8/VP9 which moves on since it has a consecutive stream > > of picture IDs). > > > > Even if FEC retransmission did work it's a huge waste of bandwidth, > > since it just adds additional overhead that has to be unconditionally > > transmitted. This bandwidth is better used to send higher-quality > > frames. > > > > BUG=webrtc:5264 > > R=stefan@webrtc.org > > > > Committed: https://crrev.com/25558ad819b4df41ba51537e26a77480ace1e525 > > Cr-Commit-Position: refs/heads/master@{#11601} > > TBR=stefan@webrtc.org,pbos@webrtc.org > # Skipping CQ checks because original CL landed less than 1 days ago. > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:5264 > > Committed: https://crrev.com/29ffdc1a15e31bd81e806ff135c2100d811714f0 > Cr-Commit-Position: refs/heads/master@{#11607} TBR=stefan@webrtc.org,deadbeef@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=webrtc:5264 Review URL: https://codereview.webrtc.org/1697093002 . Cr-Commit-Position: refs/heads/master@{#11621}
2016-02-15 11:27:15 +01:00
// At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
// Configure some network delay.
const int kNetworkDelayMs = 100;
FakeNetworkPipe::Config config;
config.loss_percent = 5;
Reland of Don't send FEC for H.264 with NACK enabled. (patchset #1 id:1 of https://codereview.webrtc.org/1692783005/ ) Reason for revert: Disabling tests on memcheck that time out due to using real VP8 encoders. Original issue's description: > Revert of Don't send FEC for H.264 with NACK enabled. (patchset #5 id:80001 of https://codereview.webrtc.org/1687303002/ ) > > Reason for revert: > Broke the VerifyHistogramStatsWithRed test on the Windows DrMemory Full bot and Linux Memcheck bot. Please fix the test and reland. > > Original issue's description: > > Don't send FEC for H.264 with NACK enabled. > > > > The H.264 does not contain picture IDs and are not sufficient to > > determine that a packet may be skipped. This causes retransmission > > requests for FEC that are currently dropped by the sender (since they > > should be redundant). > > > > The receiver is then unable to continue without having the packet gap > > filled (unlike VP8/VP9 which moves on since it has a consecutive stream > > of picture IDs). > > > > Even if FEC retransmission did work it's a huge waste of bandwidth, > > since it just adds additional overhead that has to be unconditionally > > transmitted. This bandwidth is better used to send higher-quality > > frames. > > > > BUG=webrtc:5264 > > R=stefan@webrtc.org > > > > Committed: https://crrev.com/25558ad819b4df41ba51537e26a77480ace1e525 > > Cr-Commit-Position: refs/heads/master@{#11601} > > TBR=stefan@webrtc.org,pbos@webrtc.org > # Skipping CQ checks because original CL landed less than 1 days ago. > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:5264 > > Committed: https://crrev.com/29ffdc1a15e31bd81e806ff135c2100d811714f0 > Cr-Commit-Position: refs/heads/master@{#11607} TBR=stefan@webrtc.org,deadbeef@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=webrtc:5264 Review URL: https://codereview.webrtc.org/1697093002 . Cr-Commit-Position: refs/heads/master@{#11621}
2016-02-15 11:27:15 +01:00
config.queue_delay_ms = kNetworkDelayMs;
return new test::PacketTransport(
task_queue, sender_call, this, test::PacketTransport::kSender,
VideoSendStreamTest::payload_type_map_, config);
Reland of Don't send FEC for H.264 with NACK enabled. (patchset #1 id:1 of https://codereview.webrtc.org/1692783005/ ) Reason for revert: Disabling tests on memcheck that time out due to using real VP8 encoders. Original issue's description: > Revert of Don't send FEC for H.264 with NACK enabled. (patchset #5 id:80001 of https://codereview.webrtc.org/1687303002/ ) > > Reason for revert: > Broke the VerifyHistogramStatsWithRed test on the Windows DrMemory Full bot and Linux Memcheck bot. Please fix the test and reland. > > Original issue's description: > > Don't send FEC for H.264 with NACK enabled. > > > > The H.264 does not contain picture IDs and are not sufficient to > > determine that a packet may be skipped. This causes retransmission > > requests for FEC that are currently dropped by the sender (since they > > should be redundant). > > > > The receiver is then unable to continue without having the packet gap > > filled (unlike VP8/VP9 which moves on since it has a consecutive stream > > of picture IDs). > > > > Even if FEC retransmission did work it's a huge waste of bandwidth, > > since it just adds additional overhead that has to be unconditionally > > transmitted. This bandwidth is better used to send higher-quality > > frames. > > > > BUG=webrtc:5264 > > R=stefan@webrtc.org > > > > Committed: https://crrev.com/25558ad819b4df41ba51537e26a77480ace1e525 > > Cr-Commit-Position: refs/heads/master@{#11601} > > TBR=stefan@webrtc.org,pbos@webrtc.org > # Skipping CQ checks because original CL landed less than 1 days ago. > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:5264 > > Committed: https://crrev.com/29ffdc1a15e31bd81e806ff135c2100d811714f0 > Cr-Commit-Position: refs/heads/master@{#11607} TBR=stefan@webrtc.org,deadbeef@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=webrtc:5264 Review URL: https://codereview.webrtc.org/1697093002 . Cr-Commit-Position: refs/heads/master@{#11621}
2016-02-15 11:27:15 +01:00
}
void ModifyVideoConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) override {
Reland of Don't send FEC for H.264 with NACK enabled. (patchset #1 id:1 of https://codereview.webrtc.org/1692783005/ ) Reason for revert: Disabling tests on memcheck that time out due to using real VP8 encoders. Original issue's description: > Revert of Don't send FEC for H.264 with NACK enabled. (patchset #5 id:80001 of https://codereview.webrtc.org/1687303002/ ) > > Reason for revert: > Broke the VerifyHistogramStatsWithRed test on the Windows DrMemory Full bot and Linux Memcheck bot. Please fix the test and reland. > > Original issue's description: > > Don't send FEC for H.264 with NACK enabled. > > > > The H.264 does not contain picture IDs and are not sufficient to > > determine that a packet may be skipped. This causes retransmission > > requests for FEC that are currently dropped by the sender (since they > > should be redundant). > > > > The receiver is then unable to continue without having the packet gap > > filled (unlike VP8/VP9 which moves on since it has a consecutive stream > > of picture IDs). > > > > Even if FEC retransmission did work it's a huge waste of bandwidth, > > since it just adds additional overhead that has to be unconditionally > > transmitted. This bandwidth is better used to send higher-quality > > frames. > > > > BUG=webrtc:5264 > > R=stefan@webrtc.org > > > > Committed: https://crrev.com/25558ad819b4df41ba51537e26a77480ace1e525 > > Cr-Commit-Position: refs/heads/master@{#11601} > > TBR=stefan@webrtc.org,pbos@webrtc.org > # Skipping CQ checks because original CL landed less than 1 days ago. > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:5264 > > Committed: https://crrev.com/29ffdc1a15e31bd81e806ff135c2100d811714f0 > Cr-Commit-Position: refs/heads/master@{#11607} TBR=stefan@webrtc.org,deadbeef@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=webrtc:5264 Review URL: https://codereview.webrtc.org/1697093002 . Cr-Commit-Position: refs/heads/master@{#11621}
2016-02-15 11:27:15 +01:00
if (use_nack_) {
send_config->rtp.nack.rtp_history_ms =
(*receive_configs)[0].rtp.nack.rtp_history_ms =
VideoSendStreamTest::kNackRtpHistoryMs;
}
send_config->encoder_settings.encoder = encoder_;
Reland of Don't send FEC for H.264 with NACK enabled. (patchset #1 id:1 of https://codereview.webrtc.org/1692783005/ ) Reason for revert: Disabling tests on memcheck that time out due to using real VP8 encoders. Original issue's description: > Revert of Don't send FEC for H.264 with NACK enabled. (patchset #5 id:80001 of https://codereview.webrtc.org/1687303002/ ) > > Reason for revert: > Broke the VerifyHistogramStatsWithRed test on the Windows DrMemory Full bot and Linux Memcheck bot. Please fix the test and reland. > > Original issue's description: > > Don't send FEC for H.264 with NACK enabled. > > > > The H.264 does not contain picture IDs and are not sufficient to > > determine that a packet may be skipped. This causes retransmission > > requests for FEC that are currently dropped by the sender (since they > > should be redundant). > > > > The receiver is then unable to continue without having the packet gap > > filled (unlike VP8/VP9 which moves on since it has a consecutive stream > > of picture IDs). > > > > Even if FEC retransmission did work it's a huge waste of bandwidth, > > since it just adds additional overhead that has to be unconditionally > > transmitted. This bandwidth is better used to send higher-quality > > frames. > > > > BUG=webrtc:5264 > > R=stefan@webrtc.org > > > > Committed: https://crrev.com/25558ad819b4df41ba51537e26a77480ace1e525 > > Cr-Commit-Position: refs/heads/master@{#11601} > > TBR=stefan@webrtc.org,pbos@webrtc.org > # Skipping CQ checks because original CL landed less than 1 days ago. > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:5264 > > Committed: https://crrev.com/29ffdc1a15e31bd81e806ff135c2100d811714f0 > Cr-Commit-Position: refs/heads/master@{#11607} TBR=stefan@webrtc.org,deadbeef@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=webrtc:5264 Review URL: https://codereview.webrtc.org/1697093002 . Cr-Commit-Position: refs/heads/master@{#11621}
2016-02-15 11:27:15 +01:00
send_config->encoder_settings.payload_name = payload_name_;
send_config->rtp.ulpfec.red_payload_type =
VideoSendStreamTest::kRedPayloadType;
send_config->rtp.ulpfec.ulpfec_payload_type =
VideoSendStreamTest::kUlpfecPayloadType;
EXPECT_FALSE(send_config->rtp.extensions.empty());
if (!header_extensions_enabled_) {
send_config->rtp.extensions.clear();
} else {
send_config->rtp.extensions.push_back(RtpExtension(
RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
}
(*receive_configs)[0].rtp.red_payload_type =
send_config->rtp.ulpfec.red_payload_type;
(*receive_configs)[0].rtp.ulpfec_payload_type =
send_config->rtp.ulpfec.ulpfec_payload_type;
}
void PerformTest() override {
EXPECT_EQ(expect_ulpfec_, Wait())
<< "Timed out waiting for ULPFEC and/or media packets.";
}
VideoEncoder* const encoder_;
std::string payload_name_;
Reland of Don't send FEC for H.264 with NACK enabled. (patchset #1 id:1 of https://codereview.webrtc.org/1692783005/ ) Reason for revert: Disabling tests on memcheck that time out due to using real VP8 encoders. Original issue's description: > Revert of Don't send FEC for H.264 with NACK enabled. (patchset #5 id:80001 of https://codereview.webrtc.org/1687303002/ ) > > Reason for revert: > Broke the VerifyHistogramStatsWithRed test on the Windows DrMemory Full bot and Linux Memcheck bot. Please fix the test and reland. > > Original issue's description: > > Don't send FEC for H.264 with NACK enabled. > > > > The H.264 does not contain picture IDs and are not sufficient to > > determine that a packet may be skipped. This causes retransmission > > requests for FEC that are currently dropped by the sender (since they > > should be redundant). > > > > The receiver is then unable to continue without having the packet gap > > filled (unlike VP8/VP9 which moves on since it has a consecutive stream > > of picture IDs). > > > > Even if FEC retransmission did work it's a huge waste of bandwidth, > > since it just adds additional overhead that has to be unconditionally > > transmitted. This bandwidth is better used to send higher-quality > > frames. > > > > BUG=webrtc:5264 > > R=stefan@webrtc.org > > > > Committed: https://crrev.com/25558ad819b4df41ba51537e26a77480ace1e525 > > Cr-Commit-Position: refs/heads/master@{#11601} > > TBR=stefan@webrtc.org,pbos@webrtc.org > # Skipping CQ checks because original CL landed less than 1 days ago. > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:5264 > > Committed: https://crrev.com/29ffdc1a15e31bd81e806ff135c2100d811714f0 > Cr-Commit-Position: refs/heads/master@{#11607} TBR=stefan@webrtc.org,deadbeef@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=webrtc:5264 Review URL: https://codereview.webrtc.org/1697093002 . Cr-Commit-Position: refs/heads/master@{#11621}
2016-02-15 11:27:15 +01:00
const bool use_nack_;
const bool expect_red_;
const bool expect_ulpfec_;
bool sent_media_;
bool sent_ulpfec_;
bool header_extensions_enabled_;
RTPHeader prev_header_;
};
TEST_F(VideoSendStreamTest, SupportsUlpfecWithExtensions) {
std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
UlpfecObserver test(true, false, true, true, "VP8", encoder.get());
RunBaseTest(&test);
}
TEST_F(VideoSendStreamTest, SupportsUlpfecWithoutExtensions) {
std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
UlpfecObserver test(false, false, true, true, "VP8", encoder.get());
Reland of Don't send FEC for H.264 with NACK enabled. (patchset #1 id:1 of https://codereview.webrtc.org/1692783005/ ) Reason for revert: Disabling tests on memcheck that time out due to using real VP8 encoders. Original issue's description: > Revert of Don't send FEC for H.264 with NACK enabled. (patchset #5 id:80001 of https://codereview.webrtc.org/1687303002/ ) > > Reason for revert: > Broke the VerifyHistogramStatsWithRed test on the Windows DrMemory Full bot and Linux Memcheck bot. Please fix the test and reland. > > Original issue's description: > > Don't send FEC for H.264 with NACK enabled. > > > > The H.264 does not contain picture IDs and are not sufficient to > > determine that a packet may be skipped. This causes retransmission > > requests for FEC that are currently dropped by the sender (since they > > should be redundant). > > > > The receiver is then unable to continue without having the packet gap > > filled (unlike VP8/VP9 which moves on since it has a consecutive stream > > of picture IDs). > > > > Even if FEC retransmission did work it's a huge waste of bandwidth, > > since it just adds additional overhead that has to be unconditionally > > transmitted. This bandwidth is better used to send higher-quality > > frames. > > > > BUG=webrtc:5264 > > R=stefan@webrtc.org > > > > Committed: https://crrev.com/25558ad819b4df41ba51537e26a77480ace1e525 > > Cr-Commit-Position: refs/heads/master@{#11601} > > TBR=stefan@webrtc.org,pbos@webrtc.org > # Skipping CQ checks because original CL landed less than 1 days ago. > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:5264 > > Committed: https://crrev.com/29ffdc1a15e31bd81e806ff135c2100d811714f0 > Cr-Commit-Position: refs/heads/master@{#11607} TBR=stefan@webrtc.org,deadbeef@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=webrtc:5264 Review URL: https://codereview.webrtc.org/1697093002 . Cr-Commit-Position: refs/heads/master@{#11621}
2016-02-15 11:27:15 +01:00
RunBaseTest(&test);
}
class VideoSendStreamWithoutUlpfecTest : public VideoSendStreamTest {
protected:
VideoSendStreamWithoutUlpfecTest()
: field_trial_("WebRTC-DisableUlpFecExperiment/Enabled/") {}
test::ScopedFieldTrials field_trial_;
};
TEST_F(VideoSendStreamWithoutUlpfecTest, NoUlpfecIfDisabledThroughFieldTrial) {
std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
UlpfecObserver test(false, false, true, false, "VP8", encoder.get());
RunBaseTest(&test);
}
Reland of Don't send FEC for H.264 with NACK enabled. (patchset #1 id:1 of https://codereview.webrtc.org/1692783005/ ) Reason for revert: Disabling tests on memcheck that time out due to using real VP8 encoders. Original issue's description: > Revert of Don't send FEC for H.264 with NACK enabled. (patchset #5 id:80001 of https://codereview.webrtc.org/1687303002/ ) > > Reason for revert: > Broke the VerifyHistogramStatsWithRed test on the Windows DrMemory Full bot and Linux Memcheck bot. Please fix the test and reland. > > Original issue's description: > > Don't send FEC for H.264 with NACK enabled. > > > > The H.264 does not contain picture IDs and are not sufficient to > > determine that a packet may be skipped. This causes retransmission > > requests for FEC that are currently dropped by the sender (since they > > should be redundant). > > > > The receiver is then unable to continue without having the packet gap > > filled (unlike VP8/VP9 which moves on since it has a consecutive stream > > of picture IDs). > > > > Even if FEC retransmission did work it's a huge waste of bandwidth, > > since it just adds additional overhead that has to be unconditionally > > transmitted. This bandwidth is better used to send higher-quality > > frames. > > > > BUG=webrtc:5264 > > R=stefan@webrtc.org > > > > Committed: https://crrev.com/25558ad819b4df41ba51537e26a77480ace1e525 > > Cr-Commit-Position: refs/heads/master@{#11601} > > TBR=stefan@webrtc.org,pbos@webrtc.org > # Skipping CQ checks because original CL landed less than 1 days ago. > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:5264 > > Committed: https://crrev.com/29ffdc1a15e31bd81e806ff135c2100d811714f0 > Cr-Commit-Position: refs/heads/master@{#11607} TBR=stefan@webrtc.org,deadbeef@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=webrtc:5264 Review URL: https://codereview.webrtc.org/1697093002 . Cr-Commit-Position: refs/heads/master@{#11621}
2016-02-15 11:27:15 +01:00
// The FEC scheme used is not efficient for H264, so we should not use RED/FEC
// since we'll still have to re-request FEC packets, effectively wasting
// bandwidth since the receiver has to wait for FEC retransmissions to determine
// that the received state is actually decodable.
TEST_F(VideoSendStreamTest, DoesNotUtilizeUlpfecForH264WithNackEnabled) {
std::unique_ptr<VideoEncoder> encoder(
new test::FakeH264Encoder(Clock::GetRealTimeClock()));
UlpfecObserver test(false, true, true, false, "H264", encoder.get());
Reland of Don't send FEC for H.264 with NACK enabled. (patchset #1 id:1 of https://codereview.webrtc.org/1692783005/ ) Reason for revert: Disabling tests on memcheck that time out due to using real VP8 encoders. Original issue's description: > Revert of Don't send FEC for H.264 with NACK enabled. (patchset #5 id:80001 of https://codereview.webrtc.org/1687303002/ ) > > Reason for revert: > Broke the VerifyHistogramStatsWithRed test on the Windows DrMemory Full bot and Linux Memcheck bot. Please fix the test and reland. > > Original issue's description: > > Don't send FEC for H.264 with NACK enabled. > > > > The H.264 does not contain picture IDs and are not sufficient to > > determine that a packet may be skipped. This causes retransmission > > requests for FEC that are currently dropped by the sender (since they > > should be redundant). > > > > The receiver is then unable to continue without having the packet gap > > filled (unlike VP8/VP9 which moves on since it has a consecutive stream > > of picture IDs). > > > > Even if FEC retransmission did work it's a huge waste of bandwidth, > > since it just adds additional overhead that has to be unconditionally > > transmitted. This bandwidth is better used to send higher-quality > > frames. > > > > BUG=webrtc:5264 > > R=stefan@webrtc.org > > > > Committed: https://crrev.com/25558ad819b4df41ba51537e26a77480ace1e525 > > Cr-Commit-Position: refs/heads/master@{#11601} > > TBR=stefan@webrtc.org,pbos@webrtc.org > # Skipping CQ checks because original CL landed less than 1 days ago. > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:5264 > > Committed: https://crrev.com/29ffdc1a15e31bd81e806ff135c2100d811714f0 > Cr-Commit-Position: refs/heads/master@{#11607} TBR=stefan@webrtc.org,deadbeef@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=webrtc:5264 Review URL: https://codereview.webrtc.org/1697093002 . Cr-Commit-Position: refs/heads/master@{#11621}
2016-02-15 11:27:15 +01:00
RunBaseTest(&test);
}
// Without retransmissions FEC for H264 is fine.
Remove RED/RTX workaround from sender/receiver and VideoEngine2. In older Chrome versions, the associated payload type in the RTX header of retransmitted packets was always set to be the original media payload type, regardless of the actual payload type of the packet. This meant that packets encapsulated with RED headers had incorrect payload type information in the RTX header. Due to an assumption in the receiver, this incorrect payload type information would effectively be undone, leading to a working system. Albeit working, this behaviour was undesired, and thus removed. In the interim, several workarounds were introduced to not destroy interop between old and new Chrome versions: (1) https://codereview.webrtc.org/1649493004 - If no payload type mapping existed for RED over RTX, the payload type of the underlying media would be used. - If RED had been negotiated, received RTX packets would always be assumed to contain RED. (2) https://codereview.webrtc.org/1964473002 - If RED was removed from the remote description answer, it would be disabled in the local receiver as well. (3) https://codereview.webrtc.org/2033763002 - If RED was negotiated in the SDP, it would always be used, regardless if ULPFEC was negotiated and used, or not. Since the Chrome versions that exhibited the original bug now are very old, this CL removes the workarounds from (1) and (2). In particular, after this change, we will have the following behaviour: - We assume that a payload type mapping for RED over RTX always is set. If this is not the case, the RTX packet is not sent. - The associated payload type of received RTX packets will always be obeyed. - The (non)-existence of RED in the remote description does not affect the local receiver. The workaround in (3) still needs to exist, in order to interop with receivers that did not have the workarounds in (1) and (2) removed. The change in (3) can be removed in a couple of Chrome versions. TESTED=Using AppRTC between patched Chrome (connected to ethernet) and standard Chrome M54 (connected to lossy internal Google WiFi), with and without FEC turned off using AppRTC flag. Also using "Munge SDP" sample on patched Chrome over loopback interface, with 100ms delay and 5% packet loss simulated using tc. BUG=webrtc:6650 Review-Url: https://codereview.webrtc.org/2469093003 Cr-Commit-Position: refs/heads/master@{#15038}
2016-11-11 03:28:30 -08:00
TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForH264WithoutNackEnabled) {
std::unique_ptr<VideoEncoder> encoder(
new test::FakeH264Encoder(Clock::GetRealTimeClock()));
UlpfecObserver test(false, false, true, true, "H264", encoder.get());
Reland of Don't send FEC for H.264 with NACK enabled. (patchset #1 id:1 of https://codereview.webrtc.org/1692783005/ ) Reason for revert: Disabling tests on memcheck that time out due to using real VP8 encoders. Original issue's description: > Revert of Don't send FEC for H.264 with NACK enabled. (patchset #5 id:80001 of https://codereview.webrtc.org/1687303002/ ) > > Reason for revert: > Broke the VerifyHistogramStatsWithRed test on the Windows DrMemory Full bot and Linux Memcheck bot. Please fix the test and reland. > > Original issue's description: > > Don't send FEC for H.264 with NACK enabled. > > > > The H.264 does not contain picture IDs and are not sufficient to > > determine that a packet may be skipped. This causes retransmission > > requests for FEC that are currently dropped by the sender (since they > > should be redundant). > > > > The receiver is then unable to continue without having the packet gap > > filled (unlike VP8/VP9 which moves on since it has a consecutive stream > > of picture IDs). > > > > Even if FEC retransmission did work it's a huge waste of bandwidth, > > since it just adds additional overhead that has to be unconditionally > > transmitted. This bandwidth is better used to send higher-quality > > frames. > > > > BUG=webrtc:5264 > > R=stefan@webrtc.org > > > > Committed: https://crrev.com/25558ad819b4df41ba51537e26a77480ace1e525 > > Cr-Commit-Position: refs/heads/master@{#11601} > > TBR=stefan@webrtc.org,pbos@webrtc.org > # Skipping CQ checks because original CL landed less than 1 days ago. > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:5264 > > Committed: https://crrev.com/29ffdc1a15e31bd81e806ff135c2100d811714f0 > Cr-Commit-Position: refs/heads/master@{#11607} TBR=stefan@webrtc.org,deadbeef@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=webrtc:5264 Review URL: https://codereview.webrtc.org/1697093002 . Cr-Commit-Position: refs/heads/master@{#11621}
2016-02-15 11:27:15 +01:00
RunBaseTest(&test);
}
// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp8WithNackEnabled) {
std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
UlpfecObserver test(false, true, true, true, "VP8", encoder.get());
Reland of Don't send FEC for H.264 with NACK enabled. (patchset #1 id:1 of https://codereview.webrtc.org/1692783005/ ) Reason for revert: Disabling tests on memcheck that time out due to using real VP8 encoders. Original issue's description: > Revert of Don't send FEC for H.264 with NACK enabled. (patchset #5 id:80001 of https://codereview.webrtc.org/1687303002/ ) > > Reason for revert: > Broke the VerifyHistogramStatsWithRed test on the Windows DrMemory Full bot and Linux Memcheck bot. Please fix the test and reland. > > Original issue's description: > > Don't send FEC for H.264 with NACK enabled. > > > > The H.264 does not contain picture IDs and are not sufficient to > > determine that a packet may be skipped. This causes retransmission > > requests for FEC that are currently dropped by the sender (since they > > should be redundant). > > > > The receiver is then unable to continue without having the packet gap > > filled (unlike VP8/VP9 which moves on since it has a consecutive stream > > of picture IDs). > > > > Even if FEC retransmission did work it's a huge waste of bandwidth, > > since it just adds additional overhead that has to be unconditionally > > transmitted. This bandwidth is better used to send higher-quality > > frames. > > > > BUG=webrtc:5264 > > R=stefan@webrtc.org > > > > Committed: https://crrev.com/25558ad819b4df41ba51537e26a77480ace1e525 > > Cr-Commit-Position: refs/heads/master@{#11601} > > TBR=stefan@webrtc.org,pbos@webrtc.org > # Skipping CQ checks because original CL landed less than 1 days ago. > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:5264 > > Committed: https://crrev.com/29ffdc1a15e31bd81e806ff135c2100d811714f0 > Cr-Commit-Position: refs/heads/master@{#11607} TBR=stefan@webrtc.org,deadbeef@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=webrtc:5264 Review URL: https://codereview.webrtc.org/1697093002 . Cr-Commit-Position: refs/heads/master@{#11621}
2016-02-15 11:27:15 +01:00
RunBaseTest(&test);
}
#if !defined(RTC_DISABLE_VP9)
// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp9WithNackEnabled) {
std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
UlpfecObserver test(false, true, true, true, "VP9", encoder.get());
RunBaseTest(&test);
}
#endif // !defined(RTC_DISABLE_VP9)
TEST_F(VideoSendStreamTest, SupportsUlpfecWithMultithreadedH264) {
std::unique_ptr<VideoEncoder> encoder(
new test::MultithreadedFakeH264Encoder(Clock::GetRealTimeClock()));
UlpfecObserver test(false, false, true, true, "H264", encoder.get());
RunBaseTest(&test);
}
// TODO(brandtr): Move these FlexFEC tests when we have created
// FlexfecSendStream.
class FlexfecObserver : public test::EndToEndTest {
public:
FlexfecObserver(bool header_extensions_enabled,
bool use_nack,
const std::string& codec,
VideoEncoder* encoder)
: EndToEndTest(VideoSendStreamTest::kDefaultTimeoutMs),
encoder_(encoder),
payload_name_(codec),
use_nack_(use_nack),
sent_media_(false),
sent_flexfec_(false),
header_extensions_enabled_(header_extensions_enabled) {}
size_t GetNumFlexfecStreams() const override { return 1; }
private:
Action OnSendRtp(const uint8_t* packet, size_t length) override {
RTPHeader header;
EXPECT_TRUE(parser_->Parse(packet, length, &header));
if (header.payloadType == VideoSendStreamTest::kFlexfecPayloadType) {
EXPECT_EQ(VideoSendStreamTest::kFlexfecSendSsrc, header.ssrc);
sent_flexfec_ = true;
} else {
EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
header.payloadType);
EXPECT_EQ(VideoSendStreamTest::kVideoSendSsrcs[0], header.ssrc);
sent_media_ = true;
}
if (header_extensions_enabled_) {
EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
}
if (sent_media_ && sent_flexfec_) {
observation_complete_.Set();
}
return SEND_PACKET;
}
test::PacketTransport* CreateSendTransport(
test::SingleThreadedTaskQueueForTesting* task_queue,
Call* sender_call) override {
// At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
// Therefore we need some network delay.
const int kNetworkDelayMs = 100;
FakeNetworkPipe::Config config;
config.loss_percent = 5;
config.queue_delay_ms = kNetworkDelayMs;
return new test::PacketTransport(
task_queue, sender_call, this, test::PacketTransport::kSender,
VideoSendStreamTest::payload_type_map_, config);
}
void ModifyVideoConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) override {
if (use_nack_) {
send_config->rtp.nack.rtp_history_ms =
(*receive_configs)[0].rtp.nack.rtp_history_ms =
VideoSendStreamTest::kNackRtpHistoryMs;
}
send_config->encoder_settings.encoder = encoder_;
send_config->encoder_settings.payload_name = payload_name_;
if (header_extensions_enabled_) {
send_config->rtp.extensions.push_back(RtpExtension(
RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
send_config->rtp.extensions.push_back(RtpExtension(
RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
} else {
send_config->rtp.extensions.clear();
}
}
void PerformTest() override {
EXPECT_TRUE(Wait())
<< "Timed out waiting for FlexFEC and/or media packets.";
}
VideoEncoder* const encoder_;
std::string payload_name_;
const bool use_nack_;
bool sent_media_;
bool sent_flexfec_;
bool header_extensions_enabled_;
};
TEST_F(VideoSendStreamTest, SupportsFlexfecVp8) {
std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
FlexfecObserver test(false, false, "VP8", encoder.get());
RunBaseTest(&test);
}
TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp8) {
std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
FlexfecObserver test(false, true, "VP8", encoder.get());
RunBaseTest(&test);
}
TEST_F(VideoSendStreamTest, SupportsFlexfecWithRtpExtensionsVp8) {
std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
FlexfecObserver test(true, false, "VP8", encoder.get());
RunBaseTest(&test);
}
#if !defined(RTC_DISABLE_VP9)
TEST_F(VideoSendStreamTest, SupportsFlexfecVp9) {
std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
FlexfecObserver test(false, false, "VP9", encoder.get());
RunBaseTest(&test);
}
TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp9) {
std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
FlexfecObserver test(false, true, "VP9", encoder.get());
RunBaseTest(&test);
}
#endif // defined(RTC_DISABLE_VP9)
TEST_F(VideoSendStreamTest, SupportsFlexfecH264) {
std::unique_ptr<VideoEncoder> encoder(
new test::FakeH264Encoder(Clock::GetRealTimeClock()));
FlexfecObserver test(false, false, "H264", encoder.get());
RunBaseTest(&test);
}
TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackH264) {
std::unique_ptr<VideoEncoder> encoder(
new test::FakeH264Encoder(Clock::GetRealTimeClock()));
FlexfecObserver test(false, true, "H264", encoder.get());
RunBaseTest(&test);
}
TEST_F(VideoSendStreamTest, SupportsFlexfecWithMultithreadedH264) {
std::unique_ptr<VideoEncoder> encoder(
new test::MultithreadedFakeH264Encoder(Clock::GetRealTimeClock()));
FlexfecObserver test(false, false, "H264", encoder.get());
RunBaseTest(&test);
}
void VideoSendStreamTest::TestNackRetransmission(
uint32_t retransmit_ssrc,
uint8_t retransmit_payload_type) {
class NackObserver : public test::SendTest {
public:
explicit NackObserver(uint32_t retransmit_ssrc,
uint8_t retransmit_payload_type)
: SendTest(kDefaultTimeoutMs),
send_count_(0),
retransmit_ssrc_(retransmit_ssrc),
retransmit_payload_type_(retransmit_payload_type),
nacked_sequence_number_(-1) {
}
private:
Action OnSendRtp(const uint8_t* packet, size_t length) override {
RTPHeader header;
EXPECT_TRUE(parser_->Parse(packet, length, &header));
// Nack second packet after receiving the third one.
if (++send_count_ == 3) {
uint16_t nack_sequence_number = header.sequenceNumber - 1;
nacked_sequence_number_ = nack_sequence_number;
RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(), nullptr,
nullptr, nullptr, transport_adapter_.get());
rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
RTCPSender::FeedbackState feedback_state;
EXPECT_EQ(0,
rtcp_sender.SendRTCP(
feedback_state, kRtcpNack, 1, &nack_sequence_number));
}
uint16_t sequence_number = header.sequenceNumber;
if (header.ssrc == retransmit_ssrc_ &&
retransmit_ssrc_ != kVideoSendSsrcs[0]) {
// Not kVideoSendSsrcs[0], assume correct RTX packet. Extract sequence
// number.
const uint8_t* rtx_header = packet + header.headerLength;
sequence_number = (rtx_header[0] << 8) + rtx_header[1];
}
if (sequence_number == nacked_sequence_number_) {
EXPECT_EQ(retransmit_ssrc_, header.ssrc);
EXPECT_EQ(retransmit_payload_type_, header.payloadType);
observation_complete_.Set();
}
return SEND_PACKET;
}
void ModifyVideoConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) override {
transport_adapter_.reset(
new internal::TransportAdapter(send_config->send_transport));
transport_adapter_->Enable();
send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
send_config->rtp.rtx.payload_type = retransmit_payload_type_;
if (retransmit_ssrc_ != kVideoSendSsrcs[0])
send_config->rtp.rtx.ssrcs.push_back(retransmit_ssrc_);
}
void PerformTest() override {
EXPECT_TRUE(Wait()) << "Timed out while waiting for NACK retransmission.";
}
std::unique_ptr<internal::TransportAdapter> transport_adapter_;
int send_count_;
uint32_t retransmit_ssrc_;
uint8_t retransmit_payload_type_;
int nacked_sequence_number_;
} test(retransmit_ssrc, retransmit_payload_type);
RunBaseTest(&test);
}
TEST_F(VideoSendStreamTest, RetransmitsNack) {
// Normal NACKs should use the send SSRC.
TestNackRetransmission(kVideoSendSsrcs[0], kFakeVideoSendPayloadType);
}
TEST_F(VideoSendStreamTest, RetransmitsNackOverRtx) {
// NACKs over RTX should use a separate SSRC.
TestNackRetransmission(kSendRtxSsrcs[0], kSendRtxPayloadType);
}
void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format,
bool with_fec) {
// Use a fake encoder to output a frame of every size in the range [90, 290],
// for each size making sure that the exact number of payload bytes received
// is correct and that packets are fragmented to respect max packet size.
static const size_t kMaxPacketSize = 128;
static const size_t start = 90;
static const size_t stop = 290;
// Observer that verifies that the expected number of packets and bytes
// arrive for each frame size, from start_size to stop_size.
class FrameFragmentationTest : public test::SendTest,
public EncodedFrameObserver {
public:
FrameFragmentationTest(size_t max_packet_size,
size_t start_size,
size_t stop_size,
bool test_generic_packetization,
bool use_fec)
: SendTest(kLongTimeoutMs),
encoder_(stop),
max_packet_size_(max_packet_size),
stop_size_(stop_size),
test_generic_packetization_(test_generic_packetization),
use_fec_(use_fec),
packet_count_(0),
accumulated_size_(0),
accumulated_payload_(0),
fec_packet_received_(false),
current_size_rtp_(start_size),
current_size_frame_(static_cast<int>(start_size)) {
// Fragmentation required, this test doesn't make sense without it.
encoder_.SetFrameSize(start_size);
RTC_DCHECK_GT(stop_size, max_packet_size);
}
private:
Action OnSendRtp(const uint8_t* packet, size_t size) override {
size_t length = size;
RTPHeader header;
EXPECT_TRUE(parser_->Parse(packet, length, &header));
EXPECT_LE(length, max_packet_size_);
if (use_fec_) {
uint8_t payload_type = packet[header.headerLength];
bool is_fec = header.payloadType == kRedPayloadType &&
payload_type == kUlpfecPayloadType;
if (is_fec) {
fec_packet_received_ = true;
return SEND_PACKET;
}
}
accumulated_size_ += length;
if (use_fec_)
TriggerLossReport(header);
if (test_generic_packetization_) {
size_t overhead = header.headerLength + header.paddingLength;
// Only remove payload header and RED header if the packet actually
// contains payload.
if (length > overhead) {
overhead += (1 /* Generic header */);
if (use_fec_)
overhead += 1; // RED for FEC header.
}
EXPECT_GE(length, overhead);
accumulated_payload_ += length - overhead;
}
// Marker bit set indicates last packet of a frame.
if (header.markerBit) {
if (use_fec_ && accumulated_payload_ == current_size_rtp_ - 1) {
// With FEC enabled, frame size is incremented asynchronously, so
// "old" frames one byte too small may arrive. Accept, but don't
// increase expected frame size.
accumulated_size_ = 0;
accumulated_payload_ = 0;
return SEND_PACKET;
}
EXPECT_GE(accumulated_size_, current_size_rtp_);
if (test_generic_packetization_) {
EXPECT_EQ(current_size_rtp_, accumulated_payload_);
}
// Last packet of frame; reset counters.
accumulated_size_ = 0;
accumulated_payload_ = 0;
if (current_size_rtp_ == stop_size_) {
// Done! (Don't increase size again, might arrive more @ stop_size).
observation_complete_.Set();
} else {
// Increase next expected frame size. If testing with FEC, make sure
// a FEC packet has been received for this frame size before
// proceeding, to make sure that redundancy packets don't exceed
// size limit.
if (!use_fec_) {
++current_size_rtp_;
} else if (fec_packet_received_) {
fec_packet_received_ = false;
++current_size_rtp_;
rtc::CritScope lock(&mutex_);
++current_size_frame_;
}
}
}
return SEND_PACKET;
}
void TriggerLossReport(const RTPHeader& header) {
// Send lossy receive reports to trigger FEC enabling.
const int kLossPercent = 5;
if (packet_count_++ % (100 / kLossPercent) != 0) {
FakeReceiveStatistics lossy_receive_stats(
kVideoSendSsrcs[0], header.sequenceNumber,
(packet_count_ * (100 - kLossPercent)) / 100, // Cumulative lost.
static_cast<uint8_t>((255 * kLossPercent) / 100)); // Loss percent.
RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(),
&lossy_receive_stats, nullptr, nullptr,
transport_adapter_.get());
rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
RTCPSender::FeedbackState feedback_state;
EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
}
}
void EncodedFrameCallback(const EncodedFrame& encoded_frame) override {
rtc::CritScope lock(&mutex_);
// Increase frame size for next encoded frame, in the context of the
// encoder thread.
if (!use_fec_ && current_size_frame_ < static_cast<int32_t>(stop_size_)) {
++current_size_frame_;
}
encoder_.SetFrameSize(static_cast<size_t>(current_size_frame_));
}
Call::Config GetSenderCallConfig() override {
Call::Config config(event_log_.get());
const int kMinBitrateBps = 30000;
config.bitrate_config.min_bitrate_bps = kMinBitrateBps;
return config;
}
void ModifyVideoConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) override {
transport_adapter_.reset(
new internal::TransportAdapter(send_config->send_transport));
transport_adapter_->Enable();
if (use_fec_) {
send_config->rtp.ulpfec.red_payload_type = kRedPayloadType;
send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType;
}
if (!test_generic_packetization_)
send_config->encoder_settings.payload_name = "VP8";
send_config->encoder_settings.encoder = &encoder_;
send_config->rtp.max_packet_size = kMaxPacketSize;
send_config->post_encode_callback = this;
// Make sure there is at least one extension header, to make the RTP
// header larger than the base length of 12 bytes.
EXPECT_FALSE(send_config->rtp.extensions.empty());
// Setup screen content disables frame dropping which makes this easier.
class VideoStreamFactory
: public VideoEncoderConfig::VideoStreamFactoryInterface {
public:
explicit VideoStreamFactory(size_t num_temporal_layers)
: num_temporal_layers_(num_temporal_layers) {
EXPECT_GT(num_temporal_layers, 0u);
}
private:
std::vector<VideoStream> CreateEncoderStreams(
int width,
int height,
const VideoEncoderConfig& encoder_config) override {
std::vector<VideoStream> streams =
test::CreateVideoStreams(width, height, encoder_config);
for (VideoStream& stream : streams) {
stream.temporal_layer_thresholds_bps.resize(num_temporal_layers_ -
1);
}
return streams;
}
const size_t num_temporal_layers_;
};
encoder_config->video_stream_factory =
new rtc::RefCountedObject<VideoStreamFactory>(2);
encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
}
void PerformTest() override {
EXPECT_TRUE(Wait()) << "Timed out while observing incoming RTP packets.";
}
std::unique_ptr<internal::TransportAdapter> transport_adapter_;
test::ConfigurableFrameSizeEncoder encoder_;
const size_t max_packet_size_;
const size_t stop_size_;
const bool test_generic_packetization_;
const bool use_fec_;
uint32_t packet_count_;
size_t accumulated_size_;
size_t accumulated_payload_;
bool fec_packet_received_;
size_t current_size_rtp_;
rtc::CriticalSection mutex_;
int current_size_frame_ RTC_GUARDED_BY(mutex_);
};
// Don't auto increment if FEC is used; continue sending frame size until
// a FEC packet has been received.
FrameFragmentationTest test(
kMaxPacketSize, start, stop, format == kGeneric, with_fec);
RunBaseTest(&test);
}
// TODO(sprang): Is there any way of speeding up these tests?
TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSize) {
TestPacketFragmentationSize(kGeneric, false);
}
TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSizeWithFec) {
TestPacketFragmentationSize(kGeneric, true);
}
TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSize) {
TestPacketFragmentationSize(kVP8, false);
}
TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSizeWithFec) {
TestPacketFragmentationSize(kVP8, true);
}
// The test will go through a number of phases.
// 1. Start sending packets.
// 2. As soon as the RTP stream has been detected, signal a low REMB value to
// suspend the stream.
// 3. Wait until |kSuspendTimeFrames| have been captured without seeing any RTP
// packets.
// 4. Signal a high REMB and then wait for the RTP stream to start again.
// When the stream is detected again, and the stats show that the stream
// is no longer suspended, the test ends.
TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) {
static const int kSuspendTimeFrames = 60; // Suspend for 2 seconds @ 30 fps.
class RembObserver : public test::SendTest,
public rtc::VideoSinkInterface<VideoFrame> {
public:
RembObserver()
: SendTest(kDefaultTimeoutMs),
clock_(Clock::GetRealTimeClock()),
stream_(nullptr),
test_state_(kBeforeSuspend),
rtp_count_(0),
last_sequence_number_(0),
suspended_frame_count_(0),
low_remb_bps_(0),
high_remb_bps_(0) {}
private:
Action OnSendRtp(const uint8_t* packet, size_t length) override {
rtc::CritScope lock(&crit_);
++rtp_count_;
RTPHeader header;
EXPECT_TRUE(parser_->Parse(packet, length, &header));
last_sequence_number_ = header.sequenceNumber;
if (test_state_ == kBeforeSuspend) {
// The stream has started. Try to suspend it.
SendRtcpFeedback(low_remb_bps_);
test_state_ = kDuringSuspend;
} else if (test_state_ == kDuringSuspend) {
if (header.paddingLength == 0) {
// Received non-padding packet during suspension period. Reset the
// counter.
suspended_frame_count_ = 0;
}
SendRtcpFeedback(0); // REMB is only sent if value is > 0.
} else if (test_state_ == kWaitingForPacket) {
if (header.paddingLength == 0) {
// Non-padding packet observed. Test is almost complete. Will just
// have to wait for the stats to change.
test_state_ = kWaitingForStats;
}
SendRtcpFeedback(0); // REMB is only sent if value is > 0.
} else if (test_state_ == kWaitingForStats) {
VideoSendStream::Stats stats = stream_->GetStats();
if (stats.suspended == false) {
// Stats flipped to false. Test is complete.
observation_complete_.Set();
}
SendRtcpFeedback(0); // REMB is only sent if value is > 0.
}
return SEND_PACKET;
}
// This method implements the rtc::VideoSinkInterface. This is called when
// a frame is provided to the VideoSendStream.
void OnFrame(const VideoFrame& video_frame) override {
rtc::CritScope lock(&crit_);
if (test_state_ == kDuringSuspend &&
++suspended_frame_count_ > kSuspendTimeFrames) {
VideoSendStream::Stats stats = stream_->GetStats();
EXPECT_TRUE(stats.suspended);
SendRtcpFeedback(high_remb_bps_);
test_state_ = kWaitingForPacket;
}
}
void set_low_remb_bps(int value) {
rtc::CritScope lock(&crit_);
low_remb_bps_ = value;
}
void set_high_remb_bps(int value) {
rtc::CritScope lock(&crit_);
high_remb_bps_ = value;
}
void OnVideoStreamsCreated(
VideoSendStream* send_stream,
const std::vector<VideoReceiveStream*>& receive_streams) override {
stream_ = send_stream;
}
void ModifyVideoConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) override {
RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
transport_adapter_.reset(
new internal::TransportAdapter(send_config->send_transport));
transport_adapter_->Enable();
send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
send_config->pre_encode_callback = this;
send_config->suspend_below_min_bitrate = true;
int min_bitrate_bps =
test::DefaultVideoStreamFactory::kDefaultMinBitratePerStream[0];
set_low_remb_bps(min_bitrate_bps - 10000);
int threshold_window = std::max(min_bitrate_bps / 10, 20000);
ASSERT_GT(encoder_config->max_bitrate_bps,
min_bitrate_bps + threshold_window + 5000);
set_high_remb_bps(min_bitrate_bps + threshold_window + 5000);
}
void PerformTest() override {
EXPECT_TRUE(Wait()) << "Timed out during suspend-below-min-bitrate test.";
}
enum TestState {
kBeforeSuspend,
kDuringSuspend,
kWaitingForPacket,
kWaitingForStats
};
virtual void SendRtcpFeedback(int remb_value)
RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_) {
FakeReceiveStatistics receive_stats(kVideoSendSsrcs[0],
last_sequence_number_, rtp_count_, 0);
RTCPSender rtcp_sender(false, clock_, &receive_stats, nullptr, nullptr,
transport_adapter_.get());
rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
if (remb_value > 0) {
rtcp_sender.SetRemb(remb_value, std::vector<uint32_t>());
}
RTCPSender::FeedbackState feedback_state;
EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
}
std::unique_ptr<internal::TransportAdapter> transport_adapter_;
Clock* const clock_;
VideoSendStream* stream_;
rtc::CriticalSection crit_;
TestState test_state_ RTC_GUARDED_BY(crit_);
int rtp_count_ RTC_GUARDED_BY(crit_);
int last_sequence_number_ RTC_GUARDED_BY(crit_);
int suspended_frame_count_ RTC_GUARDED_BY(crit_);
int low_remb_bps_ RTC_GUARDED_BY(crit_);
int high_remb_bps_ RTC_GUARDED_BY(crit_);
} test;
RunBaseTest(&test);
}
// This test that padding stops being send after a while if the Camera stops
// producing video frames and that padding resumes if the camera restarts.
TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) {
class NoPaddingWhenVideoIsMuted : public test::SendTest {
public:
NoPaddingWhenVideoIsMuted()
: SendTest(kDefaultTimeoutMs),
clock_(Clock::GetRealTimeClock()),
last_packet_time_ms_(-1),
capturer_(nullptr) {
}
private:
Action OnSendRtp(const uint8_t* packet, size_t length) override {
rtc::CritScope lock(&crit_);
last_packet_time_ms_ = clock_->TimeInMilliseconds();
RTPHeader header;
parser_->Parse(packet, length, &header);
const bool only_padding =
header.headerLength + header.paddingLength == length;
if (test_state_ == kBeforeStopCapture) {
capturer_->Stop();
test_state_ = kWaitingForPadding;
} else if (test_state_ == kWaitingForPadding && only_padding) {
test_state_ = kWaitingForNoPackets;
} else if (test_state_ == kWaitingForPaddingAfterCameraRestart &&
only_padding) {
observation_complete_.Set();
}
return SEND_PACKET;
}
Action OnSendRtcp(const uint8_t* packet, size_t length) override {
rtc::CritScope lock(&crit_);
const int kNoPacketsThresholdMs = 2000;
if (test_state_ == kWaitingForNoPackets &&
(last_packet_time_ms_ > 0 &&
clock_->TimeInMilliseconds() - last_packet_time_ms_ >
kNoPacketsThresholdMs)) {
capturer_->Start();
test_state_ = kWaitingForPaddingAfterCameraRestart;
}
return SEND_PACKET;
}
size_t GetNumVideoStreams() const override { return 3; }
void OnFrameGeneratorCapturerCreated(
test::FrameGeneratorCapturer* frame_generator_capturer) override {
rtc::CritScope lock(&crit_);
capturer_ = frame_generator_capturer;
}
void PerformTest() override {
EXPECT_TRUE(Wait())
<< "Timed out while waiting for RTP packets to stop being sent.";
}
enum TestState {
kBeforeStopCapture,
kWaitingForPadding,
kWaitingForNoPackets,
kWaitingForPaddingAfterCameraRestart
};
TestState test_state_ = kBeforeStopCapture;
Clock* const clock_;
std::unique_ptr<internal::TransportAdapter> transport_adapter_;
rtc::CriticalSection crit_;
int64_t last_packet_time_ms_ RTC_GUARDED_BY(crit_);
test::FrameGeneratorCapturer* capturer_ RTC_GUARDED_BY(crit_);
} test;
RunBaseTest(&test);
}
TEST_F(VideoSendStreamTest, PaddingIsPrimarilyRetransmissions) {
const int kCapacityKbps = 10000; // 10 Mbps
class PaddingIsPrimarilyRetransmissions : public test::EndToEndTest {
public:
PaddingIsPrimarilyRetransmissions()
: EndToEndTest(kDefaultTimeoutMs),
clock_(Clock::GetRealTimeClock()),
padding_length_(0),
total_length_(0),
call_(nullptr) {}
private:
void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
call_ = sender_call;
}
Action OnSendRtp(const uint8_t* packet, size_t length) override {
rtc::CritScope lock(&crit_);
RTPHeader header;
parser_->Parse(packet, length, &header);
padding_length_ += header.paddingLength;
total_length_ += length;
return SEND_PACKET;
}
test::PacketTransport* CreateSendTransport(
test::SingleThreadedTaskQueueForTesting* task_queue,
Call* sender_call) override {
const int kNetworkDelayMs = 50;
FakeNetworkPipe::Config config;
config.loss_percent = 10;
config.link_capacity_kbps = kCapacityKbps;
config.queue_delay_ms = kNetworkDelayMs;
return new test::PacketTransport(task_queue, sender_call, this,
Reland of Don't hardcode MediaType::ANY in FakeNetworkPipe. (patchset #1 id:1 of https://codereview.webrtc.org/2784543002/ ) Reason for revert: Intend to fix perf failures and reland. Original issue's description: > Revert of Don't hardcode MediaType::ANY in FakeNetworkPipe. (patchset #4 id:60001 of https://codereview.webrtc.org/2774463003/ ) > > Reason for revert: > Reverting since this seems to break multiple WebRTC Perf buildbots > > Original issue's description: > > Don't hardcode MediaType::ANY in FakeNetworkPipe. > > > > Instead let each test set the appropriate media type. This simplifies > > demuxing in Call and later in RtpTransportController. > > > > BUG=webrtc:7135 > > > > Review-Url: https://codereview.webrtc.org/2774463003 > > Cr-Commit-Position: refs/heads/master@{#17418} > > Committed: https://chromium.googlesource.com/external/webrtc/+/9c47b00e24da2941eb095df5a4459c6d98a8a88d > > TBR=stefan@webrtc.org,deadbeef@webrtc.org,solenberg@webrtc.org,pbos@webrtc.org,sprang@webrtc.org,nisse@webrtc.org > # Skipping CQ checks because original CL landed less than 1 days ago. > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:7135 > > Review-Url: https://codereview.webrtc.org/2784543002 > Cr-Commit-Position: refs/heads/master@{#17427} > Committed: https://chromium.googlesource.com/external/webrtc/+/3a3bd5061089da5327fc549337a8430054d66057 TBR=stefan@webrtc.org,deadbeef@webrtc.org,solenberg@webrtc.org,pbos@webrtc.org,sprang@webrtc.org,lliuu@webrtc.org # Skipping CQ checks because original CL landed less than 1 days ago. NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=webrtc:7135 Review-Url: https://codereview.webrtc.org/2783853002 Cr-Commit-Position: refs/heads/master@{#17459}
2017-03-29 23:57:43 -07:00
test::PacketTransport::kSender,
payload_type_map_, config);
}
void ModifyVideoConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) override {
// Turn on RTX.
send_config->rtp.rtx.payload_type = kFakeVideoSendPayloadType;
send_config->rtp.rtx.ssrcs.push_back(kVideoSendSsrcs[0]);
}
void PerformTest() override {
// TODO(isheriff): Some platforms do not ramp up as expected to full
// capacity due to packet scheduling delays. Fix that before getting
// rid of this.
SleepMs(5000);
{
rtc::CritScope lock(&crit_);
// Expect padding to be a small percentage of total bytes sent.
EXPECT_LT(padding_length_, .1 * total_length_);
}
}
rtc::CriticalSection crit_;
Clock* const clock_;
size_t padding_length_ RTC_GUARDED_BY(crit_);
size_t total_length_ RTC_GUARDED_BY(crit_);
Call* call_;
} test;
RunBaseTest(&test);
}
// This test first observes "high" bitrate use at which point it sends a REMB to
// indicate that it should be lowered significantly. The test then observes that
// the bitrate observed is sinking well below the min-transmit-bitrate threshold
// to verify that the min-transmit bitrate respects incoming REMB.
//
// Note that the test starts at "high" bitrate and does not ramp up to "higher"
// bitrate since no receiver block or remb is sent in the initial phase.
TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) {
static const int kMinTransmitBitrateBps = 400000;
static const int kHighBitrateBps = 150000;
static const int kRembBitrateBps = 80000;
static const int kRembRespectedBitrateBps = 100000;
class BitrateObserver : public test::SendTest {
public:
BitrateObserver()
: SendTest(kDefaultTimeoutMs),
retranmission_rate_limiter_(Clock::GetRealTimeClock(), 1000),
stream_(nullptr),
bitrate_capped_(false) {}
private:
Action OnSendRtp(const uint8_t* packet, size_t length) override {
if (RtpHeaderParser::IsRtcp(packet, length))
return DROP_PACKET;
RTPHeader header;
if (!parser_->Parse(packet, length, &header))
return DROP_PACKET;
RTC_DCHECK(stream_);
VideoSendStream::Stats stats = stream_->GetStats();
if (!stats.substreams.empty()) {
EXPECT_EQ(1u, stats.substreams.size());
int total_bitrate_bps =
stats.substreams.begin()->second.total_bitrate_bps;
test::PrintResult("bitrate_stats_",
"min_transmit_bitrate_low_remb",
"bitrate_bps",
static_cast<size_t>(total_bitrate_bps),
"bps",
false);
if (total_bitrate_bps > kHighBitrateBps) {
rtp_rtcp_->SetRemb(kRembBitrateBps,
std::vector<uint32_t>(1, header.ssrc));
rtp_rtcp_->Process();
bitrate_capped_ = true;
} else if (bitrate_capped_ &&
total_bitrate_bps < kRembRespectedBitrateBps) {
observation_complete_.Set();
}
}
// Packets don't have to be delivered since the test is the receiver.
return DROP_PACKET;
}
void OnVideoStreamsCreated(
VideoSendStream* send_stream,
const std::vector<VideoReceiveStream*>& receive_streams) override {
stream_ = send_stream;
RtpRtcp::Configuration config;
config.outgoing_transport = feedback_transport_.get();
config.retransmission_rate_limiter = &retranmission_rate_limiter_;
rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config));
rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
}
void ModifyVideoConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) override {
feedback_transport_.reset(
new internal::TransportAdapter(send_config->send_transport));
feedback_transport_->Enable();
encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
}
void PerformTest() override {
EXPECT_TRUE(Wait())
<< "Timeout while waiting for low bitrate stats after REMB.";
}
std::unique_ptr<RtpRtcp> rtp_rtcp_;
std::unique_ptr<internal::TransportAdapter> feedback_transport_;
RateLimiter retranmission_rate_limiter_;
VideoSendStream* stream_;
bool bitrate_capped_;
} test;
RunBaseTest(&test);
}
TEST_F(VideoSendStreamTest, ChangingNetworkRoute) {
static const int kStartBitrateBps = 300000;
static const int kNewMaxBitrateBps = 1234567;
static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
class ChangingNetworkRouteTest : public test::EndToEndTest {
public:
explicit ChangingNetworkRouteTest(
test::SingleThreadedTaskQueueForTesting* task_queue)
: EndToEndTest(test::CallTest::kDefaultTimeoutMs),
task_queue_(task_queue),
call_(nullptr) {
EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
kRtpExtensionTransportSequenceNumber, kExtensionId));
}
void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
call_ = sender_call;
}
void ModifyVideoConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) override {
send_config->rtp.extensions.clear();
send_config->rtp.extensions.push_back(RtpExtension(
RtpExtension::kTransportSequenceNumberUri, kExtensionId));
(*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
(*receive_configs)[0].rtp.transport_cc = true;
}
void ModifyAudioConfigs(
AudioSendStream::Config* send_config,
std::vector<AudioReceiveStream::Config>* receive_configs) override {
send_config->rtp.extensions.clear();
send_config->rtp.extensions.push_back(RtpExtension(
RtpExtension::kTransportSequenceNumberUri, kExtensionId));
(*receive_configs)[0].rtp.extensions.clear();
(*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
(*receive_configs)[0].rtp.transport_cc = true;
}
Action OnSendRtp(const uint8_t* packet, size_t length) override {
if (call_->GetStats().send_bandwidth_bps > kStartBitrateBps) {
observation_complete_.Set();
}
return SEND_PACKET;
}
void PerformTest() override {
rtc::NetworkRoute new_route(true, 10, 20, -1);
Call::Config::BitrateConfig bitrate_config;
task_queue_->SendTask([this, &new_route, &bitrate_config]() {
call_->OnNetworkRouteChanged("transport", new_route);
bitrate_config.start_bitrate_bps = kStartBitrateBps;
call_->SetBitrateConfig(bitrate_config);
});
EXPECT_TRUE(Wait())
<< "Timed out while waiting for start bitrate to be exceeded.";
task_queue_->SendTask([this, &new_route, &bitrate_config]() {
bitrate_config.start_bitrate_bps = -1;
bitrate_config.max_bitrate_bps = kNewMaxBitrateBps;
call_->SetBitrateConfig(bitrate_config);
// TODO(holmer): We should set the last sent packet id here and verify
// that we correctly ignore any packet loss reported prior to that id.
++new_route.local_network_id;
call_->OnNetworkRouteChanged("transport", new_route);
EXPECT_GE(call_->GetStats().send_bandwidth_bps, kStartBitrateBps);
});
}
private:
test::SingleThreadedTaskQueueForTesting* const task_queue_;
Call* call_;
} test(&task_queue_);
RunBaseTest(&test);
}
TEST_F(VideoSendStreamTest, ChangingTransportOverhead) {
class ChangingTransportOverheadTest : public test::EndToEndTest {
public:
explicit ChangingTransportOverheadTest(
test::SingleThreadedTaskQueueForTesting* task_queue)
: EndToEndTest(test::CallTest::kDefaultTimeoutMs),
task_queue_(task_queue),
call_(nullptr),
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
packets_sent_(0),
transport_overhead_(0) {}
void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
call_ = sender_call;
}
Action OnSendRtp(const uint8_t* packet, size_t length) override {
EXPECT_LE(length, kMaxRtpPacketSize);
rtc::CritScope cs(&lock_);
if (++packets_sent_ < 100)
return SEND_PACKET;
observation_complete_.Set();
return SEND_PACKET;
}
void ModifyVideoConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) override {
send_config->rtp.max_packet_size = kMaxRtpPacketSize;
}
void PerformTest() override {
task_queue_->SendTask([this]() {
transport_overhead_ = 100;
call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
transport_overhead_);
});
EXPECT_TRUE(Wait());
{
rtc::CritScope cs(&lock_);
packets_sent_ = 0;
}
task_queue_->SendTask([this]() {
transport_overhead_ = 500;
call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
transport_overhead_);
});
EXPECT_TRUE(Wait());
}
private:
test::SingleThreadedTaskQueueForTesting* const task_queue_;
Call* call_;
rtc::CriticalSection lock_;
int packets_sent_ RTC_GUARDED_BY(lock_);
int transport_overhead_;
const size_t kMaxRtpPacketSize = 1000;
} test(&task_queue_);
RunBaseTest(&test);
}
// Test class takes takes as argument a switch selecting if type switch should
// occur and a function pointer to reset the send stream. This is necessary
// since you cannot change the content type of a VideoSendStream, you need to
// recreate it. Stopping and recreating the stream can only be done on the main
// thread and in the context of VideoSendStreamTest (not BaseTest).
template <typename T>
class MaxPaddingSetTest : public test::SendTest {
public:
static const uint32_t kMinTransmitBitrateBps = 400000;
static const uint32_t kActualEncodeBitrateBps = 40000;
static const uint32_t kMinPacketsToSend = 50;
explicit MaxPaddingSetTest(bool test_switch_content_type, T* stream_reset_fun)
: SendTest(test::CallTest::kDefaultTimeoutMs),
content_switch_event_(false, false),
call_(nullptr),
send_stream_(nullptr),
send_stream_config_(nullptr),
packets_sent_(0),
running_without_padding_(test_switch_content_type),
stream_resetter_(stream_reset_fun) {
RTC_DCHECK(stream_resetter_);
}
void OnVideoStreamsCreated(
VideoSendStream* send_stream,
const std::vector<VideoReceiveStream*>& receive_streams) override {
rtc::CritScope lock(&crit_);
send_stream_ = send_stream;
}
void ModifyVideoConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) override {
RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
if (RunningWithoutPadding()) {
encoder_config->min_transmit_bitrate_bps = 0;
encoder_config->content_type =
VideoEncoderConfig::ContentType::kRealtimeVideo;
} else {
encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
}
send_stream_config_ = send_config->Copy();
encoder_config_ = encoder_config->Copy();
}
void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
call_ = sender_call;
}
Action OnSendRtp(const uint8_t* packet, size_t length) override {
rtc::CritScope lock(&crit_);
if (running_without_padding_)
EXPECT_EQ(0, call_->GetStats().max_padding_bitrate_bps);
// Wait until at least kMinPacketsToSend frames have been encoded, so that
// we have reliable data.
if (++packets_sent_ < kMinPacketsToSend)
return SEND_PACKET;
if (running_without_padding_) {
// We've sent kMinPacketsToSend packets with default configuration, switch
// to enabling screen content and setting min transmit bitrate.
// Note that we need to recreate the stream if changing content type.
packets_sent_ = 0;
encoder_config_.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
running_without_padding_ = false;
content_switch_event_.Set();
return SEND_PACKET;
}
// Make sure the pacer has been configured with a min transmit bitrate.
if (call_->GetStats().max_padding_bitrate_bps > 0)
observation_complete_.Set();
return SEND_PACKET;
}
void PerformTest() override {
if (RunningWithoutPadding()) {
ASSERT_TRUE(
content_switch_event_.Wait(test::CallTest::kDefaultTimeoutMs));
(*stream_resetter_)(send_stream_config_, encoder_config_);
}
ASSERT_TRUE(Wait()) << "Timed out waiting for a valid padding bitrate.";
}
private:
bool RunningWithoutPadding() const {
rtc::CritScope lock(&crit_);
return running_without_padding_;
}
rtc::CriticalSection crit_;
rtc::Event content_switch_event_;
Call* call_;
VideoSendStream* send_stream_ RTC_GUARDED_BY(crit_);
VideoSendStream::Config send_stream_config_;
VideoEncoderConfig encoder_config_;
uint32_t packets_sent_ RTC_GUARDED_BY(crit_);
bool running_without_padding_;
T* const stream_resetter_;
};
TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrate) {
auto reset_fun = [](const VideoSendStream::Config& send_stream_config,
const VideoEncoderConfig& encoder_config) {};
MaxPaddingSetTest<decltype(reset_fun)> test(false, &reset_fun);
RunBaseTest(&test);
}
TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrateAfterContentSwitch) {
// Function for removing and recreating the send stream with a new config.
auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
const VideoEncoderConfig& encoder_config) {
task_queue_.SendTask([this, &send_stream_config, &encoder_config]() {
Stop();
sender_call_->DestroyVideoSendStream(video_send_stream_);
video_send_config_ = send_stream_config.Copy();
video_encoder_config_ = encoder_config.Copy();
video_send_stream_ = sender_call_->CreateVideoSendStream(
video_send_config_.Copy(), video_encoder_config_.Copy());
video_send_stream_->SetSource(
frame_generator_capturer_.get(),
VideoSendStream::DegradationPreference::kMaintainResolution);
Start();
});
};
MaxPaddingSetTest<decltype(reset_fun)> test(true, &reset_fun);
RunBaseTest(&test);
}
// This test verifies that new frame sizes reconfigures encoders even though not
// (yet) sending. The purpose of this is to permit encoding as quickly as
// possible once we start sending. Likely the frames being input are from the
// same source that will be sent later, which just means that we're ready
// earlier.
TEST_F(VideoSendStreamTest,
EncoderReconfigureOnResolutionChangeWhenNotSending) {
class EncoderObserver : public test::FakeEncoder {
public:
EncoderObserver()
: FakeEncoder(Clock::GetRealTimeClock()),
init_encode_called_(false, false),
number_of_initializations_(0),
last_initialized_frame_width_(0),
last_initialized_frame_height_(0) {}
void WaitForResolution(int width, int height) {
{
rtc::CritScope lock(&crit_);
if (last_initialized_frame_width_ == width &&
last_initialized_frame_height_ == height) {
return;
}
}
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
EXPECT_TRUE(
init_encode_called_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
{
rtc::CritScope lock(&crit_);
EXPECT_EQ(width, last_initialized_frame_width_);
EXPECT_EQ(height, last_initialized_frame_height_);
}
}
private:
int32_t InitEncode(const VideoCodec* config,
int32_t number_of_cores,
size_t max_payload_size) override {
rtc::CritScope lock(&crit_);
last_initialized_frame_width_ = config->width;
last_initialized_frame_height_ = config->height;
++number_of_initializations_;
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
init_encode_called_.Set();
return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
}
int32_t Encode(const VideoFrame& input_image,
const CodecSpecificInfo* codec_specific_info,
const std::vector<FrameType>* frame_types) override {
ADD_FAILURE()
<< "Unexpected Encode call since the send stream is not started";
return 0;
}
rtc::CriticalSection crit_;
rtc::Event init_encode_called_;
size_t number_of_initializations_ RTC_GUARDED_BY(&crit_);
int last_initialized_frame_width_ RTC_GUARDED_BY(&crit_);
int last_initialized_frame_height_ RTC_GUARDED_BY(&crit_);
};
test::NullTransport transport;
EncoderObserver encoder;
task_queue_.SendTask([this, &transport, &encoder]() {
CreateSenderCall(Call::Config(event_log_.get()));
CreateSendConfig(1, 0, 0, &transport);
video_send_config_.encoder_settings.encoder = &encoder;
CreateVideoStreams();
CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
kDefaultHeight);
frame_generator_capturer_->Start();
});
encoder.WaitForResolution(kDefaultWidth, kDefaultHeight);
task_queue_.SendTask([this]() {
frame_generator_capturer_->ChangeResolution(kDefaultWidth * 2,
kDefaultHeight * 2);
});
encoder.WaitForResolution(kDefaultWidth * 2, kDefaultHeight * 2);
task_queue_.SendTask([this]() {
DestroyStreams();
DestroyCalls();
});
}
TEST_F(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) {
class StartBitrateObserver : public test::FakeEncoder {
public:
StartBitrateObserver()
Reland of Initialize/configure video encoders asychronously. (patchset #1 id:1 of https://codereview.webrtc.org/1821983002/ ) Reason for revert: RTCVideoEncoder has been updated to not make assumptions on calling threads/post back to a worker thread. This should now be landable again. Original issue's description: > Revert of Initialize/configure video encoders asychronously. (patchset #4 id:60001 of https://codereview.webrtc.org/1757313002/ ) > > Reason for revert: > Breaks RTCVideoEncoder which has incorrect assumptions on where InitEncode etc. is called from. Temporarily reverting until RTCVideoEncoder has been updated. > > Original issue's description: > > Initialize/configure video encoders asychronously. > > > > Greatly speeds up setRemoteDescription() by moving encoder initialization > > off the main worker thread, which is free to move onto gathering ICE > > candidates and other tasks while InitEncode() is performed. It also > > un-blocks PeerConnection GetStats() which is no longer blocked on > > encoder initialization. > > > > BUG=webrtc:5410 > > R=stefan@webrtc.org > > > > Committed: https://chromium.googlesource.com/external/webrtc/+/fb647a67be94bb3c940d8b5fba01972f7ce91a29 > > R=stefan@webrtc.org > # Not skipping CQ checks because original CL landed more than 1 days ago. > BUG=chromium:595274, chromium:595308, webrtc:5410 > > Committed: https://crrev.com/81cbd924447d507559dbd6e6d1f9fe439fcf2716 > Cr-Commit-Position: refs/heads/master@{#12086} TBR=stefan@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=chromium:595274, chromium:595308, webrtc:5410 Review URL: https://codereview.webrtc.org/1896413002 Cr-Commit-Position: refs/heads/master@{#12446}
2016-04-20 06:35:56 -07:00
: FakeEncoder(Clock::GetRealTimeClock()),
start_bitrate_changed_(false, false),
start_bitrate_kbps_(0) {}
int32_t InitEncode(const VideoCodec* config,
int32_t number_of_cores,
size_t max_payload_size) override {
rtc::CritScope lock(&crit_);
start_bitrate_kbps_ = config->startBitrate;
Reland of Initialize/configure video encoders asychronously. (patchset #1 id:1 of https://codereview.webrtc.org/1821983002/ ) Reason for revert: RTCVideoEncoder has been updated to not make assumptions on calling threads/post back to a worker thread. This should now be landable again. Original issue's description: > Revert of Initialize/configure video encoders asychronously. (patchset #4 id:60001 of https://codereview.webrtc.org/1757313002/ ) > > Reason for revert: > Breaks RTCVideoEncoder which has incorrect assumptions on where InitEncode etc. is called from. Temporarily reverting until RTCVideoEncoder has been updated. > > Original issue's description: > > Initialize/configure video encoders asychronously. > > > > Greatly speeds up setRemoteDescription() by moving encoder initialization > > off the main worker thread, which is free to move onto gathering ICE > > candidates and other tasks while InitEncode() is performed. It also > > un-blocks PeerConnection GetStats() which is no longer blocked on > > encoder initialization. > > > > BUG=webrtc:5410 > > R=stefan@webrtc.org > > > > Committed: https://chromium.googlesource.com/external/webrtc/+/fb647a67be94bb3c940d8b5fba01972f7ce91a29 > > R=stefan@webrtc.org > # Not skipping CQ checks because original CL landed more than 1 days ago. > BUG=chromium:595274, chromium:595308, webrtc:5410 > > Committed: https://crrev.com/81cbd924447d507559dbd6e6d1f9fe439fcf2716 > Cr-Commit-Position: refs/heads/master@{#12086} TBR=stefan@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=chromium:595274, chromium:595308, webrtc:5410 Review URL: https://codereview.webrtc.org/1896413002 Cr-Commit-Position: refs/heads/master@{#12446}
2016-04-20 06:35:56 -07:00
start_bitrate_changed_.Set();
return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
}
int32_t SetRates(uint32_t new_target_bitrate, uint32_t framerate) override {
rtc::CritScope lock(&crit_);
start_bitrate_kbps_ = new_target_bitrate;
Reland of Initialize/configure video encoders asychronously. (patchset #1 id:1 of https://codereview.webrtc.org/1821983002/ ) Reason for revert: RTCVideoEncoder has been updated to not make assumptions on calling threads/post back to a worker thread. This should now be landable again. Original issue's description: > Revert of Initialize/configure video encoders asychronously. (patchset #4 id:60001 of https://codereview.webrtc.org/1757313002/ ) > > Reason for revert: > Breaks RTCVideoEncoder which has incorrect assumptions on where InitEncode etc. is called from. Temporarily reverting until RTCVideoEncoder has been updated. > > Original issue's description: > > Initialize/configure video encoders asychronously. > > > > Greatly speeds up setRemoteDescription() by moving encoder initialization > > off the main worker thread, which is free to move onto gathering ICE > > candidates and other tasks while InitEncode() is performed. It also > > un-blocks PeerConnection GetStats() which is no longer blocked on > > encoder initialization. > > > > BUG=webrtc:5410 > > R=stefan@webrtc.org > > > > Committed: https://chromium.googlesource.com/external/webrtc/+/fb647a67be94bb3c940d8b5fba01972f7ce91a29 > > R=stefan@webrtc.org > # Not skipping CQ checks because original CL landed more than 1 days ago. > BUG=chromium:595274, chromium:595308, webrtc:5410 > > Committed: https://crrev.com/81cbd924447d507559dbd6e6d1f9fe439fcf2716 > Cr-Commit-Position: refs/heads/master@{#12086} TBR=stefan@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=chromium:595274, chromium:595308, webrtc:5410 Review URL: https://codereview.webrtc.org/1896413002 Cr-Commit-Position: refs/heads/master@{#12446}
2016-04-20 06:35:56 -07:00
start_bitrate_changed_.Set();
return FakeEncoder::SetRates(new_target_bitrate, framerate);
}
int GetStartBitrateKbps() const {
rtc::CritScope lock(&crit_);
return start_bitrate_kbps_;
}
Reland of Initialize/configure video encoders asychronously. (patchset #1 id:1 of https://codereview.webrtc.org/1821983002/ ) Reason for revert: RTCVideoEncoder has been updated to not make assumptions on calling threads/post back to a worker thread. This should now be landable again. Original issue's description: > Revert of Initialize/configure video encoders asychronously. (patchset #4 id:60001 of https://codereview.webrtc.org/1757313002/ ) > > Reason for revert: > Breaks RTCVideoEncoder which has incorrect assumptions on where InitEncode etc. is called from. Temporarily reverting until RTCVideoEncoder has been updated. > > Original issue's description: > > Initialize/configure video encoders asychronously. > > > > Greatly speeds up setRemoteDescription() by moving encoder initialization > > off the main worker thread, which is free to move onto gathering ICE > > candidates and other tasks while InitEncode() is performed. It also > > un-blocks PeerConnection GetStats() which is no longer blocked on > > encoder initialization. > > > > BUG=webrtc:5410 > > R=stefan@webrtc.org > > > > Committed: https://chromium.googlesource.com/external/webrtc/+/fb647a67be94bb3c940d8b5fba01972f7ce91a29 > > R=stefan@webrtc.org > # Not skipping CQ checks because original CL landed more than 1 days ago. > BUG=chromium:595274, chromium:595308, webrtc:5410 > > Committed: https://crrev.com/81cbd924447d507559dbd6e6d1f9fe439fcf2716 > Cr-Commit-Position: refs/heads/master@{#12086} TBR=stefan@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=chromium:595274, chromium:595308, webrtc:5410 Review URL: https://codereview.webrtc.org/1896413002 Cr-Commit-Position: refs/heads/master@{#12446}
2016-04-20 06:35:56 -07:00
bool WaitForStartBitrate() {
return start_bitrate_changed_.Wait(
VideoSendStreamTest::kDefaultTimeoutMs);
}
private:
rtc::CriticalSection crit_;
Reland of Initialize/configure video encoders asychronously. (patchset #1 id:1 of https://codereview.webrtc.org/1821983002/ ) Reason for revert: RTCVideoEncoder has been updated to not make assumptions on calling threads/post back to a worker thread. This should now be landable again. Original issue's description: > Revert of Initialize/configure video encoders asychronously. (patchset #4 id:60001 of https://codereview.webrtc.org/1757313002/ ) > > Reason for revert: > Breaks RTCVideoEncoder which has incorrect assumptions on where InitEncode etc. is called from. Temporarily reverting until RTCVideoEncoder has been updated. > > Original issue's description: > > Initialize/configure video encoders asychronously. > > > > Greatly speeds up setRemoteDescription() by moving encoder initialization > > off the main worker thread, which is free to move onto gathering ICE > > candidates and other tasks while InitEncode() is performed. It also > > un-blocks PeerConnection GetStats() which is no longer blocked on > > encoder initialization. > > > > BUG=webrtc:5410 > > R=stefan@webrtc.org > > > > Committed: https://chromium.googlesource.com/external/webrtc/+/fb647a67be94bb3c940d8b5fba01972f7ce91a29 > > R=stefan@webrtc.org > # Not skipping CQ checks because original CL landed more than 1 days ago. > BUG=chromium:595274, chromium:595308, webrtc:5410 > > Committed: https://crrev.com/81cbd924447d507559dbd6e6d1f9fe439fcf2716 > Cr-Commit-Position: refs/heads/master@{#12086} TBR=stefan@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=chromium:595274, chromium:595308, webrtc:5410 Review URL: https://codereview.webrtc.org/1896413002 Cr-Commit-Position: refs/heads/master@{#12446}
2016-04-20 06:35:56 -07:00
rtc::Event start_bitrate_changed_;
int start_bitrate_kbps_ RTC_GUARDED_BY(crit_);
};
CreateSenderCall(Call::Config(event_log_.get()));
test::NullTransport transport;
CreateSendConfig(1, 0, 0, &transport);
Call::Config::BitrateConfig bitrate_config;
bitrate_config.start_bitrate_bps = 2 * video_encoder_config_.max_bitrate_bps;
sender_call_->SetBitrateConfig(bitrate_config);
StartBitrateObserver encoder;
video_send_config_.encoder_settings.encoder = &encoder;
// Since this test does not use a capturer, set |internal_source| = true.
// Encoder configuration is otherwise updated on the next video frame.
video_send_config_.encoder_settings.internal_source = true;
CreateVideoStreams();
Reland of Initialize/configure video encoders asychronously. (patchset #1 id:1 of https://codereview.webrtc.org/1821983002/ ) Reason for revert: RTCVideoEncoder has been updated to not make assumptions on calling threads/post back to a worker thread. This should now be landable again. Original issue's description: > Revert of Initialize/configure video encoders asychronously. (patchset #4 id:60001 of https://codereview.webrtc.org/1757313002/ ) > > Reason for revert: > Breaks RTCVideoEncoder which has incorrect assumptions on where InitEncode etc. is called from. Temporarily reverting until RTCVideoEncoder has been updated. > > Original issue's description: > > Initialize/configure video encoders asychronously. > > > > Greatly speeds up setRemoteDescription() by moving encoder initialization > > off the main worker thread, which is free to move onto gathering ICE > > candidates and other tasks while InitEncode() is performed. It also > > un-blocks PeerConnection GetStats() which is no longer blocked on > > encoder initialization. > > > > BUG=webrtc:5410 > > R=stefan@webrtc.org > > > > Committed: https://chromium.googlesource.com/external/webrtc/+/fb647a67be94bb3c940d8b5fba01972f7ce91a29 > > R=stefan@webrtc.org > # Not skipping CQ checks because original CL landed more than 1 days ago. > BUG=chromium:595274, chromium:595308, webrtc:5410 > > Committed: https://crrev.com/81cbd924447d507559dbd6e6d1f9fe439fcf2716 > Cr-Commit-Position: refs/heads/master@{#12086} TBR=stefan@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=chromium:595274, chromium:595308, webrtc:5410 Review URL: https://codereview.webrtc.org/1896413002 Cr-Commit-Position: refs/heads/master@{#12446}
2016-04-20 06:35:56 -07:00
EXPECT_TRUE(encoder.WaitForStartBitrate());
EXPECT_EQ(video_encoder_config_.max_bitrate_bps / 1000,
encoder.GetStartBitrateKbps());
video_encoder_config_.max_bitrate_bps = 2 * bitrate_config.start_bitrate_bps;
video_send_stream_->ReconfigureVideoEncoder(video_encoder_config_.Copy());
// New bitrate should be reconfigured above the previous max. As there's no
// network connection this shouldn't be flaky, as no bitrate should've been
// reported in between.
Reland of Initialize/configure video encoders asychronously. (patchset #1 id:1 of https://codereview.webrtc.org/1821983002/ ) Reason for revert: RTCVideoEncoder has been updated to not make assumptions on calling threads/post back to a worker thread. This should now be landable again. Original issue's description: > Revert of Initialize/configure video encoders asychronously. (patchset #4 id:60001 of https://codereview.webrtc.org/1757313002/ ) > > Reason for revert: > Breaks RTCVideoEncoder which has incorrect assumptions on where InitEncode etc. is called from. Temporarily reverting until RTCVideoEncoder has been updated. > > Original issue's description: > > Initialize/configure video encoders asychronously. > > > > Greatly speeds up setRemoteDescription() by moving encoder initialization > > off the main worker thread, which is free to move onto gathering ICE > > candidates and other tasks while InitEncode() is performed. It also > > un-blocks PeerConnection GetStats() which is no longer blocked on > > encoder initialization. > > > > BUG=webrtc:5410 > > R=stefan@webrtc.org > > > > Committed: https://chromium.googlesource.com/external/webrtc/+/fb647a67be94bb3c940d8b5fba01972f7ce91a29 > > R=stefan@webrtc.org > # Not skipping CQ checks because original CL landed more than 1 days ago. > BUG=chromium:595274, chromium:595308, webrtc:5410 > > Committed: https://crrev.com/81cbd924447d507559dbd6e6d1f9fe439fcf2716 > Cr-Commit-Position: refs/heads/master@{#12086} TBR=stefan@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=chromium:595274, chromium:595308, webrtc:5410 Review URL: https://codereview.webrtc.org/1896413002 Cr-Commit-Position: refs/heads/master@{#12446}
2016-04-20 06:35:56 -07:00
EXPECT_TRUE(encoder.WaitForStartBitrate());
EXPECT_EQ(bitrate_config.start_bitrate_bps / 1000,
encoder.GetStartBitrateKbps());
DestroyStreams();
}
// This test that if the encoder use an internal source, VideoEncoder::SetRates
// will be called with zero bitrate during initialization and that
// VideoSendStream::Stop also triggers VideoEncoder::SetRates Start to be called
// with zero bitrate.
TEST_F(VideoSendStreamTest, VideoSendStreamStopSetEncoderRateToZero) {
class StartStopBitrateObserver : public test::FakeEncoder {
public:
StartStopBitrateObserver()
: FakeEncoder(Clock::GetRealTimeClock()),
encoder_init_(false, false),
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
bitrate_changed_(false, false) {}
int32_t InitEncode(const VideoCodec* config,
int32_t number_of_cores,
size_t max_payload_size) override {
rtc::CritScope lock(&crit_);
encoder_init_.Set();
return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
}
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
int32_t SetRateAllocation(const BitrateAllocation& bitrate,
uint32_t framerate) override {
rtc::CritScope lock(&crit_);
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
bitrate_kbps_ = rtc::Optional<int>(bitrate.get_sum_kbps());
bitrate_changed_.Set();
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
return FakeEncoder::SetRateAllocation(bitrate, framerate);
}
bool WaitForEncoderInit() {
return encoder_init_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
}
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
bool WaitBitrateChanged(bool non_zero) {
do {
rtc::Optional<int> bitrate_kbps;
{
rtc::CritScope lock(&crit_);
bitrate_kbps = bitrate_kbps_;
}
if (!bitrate_kbps)
continue;
if ((non_zero && *bitrate_kbps > 0) ||
(!non_zero && *bitrate_kbps == 0)) {
return true;
}
} while (bitrate_changed_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
return false;
}
private:
rtc::CriticalSection crit_;
rtc::Event encoder_init_;
rtc::Event bitrate_changed_;
rtc::Optional<int> bitrate_kbps_ RTC_GUARDED_BY(crit_);
};
test::NullTransport transport;
StartStopBitrateObserver encoder;
task_queue_.SendTask([this, &transport, &encoder]() {
CreateSenderCall(Call::Config(event_log_.get()));
CreateSendConfig(1, 0, 0, &transport);
sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
video_send_config_.encoder_settings.encoder = &encoder;
video_send_config_.encoder_settings.internal_source = true;
CreateVideoStreams();
});
EXPECT_TRUE(encoder.WaitForEncoderInit());
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
task_queue_.SendTask([this]() {
video_send_stream_->Start();
});
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
EXPECT_TRUE(encoder.WaitBitrateChanged(true));
task_queue_.SendTask([this]() {
video_send_stream_->Stop();
});
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
EXPECT_TRUE(encoder.WaitBitrateChanged(false));
task_queue_.SendTask([this]() {
video_send_stream_->Start();
});
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
EXPECT_TRUE(encoder.WaitBitrateChanged(true));
task_queue_.SendTask([this]() {
DestroyStreams();
DestroyCalls();
});
}
TEST_F(VideoSendStreamTest, CapturesTextureAndVideoFrames) {
class FrameObserver : public rtc::VideoSinkInterface<VideoFrame> {
public:
FrameObserver() : output_frame_event_(false, false) {}
void OnFrame(const VideoFrame& video_frame) override {
output_frames_.push_back(video_frame);
output_frame_event_.Set();
}
void WaitOutputFrame() {
const int kWaitFrameTimeoutMs = 3000;
EXPECT_TRUE(output_frame_event_.Wait(kWaitFrameTimeoutMs))
<< "Timeout while waiting for output frames.";
}
const std::vector<VideoFrame>& output_frames() const {
return output_frames_;
}
private:
// Delivered output frames.
std::vector<VideoFrame> output_frames_;
// Indicate an output frame has arrived.
rtc::Event output_frame_event_;
};
test::NullTransport transport;
FrameObserver observer;
std::vector<VideoFrame> input_frames;
task_queue_.SendTask([this, &transport, &observer, &input_frames]() {
// Initialize send stream.
CreateSenderCall(Call::Config(event_log_.get()));
CreateSendConfig(1, 0, 0, &transport);
video_send_config_.pre_encode_callback = &observer;
CreateVideoStreams();
// Prepare five input frames. Send ordinary VideoFrame and texture frames
// alternatively.
int width = 168;
int height = 132;
input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
width, height, 1, 1, kVideoRotation_0));
input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
width, height, 2, 2, kVideoRotation_0));
input_frames.push_back(CreateVideoFrame(width, height, 3));
input_frames.push_back(CreateVideoFrame(width, height, 4));
input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
width, height, 5, 5, kVideoRotation_0));
video_send_stream_->Start();
test::FrameForwarder forwarder;
video_send_stream_->SetSource(
&forwarder, VideoSendStream::DegradationPreference::kMaintainFramerate);
for (size_t i = 0; i < input_frames.size(); i++) {
forwarder.IncomingCapturedFrame(input_frames[i]);
// Wait until the output frame is received before sending the next input
// frame. Or the previous input frame may be replaced without delivering.
observer.WaitOutputFrame();
}
video_send_stream_->Stop();
video_send_stream_->SetSource(
nullptr, VideoSendStream::DegradationPreference::kMaintainFramerate);
});
// Test if the input and output frames are the same. render_time_ms and
// timestamp are not compared because capturer sets those values.
ExpectEqualFramesVector(input_frames, observer.output_frames());
task_queue_.SendTask([this]() {
DestroyStreams();
DestroyCalls();
});
}
void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
const std::vector<VideoFrame>& frames2) {
EXPECT_EQ(frames1.size(), frames2.size());
for (size_t i = 0; i < std::min(frames1.size(), frames2.size()); ++i)
// Compare frame buffers, since we don't care about differing timestamps.
EXPECT_TRUE(test::FrameBufsEqual(frames1[i].video_frame_buffer(),
frames2[i].video_frame_buffer()));
}
VideoFrame CreateVideoFrame(int width, int height, uint8_t data) {
const int kSizeY = width * height * 2;
std::unique_ptr<uint8_t[]> buffer(new uint8_t[kSizeY]);
memset(buffer.get(), data, kSizeY);
VideoFrame frame(I420Buffer::Create(width, height), kVideoRotation_0, data);
frame.set_timestamp(data);
// Use data as a ms timestamp.
frame.set_timestamp_us(data * rtc::kNumMicrosecsPerMillisec);
return frame;
}
TEST_F(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) {
class EncoderStateObserver : public test::SendTest, public VideoEncoder {
public:
explicit EncoderStateObserver(
test::SingleThreadedTaskQueueForTesting* task_queue)
: SendTest(kDefaultTimeoutMs),
task_queue_(task_queue),
stream_(nullptr),
initialized_(false),
callback_registered_(false),
num_releases_(0),
released_(false) {}
bool IsReleased() {
rtc::CritScope lock(&crit_);
return released_;
}
bool IsReadyForEncode() {
rtc::CritScope lock(&crit_);
return initialized_ && callback_registered_;
}
size_t num_releases() {
rtc::CritScope lock(&crit_);
return num_releases_;
}
private:
int32_t InitEncode(const VideoCodec* codecSettings,
int32_t numberOfCores,
size_t maxPayloadSize) override {
rtc::CritScope lock(&crit_);
EXPECT_FALSE(initialized_);
initialized_ = true;
released_ = false;
return 0;
}
int32_t Encode(const VideoFrame& inputImage,
const CodecSpecificInfo* codecSpecificInfo,
const std::vector<FrameType>* frame_types) override {
EXPECT_TRUE(IsReadyForEncode());
observation_complete_.Set();
return 0;
}
int32_t RegisterEncodeCompleteCallback(
EncodedImageCallback* callback) override {
rtc::CritScope lock(&crit_);
EXPECT_TRUE(initialized_);
callback_registered_ = true;
return 0;
}
int32_t Release() override {
rtc::CritScope lock(&crit_);
EXPECT_TRUE(IsReadyForEncode());
EXPECT_FALSE(released_);
initialized_ = false;
callback_registered_ = false;
released_ = true;
++num_releases_;
return 0;
}
int32_t SetChannelParameters(uint32_t packetLoss, int64_t rtt) override {
EXPECT_TRUE(IsReadyForEncode());
return 0;
}
int32_t SetRates(uint32_t newBitRate, uint32_t frameRate) override {
EXPECT_TRUE(IsReadyForEncode());
return 0;
}
void OnVideoStreamsCreated(
VideoSendStream* send_stream,
const std::vector<VideoReceiveStream*>& receive_streams) override {
stream_ = send_stream;
}
void ModifyVideoConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) override {
send_config->encoder_settings.encoder = this;
encoder_config_ = encoder_config->Copy();
}
void PerformTest() override {
EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
task_queue_->SendTask([this]() {
EXPECT_EQ(0u, num_releases());
stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
EXPECT_EQ(0u, num_releases());
stream_->Stop();
// Encoder should not be released before destroying the VideoSendStream.
EXPECT_FALSE(IsReleased());
EXPECT_TRUE(IsReadyForEncode());
stream_->Start();
});
// Sanity check, make sure we still encode frames with this encoder.
EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
}
test::SingleThreadedTaskQueueForTesting* const task_queue_;
rtc::CriticalSection crit_;
VideoSendStream* stream_;
bool initialized_ RTC_GUARDED_BY(crit_);
bool callback_registered_ RTC_GUARDED_BY(crit_);
size_t num_releases_ RTC_GUARDED_BY(crit_);
bool released_ RTC_GUARDED_BY(crit_);
VideoEncoderConfig encoder_config_;
} test_encoder(&task_queue_);
RunBaseTest(&test_encoder);
EXPECT_TRUE(test_encoder.IsReleased());
EXPECT_EQ(1u, test_encoder.num_releases());
}
TEST_F(VideoSendStreamTest, EncoderSetupPropagatesCommonEncoderConfigValues) {
class VideoCodecConfigObserver : public test::SendTest,
public test::FakeEncoder {
public:
VideoCodecConfigObserver()
: SendTest(kDefaultTimeoutMs),
FakeEncoder(Clock::GetRealTimeClock()),
Reland of Initialize/configure video encoders asychronously. (patchset #1 id:1 of https://codereview.webrtc.org/1821983002/ ) Reason for revert: RTCVideoEncoder has been updated to not make assumptions on calling threads/post back to a worker thread. This should now be landable again. Original issue's description: > Revert of Initialize/configure video encoders asychronously. (patchset #4 id:60001 of https://codereview.webrtc.org/1757313002/ ) > > Reason for revert: > Breaks RTCVideoEncoder which has incorrect assumptions on where InitEncode etc. is called from. Temporarily reverting until RTCVideoEncoder has been updated. > > Original issue's description: > > Initialize/configure video encoders asychronously. > > > > Greatly speeds up setRemoteDescription() by moving encoder initialization > > off the main worker thread, which is free to move onto gathering ICE > > candidates and other tasks while InitEncode() is performed. It also > > un-blocks PeerConnection GetStats() which is no longer blocked on > > encoder initialization. > > > > BUG=webrtc:5410 > > R=stefan@webrtc.org > > > > Committed: https://chromium.googlesource.com/external/webrtc/+/fb647a67be94bb3c940d8b5fba01972f7ce91a29 > > R=stefan@webrtc.org > # Not skipping CQ checks because original CL landed more than 1 days ago. > BUG=chromium:595274, chromium:595308, webrtc:5410 > > Committed: https://crrev.com/81cbd924447d507559dbd6e6d1f9fe439fcf2716 > Cr-Commit-Position: refs/heads/master@{#12086} TBR=stefan@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=chromium:595274, chromium:595308, webrtc:5410 Review URL: https://codereview.webrtc.org/1896413002 Cr-Commit-Position: refs/heads/master@{#12446}
2016-04-20 06:35:56 -07:00
init_encode_event_(false, false),
num_initializations_(0),
stream_(nullptr) {}
private:
void ModifyVideoConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) override {
send_config->encoder_settings.encoder = this;
encoder_config->max_bitrate_bps = kFirstMaxBitrateBps;
encoder_config_ = encoder_config->Copy();
}
void OnVideoStreamsCreated(
VideoSendStream* send_stream,
const std::vector<VideoReceiveStream*>& receive_streams) override {
stream_ = send_stream;
}
int32_t InitEncode(const VideoCodec* config,
int32_t number_of_cores,
size_t max_payload_size) override {
if (num_initializations_ == 0) {
// Verify default values.
EXPECT_EQ(kFirstMaxBitrateBps / 1000, config->maxBitrate);
} else {
// Verify that changed values are propagated.
EXPECT_EQ(kSecondMaxBitrateBps / 1000, config->maxBitrate);
}
++num_initializations_;
init_encode_event_.Set();
return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
}
void PerformTest() override {
Reland of Initialize/configure video encoders asychronously. (patchset #1 id:1 of https://codereview.webrtc.org/1821983002/ ) Reason for revert: RTCVideoEncoder has been updated to not make assumptions on calling threads/post back to a worker thread. This should now be landable again. Original issue's description: > Revert of Initialize/configure video encoders asychronously. (patchset #4 id:60001 of https://codereview.webrtc.org/1757313002/ ) > > Reason for revert: > Breaks RTCVideoEncoder which has incorrect assumptions on where InitEncode etc. is called from. Temporarily reverting until RTCVideoEncoder has been updated. > > Original issue's description: > > Initialize/configure video encoders asychronously. > > > > Greatly speeds up setRemoteDescription() by moving encoder initialization > > off the main worker thread, which is free to move onto gathering ICE > > candidates and other tasks while InitEncode() is performed. It also > > un-blocks PeerConnection GetStats() which is no longer blocked on > > encoder initialization. > > > > BUG=webrtc:5410 > > R=stefan@webrtc.org > > > > Committed: https://chromium.googlesource.com/external/webrtc/+/fb647a67be94bb3c940d8b5fba01972f7ce91a29 > > R=stefan@webrtc.org > # Not skipping CQ checks because original CL landed more than 1 days ago. > BUG=chromium:595274, chromium:595308, webrtc:5410 > > Committed: https://crrev.com/81cbd924447d507559dbd6e6d1f9fe439fcf2716 > Cr-Commit-Position: refs/heads/master@{#12086} TBR=stefan@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=chromium:595274, chromium:595308, webrtc:5410 Review URL: https://codereview.webrtc.org/1896413002 Cr-Commit-Position: refs/heads/master@{#12446}
2016-04-20 06:35:56 -07:00
EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
EXPECT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
encoder_config_.max_bitrate_bps = kSecondMaxBitrateBps;
stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
Reland of Initialize/configure video encoders asychronously. (patchset #1 id:1 of https://codereview.webrtc.org/1821983002/ ) Reason for revert: RTCVideoEncoder has been updated to not make assumptions on calling threads/post back to a worker thread. This should now be landable again. Original issue's description: > Revert of Initialize/configure video encoders asychronously. (patchset #4 id:60001 of https://codereview.webrtc.org/1757313002/ ) > > Reason for revert: > Breaks RTCVideoEncoder which has incorrect assumptions on where InitEncode etc. is called from. Temporarily reverting until RTCVideoEncoder has been updated. > > Original issue's description: > > Initialize/configure video encoders asychronously. > > > > Greatly speeds up setRemoteDescription() by moving encoder initialization > > off the main worker thread, which is free to move onto gathering ICE > > candidates and other tasks while InitEncode() is performed. It also > > un-blocks PeerConnection GetStats() which is no longer blocked on > > encoder initialization. > > > > BUG=webrtc:5410 > > R=stefan@webrtc.org > > > > Committed: https://chromium.googlesource.com/external/webrtc/+/fb647a67be94bb3c940d8b5fba01972f7ce91a29 > > R=stefan@webrtc.org > # Not skipping CQ checks because original CL landed more than 1 days ago. > BUG=chromium:595274, chromium:595308, webrtc:5410 > > Committed: https://crrev.com/81cbd924447d507559dbd6e6d1f9fe439fcf2716 > Cr-Commit-Position: refs/heads/master@{#12086} TBR=stefan@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=chromium:595274, chromium:595308, webrtc:5410 Review URL: https://codereview.webrtc.org/1896413002 Cr-Commit-Position: refs/heads/master@{#12446}
2016-04-20 06:35:56 -07:00
EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
EXPECT_EQ(2u, num_initializations_)
<< "ReconfigureVideoEncoder did not reinitialize the encoder with "
"new encoder settings.";
}
const uint32_t kFirstMaxBitrateBps = 1000000;
const uint32_t kSecondMaxBitrateBps = 2000000;
Reland of Initialize/configure video encoders asychronously. (patchset #1 id:1 of https://codereview.webrtc.org/1821983002/ ) Reason for revert: RTCVideoEncoder has been updated to not make assumptions on calling threads/post back to a worker thread. This should now be landable again. Original issue's description: > Revert of Initialize/configure video encoders asychronously. (patchset #4 id:60001 of https://codereview.webrtc.org/1757313002/ ) > > Reason for revert: > Breaks RTCVideoEncoder which has incorrect assumptions on where InitEncode etc. is called from. Temporarily reverting until RTCVideoEncoder has been updated. > > Original issue's description: > > Initialize/configure video encoders asychronously. > > > > Greatly speeds up setRemoteDescription() by moving encoder initialization > > off the main worker thread, which is free to move onto gathering ICE > > candidates and other tasks while InitEncode() is performed. It also > > un-blocks PeerConnection GetStats() which is no longer blocked on > > encoder initialization. > > > > BUG=webrtc:5410 > > R=stefan@webrtc.org > > > > Committed: https://chromium.googlesource.com/external/webrtc/+/fb647a67be94bb3c940d8b5fba01972f7ce91a29 > > R=stefan@webrtc.org > # Not skipping CQ checks because original CL landed more than 1 days ago. > BUG=chromium:595274, chromium:595308, webrtc:5410 > > Committed: https://crrev.com/81cbd924447d507559dbd6e6d1f9fe439fcf2716 > Cr-Commit-Position: refs/heads/master@{#12086} TBR=stefan@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=chromium:595274, chromium:595308, webrtc:5410 Review URL: https://codereview.webrtc.org/1896413002 Cr-Commit-Position: refs/heads/master@{#12446}
2016-04-20 06:35:56 -07:00
rtc::Event init_encode_event_;
size_t num_initializations_;
VideoSendStream* stream_;
VideoEncoderConfig encoder_config_;
} test;
RunBaseTest(&test);
}
static const size_t kVideoCodecConfigObserverNumberOfTemporalLayers = 4;
template <typename T>
class VideoCodecConfigObserver : public test::SendTest,
public test::FakeEncoder {
public:
VideoCodecConfigObserver(VideoCodecType video_codec_type,
const char* codec_name)
: SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
FakeEncoder(Clock::GetRealTimeClock()),
video_codec_type_(video_codec_type),
codec_name_(codec_name),
Reland of Initialize/configure video encoders asychronously. (patchset #1 id:1 of https://codereview.webrtc.org/1821983002/ ) Reason for revert: RTCVideoEncoder has been updated to not make assumptions on calling threads/post back to a worker thread. This should now be landable again. Original issue's description: > Revert of Initialize/configure video encoders asychronously. (patchset #4 id:60001 of https://codereview.webrtc.org/1757313002/ ) > > Reason for revert: > Breaks RTCVideoEncoder which has incorrect assumptions on where InitEncode etc. is called from. Temporarily reverting until RTCVideoEncoder has been updated. > > Original issue's description: > > Initialize/configure video encoders asychronously. > > > > Greatly speeds up setRemoteDescription() by moving encoder initialization > > off the main worker thread, which is free to move onto gathering ICE > > candidates and other tasks while InitEncode() is performed. It also > > un-blocks PeerConnection GetStats() which is no longer blocked on > > encoder initialization. > > > > BUG=webrtc:5410 > > R=stefan@webrtc.org > > > > Committed: https://chromium.googlesource.com/external/webrtc/+/fb647a67be94bb3c940d8b5fba01972f7ce91a29 > > R=stefan@webrtc.org > # Not skipping CQ checks because original CL landed more than 1 days ago. > BUG=chromium:595274, chromium:595308, webrtc:5410 > > Committed: https://crrev.com/81cbd924447d507559dbd6e6d1f9fe439fcf2716 > Cr-Commit-Position: refs/heads/master@{#12086} TBR=stefan@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=chromium:595274, chromium:595308, webrtc:5410 Review URL: https://codereview.webrtc.org/1896413002 Cr-Commit-Position: refs/heads/master@{#12446}
2016-04-20 06:35:56 -07:00
init_encode_event_(false, false),
num_initializations_(0),
stream_(nullptr) {
memset(&encoder_settings_, 0, sizeof(encoder_settings_));
}
private:
class VideoStreamFactory
: public VideoEncoderConfig::VideoStreamFactoryInterface {
public:
VideoStreamFactory() {}
private:
std::vector<VideoStream> CreateEncoderStreams(
int width,
int height,
const VideoEncoderConfig& encoder_config) override {
std::vector<VideoStream> streams =
test::CreateVideoStreams(width, height, encoder_config);
for (size_t i = 0; i < streams.size(); ++i) {
streams[i].temporal_layer_thresholds_bps.resize(
kVideoCodecConfigObserverNumberOfTemporalLayers - 1);
}
return streams;
}
};
void ModifyVideoConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) override {
send_config->encoder_settings.encoder = this;
send_config->encoder_settings.payload_name = codec_name_;
encoder_config->encoder_specific_settings = GetEncoderSpecificSettings();
encoder_config->video_stream_factory =
new rtc::RefCountedObject<VideoStreamFactory>();
encoder_config_ = encoder_config->Copy();
}
void OnVideoStreamsCreated(
VideoSendStream* send_stream,
const std::vector<VideoReceiveStream*>& receive_streams) override {
stream_ = send_stream;
}
int32_t InitEncode(const VideoCodec* config,
int32_t number_of_cores,
size_t max_payload_size) override {
EXPECT_EQ(video_codec_type_, config->codecType);
VerifyCodecSpecifics(*config);
++num_initializations_;
init_encode_event_.Set();
return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
}
void VerifyCodecSpecifics(const VideoCodec& config) const;
rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
GetEncoderSpecificSettings() const;
void PerformTest() override {
Reland of Initialize/configure video encoders asychronously. (patchset #1 id:1 of https://codereview.webrtc.org/1821983002/ ) Reason for revert: RTCVideoEncoder has been updated to not make assumptions on calling threads/post back to a worker thread. This should now be landable again. Original issue's description: > Revert of Initialize/configure video encoders asychronously. (patchset #4 id:60001 of https://codereview.webrtc.org/1757313002/ ) > > Reason for revert: > Breaks RTCVideoEncoder which has incorrect assumptions on where InitEncode etc. is called from. Temporarily reverting until RTCVideoEncoder has been updated. > > Original issue's description: > > Initialize/configure video encoders asychronously. > > > > Greatly speeds up setRemoteDescription() by moving encoder initialization > > off the main worker thread, which is free to move onto gathering ICE > > candidates and other tasks while InitEncode() is performed. It also > > un-blocks PeerConnection GetStats() which is no longer blocked on > > encoder initialization. > > > > BUG=webrtc:5410 > > R=stefan@webrtc.org > > > > Committed: https://chromium.googlesource.com/external/webrtc/+/fb647a67be94bb3c940d8b5fba01972f7ce91a29 > > R=stefan@webrtc.org > # Not skipping CQ checks because original CL landed more than 1 days ago. > BUG=chromium:595274, chromium:595308, webrtc:5410 > > Committed: https://crrev.com/81cbd924447d507559dbd6e6d1f9fe439fcf2716 > Cr-Commit-Position: refs/heads/master@{#12086} TBR=stefan@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=chromium:595274, chromium:595308, webrtc:5410 Review URL: https://codereview.webrtc.org/1896413002 Cr-Commit-Position: refs/heads/master@{#12446}
2016-04-20 06:35:56 -07:00
EXPECT_TRUE(
init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
ASSERT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
encoder_settings_.frameDroppingOn = true;
encoder_config_.encoder_specific_settings = GetEncoderSpecificSettings();
stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
Reland of Initialize/configure video encoders asychronously. (patchset #1 id:1 of https://codereview.webrtc.org/1821983002/ ) Reason for revert: RTCVideoEncoder has been updated to not make assumptions on calling threads/post back to a worker thread. This should now be landable again. Original issue's description: > Revert of Initialize/configure video encoders asychronously. (patchset #4 id:60001 of https://codereview.webrtc.org/1757313002/ ) > > Reason for revert: > Breaks RTCVideoEncoder which has incorrect assumptions on where InitEncode etc. is called from. Temporarily reverting until RTCVideoEncoder has been updated. > > Original issue's description: > > Initialize/configure video encoders asychronously. > > > > Greatly speeds up setRemoteDescription() by moving encoder initialization > > off the main worker thread, which is free to move onto gathering ICE > > candidates and other tasks while InitEncode() is performed. It also > > un-blocks PeerConnection GetStats() which is no longer blocked on > > encoder initialization. > > > > BUG=webrtc:5410 > > R=stefan@webrtc.org > > > > Committed: https://chromium.googlesource.com/external/webrtc/+/fb647a67be94bb3c940d8b5fba01972f7ce91a29 > > R=stefan@webrtc.org > # Not skipping CQ checks because original CL landed more than 1 days ago. > BUG=chromium:595274, chromium:595308, webrtc:5410 > > Committed: https://crrev.com/81cbd924447d507559dbd6e6d1f9fe439fcf2716 > Cr-Commit-Position: refs/heads/master@{#12086} TBR=stefan@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=chromium:595274, chromium:595308, webrtc:5410 Review URL: https://codereview.webrtc.org/1896413002 Cr-Commit-Position: refs/heads/master@{#12446}
2016-04-20 06:35:56 -07:00
ASSERT_TRUE(
init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
EXPECT_EQ(2u, num_initializations_)
<< "ReconfigureVideoEncoder did not reinitialize the encoder with "
"new encoder settings.";
}
int32_t Encode(const VideoFrame& input_image,
const CodecSpecificInfo* codec_specific_info,
const std::vector<FrameType>* frame_types) override {
// Silently skip the encode, FakeEncoder::Encode doesn't produce VP8.
return 0;
}
T encoder_settings_;
const VideoCodecType video_codec_type_;
const char* const codec_name_;
Reland of Initialize/configure video encoders asychronously. (patchset #1 id:1 of https://codereview.webrtc.org/1821983002/ ) Reason for revert: RTCVideoEncoder has been updated to not make assumptions on calling threads/post back to a worker thread. This should now be landable again. Original issue's description: > Revert of Initialize/configure video encoders asychronously. (patchset #4 id:60001 of https://codereview.webrtc.org/1757313002/ ) > > Reason for revert: > Breaks RTCVideoEncoder which has incorrect assumptions on where InitEncode etc. is called from. Temporarily reverting until RTCVideoEncoder has been updated. > > Original issue's description: > > Initialize/configure video encoders asychronously. > > > > Greatly speeds up setRemoteDescription() by moving encoder initialization > > off the main worker thread, which is free to move onto gathering ICE > > candidates and other tasks while InitEncode() is performed. It also > > un-blocks PeerConnection GetStats() which is no longer blocked on > > encoder initialization. > > > > BUG=webrtc:5410 > > R=stefan@webrtc.org > > > > Committed: https://chromium.googlesource.com/external/webrtc/+/fb647a67be94bb3c940d8b5fba01972f7ce91a29 > > R=stefan@webrtc.org > # Not skipping CQ checks because original CL landed more than 1 days ago. > BUG=chromium:595274, chromium:595308, webrtc:5410 > > Committed: https://crrev.com/81cbd924447d507559dbd6e6d1f9fe439fcf2716 > Cr-Commit-Position: refs/heads/master@{#12086} TBR=stefan@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=chromium:595274, chromium:595308, webrtc:5410 Review URL: https://codereview.webrtc.org/1896413002 Cr-Commit-Position: refs/heads/master@{#12446}
2016-04-20 06:35:56 -07:00
rtc::Event init_encode_event_;
size_t num_initializations_;
VideoSendStream* stream_;
VideoEncoderConfig encoder_config_;
};
template <>
void VideoCodecConfigObserver<VideoCodecH264>::VerifyCodecSpecifics(
const VideoCodec& config) const {
EXPECT_EQ(
0, memcmp(&config.H264(), &encoder_settings_, sizeof(encoder_settings_)));
}
template <>
rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
VideoCodecConfigObserver<VideoCodecH264>::GetEncoderSpecificSettings() const {
return new rtc::RefCountedObject<
VideoEncoderConfig::H264EncoderSpecificSettings>(encoder_settings_);
}
template <>
void VideoCodecConfigObserver<VideoCodecVP8>::VerifyCodecSpecifics(
const VideoCodec& config) const {
// Check that the number of temporal layers has propagated properly to
// VideoCodec.
EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
config.VP8().numberOfTemporalLayers);
for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
config.simulcastStream[i].numberOfTemporalLayers);
}
// Set expected temporal layers as they should have been set when
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
// reconfiguring the encoder and not match the set config. Also copy the
// TemporalLayersFactory pointer that has been injected by VideoStreamEncoder.
VideoCodecVP8 encoder_settings = encoder_settings_;
encoder_settings.numberOfTemporalLayers =
kVideoCodecConfigObserverNumberOfTemporalLayers;
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
encoder_settings.tl_factory = config.VP8().tl_factory;
EXPECT_EQ(
0, memcmp(&config.VP8(), &encoder_settings, sizeof(encoder_settings_)));
}
template <>
rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
VideoCodecConfigObserver<VideoCodecVP8>::GetEncoderSpecificSettings() const {
return new rtc::RefCountedObject<
VideoEncoderConfig::Vp8EncoderSpecificSettings>(encoder_settings_);
}
template <>
void VideoCodecConfigObserver<VideoCodecVP9>::VerifyCodecSpecifics(
const VideoCodec& config) const {
// Check that the number of temporal layers has propagated properly to
// VideoCodec.
EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
config.VP9().numberOfTemporalLayers);
for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
config.simulcastStream[i].numberOfTemporalLayers);
}
// Set expected temporal layers as they should have been set when
// reconfiguring the encoder and not match the set config.
VideoCodecVP9 encoder_settings = encoder_settings_;
encoder_settings.numberOfTemporalLayers =
kVideoCodecConfigObserverNumberOfTemporalLayers;
EXPECT_EQ(
0, memcmp(&(config.VP9()), &encoder_settings, sizeof(encoder_settings_)));
}
template <>
rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
VideoCodecConfigObserver<VideoCodecVP9>::GetEncoderSpecificSettings() const {
return new rtc::RefCountedObject<
VideoEncoderConfig::Vp9EncoderSpecificSettings>(encoder_settings_);
}
TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp8Config) {
VideoCodecConfigObserver<VideoCodecVP8> test(kVideoCodecVP8, "VP8");
RunBaseTest(&test);
}
TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp9Config) {
VideoCodecConfigObserver<VideoCodecVP9> test(kVideoCodecVP9, "VP9");
RunBaseTest(&test);
}
TEST_F(VideoSendStreamTest, EncoderSetupPropagatesH264Config) {
VideoCodecConfigObserver<VideoCodecH264> test(kVideoCodecH264, "H264");
RunBaseTest(&test);
}
TEST_F(VideoSendStreamTest, RtcpSenderReportContainsMediaBytesSent) {
class RtcpSenderReportTest : public test::SendTest {
public:
RtcpSenderReportTest() : SendTest(kDefaultTimeoutMs),
rtp_packets_sent_(0),
media_bytes_sent_(0) {}
private:
Action OnSendRtp(const uint8_t* packet, size_t length) override {
rtc::CritScope lock(&crit_);
RTPHeader header;
EXPECT_TRUE(parser_->Parse(packet, length, &header));
++rtp_packets_sent_;
media_bytes_sent_ += length - header.headerLength - header.paddingLength;
return SEND_PACKET;
}
Action OnSendRtcp(const uint8_t* packet, size_t length) override {
rtc::CritScope lock(&crit_);
test::RtcpPacketParser parser;
EXPECT_TRUE(parser.Parse(packet, length));
if (parser.sender_report()->num_packets() > 0) {
// Only compare sent media bytes if SenderPacketCount matches the
// number of sent rtp packets (a new rtp packet could be sent before
// the rtcp packet).
if (parser.sender_report()->sender_octet_count() > 0 &&
parser.sender_report()->sender_packet_count() ==
rtp_packets_sent_) {
EXPECT_EQ(media_bytes_sent_,
parser.sender_report()->sender_octet_count());
observation_complete_.Set();
}
}
return SEND_PACKET;
}
void PerformTest() override {
EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP sender report.";
}
rtc::CriticalSection crit_;
size_t rtp_packets_sent_ RTC_GUARDED_BY(&crit_);
size_t media_bytes_sent_ RTC_GUARDED_BY(&crit_);
} test;
RunBaseTest(&test);
}
TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) {
static const int kScreencastTargetBitrateKbps = 200;
class VideoStreamFactory
: public VideoEncoderConfig::VideoStreamFactoryInterface {
public:
VideoStreamFactory() {}
private:
std::vector<VideoStream> CreateEncoderStreams(
int width,
int height,
const VideoEncoderConfig& encoder_config) override {
std::vector<VideoStream> streams =
test::CreateVideoStreams(width, height, encoder_config);
EXPECT_TRUE(streams[0].temporal_layer_thresholds_bps.empty());
streams[0].temporal_layer_thresholds_bps.push_back(
kScreencastTargetBitrateKbps * 1000);
return streams;
}
};
class ScreencastTargetBitrateTest : public test::SendTest,
public test::FakeEncoder {
public:
ScreencastTargetBitrateTest()
: SendTest(kDefaultTimeoutMs),
test::FakeEncoder(Clock::GetRealTimeClock()) {}
private:
int32_t InitEncode(const VideoCodec* config,
int32_t number_of_cores,
size_t max_payload_size) override {
EXPECT_EQ(static_cast<unsigned int>(kScreencastTargetBitrateKbps),
config->targetBitrate);
observation_complete_.Set();
return test::FakeEncoder::InitEncode(
config, number_of_cores, max_payload_size);
}
void ModifyVideoConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) override {
send_config->encoder_settings.encoder = this;
EXPECT_EQ(1u, encoder_config->number_of_streams);
encoder_config->video_stream_factory =
new rtc::RefCountedObject<VideoStreamFactory>();
encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
}
void PerformTest() override {
EXPECT_TRUE(Wait())
<< "Timed out while waiting for the encoder to be initialized.";
}
} test;
RunBaseTest(&test);
}
TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
// These are chosen to be "kind of odd" to not be accidentally checked against
// default values.
static const int kMinBitrateKbps = 137;
static const int kStartBitrateKbps = 345;
static const int kLowerMaxBitrateKbps = 312;
static const int kMaxBitrateKbps = 413;
static const int kIncreasedStartBitrateKbps = 451;
static const int kIncreasedMaxBitrateKbps = 597;
class EncoderBitrateThresholdObserver : public test::SendTest,
public test::FakeEncoder {
public:
explicit EncoderBitrateThresholdObserver(
test::SingleThreadedTaskQueueForTesting* task_queue)
: SendTest(kDefaultTimeoutMs),
FakeEncoder(Clock::GetRealTimeClock()),
task_queue_(task_queue),
Reland of Initialize/configure video encoders asychronously. (patchset #1 id:1 of https://codereview.webrtc.org/1821983002/ ) Reason for revert: RTCVideoEncoder has been updated to not make assumptions on calling threads/post back to a worker thread. This should now be landable again. Original issue's description: > Revert of Initialize/configure video encoders asychronously. (patchset #4 id:60001 of https://codereview.webrtc.org/1757313002/ ) > > Reason for revert: > Breaks RTCVideoEncoder which has incorrect assumptions on where InitEncode etc. is called from. Temporarily reverting until RTCVideoEncoder has been updated. > > Original issue's description: > > Initialize/configure video encoders asychronously. > > > > Greatly speeds up setRemoteDescription() by moving encoder initialization > > off the main worker thread, which is free to move onto gathering ICE > > candidates and other tasks while InitEncode() is performed. It also > > un-blocks PeerConnection GetStats() which is no longer blocked on > > encoder initialization. > > > > BUG=webrtc:5410 > > R=stefan@webrtc.org > > > > Committed: https://chromium.googlesource.com/external/webrtc/+/fb647a67be94bb3c940d8b5fba01972f7ce91a29 > > R=stefan@webrtc.org > # Not skipping CQ checks because original CL landed more than 1 days ago. > BUG=chromium:595274, chromium:595308, webrtc:5410 > > Committed: https://crrev.com/81cbd924447d507559dbd6e6d1f9fe439fcf2716 > Cr-Commit-Position: refs/heads/master@{#12086} TBR=stefan@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=chromium:595274, chromium:595308, webrtc:5410 Review URL: https://codereview.webrtc.org/1896413002 Cr-Commit-Position: refs/heads/master@{#12446}
2016-04-20 06:35:56 -07:00
init_encode_event_(false, false),
bitrate_changed_event_(false, false),
target_bitrate_(0),
num_initializations_(0),
call_(nullptr),
send_stream_(nullptr) {}
private:
int32_t InitEncode(const VideoCodec* codecSettings,
int32_t numberOfCores,
size_t maxPayloadSize) override {
EXPECT_GE(codecSettings->startBitrate, codecSettings->minBitrate);
EXPECT_LE(codecSettings->startBitrate, codecSettings->maxBitrate);
if (num_initializations_ == 0) {
EXPECT_EQ(static_cast<unsigned int>(kMinBitrateKbps),
codecSettings->minBitrate);
EXPECT_EQ(static_cast<unsigned int>(kStartBitrateKbps),
codecSettings->startBitrate);
EXPECT_EQ(static_cast<unsigned int>(kMaxBitrateKbps),
codecSettings->maxBitrate);
observation_complete_.Set();
} else if (num_initializations_ == 1) {
EXPECT_EQ(static_cast<unsigned int>(kLowerMaxBitrateKbps),
codecSettings->maxBitrate);
// The start bitrate should be kept (-1) and capped to the max bitrate.
// Since this is not an end-to-end call no receiver should have been
// returning a REMB that could lower this estimate.
EXPECT_EQ(codecSettings->startBitrate, codecSettings->maxBitrate);
} else if (num_initializations_ == 2) {
EXPECT_EQ(static_cast<unsigned int>(kIncreasedMaxBitrateKbps),
codecSettings->maxBitrate);
// The start bitrate will be whatever the rate BitRateController
// has currently configured but in the span of the set max and min
// bitrate.
}
++num_initializations_;
init_encode_event_.Set();
return FakeEncoder::InitEncode(codecSettings, numberOfCores,
maxPayloadSize);
}
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
int32_t SetRateAllocation(const BitrateAllocation& bitrate,
uint32_t frameRate) override {
{
rtc::CritScope lock(&crit_);
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
if (target_bitrate_ == bitrate.get_sum_kbps()) {
return FakeEncoder::SetRateAllocation(bitrate, frameRate);
}
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
target_bitrate_ = bitrate.get_sum_kbps();
}
bitrate_changed_event_.Set();
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
return FakeEncoder::SetRateAllocation(bitrate, frameRate);
}
void WaitForSetRates(uint32_t expected_bitrate) {
EXPECT_TRUE(
bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
<< "Timed out while waiting encoder rate to be set.";
rtc::CritScope lock(&crit_);
EXPECT_EQ(expected_bitrate, target_bitrate_);
}
Call::Config GetSenderCallConfig() override {
Call::Config config(event_log_.get());
config.bitrate_config.min_bitrate_bps = kMinBitrateKbps * 1000;
config.bitrate_config.start_bitrate_bps = kStartBitrateKbps * 1000;
config.bitrate_config.max_bitrate_bps = kMaxBitrateKbps * 1000;
return config;
}
class VideoStreamFactory
: public VideoEncoderConfig::VideoStreamFactoryInterface {
public:
explicit VideoStreamFactory(int min_bitrate_bps)
: min_bitrate_bps_(min_bitrate_bps) {}
private:
std::vector<VideoStream> CreateEncoderStreams(
int width,
int height,
const VideoEncoderConfig& encoder_config) override {
std::vector<VideoStream> streams =
test::CreateVideoStreams(width, height, encoder_config);
streams[0].min_bitrate_bps = min_bitrate_bps_;
return streams;
}
const int min_bitrate_bps_;
};
void ModifyVideoConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) override {
send_config->encoder_settings.encoder = this;
// Set bitrates lower/higher than min/max to make sure they are properly
// capped.
encoder_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
// Create a new StreamFactory to be able to set
// |VideoStream.min_bitrate_bps|.
encoder_config->video_stream_factory =
new rtc::RefCountedObject<VideoStreamFactory>(kMinBitrateKbps * 1000);
encoder_config_ = encoder_config->Copy();
}
void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
call_ = sender_call;
}
void OnVideoStreamsCreated(
VideoSendStream* send_stream,
const std::vector<VideoReceiveStream*>& receive_streams) override {
send_stream_ = send_stream;
}
void PerformTest() override {
Reland of Initialize/configure video encoders asychronously. (patchset #1 id:1 of https://codereview.webrtc.org/1821983002/ ) Reason for revert: RTCVideoEncoder has been updated to not make assumptions on calling threads/post back to a worker thread. This should now be landable again. Original issue's description: > Revert of Initialize/configure video encoders asychronously. (patchset #4 id:60001 of https://codereview.webrtc.org/1757313002/ ) > > Reason for revert: > Breaks RTCVideoEncoder which has incorrect assumptions on where InitEncode etc. is called from. Temporarily reverting until RTCVideoEncoder has been updated. > > Original issue's description: > > Initialize/configure video encoders asychronously. > > > > Greatly speeds up setRemoteDescription() by moving encoder initialization > > off the main worker thread, which is free to move onto gathering ICE > > candidates and other tasks while InitEncode() is performed. It also > > un-blocks PeerConnection GetStats() which is no longer blocked on > > encoder initialization. > > > > BUG=webrtc:5410 > > R=stefan@webrtc.org > > > > Committed: https://chromium.googlesource.com/external/webrtc/+/fb647a67be94bb3c940d8b5fba01972f7ce91a29 > > R=stefan@webrtc.org > # Not skipping CQ checks because original CL landed more than 1 days ago. > BUG=chromium:595274, chromium:595308, webrtc:5410 > > Committed: https://crrev.com/81cbd924447d507559dbd6e6d1f9fe439fcf2716 > Cr-Commit-Position: refs/heads/master@{#12086} TBR=stefan@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=chromium:595274, chromium:595308, webrtc:5410 Review URL: https://codereview.webrtc.org/1896413002 Cr-Commit-Position: refs/heads/master@{#12446}
2016-04-20 06:35:56 -07:00
ASSERT_TRUE(
init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
<< "Timed out while waiting for encoder to be configured.";
WaitForSetRates(kStartBitrateKbps);
Call::Config::BitrateConfig bitrate_config;
bitrate_config.start_bitrate_bps = kIncreasedStartBitrateKbps * 1000;
bitrate_config.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
task_queue_->SendTask([this, &bitrate_config]() {
call_->SetBitrateConfig(bitrate_config);
});
// Encoder rate is capped by EncoderConfig max_bitrate_bps.
WaitForSetRates(kMaxBitrateKbps);
encoder_config_.max_bitrate_bps = kLowerMaxBitrateKbps * 1000;
send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
Reland of Initialize/configure video encoders asychronously. (patchset #1 id:1 of https://codereview.webrtc.org/1821983002/ ) Reason for revert: RTCVideoEncoder has been updated to not make assumptions on calling threads/post back to a worker thread. This should now be landable again. Original issue's description: > Revert of Initialize/configure video encoders asychronously. (patchset #4 id:60001 of https://codereview.webrtc.org/1757313002/ ) > > Reason for revert: > Breaks RTCVideoEncoder which has incorrect assumptions on where InitEncode etc. is called from. Temporarily reverting until RTCVideoEncoder has been updated. > > Original issue's description: > > Initialize/configure video encoders asychronously. > > > > Greatly speeds up setRemoteDescription() by moving encoder initialization > > off the main worker thread, which is free to move onto gathering ICE > > candidates and other tasks while InitEncode() is performed. It also > > un-blocks PeerConnection GetStats() which is no longer blocked on > > encoder initialization. > > > > BUG=webrtc:5410 > > R=stefan@webrtc.org > > > > Committed: https://chromium.googlesource.com/external/webrtc/+/fb647a67be94bb3c940d8b5fba01972f7ce91a29 > > R=stefan@webrtc.org > # Not skipping CQ checks because original CL landed more than 1 days ago. > BUG=chromium:595274, chromium:595308, webrtc:5410 > > Committed: https://crrev.com/81cbd924447d507559dbd6e6d1f9fe439fcf2716 > Cr-Commit-Position: refs/heads/master@{#12086} TBR=stefan@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=chromium:595274, chromium:595308, webrtc:5410 Review URL: https://codereview.webrtc.org/1896413002 Cr-Commit-Position: refs/heads/master@{#12446}
2016-04-20 06:35:56 -07:00
ASSERT_TRUE(
init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
EXPECT_EQ(2, num_initializations_)
<< "Encoder should have been reconfigured with the new value.";
WaitForSetRates(kLowerMaxBitrateKbps);
encoder_config_.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
Reland of Initialize/configure video encoders asychronously. (patchset #1 id:1 of https://codereview.webrtc.org/1821983002/ ) Reason for revert: RTCVideoEncoder has been updated to not make assumptions on calling threads/post back to a worker thread. This should now be landable again. Original issue's description: > Revert of Initialize/configure video encoders asychronously. (patchset #4 id:60001 of https://codereview.webrtc.org/1757313002/ ) > > Reason for revert: > Breaks RTCVideoEncoder which has incorrect assumptions on where InitEncode etc. is called from. Temporarily reverting until RTCVideoEncoder has been updated. > > Original issue's description: > > Initialize/configure video encoders asychronously. > > > > Greatly speeds up setRemoteDescription() by moving encoder initialization > > off the main worker thread, which is free to move onto gathering ICE > > candidates and other tasks while InitEncode() is performed. It also > > un-blocks PeerConnection GetStats() which is no longer blocked on > > encoder initialization. > > > > BUG=webrtc:5410 > > R=stefan@webrtc.org > > > > Committed: https://chromium.googlesource.com/external/webrtc/+/fb647a67be94bb3c940d8b5fba01972f7ce91a29 > > R=stefan@webrtc.org > # Not skipping CQ checks because original CL landed more than 1 days ago. > BUG=chromium:595274, chromium:595308, webrtc:5410 > > Committed: https://crrev.com/81cbd924447d507559dbd6e6d1f9fe439fcf2716 > Cr-Commit-Position: refs/heads/master@{#12086} TBR=stefan@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=chromium:595274, chromium:595308, webrtc:5410 Review URL: https://codereview.webrtc.org/1896413002 Cr-Commit-Position: refs/heads/master@{#12446}
2016-04-20 06:35:56 -07:00
ASSERT_TRUE(
init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
EXPECT_EQ(3, num_initializations_)
<< "Encoder should have been reconfigured with the new value.";
// Expected target bitrate is the start bitrate set in the call to
// call_->SetBitrateConfig.
WaitForSetRates(kIncreasedStartBitrateKbps);
}
test::SingleThreadedTaskQueueForTesting* const task_queue_;
Reland of Initialize/configure video encoders asychronously. (patchset #1 id:1 of https://codereview.webrtc.org/1821983002/ ) Reason for revert: RTCVideoEncoder has been updated to not make assumptions on calling threads/post back to a worker thread. This should now be landable again. Original issue's description: > Revert of Initialize/configure video encoders asychronously. (patchset #4 id:60001 of https://codereview.webrtc.org/1757313002/ ) > > Reason for revert: > Breaks RTCVideoEncoder which has incorrect assumptions on where InitEncode etc. is called from. Temporarily reverting until RTCVideoEncoder has been updated. > > Original issue's description: > > Initialize/configure video encoders asychronously. > > > > Greatly speeds up setRemoteDescription() by moving encoder initialization > > off the main worker thread, which is free to move onto gathering ICE > > candidates and other tasks while InitEncode() is performed. It also > > un-blocks PeerConnection GetStats() which is no longer blocked on > > encoder initialization. > > > > BUG=webrtc:5410 > > R=stefan@webrtc.org > > > > Committed: https://chromium.googlesource.com/external/webrtc/+/fb647a67be94bb3c940d8b5fba01972f7ce91a29 > > R=stefan@webrtc.org > # Not skipping CQ checks because original CL landed more than 1 days ago. > BUG=chromium:595274, chromium:595308, webrtc:5410 > > Committed: https://crrev.com/81cbd924447d507559dbd6e6d1f9fe439fcf2716 > Cr-Commit-Position: refs/heads/master@{#12086} TBR=stefan@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=chromium:595274, chromium:595308, webrtc:5410 Review URL: https://codereview.webrtc.org/1896413002 Cr-Commit-Position: refs/heads/master@{#12446}
2016-04-20 06:35:56 -07:00
rtc::Event init_encode_event_;
rtc::Event bitrate_changed_event_;
rtc::CriticalSection crit_;
uint32_t target_bitrate_ RTC_GUARDED_BY(&crit_);
int num_initializations_;
webrtc::Call* call_;
webrtc::VideoSendStream* send_stream_;
webrtc::VideoEncoderConfig encoder_config_;
} test(&task_queue_);
RunBaseTest(&test);
}
TEST_F(VideoSendStreamTest, ReportsSentResolution) {
static const size_t kNumStreams = 3;
// Unusual resolutions to make sure that they are the ones being reported.
static const struct {
int width;
int height;
} kEncodedResolution[kNumStreams] = {
{241, 181}, {300, 121}, {121, 221}};
class ScreencastTargetBitrateTest : public test::SendTest,
public test::FakeEncoder {
public:
ScreencastTargetBitrateTest()
: SendTest(kDefaultTimeoutMs),
test::FakeEncoder(Clock::GetRealTimeClock()),
send_stream_(nullptr) {}
private:
int32_t Encode(const VideoFrame& input_image,
const CodecSpecificInfo* codecSpecificInfo,
const std::vector<FrameType>* frame_types) override {
CodecSpecificInfo specifics;
specifics.codecType = kVideoCodecGeneric;
uint8_t buffer[16] = {0};
EncodedImage encoded(buffer, sizeof(buffer), sizeof(buffer));
encoded._timeStamp = input_image.timestamp();
encoded.capture_time_ms_ = input_image.render_time_ms();
for (size_t i = 0; i < kNumStreams; ++i) {
specifics.codecSpecific.generic.simulcast_idx = static_cast<uint8_t>(i);
encoded._frameType = (*frame_types)[i];
encoded._encodedWidth = kEncodedResolution[i].width;
encoded._encodedHeight = kEncodedResolution[i].height;
EncodedImageCallback* callback;
{
rtc::CritScope cs(&crit_sect_);
callback = callback_;
}
RTC_DCHECK(callback);
if (callback->OnEncodedImage(encoded, &specifics, nullptr).error !=
EncodedImageCallback::Result::OK) {
return -1;
}
}
observation_complete_.Set();
return 0;
}
void ModifyVideoConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) override {
send_config->encoder_settings.encoder = this;
EXPECT_EQ(kNumStreams, encoder_config->number_of_streams);
}
size_t GetNumVideoStreams() const override { return kNumStreams; }
void PerformTest() override {
EXPECT_TRUE(Wait())
<< "Timed out while waiting for the encoder to send one frame.";
VideoSendStream::Stats stats = send_stream_->GetStats();
for (size_t i = 0; i < kNumStreams; ++i) {
ASSERT_TRUE(stats.substreams.find(kVideoSendSsrcs[i]) !=
stats.substreams.end())
<< "No stats for SSRC: " << kVideoSendSsrcs[i]
<< ", stats should exist as soon as frames have been encoded.";
VideoSendStream::StreamStats ssrc_stats =
stats.substreams[kVideoSendSsrcs[i]];
EXPECT_EQ(kEncodedResolution[i].width, ssrc_stats.width);
EXPECT_EQ(kEncodedResolution[i].height, ssrc_stats.height);
}
}
void OnVideoStreamsCreated(
VideoSendStream* send_stream,
const std::vector<VideoReceiveStream*>& receive_streams) override {
send_stream_ = send_stream;
}
VideoSendStream* send_stream_;
} test;
RunBaseTest(&test);
}
#if !defined(RTC_DISABLE_VP9)
class Vp9HeaderObserver : public test::SendTest {
public:
Vp9HeaderObserver()
: SendTest(VideoSendStreamTest::kLongTimeoutMs),
vp9_encoder_(VP9Encoder::Create()),
vp9_settings_(VideoEncoder::GetDefaultVp9Settings()),
packets_sent_(0),
frames_sent_(0),
expected_width_(0),
expected_height_(0) {}
virtual void ModifyVideoConfigsHook(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) {}
virtual void InspectHeader(const RTPVideoHeaderVP9& vp9) = 0;
private:
const int kVp9PayloadType = test::CallTest::kVideoSendPayloadType;
class VideoStreamFactory
: public VideoEncoderConfig::VideoStreamFactoryInterface {
public:
explicit VideoStreamFactory(size_t number_of_temporal_layers)
: number_of_temporal_layers_(number_of_temporal_layers) {}
private:
std::vector<VideoStream> CreateEncoderStreams(
int width,
int height,
const VideoEncoderConfig& encoder_config) override {
std::vector<VideoStream> streams =
test::CreateVideoStreams(width, height, encoder_config);
streams[0].temporal_layer_thresholds_bps.resize(
number_of_temporal_layers_ - 1);
return streams;
}
const size_t number_of_temporal_layers_;
};
void ModifyVideoConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) override {
send_config->encoder_settings.encoder = vp9_encoder_.get();
send_config->encoder_settings.payload_name = "VP9";
send_config->encoder_settings.payload_type = kVp9PayloadType;
ModifyVideoConfigsHook(send_config, receive_configs, encoder_config);
encoder_config->encoder_specific_settings = new rtc::RefCountedObject<
VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings_);
EXPECT_EQ(1u, encoder_config->number_of_streams);
encoder_config->video_stream_factory =
new rtc::RefCountedObject<VideoStreamFactory>(
vp9_settings_.numberOfTemporalLayers);
encoder_config_ = encoder_config->Copy();
}
void ModifyVideoCaptureStartResolution(int* width,
int* height,
int* frame_rate) override {
expected_width_ = *width;
expected_height_ = *height;
}
void PerformTest() override {
EXPECT_TRUE(Wait()) << "Test timed out waiting for VP9 packet, num frames "
<< frames_sent_;
}
Action OnSendRtp(const uint8_t* packet, size_t length) override {
RTPHeader header;
EXPECT_TRUE(parser_->Parse(packet, length, &header));
EXPECT_EQ(kVp9PayloadType, header.payloadType);
const uint8_t* payload = packet + header.headerLength;
size_t payload_length = length - header.headerLength - header.paddingLength;
bool new_packet = packets_sent_ == 0 ||
IsNewerSequenceNumber(header.sequenceNumber,
last_header_.sequenceNumber);
if (payload_length > 0 && new_packet) {
RtpDepacketizer::ParsedPayload parsed;
RtpDepacketizerVp9 depacketizer;
EXPECT_TRUE(depacketizer.Parse(&parsed, payload, payload_length));
EXPECT_EQ(RtpVideoCodecTypes::kRtpVideoVp9, parsed.type.Video.codec);
// Verify common fields for all configurations.
VerifyCommonHeader(parsed.type.Video.codecHeader.VP9);
CompareConsecutiveFrames(header, parsed.type.Video);
// Verify configuration specific settings.
InspectHeader(parsed.type.Video.codecHeader.VP9);
++packets_sent_;
if (header.markerBit) {
++frames_sent_;
}
last_header_ = header;
last_vp9_ = parsed.type.Video.codecHeader.VP9;
}
return SEND_PACKET;
}
protected:
bool ContinuousPictureId(const RTPVideoHeaderVP9& vp9) const {
if (last_vp9_.picture_id > vp9.picture_id) {
return vp9.picture_id == 0; // Wrap.
} else {
return vp9.picture_id == last_vp9_.picture_id + 1;
}
}
void VerifySpatialIdxWithinFrame(const RTPVideoHeaderVP9& vp9) const {
bool new_layer = vp9.spatial_idx != last_vp9_.spatial_idx;
EXPECT_EQ(new_layer, vp9.beginning_of_frame);
EXPECT_EQ(new_layer, last_vp9_.end_of_frame);
EXPECT_EQ(new_layer ? last_vp9_.spatial_idx + 1 : last_vp9_.spatial_idx,
vp9.spatial_idx);
}
void VerifyFixedTemporalLayerStructure(const RTPVideoHeaderVP9& vp9,
uint8_t num_layers) const {
switch (num_layers) {
case 0:
VerifyTemporalLayerStructure0(vp9);
break;
case 1:
VerifyTemporalLayerStructure1(vp9);
break;
case 2:
VerifyTemporalLayerStructure2(vp9);
break;
case 3:
VerifyTemporalLayerStructure3(vp9);
break;
default:
RTC_NOTREACHED();
}
}
Reland of Work on flexible mode and screen sharing. (patchset #1 id:1 of https://codereview.webrtc.org/1438543002/ ) Reason for revert: Failed test not related to this CL (test fails on master at an earlier date), re-landing original CL.. (This time from my @webrtc account.) Original issue's description: > Revert of Work on flexible mode and screen sharing. (patchset #28 id:520001 of https://codereview.webrtc.org/1328113004/ ) > > Reason for revert: > Seems to break VideoSendStreamTest.ReconfigureBitratesSetsEncoderBitratesCorrectly on Linux Memcheck buildbot. > > Original issue's description: > > Work on flexible mode and screen sharing. > > > > Implement VP8 style screensharing but with spatial layers. > > Implement flexible mode. > > > > Files from other patches: > > generic_encoder.cc > > layer_filtering_transport.cc > > > > BUG=webrtc:4914 > > > > Committed: https://crrev.com/77ccfb4d16c148e61a316746bb5d9705e8b39f4a > > Cr-Commit-Position: refs/heads/master@{#10572} > > TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,philipel@webrtc.org > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:4914 > > Committed: https://crrev.com/0be8f1d347bdb171462df89c2a4c69b3f3eb7519 > Cr-Commit-Position: refs/heads/master@{#10578} TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,terelius@webrtc.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=webrtc:4914 Review URL: https://codereview.webrtc.org/1431283002 Cr-Commit-Position: refs/heads/master@{#10581}
2015-11-10 07:17:23 -08:00
void VerifyTemporalLayerStructure0(const RTPVideoHeaderVP9& vp9) const {
EXPECT_EQ(kNoTl0PicIdx, vp9.tl0_pic_idx);
EXPECT_EQ(kNoTemporalIdx, vp9.temporal_idx); // no tid
EXPECT_FALSE(vp9.temporal_up_switch);
}
void VerifyTemporalLayerStructure1(const RTPVideoHeaderVP9& vp9) const {
EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
EXPECT_EQ(0, vp9.temporal_idx); // 0,0,0,...
EXPECT_FALSE(vp9.temporal_up_switch);
}
void VerifyTemporalLayerStructure2(const RTPVideoHeaderVP9& vp9) const {
EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
EXPECT_GE(vp9.temporal_idx, 0); // 0,1,0,1,... (tid reset on I-frames).
EXPECT_LE(vp9.temporal_idx, 1);
EXPECT_EQ(vp9.temporal_idx > 0, vp9.temporal_up_switch);
if (IsNewPictureId(vp9)) {
uint8_t expected_tid =
(!vp9.inter_pic_predicted || last_vp9_.temporal_idx == 1) ? 0 : 1;
EXPECT_EQ(expected_tid, vp9.temporal_idx);
}
}
void VerifyTemporalLayerStructure3(const RTPVideoHeaderVP9& vp9) const {
EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
EXPECT_GE(vp9.temporal_idx, 0); // 0,2,1,2,... (tid reset on I-frames).
EXPECT_LE(vp9.temporal_idx, 2);
if (IsNewPictureId(vp9) && vp9.inter_pic_predicted) {
EXPECT_NE(vp9.temporal_idx, last_vp9_.temporal_idx);
switch (vp9.temporal_idx) {
case 0:
EXPECT_EQ(2, last_vp9_.temporal_idx);
EXPECT_FALSE(vp9.temporal_up_switch);
break;
case 1:
EXPECT_EQ(2, last_vp9_.temporal_idx);
EXPECT_TRUE(vp9.temporal_up_switch);
break;
case 2:
EXPECT_EQ(last_vp9_.temporal_idx == 0, vp9.temporal_up_switch);
break;
}
}
}
void VerifyTl0Idx(const RTPVideoHeaderVP9& vp9) const {
if (vp9.tl0_pic_idx == kNoTl0PicIdx)
return;
uint8_t expected_tl0_idx = last_vp9_.tl0_pic_idx;
if (vp9.temporal_idx == 0)
++expected_tl0_idx;
EXPECT_EQ(expected_tl0_idx, vp9.tl0_pic_idx);
}
bool IsNewPictureId(const RTPVideoHeaderVP9& vp9) const {
return frames_sent_ > 0 && (vp9.picture_id != last_vp9_.picture_id);
}
// Flexible mode (F=1): Non-flexible mode (F=0):
//
// +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
// |I|P|L|F|B|E|V|-| |I|P|L|F|B|E|V|-|
// +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
// I: |M| PICTURE ID | I: |M| PICTURE ID |
// +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
// M: | EXTENDED PID | M: | EXTENDED PID |
// +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
// L: | T |U| S |D| L: | T |U| S |D|
// +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
// P,F: | P_DIFF |X|N| | TL0PICIDX |
// +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
// X: |EXTENDED P_DIFF| V: | SS .. |
// +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
// V: | SS .. |
// +-+-+-+-+-+-+-+-+
void VerifyCommonHeader(const RTPVideoHeaderVP9& vp9) const {
EXPECT_EQ(kMaxTwoBytePictureId, vp9.max_picture_id); // M:1
EXPECT_NE(kNoPictureId, vp9.picture_id); // I:1
EXPECT_EQ(vp9_settings_.flexibleMode, vp9.flexible_mode); // F
Reland "Keep spatial_idx=kNoSpatialIdx(255) if there is no layer indices." This is a reland of 47836b4ebb8a5c71695b5ec07bffd5ee4e3bc2ff Internal tests are synced with the fix. Original change's description: > Keep spatial_idx=kNoSpatialIdx(255) if there is no layer indices. > > spatial_idx is not present in RTP header if there is no temporal or > spatial layering. But the parser sets spatial_idx to 0 in this case. > When reflector repacketizes such packets it writes layering indices > into outgoing packets. When packets arrive to receiver it thinks that > it deals with multi layer stream and passes it through special path > in Vp9 reference frame finder which never outputs inter frames. > > I modified the parser such that it keeps spatial_idx=kNoSpatialIdx(255) > when there is no layer indices in RTP header. Related unit tests have > been modified as well. > > Bug: none > Change-Id: I14498cafb4e57797577dc873298c35b243479f88 > Reviewed-on: https://webrtc-review.googlesource.com/17980 > Commit-Queue: Sergey Silkin <ssilkin@webrtc.org> > Reviewed-by: Erik Språng <sprang@webrtc.org> > Reviewed-by: Åsa Persson <asapersson@webrtc.org> > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#20560} TBR=brandtr@webrtc.org,asapersson@webrtc.org,sprang@webrtc.org Bug: none Change-Id: I6087a8b20a926296b30432d69251670120b2a20c Reviewed-on: https://webrtc-review.googlesource.com/20940 Reviewed-by: Sergey Silkin <ssilkin@webrtc.org> Commit-Queue: Sergey Silkin <ssilkin@webrtc.org> Cr-Commit-Position: refs/heads/master@{#20591}
2017-11-06 11:49:19 +01:00
if (vp9_settings_.numberOfSpatialLayers > 1) {
EXPECT_LT(vp9.spatial_idx, vp9_settings_.numberOfSpatialLayers);
} else if (vp9_settings_.numberOfTemporalLayers > 1) {
EXPECT_EQ(vp9.spatial_idx, 0);
} else {
EXPECT_EQ(vp9.spatial_idx, kNoSpatialIdx);
}
if (vp9_settings_.numberOfTemporalLayers > 1) {
EXPECT_LT(vp9.temporal_idx, vp9_settings_.numberOfTemporalLayers);
} else if (vp9_settings_.numberOfSpatialLayers > 1) {
EXPECT_EQ(vp9.temporal_idx, 0);
} else {
EXPECT_EQ(vp9.temporal_idx, kNoTemporalIdx);
}
if (vp9.ss_data_available) // V
VerifySsData(vp9);
if (frames_sent_ == 0)
EXPECT_FALSE(vp9.inter_pic_predicted); // P
if (!vp9.inter_pic_predicted) {
EXPECT_TRUE(vp9.temporal_idx == 0 || vp9.temporal_idx == kNoTemporalIdx);
EXPECT_FALSE(vp9.temporal_up_switch);
}
}
// Scalability structure (SS).
//
// +-+-+-+-+-+-+-+-+
// V: | N_S |Y|G|-|-|-|
// +-+-+-+-+-+-+-+-+
// Y: | WIDTH | N_S + 1 times
// +-+-+-+-+-+-+-+-+
// | HEIGHT |
// +-+-+-+-+-+-+-+-+
// G: | N_G |
// +-+-+-+-+-+-+-+-+
// N_G: | T |U| R |-|-| N_G times
// +-+-+-+-+-+-+-+-+
// | P_DIFF | R times
// +-+-+-+-+-+-+-+-+
void VerifySsData(const RTPVideoHeaderVP9& vp9) const {
EXPECT_TRUE(vp9.ss_data_available); // V
EXPECT_EQ(vp9_settings_.numberOfSpatialLayers, // N_S + 1
vp9.num_spatial_layers);
EXPECT_TRUE(vp9.spatial_layer_resolution_present); // Y:1
int expected_width = expected_width_;
int expected_height = expected_height_;
for (int i = static_cast<int>(vp9.num_spatial_layers) - 1; i >= 0; --i) {
EXPECT_EQ(expected_width, vp9.width[i]); // WIDTH
EXPECT_EQ(expected_height, vp9.height[i]); // HEIGHT
expected_width /= 2;
expected_height /= 2;
}
}
void CompareConsecutiveFrames(const RTPHeader& header,
const RTPVideoHeader& video) const {
const RTPVideoHeaderVP9& vp9 = video.codecHeader.VP9;
bool new_frame = packets_sent_ == 0 ||
IsNewerTimestamp(header.timestamp, last_header_.timestamp);
Reland of Rename RTPVideoHeader.isFirstPacket to .is_first_packet_in_frame. Add RTC_DEPRACATed anonymous unions to not break downstream projects. Orignal issue's description: > commit 0ad21111fcc57a7e978edba3c4263f0062d7f9ff > Author: danilchap <danilchap@webrtc.org> > Date: Mon Dec 19 09:36:33 2016 -0800 > > Revert of Rename RTPVideoHeader.isFirstPacket to > .is_first_packet_in_frame. (patchset #1 id:1 of > https://codereview.webrtc.org/2574943003/ ) > > Reason for revert: > breaks downstream project. > > Can you make this change in a compatible way using anonymous > union: > union { > bool is_first_packet_in_frame; > RTC_DEPRECATED bool isFirstPacket; > }; > (unfortunetly this this treak breaks braced initialization in > rtp_rtcp_impl_unittest.cc, > so that should be rewritting in a more classic way) > > Original issue's description: > > Rename RTPVideoHeader.isFirstPacket to > > .is_first_packet_in_frame. > > > > Name should represent the actual meaning. > > > > BUG=None > > > > Review-Url: https://codereview.webrtc.org/2574943003 > > Cr-Commit-Position: refs/heads/master@{#15684} > > Committed: > > https://chromium.googlesource.com/external/webrtc/+/efde90838055f44ca05863ba020ca02c88b6d14c > > TBR=stefan@webrtc.org,sprang@webrtc.org,johan@webrtc.org > # Skipping CQ checks because original CL landed less than 1 days > ago. > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=None > > Review-Url: https://codereview.webrtc.org/2589783003 > Cr-Commit-Position: refs/heads/master@{#15686} > BUG=None Review-Url: https://codereview.webrtc.org/2614503002 Cr-Commit-Position: refs/heads/master@{#15987}
2017-01-10 04:21:35 -08:00
EXPECT_EQ(new_frame, video.is_first_packet_in_frame);
if (!new_frame) {
EXPECT_FALSE(last_header_.markerBit);
EXPECT_EQ(last_header_.timestamp, header.timestamp);
EXPECT_EQ(last_vp9_.picture_id, vp9.picture_id);
EXPECT_EQ(last_vp9_.temporal_idx, vp9.temporal_idx);
EXPECT_EQ(last_vp9_.tl0_pic_idx, vp9.tl0_pic_idx);
VerifySpatialIdxWithinFrame(vp9);
return;
}
// New frame.
EXPECT_TRUE(vp9.beginning_of_frame);
// Compare with last packet in previous frame.
if (frames_sent_ == 0)
return;
EXPECT_TRUE(last_vp9_.end_of_frame);
EXPECT_TRUE(last_header_.markerBit);
EXPECT_TRUE(ContinuousPictureId(vp9));
VerifyTl0Idx(vp9);
}
std::unique_ptr<VP9Encoder> vp9_encoder_;
VideoCodecVP9 vp9_settings_;
webrtc::VideoEncoderConfig encoder_config_;
RTPHeader last_header_;
RTPVideoHeaderVP9 last_vp9_;
size_t packets_sent_;
size_t frames_sent_;
int expected_width_;
int expected_height_;
};
TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl1SLayers) {
const uint8_t kNumTemporalLayers = 1;
const uint8_t kNumSpatialLayers = 1;
TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
}
TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl1SLayers) {
const uint8_t kNumTemporalLayers = 2;
const uint8_t kNumSpatialLayers = 1;
TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
}
TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl1SLayers) {
const uint8_t kNumTemporalLayers = 3;
const uint8_t kNumSpatialLayers = 1;
TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
}
TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl2SLayers) {
const uint8_t kNumTemporalLayers = 1;
const uint8_t kNumSpatialLayers = 2;
TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
}
TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl2SLayers) {
const uint8_t kNumTemporalLayers = 2;
const uint8_t kNumSpatialLayers = 2;
TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
}
TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl2SLayers) {
const uint8_t kNumTemporalLayers = 3;
const uint8_t kNumSpatialLayers = 2;
TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
}
void VideoSendStreamTest::TestVp9NonFlexMode(uint8_t num_temporal_layers,
uint8_t num_spatial_layers) {
static const size_t kNumFramesToSend = 100;
// Set to < kNumFramesToSend and coprime to length of temporal layer
// structures to verify temporal id reset on key frame.
static const int kKeyFrameInterval = 31;
class NonFlexibleMode : public Vp9HeaderObserver {
public:
NonFlexibleMode(uint8_t num_temporal_layers, uint8_t num_spatial_layers)
: num_temporal_layers_(num_temporal_layers),
num_spatial_layers_(num_spatial_layers),
l_field_(num_temporal_layers > 1 || num_spatial_layers > 1) {}
void ModifyVideoConfigsHook(
Reland of Work on flexible mode and screen sharing. (patchset #1 id:1 of https://codereview.webrtc.org/1438543002/ ) Reason for revert: Failed test not related to this CL (test fails on master at an earlier date), re-landing original CL.. (This time from my @webrtc account.) Original issue's description: > Revert of Work on flexible mode and screen sharing. (patchset #28 id:520001 of https://codereview.webrtc.org/1328113004/ ) > > Reason for revert: > Seems to break VideoSendStreamTest.ReconfigureBitratesSetsEncoderBitratesCorrectly on Linux Memcheck buildbot. > > Original issue's description: > > Work on flexible mode and screen sharing. > > > > Implement VP8 style screensharing but with spatial layers. > > Implement flexible mode. > > > > Files from other patches: > > generic_encoder.cc > > layer_filtering_transport.cc > > > > BUG=webrtc:4914 > > > > Committed: https://crrev.com/77ccfb4d16c148e61a316746bb5d9705e8b39f4a > > Cr-Commit-Position: refs/heads/master@{#10572} > > TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,philipel@webrtc.org > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:4914 > > Committed: https://crrev.com/0be8f1d347bdb171462df89c2a4c69b3f3eb7519 > Cr-Commit-Position: refs/heads/master@{#10578} TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,terelius@webrtc.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=webrtc:4914 Review URL: https://codereview.webrtc.org/1431283002 Cr-Commit-Position: refs/heads/master@{#10581}
2015-11-10 07:17:23 -08:00
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) override {
vp9_settings_.flexibleMode = false;
vp9_settings_.frameDroppingOn = false;
vp9_settings_.keyFrameInterval = kKeyFrameInterval;
vp9_settings_.numberOfTemporalLayers = num_temporal_layers_;
vp9_settings_.numberOfSpatialLayers = num_spatial_layers_;
}
void InspectHeader(const RTPVideoHeaderVP9& vp9) override {
Reland "Keep spatial_idx=kNoSpatialIdx(255) if there is no layer indices." This is a reland of 47836b4ebb8a5c71695b5ec07bffd5ee4e3bc2ff Internal tests are synced with the fix. Original change's description: > Keep spatial_idx=kNoSpatialIdx(255) if there is no layer indices. > > spatial_idx is not present in RTP header if there is no temporal or > spatial layering. But the parser sets spatial_idx to 0 in this case. > When reflector repacketizes such packets it writes layering indices > into outgoing packets. When packets arrive to receiver it thinks that > it deals with multi layer stream and passes it through special path > in Vp9 reference frame finder which never outputs inter frames. > > I modified the parser such that it keeps spatial_idx=kNoSpatialIdx(255) > when there is no layer indices in RTP header. Related unit tests have > been modified as well. > > Bug: none > Change-Id: I14498cafb4e57797577dc873298c35b243479f88 > Reviewed-on: https://webrtc-review.googlesource.com/17980 > Commit-Queue: Sergey Silkin <ssilkin@webrtc.org> > Reviewed-by: Erik Språng <sprang@webrtc.org> > Reviewed-by: Åsa Persson <asapersson@webrtc.org> > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#20560} TBR=brandtr@webrtc.org,asapersson@webrtc.org,sprang@webrtc.org Bug: none Change-Id: I6087a8b20a926296b30432d69251670120b2a20c Reviewed-on: https://webrtc-review.googlesource.com/20940 Reviewed-by: Sergey Silkin <ssilkin@webrtc.org> Commit-Queue: Sergey Silkin <ssilkin@webrtc.org> Cr-Commit-Position: refs/heads/master@{#20591}
2017-11-06 11:49:19 +01:00
bool ss_data_expected =
!vp9.inter_pic_predicted && vp9.beginning_of_frame &&
(vp9.spatial_idx == 0 || vp9.spatial_idx == kNoSpatialIdx);
EXPECT_EQ(ss_data_expected, vp9.ss_data_available);
Reland "Keep spatial_idx=kNoSpatialIdx(255) if there is no layer indices." This is a reland of 47836b4ebb8a5c71695b5ec07bffd5ee4e3bc2ff Internal tests are synced with the fix. Original change's description: > Keep spatial_idx=kNoSpatialIdx(255) if there is no layer indices. > > spatial_idx is not present in RTP header if there is no temporal or > spatial layering. But the parser sets spatial_idx to 0 in this case. > When reflector repacketizes such packets it writes layering indices > into outgoing packets. When packets arrive to receiver it thinks that > it deals with multi layer stream and passes it through special path > in Vp9 reference frame finder which never outputs inter frames. > > I modified the parser such that it keeps spatial_idx=kNoSpatialIdx(255) > when there is no layer indices in RTP header. Related unit tests have > been modified as well. > > Bug: none > Change-Id: I14498cafb4e57797577dc873298c35b243479f88 > Reviewed-on: https://webrtc-review.googlesource.com/17980 > Commit-Queue: Sergey Silkin <ssilkin@webrtc.org> > Reviewed-by: Erik Språng <sprang@webrtc.org> > Reviewed-by: Åsa Persson <asapersson@webrtc.org> > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#20560} TBR=brandtr@webrtc.org,asapersson@webrtc.org,sprang@webrtc.org Bug: none Change-Id: I6087a8b20a926296b30432d69251670120b2a20c Reviewed-on: https://webrtc-review.googlesource.com/20940 Reviewed-by: Sergey Silkin <ssilkin@webrtc.org> Commit-Queue: Sergey Silkin <ssilkin@webrtc.org> Cr-Commit-Position: refs/heads/master@{#20591}
2017-11-06 11:49:19 +01:00
if (num_spatial_layers_ > 1) {
EXPECT_EQ(vp9.spatial_idx > 0, vp9.inter_layer_predicted);
} else {
EXPECT_FALSE(vp9.inter_layer_predicted);
}
EXPECT_EQ(!vp9.inter_pic_predicted,
frames_sent_ % kKeyFrameInterval == 0);
if (IsNewPictureId(vp9)) {
Reland "Keep spatial_idx=kNoSpatialIdx(255) if there is no layer indices." This is a reland of 47836b4ebb8a5c71695b5ec07bffd5ee4e3bc2ff Internal tests are synced with the fix. Original change's description: > Keep spatial_idx=kNoSpatialIdx(255) if there is no layer indices. > > spatial_idx is not present in RTP header if there is no temporal or > spatial layering. But the parser sets spatial_idx to 0 in this case. > When reflector repacketizes such packets it writes layering indices > into outgoing packets. When packets arrive to receiver it thinks that > it deals with multi layer stream and passes it through special path > in Vp9 reference frame finder which never outputs inter frames. > > I modified the parser such that it keeps spatial_idx=kNoSpatialIdx(255) > when there is no layer indices in RTP header. Related unit tests have > been modified as well. > > Bug: none > Change-Id: I14498cafb4e57797577dc873298c35b243479f88 > Reviewed-on: https://webrtc-review.googlesource.com/17980 > Commit-Queue: Sergey Silkin <ssilkin@webrtc.org> > Reviewed-by: Erik Språng <sprang@webrtc.org> > Reviewed-by: Åsa Persson <asapersson@webrtc.org> > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#20560} TBR=brandtr@webrtc.org,asapersson@webrtc.org,sprang@webrtc.org Bug: none Change-Id: I6087a8b20a926296b30432d69251670120b2a20c Reviewed-on: https://webrtc-review.googlesource.com/20940 Reviewed-by: Sergey Silkin <ssilkin@webrtc.org> Commit-Queue: Sergey Silkin <ssilkin@webrtc.org> Cr-Commit-Position: refs/heads/master@{#20591}
2017-11-06 11:49:19 +01:00
if (num_temporal_layers_ == 1 && num_spatial_layers_ == 1) {
EXPECT_EQ(kNoSpatialIdx, vp9.spatial_idx);
} else {
EXPECT_EQ(0, vp9.spatial_idx);
}
if (num_spatial_layers_ > 1)
EXPECT_EQ(num_spatial_layers_ - 1, last_vp9_.spatial_idx);
}
VerifyFixedTemporalLayerStructure(vp9,
l_field_ ? num_temporal_layers_ : 0);
Reland of Work on flexible mode and screen sharing. (patchset #1 id:1 of https://codereview.webrtc.org/1438543002/ ) Reason for revert: Failed test not related to this CL (test fails on master at an earlier date), re-landing original CL.. (This time from my @webrtc account.) Original issue's description: > Revert of Work on flexible mode and screen sharing. (patchset #28 id:520001 of https://codereview.webrtc.org/1328113004/ ) > > Reason for revert: > Seems to break VideoSendStreamTest.ReconfigureBitratesSetsEncoderBitratesCorrectly on Linux Memcheck buildbot. > > Original issue's description: > > Work on flexible mode and screen sharing. > > > > Implement VP8 style screensharing but with spatial layers. > > Implement flexible mode. > > > > Files from other patches: > > generic_encoder.cc > > layer_filtering_transport.cc > > > > BUG=webrtc:4914 > > > > Committed: https://crrev.com/77ccfb4d16c148e61a316746bb5d9705e8b39f4a > > Cr-Commit-Position: refs/heads/master@{#10572} > > TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,philipel@webrtc.org > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:4914 > > Committed: https://crrev.com/0be8f1d347bdb171462df89c2a4c69b3f3eb7519 > Cr-Commit-Position: refs/heads/master@{#10578} TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,terelius@webrtc.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=webrtc:4914 Review URL: https://codereview.webrtc.org/1431283002 Cr-Commit-Position: refs/heads/master@{#10581}
2015-11-10 07:17:23 -08:00
if (frames_sent_ > kNumFramesToSend)
observation_complete_.Set();
Reland of Work on flexible mode and screen sharing. (patchset #1 id:1 of https://codereview.webrtc.org/1438543002/ ) Reason for revert: Failed test not related to this CL (test fails on master at an earlier date), re-landing original CL.. (This time from my @webrtc account.) Original issue's description: > Revert of Work on flexible mode and screen sharing. (patchset #28 id:520001 of https://codereview.webrtc.org/1328113004/ ) > > Reason for revert: > Seems to break VideoSendStreamTest.ReconfigureBitratesSetsEncoderBitratesCorrectly on Linux Memcheck buildbot. > > Original issue's description: > > Work on flexible mode and screen sharing. > > > > Implement VP8 style screensharing but with spatial layers. > > Implement flexible mode. > > > > Files from other patches: > > generic_encoder.cc > > layer_filtering_transport.cc > > > > BUG=webrtc:4914 > > > > Committed: https://crrev.com/77ccfb4d16c148e61a316746bb5d9705e8b39f4a > > Cr-Commit-Position: refs/heads/master@{#10572} > > TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,philipel@webrtc.org > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:4914 > > Committed: https://crrev.com/0be8f1d347bdb171462df89c2a4c69b3f3eb7519 > Cr-Commit-Position: refs/heads/master@{#10578} TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,terelius@webrtc.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=webrtc:4914 Review URL: https://codereview.webrtc.org/1431283002 Cr-Commit-Position: refs/heads/master@{#10581}
2015-11-10 07:17:23 -08:00
}
const uint8_t num_temporal_layers_;
const uint8_t num_spatial_layers_;
const bool l_field_;
} test(num_temporal_layers, num_spatial_layers);
Reland of Work on flexible mode and screen sharing. (patchset #1 id:1 of https://codereview.webrtc.org/1438543002/ ) Reason for revert: Failed test not related to this CL (test fails on master at an earlier date), re-landing original CL.. (This time from my @webrtc account.) Original issue's description: > Revert of Work on flexible mode and screen sharing. (patchset #28 id:520001 of https://codereview.webrtc.org/1328113004/ ) > > Reason for revert: > Seems to break VideoSendStreamTest.ReconfigureBitratesSetsEncoderBitratesCorrectly on Linux Memcheck buildbot. > > Original issue's description: > > Work on flexible mode and screen sharing. > > > > Implement VP8 style screensharing but with spatial layers. > > Implement flexible mode. > > > > Files from other patches: > > generic_encoder.cc > > layer_filtering_transport.cc > > > > BUG=webrtc:4914 > > > > Committed: https://crrev.com/77ccfb4d16c148e61a316746bb5d9705e8b39f4a > > Cr-Commit-Position: refs/heads/master@{#10572} > > TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,philipel@webrtc.org > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:4914 > > Committed: https://crrev.com/0be8f1d347bdb171462df89c2a4c69b3f3eb7519 > Cr-Commit-Position: refs/heads/master@{#10578} TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,terelius@webrtc.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=webrtc:4914 Review URL: https://codereview.webrtc.org/1431283002 Cr-Commit-Position: refs/heads/master@{#10581}
2015-11-10 07:17:23 -08:00
RunBaseTest(&test);
Reland of Work on flexible mode and screen sharing. (patchset #1 id:1 of https://codereview.webrtc.org/1438543002/ ) Reason for revert: Failed test not related to this CL (test fails on master at an earlier date), re-landing original CL.. (This time from my @webrtc account.) Original issue's description: > Revert of Work on flexible mode and screen sharing. (patchset #28 id:520001 of https://codereview.webrtc.org/1328113004/ ) > > Reason for revert: > Seems to break VideoSendStreamTest.ReconfigureBitratesSetsEncoderBitratesCorrectly on Linux Memcheck buildbot. > > Original issue's description: > > Work on flexible mode and screen sharing. > > > > Implement VP8 style screensharing but with spatial layers. > > Implement flexible mode. > > > > Files from other patches: > > generic_encoder.cc > > layer_filtering_transport.cc > > > > BUG=webrtc:4914 > > > > Committed: https://crrev.com/77ccfb4d16c148e61a316746bb5d9705e8b39f4a > > Cr-Commit-Position: refs/heads/master@{#10572} > > TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,philipel@webrtc.org > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:4914 > > Committed: https://crrev.com/0be8f1d347bdb171462df89c2a4c69b3f3eb7519 > Cr-Commit-Position: refs/heads/master@{#10578} TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,terelius@webrtc.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=webrtc:4914 Review URL: https://codereview.webrtc.org/1431283002 Cr-Commit-Position: refs/heads/master@{#10581}
2015-11-10 07:17:23 -08:00
}
TEST_F(VideoSendStreamTest, Vp9NonFlexModeSmallResolution) {
static const size_t kNumFramesToSend = 50;
static const int kWidth = 4;
static const int kHeight = 4;
class NonFlexibleModeResolution : public Vp9HeaderObserver {
void ModifyVideoConfigsHook(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) override {
vp9_settings_.flexibleMode = false;
vp9_settings_.numberOfTemporalLayers = 1;
vp9_settings_.numberOfSpatialLayers = 1;
EXPECT_EQ(1u, encoder_config->number_of_streams);
}
void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
if (frames_sent_ > kNumFramesToSend)
observation_complete_.Set();
}
void ModifyVideoCaptureStartResolution(int* width,
int* height,
int* frame_rate) override {
expected_width_ = kWidth;
expected_height_ = kHeight;
*width = kWidth;
*height = kHeight;
}
} test;
RunBaseTest(&test);
}
Roll chromium_revision 22b81f6c45..d604de96c9 (459032:459307) MB changes were needed due to https://codereview.chromium.org/2767833002 FullStackTest.ScreenshareSlidesVP9_2SL test was disabled due to libvpx regression, see webrtc:7401. Roll chromium_revision 22b81f6c45..d604de96c9 (459032:459307) Change log: https://chromium.googlesource.com/chromium/src/+log/22b81f6c45..d604de96c9 Full diff: https://chromium.googlesource.com/chromium/src/+/22b81f6c45..d604de96c9 Changed dependencies: * src/base: https://chromium.googlesource.com/chromium/src/base/+log/258342709c..d49079a0cb * src/build: https://chromium.googlesource.com/chromium/src/build/+log/4a2354d6ce..a18678dc18 * src/ios: https://chromium.googlesource.com/chromium/src/ios/+log/f825ec1419..4afbbbaa88 * src/testing: https://chromium.googlesource.com/chromium/src/testing/+log/83a00745ef..7a028befe4 * src/third_party: https://chromium.googlesource.com/chromium/src/third_party/+log/5c1951e265..5903b09f59 * src/third_party/catapult: https://chromium.googlesource.com/external/github.com/catapult-project/catapult.git/+log/1b6a20ab7e..5c300b0898 * src/third_party/ffmpeg: https://chromium.googlesource.com/chromium/third_party/ffmpeg.git/+log/b9acb5c51e..6d2e444456 * src/third_party/libvpx/source/libvpx: https://chromium.googlesource.com/webm/libvpx.git/+log/8121f85473..2fac50fa0e * src/tools: https://chromium.googlesource.com/chromium/src/tools/+log/a4f9a9e9e9..3a6ca3a28a DEPS diff: https://chromium.googlesource.com/chromium/src/+/22b81f6c45..d604de96c9/DEPS No update to Clang. TBR=marpan@webrtc.org, BUG=webrtc:7401 Review-Url: https://codereview.webrtc.org/2777553002 Cr-Commit-Position: refs/heads/master@{#17376}
2017-03-24 12:17:33 -07:00
#if defined(WEBRTC_ANDROID)
// Crashes on Android; bugs.webrtc.org/7401
#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
#else
#define MAYBE_Vp9FlexModeRefCount Vp9FlexModeRefCount
#endif
TEST_F(VideoSendStreamTest, MAYBE_Vp9FlexModeRefCount) {
class FlexibleMode : public Vp9HeaderObserver {
void ModifyVideoConfigsHook(
Reland of Work on flexible mode and screen sharing. (patchset #1 id:1 of https://codereview.webrtc.org/1438543002/ ) Reason for revert: Failed test not related to this CL (test fails on master at an earlier date), re-landing original CL.. (This time from my @webrtc account.) Original issue's description: > Revert of Work on flexible mode and screen sharing. (patchset #28 id:520001 of https://codereview.webrtc.org/1328113004/ ) > > Reason for revert: > Seems to break VideoSendStreamTest.ReconfigureBitratesSetsEncoderBitratesCorrectly on Linux Memcheck buildbot. > > Original issue's description: > > Work on flexible mode and screen sharing. > > > > Implement VP8 style screensharing but with spatial layers. > > Implement flexible mode. > > > > Files from other patches: > > generic_encoder.cc > > layer_filtering_transport.cc > > > > BUG=webrtc:4914 > > > > Committed: https://crrev.com/77ccfb4d16c148e61a316746bb5d9705e8b39f4a > > Cr-Commit-Position: refs/heads/master@{#10572} > > TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,philipel@webrtc.org > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:4914 > > Committed: https://crrev.com/0be8f1d347bdb171462df89c2a4c69b3f3eb7519 > Cr-Commit-Position: refs/heads/master@{#10578} TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,terelius@webrtc.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=webrtc:4914 Review URL: https://codereview.webrtc.org/1431283002 Cr-Commit-Position: refs/heads/master@{#10581}
2015-11-10 07:17:23 -08:00
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) override {
encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
Reland of Work on flexible mode and screen sharing. (patchset #1 id:1 of https://codereview.webrtc.org/1438543002/ ) Reason for revert: Failed test not related to this CL (test fails on master at an earlier date), re-landing original CL.. (This time from my @webrtc account.) Original issue's description: > Revert of Work on flexible mode and screen sharing. (patchset #28 id:520001 of https://codereview.webrtc.org/1328113004/ ) > > Reason for revert: > Seems to break VideoSendStreamTest.ReconfigureBitratesSetsEncoderBitratesCorrectly on Linux Memcheck buildbot. > > Original issue's description: > > Work on flexible mode and screen sharing. > > > > Implement VP8 style screensharing but with spatial layers. > > Implement flexible mode. > > > > Files from other patches: > > generic_encoder.cc > > layer_filtering_transport.cc > > > > BUG=webrtc:4914 > > > > Committed: https://crrev.com/77ccfb4d16c148e61a316746bb5d9705e8b39f4a > > Cr-Commit-Position: refs/heads/master@{#10572} > > TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,philipel@webrtc.org > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:4914 > > Committed: https://crrev.com/0be8f1d347bdb171462df89c2a4c69b3f3eb7519 > Cr-Commit-Position: refs/heads/master@{#10578} TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,terelius@webrtc.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=webrtc:4914 Review URL: https://codereview.webrtc.org/1431283002 Cr-Commit-Position: refs/heads/master@{#10581}
2015-11-10 07:17:23 -08:00
vp9_settings_.flexibleMode = true;
vp9_settings_.numberOfTemporalLayers = 1;
vp9_settings_.numberOfSpatialLayers = 2;
Reland of Work on flexible mode and screen sharing. (patchset #1 id:1 of https://codereview.webrtc.org/1438543002/ ) Reason for revert: Failed test not related to this CL (test fails on master at an earlier date), re-landing original CL.. (This time from my @webrtc account.) Original issue's description: > Revert of Work on flexible mode and screen sharing. (patchset #28 id:520001 of https://codereview.webrtc.org/1328113004/ ) > > Reason for revert: > Seems to break VideoSendStreamTest.ReconfigureBitratesSetsEncoderBitratesCorrectly on Linux Memcheck buildbot. > > Original issue's description: > > Work on flexible mode and screen sharing. > > > > Implement VP8 style screensharing but with spatial layers. > > Implement flexible mode. > > > > Files from other patches: > > generic_encoder.cc > > layer_filtering_transport.cc > > > > BUG=webrtc:4914 > > > > Committed: https://crrev.com/77ccfb4d16c148e61a316746bb5d9705e8b39f4a > > Cr-Commit-Position: refs/heads/master@{#10572} > > TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,philipel@webrtc.org > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:4914 > > Committed: https://crrev.com/0be8f1d347bdb171462df89c2a4c69b3f3eb7519 > Cr-Commit-Position: refs/heads/master@{#10578} TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,terelius@webrtc.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=webrtc:4914 Review URL: https://codereview.webrtc.org/1431283002 Cr-Commit-Position: refs/heads/master@{#10581}
2015-11-10 07:17:23 -08:00
}
void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
EXPECT_TRUE(vp9_header.flexible_mode);
EXPECT_EQ(kNoTl0PicIdx, vp9_header.tl0_pic_idx);
if (vp9_header.inter_pic_predicted) {
EXPECT_GT(vp9_header.num_ref_pics, 0u);
observation_complete_.Set();
Reland of Work on flexible mode and screen sharing. (patchset #1 id:1 of https://codereview.webrtc.org/1438543002/ ) Reason for revert: Failed test not related to this CL (test fails on master at an earlier date), re-landing original CL.. (This time from my @webrtc account.) Original issue's description: > Revert of Work on flexible mode and screen sharing. (patchset #28 id:520001 of https://codereview.webrtc.org/1328113004/ ) > > Reason for revert: > Seems to break VideoSendStreamTest.ReconfigureBitratesSetsEncoderBitratesCorrectly on Linux Memcheck buildbot. > > Original issue's description: > > Work on flexible mode and screen sharing. > > > > Implement VP8 style screensharing but with spatial layers. > > Implement flexible mode. > > > > Files from other patches: > > generic_encoder.cc > > layer_filtering_transport.cc > > > > BUG=webrtc:4914 > > > > Committed: https://crrev.com/77ccfb4d16c148e61a316746bb5d9705e8b39f4a > > Cr-Commit-Position: refs/heads/master@{#10572} > > TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,philipel@webrtc.org > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:4914 > > Committed: https://crrev.com/0be8f1d347bdb171462df89c2a4c69b3f3eb7519 > Cr-Commit-Position: refs/heads/master@{#10578} TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,terelius@webrtc.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=webrtc:4914 Review URL: https://codereview.webrtc.org/1431283002 Cr-Commit-Position: refs/heads/master@{#10581}
2015-11-10 07:17:23 -08:00
}
}
} test;
RunBaseTest(&test);
}
#endif // !defined(RTC_DISABLE_VP9)
void VideoSendStreamTest::TestRequestSourceRotateVideo(
bool support_orientation_ext) {
CreateSenderCall(Call::Config(event_log_.get()));
test::NullTransport transport;
CreateSendConfig(1, 0, 0, &transport);
video_send_config_.rtp.extensions.clear();
if (support_orientation_ext) {
video_send_config_.rtp.extensions.push_back(
RtpExtension(RtpExtension::kVideoRotationUri, 1));
}
CreateVideoStreams();
test::FrameForwarder forwarder;
video_send_stream_->SetSource(
Reland of Add framerate to VideoSinkWants and ability to signal on overuse (patchset #1 id:1 of https://codereview.webrtc.org/2783183003/ ) Reason for revert: Seem to be a flaky test rather than an issue with this cl. Creating reland, will add code to reduce flakiness to that test. Original issue's description: > Revert of Add framerate to VideoSinkWants and ability to signal on overuse (patchset #8 id:410001 of https://codereview.webrtc.org/2781433002/ ) > > Reason for revert: > This has resulted in failure of CallPerfTest.ReceivesCpuOveruseAndUnderuse test on the Win7 build bot https://build.chromium.org/p/client.webrtc.perf/builders/Win7/builds/1780 > > Original issue's description: > > Reland of Add framerate to VideoSinkWants and ability to signal on overuse (patchset #1 id:1 of https://codereview.webrtc.org/2764133002/ ) > > > > Reason for revert: > > Found issue with test case, will add fix to reland cl. > > > > Original issue's description: > > > Revert of Add framerate to VideoSinkWants and ability to signal on overuse (patchset #14 id:250001 of https://codereview.webrtc.org/2716643002/ ) > > > > > > Reason for revert: > > > Breaks perf tests: > > > https://build.chromium.org/p/client.webrtc.perf/builders/Win7/builds/1679 > > > https://build.chromium.org/p/client.webrtc.perf/builders/Android32%20Tests%20%28L%20Nexus5%29/builds/2325 > > > > > > Original issue's description: > > > > Add framerate to VideoSinkWants and ability to signal on overuse > > > > > > > > In ViEEncoder, try to reduce framerate instead of resolution if the > > > > current degradation preference is maintain-resolution rather than > > > > balanced. > > > > > > > > BUG=webrtc:4172 > > > > > > > > Review-Url: https://codereview.webrtc.org/2716643002 > > > > Cr-Commit-Position: refs/heads/master@{#17327} > > > > Committed: https://chromium.googlesource.com/external/webrtc/+/72acf2526177bb4dbb5103cd6e165eb4361a5ae6 > > > > > > TBR=nisse@webrtc.org,magjed@webrtc.org,kthelgason@webrtc.org,ilnik@webrtc.org,stefan@webrtc.org,sprang@webrtc.org > > > # Skipping CQ checks because original CL landed less than 1 days ago. > > > NOPRESUBMIT=true > > > NOTREECHECKS=true > > > NOTRY=true > > > BUG=webrtc:4172 > > > > > > Review-Url: https://codereview.webrtc.org/2764133002 > > > Cr-Commit-Position: refs/heads/master@{#17331} > > > Committed: https://chromium.googlesource.com/external/webrtc/+/8b45b11144c968b4173215c76f78c710c9a2ed0b > > > > TBR=nisse@webrtc.org,magjed@webrtc.org,kthelgason@webrtc.org,ilnik@webrtc.org,stefan@webrtc.org,skvlad@webrtc.org > > # Not skipping CQ checks because original CL landed more than 1 days ago. > > BUG=webrtc:4172 > > > > Review-Url: https://codereview.webrtc.org/2781433002 > > Cr-Commit-Position: refs/heads/master@{#17474} > > Committed: https://chromium.googlesource.com/external/webrtc/+/3ea3c77e93121b1ab9d5e46641e6764f2cca0d51 > > TBR=ilnik@webrtc.org,stefan@webrtc.org,asapersson@webrtc.org,sprang@webrtc.org > # Skipping CQ checks because original CL landed less than 1 days ago. > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:4172 > > Review-Url: https://codereview.webrtc.org/2783183003 > Cr-Commit-Position: refs/heads/master@{#17477} > Committed: https://chromium.googlesource.com/external/webrtc/+/f9ed235c9b7248694edcb46feb1f29ce7456ab59 R=ilnik@webrtc.org,stefan@webrtc.org BUG=webrtc:4172 Review-Url: https://codereview.webrtc.org/2789823002 Cr-Commit-Position: refs/heads/master@{#17498}
2017-04-02 23:53:04 -07:00
&forwarder, VideoSendStream::DegradationPreference::kMaintainFramerate);
EXPECT_TRUE(forwarder.sink_wants().rotation_applied !=
support_orientation_ext);
DestroyStreams();
}
TEST_F(VideoSendStreamTest,
RequestSourceRotateIfVideoOrientationExtensionNotSupported) {
TestRequestSourceRotateVideo(false);
}
TEST_F(VideoSendStreamTest,
DoNotRequestsRotationIfVideoOrientationExtensionSupported) {
TestRequestSourceRotateVideo(true);
}
// This test verifies that overhead is removed from the bandwidth estimate by
// testing that the maximum possible target payload rate is smaller than the
// maximum bandwidth estimate by the overhead rate.
TEST_F(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
test::ScopedFieldTrials override_field_trials(
"WebRTC-SendSideBwe-WithOverhead/Enabled/");
class RemoveOverheadFromBandwidthTest : public test::EndToEndTest,
public test::FakeEncoder {
public:
explicit RemoveOverheadFromBandwidthTest(
test::SingleThreadedTaskQueueForTesting* task_queue)
: EndToEndTest(test::CallTest::kDefaultTimeoutMs),
FakeEncoder(Clock::GetRealTimeClock()),
task_queue_(task_queue),
call_(nullptr),
max_bitrate_bps_(0),
first_packet_sent_(false),
bitrate_changed_event_(false, false) {}
int32_t SetRateAllocation(const BitrateAllocation& bitrate,
uint32_t frameRate) override {
rtc::CritScope lock(&crit_);
// Wait for the first sent packet so that videosendstream knows
// rtp_overhead.
if (first_packet_sent_) {
max_bitrate_bps_ = bitrate.get_sum_bps();
bitrate_changed_event_.Set();
}
return FakeEncoder::SetRateAllocation(bitrate, frameRate);
}
void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
call_ = sender_call;
}
void ModifyVideoConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) override {
send_config->rtp.max_packet_size = 1200;
send_config->encoder_settings.encoder = this;
EXPECT_FALSE(send_config->rtp.extensions.empty());
}
Action OnSendRtp(const uint8_t* packet, size_t length) override {
rtc::CritScope lock(&crit_);
first_packet_sent_ = true;
return SEND_PACKET;
}
void PerformTest() override {
Call::Config::BitrateConfig bitrate_config;
constexpr int kStartBitrateBps = 60000;
constexpr int kMaxBitrateBps = 60000;
constexpr int kMinBitrateBps = 10000;
bitrate_config.start_bitrate_bps = kStartBitrateBps;
bitrate_config.max_bitrate_bps = kMaxBitrateBps;
bitrate_config.min_bitrate_bps = kMinBitrateBps;
task_queue_->SendTask([this, &bitrate_config]() {
call_->SetBitrateConfig(bitrate_config);
call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO, 40);
});
// At a bitrate of 60kbps with a packet size of 1200B video and an
// overhead of 40B per packet video produces 2240bps overhead.
// So the encoder BW should be set to 57760bps.
bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
{
rtc::CritScope lock(&crit_);
EXPECT_LE(max_bitrate_bps_, 57760u);
}
}
private:
test::SingleThreadedTaskQueueForTesting* const task_queue_;
Call* call_;
rtc::CriticalSection crit_;
uint32_t max_bitrate_bps_ RTC_GUARDED_BY(&crit_);
bool first_packet_sent_ RTC_GUARDED_BY(&crit_);
rtc::Event bitrate_changed_event_;
} test(&task_queue_);
RunBaseTest(&test);
}
TEST_F(VideoSendStreamTest, SendsKeepAlive) {
const int kTimeoutMs = 50; // Really short timeout for testing.
class KeepaliveObserver : public test::SendTest {
public:
KeepaliveObserver() : SendTest(kDefaultTimeoutMs) {}
void OnRtpTransportControllerSendCreated(
RtpTransportControllerSend* controller) override {
RtpKeepAliveConfig config;
config.timeout_interval_ms = kTimeoutMs;
config.payload_type = CallTest::kDefaultKeepalivePayloadType;
controller->SetKeepAliveConfig(config);
}
private:
Action OnSendRtp(const uint8_t* packet, size_t length) override {
RTPHeader header;
EXPECT_TRUE(parser_->Parse(packet, length, &header));
if (header.payloadType != CallTest::kDefaultKeepalivePayloadType) {
// The video stream has started. Stop it now.
if (capturer_)
capturer_->Stop();
} else {
observation_complete_.Set();
}
return SEND_PACKET;
}
void PerformTest() override {
EXPECT_TRUE(Wait()) << "Timed out while waiting for keep-alive packet.";
}
void OnFrameGeneratorCapturerCreated(
test::FrameGeneratorCapturer* frame_generator_capturer) override {
capturer_ = frame_generator_capturer;
}
test::FrameGeneratorCapturer* capturer_ = nullptr;
} test;
RunBaseTest(&test);
}
TEST_F(VideoSendStreamTest, ConfiguresAlrWhenSendSideOn) {
const std::string kAlrProbingExperiment =
std::string(AlrDetector::kScreenshareProbingBweExperimentName) +
"/1.1,2875,85,20,-20,0/";
test::ScopedFieldTrials alr_experiment(kAlrProbingExperiment);
class PacingFactorObserver : public test::SendTest {
public:
PacingFactorObserver(bool configure_send_side, float expected_pacing_factor)
: test::SendTest(kDefaultTimeoutMs),
configure_send_side_(configure_send_side),
expected_pacing_factor_(expected_pacing_factor),
paced_sender_(nullptr) {}
void ModifyVideoConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) override {
// Check if send-side bwe extension is already present, and remove it if
// it is not desired.
bool has_send_side = false;
for (auto it = send_config->rtp.extensions.begin();
it != send_config->rtp.extensions.end(); ++it) {
if (it->uri == RtpExtension::kTransportSequenceNumberUri) {
if (configure_send_side_) {
has_send_side = true;
} else {
send_config->rtp.extensions.erase(it);
}
break;
}
}
if (configure_send_side_ && !has_send_side) {
// Want send side, not present by default, so add it.
send_config->rtp.extensions.emplace_back(
RtpExtension::kTransportSequenceNumberUri,
RtpExtension::kTransportSequenceNumberDefaultId);
}
// ALR only enabled for screenshare.
encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
}
void OnRtpTransportControllerSendCreated(
RtpTransportControllerSend* controller) override {
// Grab a reference to the pacer.
paced_sender_ = controller->pacer();
}
void OnVideoStreamsCreated(
VideoSendStream* send_stream,
const std::vector<VideoReceiveStream*>& receive_streams) override {
// Video streams created, check that pacer is correctly configured.
EXPECT_EQ(expected_pacing_factor_, paced_sender_->GetPacingFactor());
observation_complete_.Set();
}
void PerformTest() override {
EXPECT_TRUE(Wait()) << "Timed out while waiting for pacer config.";
}
private:
const bool configure_send_side_;
const float expected_pacing_factor_;
const PacedSender* paced_sender_;
};
// Send-side bwe on, use pacing factor from |kAlrProbingExperiment| above.
PacingFactorObserver test_with_send_side(true, 1.1f);
RunBaseTest(&test_with_send_side);
// Send-side bwe off, use default pacing factor.
PacingFactorObserver test_without_send_side(
false, PacedSender::kDefaultPaceMultiplier);
RunBaseTest(&test_without_send_side);
}
} // namespace webrtc