Move VideoStreamReceiver JSON configuration parser to test source_set.

This change moves the configuration parser that converts a JSON representation
of the VideoStreamReceiver::Config structure into a native object into the test
directory so that it can be shared with the new corpus_generator utility that is
being built. This rtc_source_set will have an additional utility function added
in a subsequent CL that will allow the generation of a VideoStreamSender::Config
from a given VideoStreamReceiver::Config and visa versa.

Bug: webrtc:10117
Change-Id: I3035826f799f8d1fcdeaa76997391f030c855a5c
Reviewed-on: https://webrtc-review.googlesource.com/c/116880
Reviewed-by: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Åsa Persson <asapersson@webrtc.org>
Commit-Queue: Benjamin Wright <benwright@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26252}
This commit is contained in:
Benjamin Wright 2019-01-11 10:48:42 -08:00 committed by Commit Bot
parent 4895b45703
commit 8efafdf84b
5 changed files with 123 additions and 63 deletions

View File

@ -874,3 +874,15 @@ if (!build_with_chromium && is_android) {
]
}
}
rtc_source_set("call_config_utils") {
sources = [
"call_config_utils.cc",
"call_config_utils.h",
]
deps = [
"../call:call_interfaces",
"../call:video_stream_api",
"../rtc_base:rtc_json",
]
}

72
test/call_config_utils.cc Normal file
View File

@ -0,0 +1,72 @@
/*
* 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/call_config_utils.h"
#include <string>
#include <vector>
namespace webrtc {
namespace test {
// Deserializes a JSON representation of the VideoReceiveStream::Config back
// into a valid object. This will not initialize the decoders or the renderer.
VideoReceiveStream::Config ParseVideoReceiveStreamJsonConfig(
webrtc::Transport* transport,
const Json::Value& json) {
auto receive_config = VideoReceiveStream::Config(transport);
for (const auto decoder_json : json["decoders"]) {
VideoReceiveStream::Decoder decoder;
decoder.video_format =
SdpVideoFormat(decoder_json["payload_name"].asString());
decoder.payload_type = decoder_json["payload_type"].asInt64();
for (const auto& params_json : decoder_json["codec_params"]) {
std::vector<std::string> members = params_json.getMemberNames();
RTC_CHECK_EQ(members.size(), 1);
decoder.video_format.parameters[members[0]] =
params_json[members[0]].asString();
}
receive_config.decoders.push_back(decoder);
}
receive_config.render_delay_ms = json["render_delay_ms"].asInt64();
receive_config.target_delay_ms = json["target_delay_ms"].asInt64();
receive_config.rtp.remote_ssrc = json["rtp"]["remote_ssrc"].asInt64();
receive_config.rtp.local_ssrc = json["rtp"]["local_ssrc"].asInt64();
receive_config.rtp.rtcp_mode =
json["rtp"]["rtcp_mode"].asString() == "RtcpMode::kCompound"
? RtcpMode::kCompound
: RtcpMode::kReducedSize;
receive_config.rtp.remb = json["rtp"]["remb"].asBool();
receive_config.rtp.transport_cc = json["rtp"]["transport_cc"].asBool();
receive_config.rtp.nack.rtp_history_ms =
json["rtp"]["nack"]["rtp_history_ms"].asInt64();
receive_config.rtp.ulpfec_payload_type =
json["rtp"]["ulpfec_payload_type"].asInt64();
receive_config.rtp.red_payload_type =
json["rtp"]["red_payload_type"].asInt64();
receive_config.rtp.rtx_ssrc = json["rtp"]["rtx_ssrc"].asInt64();
for (const auto& pl_json : json["rtp"]["rtx_payload_types"]) {
std::vector<std::string> members = pl_json.getMemberNames();
RTC_CHECK_EQ(members.size(), 1);
Json::Value rtx_payload_type = pl_json[members[0]];
receive_config.rtp.rtx_associated_payload_types[std::stoi(members[0])] =
rtx_payload_type.asInt64();
}
for (const auto& ext_json : json["rtp"]["extensions"]) {
receive_config.rtp.extensions.emplace_back(ext_json["uri"].asString(),
ext_json["id"].asInt64(),
ext_json["encrypt"].asBool());
}
return receive_config;
}
} // namespace test.
} // namespace webrtc.

29
test/call_config_utils.h Normal file
View File

@ -0,0 +1,29 @@
/*
* 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.
*/
#ifndef TEST_CALL_CONFIG_UTILS_H_
#define TEST_CALL_CONFIG_UTILS_H_
#include "call/video_receive_stream.h"
#include "rtc_base/strings/json.h"
namespace webrtc {
namespace test {
// Deserializes a JSON representation of the VideoReceiveStream::Config back
// into a valid object. This will not initialize the decoders or the renderer.
VideoReceiveStream::Config ParseVideoReceiveStreamJsonConfig(
webrtc::Transport* transport,
const Json::Value& json);
} // namespace test
} // namespace webrtc
#endif // TEST_CALL_CONFIG_UTILS_H_

View File

