webrtc_m130/test/fuzzers/utils/rtp_replayer.cc

212 lines
7.5 KiB
C++
Raw Normal View History

/*
* Copyright (c) 2019 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 "test/fuzzers/utils/rtp_replayer.h"
#include <algorithm>
Use std::make_unique instead of absl::make_unique. WebRTC is now using C++14 so there is no need to use the Abseil version of std::make_unique. This CL has been created with the following steps: git grep -l absl::make_unique | sort | uniq > /tmp/make_unique.txt git grep -l absl::WrapUnique | sort | uniq > /tmp/wrap_unique.txt git grep -l "#include <memory>" | sort | uniq > /tmp/memory.txt diff --new-line-format="" --unchanged-line-format="" \ /tmp/make_unique.txt /tmp/wrap_unique.txt | sort | \ uniq > /tmp/only_make_unique.txt diff --new-line-format="" --unchanged-line-format="" \ /tmp/only_make_unique.txt /tmp/memory.txt | \ xargs grep -l "absl/memory" > /tmp/add-memory.txt git grep -l "\babsl::make_unique\b" | \ xargs sed -i "s/\babsl::make_unique\b/std::make_unique/g" git checkout PRESUBMIT.py abseil-in-webrtc.md cat /tmp/add-memory.txt | \ xargs sed -i \ 's/#include "absl\/memory\/memory.h"/#include <memory>/g' git cl format # Manual fix order of the new inserted #include <memory> cat /tmp/only_make_unique | xargs grep -l "#include <memory>" | \ xargs sed -i '/#include "absl\/memory\/memory.h"/d' git ls-files | grep BUILD.gn | \ xargs sed -i '/\/\/third_party\/abseil-cpp\/absl\/memory/d' python tools_webrtc/gn_check_autofix.py \ -m tryserver.webrtc -b linux_rel # Repead the gn_check_autofix step for other platforms git ls-files | grep BUILD.gn | \ xargs sed -i 's/absl\/memory:memory/absl\/memory/g' git cl format Bug: webrtc:10945 Change-Id: I3fe28ea80f4dd3ba3cf28effd151d5e1f19aff89 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/153221 Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org> Reviewed-by: Alessio Bazzica <alessiob@webrtc.org> Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> Cr-Commit-Position: refs/heads/master@{#29209}
2019-09-17 17:06:18 +02:00
#include <memory>
#include <string>
#include <utility>
#include "api/task_queue/default_task_queue_factory.h"
#include "api/transport/field_trial_based_config.h"
#include "rtc_base/strings/json.h"
#include "system_wrappers/include/clock.h"
#include "test/call_config_utils.h"
#include "test/encoder_settings.h"
#include "test/fake_decoder.h"
#include "test/rtp_file_reader.h"
#include "test/rtp_header_parser.h"
#include "test/run_loop.h"
namespace webrtc {
namespace test {
void RtpReplayer::Replay(const std::string& replay_config_filepath,
const uint8_t* rtp_dump_data,
size_t rtp_dump_size) {
Use std::make_unique instead of absl::make_unique. WebRTC is now using C++14 so there is no need to use the Abseil version of std::make_unique. This CL has been created with the following steps: git grep -l absl::make_unique | sort | uniq > /tmp/make_unique.txt git grep -l absl::WrapUnique | sort | uniq > /tmp/wrap_unique.txt git grep -l "#include <memory>" | sort | uniq > /tmp/memory.txt diff --new-line-format="" --unchanged-line-format="" \ /tmp/make_unique.txt /tmp/wrap_unique.txt | sort | \ uniq > /tmp/only_make_unique.txt diff --new-line-format="" --unchanged-line-format="" \ /tmp/only_make_unique.txt /tmp/memory.txt | \ xargs grep -l "absl/memory" > /tmp/add-memory.txt git grep -l "\babsl::make_unique\b" | \ xargs sed -i "s/\babsl::make_unique\b/std::make_unique/g" git checkout PRESUBMIT.py abseil-in-webrtc.md cat /tmp/add-memory.txt | \ xargs sed -i \ 's/#include "absl\/memory\/memory.h"/#include <memory>/g' git cl format # Manual fix order of the new inserted #include <memory> cat /tmp/only_make_unique | xargs grep -l "#include <memory>" | \ xargs sed -i '/#include "absl\/memory\/memory.h"/d' git ls-files | grep BUILD.gn | \ xargs sed -i '/\/\/third_party\/abseil-cpp\/absl\/memory/d' python tools_webrtc/gn_check_autofix.py \ -m tryserver.webrtc -b linux_rel # Repead the gn_check_autofix step for other platforms git ls-files | grep BUILD.gn | \ xargs sed -i 's/absl\/memory:memory/absl\/memory/g' git cl format Bug: webrtc:10945 Change-Id: I3fe28ea80f4dd3ba3cf28effd151d5e1f19aff89 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/153221 Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org> Reviewed-by: Alessio Bazzica <alessiob@webrtc.org> Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> Cr-Commit-Position: refs/heads/master@{#29209}
2019-09-17 17:06:18 +02:00
auto stream_state = std::make_unique<StreamState>();
std::vector<VideoReceiveStream::Config> receive_stream_configs =
ReadConfigFromFile(replay_config_filepath, &(stream_state->transport));
return Replay(std::move(stream_state), std::move(receive_stream_configs),
rtp_dump_data, rtp_dump_size);
}
void RtpReplayer::Replay(
std::unique_ptr<StreamState> stream_state,
std::vector<VideoReceiveStream::Config> receive_stream_configs,
const uint8_t* rtp_dump_data,
size_t rtp_dump_size) {
RunLoop loop;
rtc::ScopedBaseFakeClock fake_clock;
// Work around: webrtc calls webrtc::Random(clock.TimeInMicroseconds())
// everywhere and Random expects non-zero seed. Let's set the clock non-zero
// to make them happy.
Use newer version of TimeDelta and TimeStamp factories in webrtc find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/TimeDelta::Micros<\(.*\)>()/TimeDelta::Micros(\1)/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/TimeDelta::Millis<\(.*\)>()/TimeDelta::Millis(\1)/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/TimeDelta::Seconds<\(.*\)>()/TimeDelta::Seconds(\1)/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/TimeDelta::us/TimeDelta::Micros/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/TimeDelta::ms/TimeDelta::Millis/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/TimeDelta::seconds/TimeDelta::Seconds/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/Timestamp::Micros<\(.*\)>()/Timestamp::Micros(\1)/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/Timestamp::Millis<\(.*\)>()/Timestamp::Millis(\1)/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/Timestamp::Seconds<\(.*\)>()/Timestamp::Seconds(\1)/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/Timestamp::us/Timestamp::Micros/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/Timestamp::ms/Timestamp::Millis/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/Timestamp::seconds/Timestamp::Seconds/g" git cl format Bug: None Change-Id: I87469d2e4a38369654da839ab7c838215a7911e7 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168402 Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> Commit-Queue: Danil Chapovalov <danilchap@webrtc.org> Cr-Commit-Position: refs/heads/master@{#30491}
2020-02-10 11:16:00 +01:00
fake_clock.SetTime(webrtc::Timestamp::Millis(1));
// Attempt to create an RtpReader from the input file.
auto rtp_reader = CreateRtpReader(rtp_dump_data, rtp_dump_size);
if (rtp_reader == nullptr) {
RTC_LOG(LS_ERROR) << "Failed to create the rtp_reader";
return;
}
// Setup the video streams based on the configuration.
webrtc::RtcEventLogNull event_log;
std::unique_ptr<TaskQueueFactory> task_queue_factory =
CreateDefaultTaskQueueFactory();
Call::Config call_config(&event_log);
call_config.task_queue_factory = task_queue_factory.get();
FieldTrialBasedConfig field_trials;
call_config.trials = &field_trials;
std::unique_ptr<Call> call(Call::Create(call_config));
SetupVideoStreams(&receive_stream_configs, stream_state.get(), call.get());
// Start replaying the provided stream now that it has been configured.
for (const auto& receive_stream : stream_state->receive_streams) {
receive_stream->Start();
}
ReplayPackets(&fake_clock, call.get(), rtp_reader.get());
for (const auto& receive_stream : stream_state->receive_streams) {
call->DestroyVideoReceiveStream(receive_stream);
}
}
std::vector<VideoReceiveStream::Config> RtpReplayer::ReadConfigFromFile(
const std::string& replay_config,
Transport* transport) {
Json::Reader json_reader;
Json::Value json_configs;
if (!json_reader.parse(replay_config, json_configs)) {
RTC_LOG(LS_ERROR)
<< "Error parsing JSON replay configuration for the fuzzer"
<< json_reader.getFormatedErrorMessages();
return {};
}
std::vector<VideoReceiveStream::Config> receive_stream_configs;
receive_stream_configs.reserve(json_configs.size());
for (const auto& json : json_configs) {
receive_stream_configs.push_back(
ParseVideoReceiveStreamJsonConfig(transport, json));
}
return receive_stream_configs;
}
void RtpReplayer::SetupVideoStreams(
std::vector<VideoReceiveStream::Config>* receive_stream_configs,
StreamState* stream_state,
Call* call) {
Use std::make_unique instead of absl::make_unique. WebRTC is now using C++14 so there is no need to use the Abseil version of std::make_unique. This CL has been created with the following steps: git grep -l absl::make_unique | sort | uniq > /tmp/make_unique.txt git grep -l absl::WrapUnique | sort | uniq > /tmp/wrap_unique.txt git grep -l "#include <memory>" | sort | uniq > /tmp/memory.txt diff --new-line-format="" --unchanged-line-format="" \ /tmp/make_unique.txt /tmp/wrap_unique.txt | sort | \ uniq > /tmp/only_make_unique.txt diff --new-line-format="" --unchanged-line-format="" \ /tmp/only_make_unique.txt /tmp/memory.txt | \ xargs grep -l "absl/memory" > /tmp/add-memory.txt git grep -l "\babsl::make_unique\b" | \ xargs sed -i "s/\babsl::make_unique\b/std::make_unique/g" git checkout PRESUBMIT.py abseil-in-webrtc.md cat /tmp/add-memory.txt | \ xargs sed -i \ 's/#include "absl\/memory\/memory.h"/#include <memory>/g' git cl format # Manual fix order of the new inserted #include <memory> cat /tmp/only_make_unique | xargs grep -l "#include <memory>" | \ xargs sed -i '/#include "absl\/memory\/memory.h"/d' git ls-files | grep BUILD.gn | \ xargs sed -i '/\/\/third_party\/abseil-cpp\/absl\/memory/d' python tools_webrtc/gn_check_autofix.py \ -m tryserver.webrtc -b linux_rel # Repead the gn_check_autofix step for other platforms git ls-files | grep BUILD.gn | \ xargs sed -i 's/absl\/memory:memory/absl\/memory/g' git cl format Bug: webrtc:10945 Change-Id: I3fe28ea80f4dd3ba3cf28effd151d5e1f19aff89 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/153221 Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org> Reviewed-by: Alessio Bazzica <alessiob@webrtc.org> Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> Cr-Commit-Position: refs/heads/master@{#29209}
2019-09-17 17:06:18 +02:00
stream_state->decoder_factory = std::make_unique<InternalDecoderFactory>();
for (auto& receive_config : *receive_stream_configs) {
// Attach the decoder for the corresponding payload type in the config.
for (auto& decoder : receive_config.decoders) {
decoder = test::CreateMatchingDecoder(decoder.payload_type,
decoder.video_format.name);
}
// Create the window to display the rendered video.
stream_state->sinks.emplace_back(
test::VideoRenderer::Create("Fuzzing WebRTC Video Config", 640, 480));
// Create a receive stream for this config.
receive_config.renderer = stream_state->sinks.back().get();
Reland "Moved VideoReceiveStream::Decoder::decoder_factory to VideoReceiveStream::Config::decoder_factory." This reverts commit a4f23ad0ce4382e3a11bc6a8c1f9f6183e722fd8. Reason for revert: Downstream fix landed. TBR=mflodman@webrtc.org Original change's description: > Revert "Moved VideoReceiveStream::Decoder::decoder_factory to VideoReceiveStream::Config::decoder_factory." > > This reverts commit acb9d8365a5f9eb1e2a9e9902690d62dab1e5759. > > Reason for revert: Break downstream stuff. > > Original change's description: > > Moved VideoReceiveStream::Decoder::decoder_factory to VideoReceiveStream::Config::decoder_factory. > > > > Bug: webrtc:9106 > > Change-Id: I85712f3ab6a734d3fad7819491d3b8e3388b47e7 > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/180342 > > Reviewed-by: Niels Moller <nisse@webrtc.org> > > Reviewed-by: Magnus Flodman <mflodman@webrtc.org> > > Commit-Queue: Philip Eliasson <philipel@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#31834} > > TBR=nisse@webrtc.org,philipel@webrtc.org,mflodman@webrtc.org > > Change-Id: I6cfdb85a154a78135839f84edf5f69673d5ab715 > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Bug: webrtc:9106 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/180807 > Reviewed-by: Philip Eliasson <philipel@webrtc.org> > Commit-Queue: Philip Eliasson <philipel@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#31835} TBR=nisse@webrtc.org,philipel@webrtc.org,mflodman@webrtc.org # Not skipping CQ checks because this is a reland. Bug: webrtc:9106 Change-Id: I03b3e68532107bec37bcc6e47a5489c84fe91ef9 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/180808 Commit-Queue: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31866}
2020-08-03 15:55:10 +00:00
receive_config.decoder_factory = stream_state->decoder_factory.get();
stream_state->receive_streams.emplace_back(
call->CreateVideoReceiveStream(std::move(receive_config)));
}
}
std::unique_ptr<test::RtpFileReader> RtpReplayer::CreateRtpReader(
const uint8_t* rtp_dump_data,
size_t rtp_dump_size) {
std::unique_ptr<test::RtpFileReader> rtp_reader(test::RtpFileReader::Create(
test::RtpFileReader::kRtpDump, rtp_dump_data, rtp_dump_size, {}));
if (!rtp_reader) {
RTC_LOG(LS_ERROR) << "Unable to open input file with any supported format";
return nullptr;
}
return rtp_reader;
}
void RtpReplayer::ReplayPackets(rtc::FakeClock* clock,
Call* call,
test::RtpFileReader* rtp_reader) {
int64_t replay_start_ms = -1;
int num_packets = 0;
std::map<uint32_t, int> unknown_packets;
while (true) {
int64_t now_ms = rtc::TimeMillis();
if (replay_start_ms == -1) {
replay_start_ms = now_ms;
}
test::RtpPacket packet;
if (!rtp_reader->NextPacket(&packet)) {
break;
}
int64_t deliver_in_ms = replay_start_ms + packet.time_ms - now_ms;
if (deliver_in_ms > 0) {
// StatsCounter::ReportMetricToAggregatedCounter is O(elapsed time).
// Set an upper limit to prevent waste time.
Use newer version of TimeDelta and TimeStamp factories in webrtc find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/TimeDelta::Micros<\(.*\)>()/TimeDelta::Micros(\1)/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/TimeDelta::Millis<\(.*\)>()/TimeDelta::Millis(\1)/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/TimeDelta::Seconds<\(.*\)>()/TimeDelta::Seconds(\1)/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/TimeDelta::us/TimeDelta::Micros/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/TimeDelta::ms/TimeDelta::Millis/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/TimeDelta::seconds/TimeDelta::Seconds/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/Timestamp::Micros<\(.*\)>()/Timestamp::Micros(\1)/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/Timestamp::Millis<\(.*\)>()/Timestamp::Millis(\1)/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/Timestamp::Seconds<\(.*\)>()/Timestamp::Seconds(\1)/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/Timestamp::us/Timestamp::Micros/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/Timestamp::ms/Timestamp::Millis/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/Timestamp::seconds/Timestamp::Seconds/g" git cl format Bug: None Change-Id: I87469d2e4a38369654da839ab7c838215a7911e7 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168402 Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> Commit-Queue: Danil Chapovalov <danilchap@webrtc.org> Cr-Commit-Position: refs/heads/master@{#30491}
2020-02-10 11:16:00 +01:00
clock->AdvanceTime(webrtc::TimeDelta::Millis(
std::min(deliver_in_ms, static_cast<int64_t>(100))));
}
++num_packets;
switch (call->Receiver()->DeliverPacket(
webrtc::MediaType::VIDEO,
rtc::CopyOnWriteBuffer(packet.data, packet.length),
/* packet_time_us */ -1)) {
case PacketReceiver::DELIVERY_OK:
break;
case PacketReceiver::DELIVERY_UNKNOWN_SSRC: {
RTPHeader header;
std::unique_ptr<RtpHeaderParser> parser(
RtpHeaderParser::CreateForTest());
parser->Parse(packet.data, packet.length, &header);
if (unknown_packets[header.ssrc] == 0) {
RTC_LOG(LS_ERROR) << "Unknown SSRC: " << header.ssrc;
}
++unknown_packets[header.ssrc];
break;
}
case PacketReceiver::DELIVERY_PACKET_ERROR: {
RTC_LOG(LS_ERROR)
<< "Packet error, corrupt packets or incorrect setup?";
RTPHeader header;
std::unique_ptr<RtpHeaderParser> parser(
RtpHeaderParser::CreateForTest());
parser->Parse(packet.data, packet.length, &header);
RTC_LOG(LS_ERROR) << "Packet packet_length=" << packet.length
<< " payload_type=" << header.payloadType
<< " sequence_number=" << header.sequenceNumber
<< " time_stamp=" << header.timestamp
<< " ssrc=" << header.ssrc;
break;
}
}
}
RTC_LOG(LS_INFO) << "num_packets: " << num_packets;
for (const auto& unknown_packet : unknown_packets) {
RTC_LOG(LS_ERROR) << "Packets for unknown ssrc " << unknown_packet.first
<< ":" << unknown_packet.second;
}
}
} // namespace test
} // namespace webrtc