@ -408,7 +408,7 @@ if (rtc_include_tests) {
rtc_executable("video_replay") {
testonly = true
sources = [
"replay.cc",
"video_replay.cc",
]
deps = [
"../api/test/video:function_video_factory",
@ -422,6 +422,7 @@ if (rtc_include_tests) {
"../rtc_base:rtc_base_approved",
"../rtc_base:rtc_json",
"../system_wrappers",
"../test:call_config_utils",
"../test:fake_video_codecs",
"../test:rtp_test_utils",
"../test:run_test",

View File

@ -13,7 +13,6 @@
#include <fstream>
#include <map>
#include <memory>
#include <sstream>
#include "absl/memory/memory.h"
#include "api/test/video/function_video_decoder_factory.h"
@ -31,6 +30,7 @@
#include "rtc_base/time_utils.h"
#include "system_wrappers/include/clock.h"
#include "system_wrappers/include/sleep.h"
#include "test/call_config_utils.h"
#include "test/call_test.h"
#include "test/encoder_settings.h"
#include "test/fake_decoder.h"
@ -222,11 +222,11 @@ class DecoderBitstreamFileWriter : public test::FakeDecoder {
~DecoderBitstreamFileWriter() { fclose(file_); }
int32_t Decode(const EncodedImage& encoded_frame,
bool /* missing_frames */,
const CodecSpecificInfo* /* codec_specific_info */,
int64_t /* render_time_ms */) override {
if (fwrite(encoded_frame._buffer, 1, encoded_frame._length, file_)
< encoded_frame._length) {
bool /* missing_frames */,
const CodecSpecificInfo* /* codec_specific_info */,
int64_t /* render_time_ms */) override {
if (fwrite(encoded_frame._buffer, 1, encoded_frame._length, file_) <
encoded_frame._length) {
RTC_LOG_ERR(LS_ERROR) << "fwrite of encoded frame failed.";
return WEBRTC_VIDEO_CODEC_ERROR;
}
@ -237,60 +237,6 @@ class DecoderBitstreamFileWriter : public test::FakeDecoder {
FILE* file_;
};
// Deserializes a JSON representation of the VideoReceiveStream::Config back
// into a valid object. This will not initialize the decoders or the renderer.
class VideoReceiveStreamConfigDeserializer final {
public:
static VideoReceiveStream::Config Deserialize(webrtc::Transport* transport,
const Json::Value& json) {
auto receive_config = VideoReceiveStream::Config(transport);
for (const auto decoder_json : json["decoders"]) {
VideoReceiveStream::Decoder decoder;
decoder.video_format =
SdpVideoFormat(decoder_json["payload_name"].asString());
decoder.payload_type = decoder_json["payload_type"].asInt64();
for (const auto& params_json : decoder_json["codec_params"]) {
std::vector<std::string> members = params_json.getMemberNames();
RTC_CHECK_EQ(members.size(), 1);
decoder.video_format.parameters[members[0]] =
params_json[members[0]].asString();
}
receive_config.decoders.push_back(decoder);
}
receive_config.render_delay_ms = json["render_delay_ms"].asInt64();
receive_config.target_delay_ms = json["target_delay_ms"].asInt64();
receive_config.rtp.remote_ssrc = json["rtp"]["remote_ssrc"].asInt64();
receive_config.rtp.local_ssrc = json["rtp"]["local_ssrc"].asInt64();
receive_config.rtp.rtcp_mode =
json["rtp"]["rtcp_mode"].asString() == "RtcpMode::kCompound"
? RtcpMode::kCompound
: RtcpMode::kReducedSize;
receive_config.rtp.remb = json["rtp"]["remb"].asBool();
receive_config.rtp.transport_cc = json["rtp"]["transport_cc"].asBool();
receive_config.rtp.nack.rtp_history_ms =
json["rtp"]["nack"]["rtp_history_ms"].asInt64();
receive_config.rtp.ulpfec_payload_type =
json["rtp"]["ulpfec_payload_type"].asInt64();
receive_config.rtp.red_payload_type =
json["rtp"]["red_payload_type"].asInt64();
receive_config.rtp.rtx_ssrc = json["rtp"]["rtx_ssrc"].asInt64();
for (const auto& pl_json : json["rtp"]["rtx_payload_types"]) {
std::vector<std::string> members = pl_json.getMemberNames();
RTC_CHECK_EQ(members.size(), 1);
Json::Value rtx_payload_type = pl_json[members[0]];
receive_config.rtp.rtx_associated_payload_types[std::stoi(members[0])] =
rtx_payload_type.asInt64();
}
for (const auto& ext_json : json["rtp"]["extensions"]) {
receive_config.rtp.extensions.emplace_back(ext_json["uri"].asString(),
ext_json["id"].asInt64(),
ext_json["encrypt"].asBool());
}
return receive_config;
}
};
// The RtpReplayer is responsible for parsing the configuration provided by the
// user, setting up the windows, recieve streams and decoders and then replaying
// the provided RTP dump.
@ -361,8 +307,8 @@ class RtpReplayer final {
size_t config_count = 0;
for (const auto& json : json_configs) {
// Create the configuration and parse the JSON into the config.
auto receive_config = VideoReceiveStreamConfigDeserializer::Deserialize(
&(stream_state->transport), json);
auto receive_config =
ParseVideoReceiveStreamJsonConfig(&(stream_state->transport), json);
// Instantiate the underlying decoder.
for (auto& decoder : receive_config.decoders) {
decoder = test::CreateMatchingDecoder(decoder.payload_type,