Remove SetVideoLogging/SetAudioLogging from ChannelManager and down the stack.
BUG=webrtc:4690
Review URL: https://codereview.webrtc.org/1457653003
Cr-Commit-Position: refs/heads/master@{#10734}
diff --git a/talk/media/base/fakemediaengine.h b/talk/media/base/fakemediaengine.h
index 44499e4..6c97b4a 100644
--- a/talk/media/base/fakemediaengine.h
+++ b/talk/media/base/fakemediaengine.h
@@ -694,14 +694,8 @@
class FakeBaseEngine {
public:
FakeBaseEngine()
- : loglevel_(-1),
- options_changed_(false),
+ : options_changed_(false),
fail_create_channel_(false) {}
- void SetLogging(int level, const char* filter) {
- loglevel_ = level;
- logfilter_ = filter;
- }
-
void set_fail_create_channel(bool fail) { fail_create_channel_ = fail; }
const std::vector<RtpHeaderExtension>& rtp_header_extensions() const {
@@ -713,8 +707,6 @@
}
protected:
- int loglevel_;
- std::string logfilter_;
// Flag used by optionsmessagehandler_unittest for checking whether any
// relevant setting has been updated.
// TODO(thaloun): Replace with explicit checks of before & after values.
@@ -913,10 +905,6 @@
}
const std::string& audio_in_device() const { return voice_.in_device_; }
const std::string& audio_out_device() const { return voice_.out_device_; }
- int voice_loglevel() const { return voice_.loglevel_; }
- const std::string& voice_logfilter() const { return voice_.logfilter_; }
- int video_loglevel() const { return video_.loglevel_; }
- const std::string& video_logfilter() const { return video_.logfilter_; }
bool capture() const { return video_.capture_; }
bool options_changed() const {
return voice_.options_changed_ || video_.options_changed_;
diff --git a/talk/media/base/mediaengine.h b/talk/media/base/mediaengine.h
index 7411b87..a03f44c 100644
--- a/talk/media/base/mediaengine.h
+++ b/talk/media/base/mediaengine.h
@@ -115,10 +115,6 @@
virtual const std::vector<RtpHeaderExtension>&
video_rtp_header_extensions() = 0;
- // Logging control
- virtual void SetVoiceLogging(int min_sev, const char* filter) = 0;
- virtual void SetVideoLogging(int min_sev, const char* filter) = 0;
-
// Starts AEC dump using existing file.
virtual bool StartAecDump(rtc::PlatformFile file) = 0;
@@ -217,13 +213,6 @@
return video_.rtp_header_extensions();
}
- virtual void SetVoiceLogging(int min_sev, const char* filter) {
- voice_.SetLogging(min_sev, filter);
- }
- virtual void SetVideoLogging(int min_sev, const char* filter) {
- video_.SetLogging(min_sev, filter);
- }
-
virtual bool StartAecDump(rtc::PlatformFile file) {
return voice_.StartAecDump(file);
}
@@ -268,7 +257,6 @@
const std::vector<RtpHeaderExtension>& rtp_header_extensions() {
return rtp_header_extensions_;
}
- void SetLogging(int min_sev, const char* filter) {}
bool StartAecDump(rtc::PlatformFile file) { return false; }
bool StartRtcEventLog(rtc::PlatformFile file) { return false; }
void StopRtcEventLog() {}
@@ -298,7 +286,6 @@
const std::vector<RtpHeaderExtension>& rtp_header_extensions() {
return rtp_header_extensions_;
}
- void SetLogging(int min_sev, const char* filter) {}
private:
std::vector<VideoCodec> codecs_;
diff --git a/talk/media/webrtc/webrtcvideoengine2.cc b/talk/media/webrtc/webrtcvideoengine2.cc
index 0f1587d..1612183 100644
--- a/talk/media/webrtc/webrtcvideoengine2.cc
+++ b/talk/media/webrtc/webrtcvideoengine2.cc
@@ -620,16 +620,6 @@
return rtp_header_extensions_;
}
-void WebRtcVideoEngine2::SetLogging(int min_sev, const char* filter) {
- // TODO(pbos): Set up logging.
- LOG(LS_VERBOSE) << "SetLogging: " << min_sev << '"' << filter << '"';
- // if min_sev == -1, we keep the current log level.
- if (min_sev < 0) {
- RTC_DCHECK(min_sev == -1);
- return;
- }
-}
-
void WebRtcVideoEngine2::SetExternalDecoderFactory(
WebRtcVideoDecoderFactory* decoder_factory) {
RTC_DCHECK(!initialized_);
diff --git a/talk/media/webrtc/webrtcvideoengine2.h b/talk/media/webrtc/webrtcvideoengine2.h
index 05f73d1..24033a1 100644
--- a/talk/media/webrtc/webrtcvideoengine2.h
+++ b/talk/media/webrtc/webrtcvideoengine2.h
@@ -119,7 +119,6 @@
const std::vector<VideoCodec>& codecs() const;
const std::vector<RtpHeaderExtension>& rtp_header_extensions() const;
- void SetLogging(int min_sev, const char* filter);
// Set a WebRtcVideoDecoderFactory for external decoding. Video engine does
// not take the ownership of |decoder_factory|. The caller needs to make sure
diff --git a/talk/media/webrtc/webrtcvoe.h b/talk/media/webrtc/webrtcvoe.h
index db6a64a..1e104b4 100644
--- a/talk/media/webrtc/webrtcvoe.h
+++ b/talk/media/webrtc/webrtcvoe.h
@@ -136,23 +136,6 @@
scoped_voe_ptr<webrtc::VoERTP_RTCP> rtp_;
scoped_voe_ptr<webrtc::VoEVolumeControl> volume_;
};
-
-// Adds indirection to static WebRtc functions, allowing them to be mocked.
-class VoETraceWrapper {
- public:
- virtual ~VoETraceWrapper() {}
-
- virtual int SetTraceFilter(const unsigned int filter) {
- return webrtc::VoiceEngine::SetTraceFilter(filter);
- }
- virtual int SetTraceFile(const char* fileNameUTF8) {
- return webrtc::VoiceEngine::SetTraceFile(fileNameUTF8);
- }
- virtual int SetTraceCallback(webrtc::TraceCallback* callback) {
- return webrtc::VoiceEngine::SetTraceCallback(callback);
- }
-};
-
} // namespace cricket
#endif // TALK_MEDIA_WEBRTCVOE_H_
diff --git a/talk/media/webrtc/webrtcvoiceengine.cc b/talk/media/webrtc/webrtcvoiceengine.cc
index c81ecdf..721990a 100644
--- a/talk/media/webrtc/webrtcvoiceengine.cc
+++ b/talk/media/webrtc/webrtcvoiceengine.cc
@@ -55,10 +55,17 @@
#include "webrtc/common.h"
#include "webrtc/modules/audio_processing/include/audio_processing.h"
#include "webrtc/system_wrappers/include/field_trial.h"
+#include "webrtc/system_wrappers/include/trace.h"
namespace cricket {
namespace {
+const int kDefaultTraceFilter = webrtc::kTraceNone | webrtc::kTraceTerseInfo |
+ webrtc::kTraceWarning | webrtc::kTraceError |
+ webrtc::kTraceCritical;
+const int kElevatedTraceFilter = kDefaultTraceFilter | webrtc::kTraceStateInfo |
+ webrtc::kTraceInfo;
+
const int kMaxNumPacketSize = 6;
struct CodecPref {
const char* name;
@@ -185,25 +192,6 @@
}
}
-// Severity is an integer because it comes is assumed to be from command line.
-int SeverityToFilter(int severity) {
- int filter = webrtc::kTraceNone;
- switch (severity) {
- case rtc::LS_VERBOSE:
- filter |= webrtc::kTraceAll;
- FALLTHROUGH();
- case rtc::LS_INFO:
- filter |= (webrtc::kTraceStateInfo | webrtc::kTraceInfo);
- FALLTHROUGH();
- case rtc::LS_WARNING:
- filter |= (webrtc::kTraceTerseInfo | webrtc::kTraceWarning);
- FALLTHROUGH();
- case rtc::LS_ERROR:
- filter |= (webrtc::kTraceError | webrtc::kTraceCritical);
- }
- return filter;
-}
-
bool IsCodec(const AudioCodec& codec, const char* ref_name) {
return (_stricmp(codec.name.c_str(), ref_name) == 0);
}
@@ -386,10 +374,6 @@
return options;
}
-std::string GetEnableString(bool enable) {
- return enable ? "enable" : "disable";
-}
-
webrtc::AudioState::Config MakeAudioStateConfig(VoEWrapper* voe_wrapper) {
webrtc::AudioState::Config config;
config.voice_engine = voe_wrapper->engine();
@@ -413,30 +397,24 @@
WebRtcVoiceEngine::WebRtcVoiceEngine()
: voe_wrapper_(new VoEWrapper()),
- tracing_(new VoETraceWrapper()),
- audio_state_(webrtc::AudioState::Create(MakeAudioStateConfig(voe()))),
- log_filter_(SeverityToFilter(kDefaultLogSeverity)) {
+ audio_state_(webrtc::AudioState::Create(MakeAudioStateConfig(voe()))) {
Construct();
}
-WebRtcVoiceEngine::WebRtcVoiceEngine(VoEWrapper* voe_wrapper,
- VoETraceWrapper* tracing)
- : voe_wrapper_(voe_wrapper),
- tracing_(tracing),
- log_filter_(SeverityToFilter(kDefaultLogSeverity)) {
+WebRtcVoiceEngine::WebRtcVoiceEngine(VoEWrapper* voe_wrapper)
+ : voe_wrapper_(voe_wrapper) {
Construct();
}
void WebRtcVoiceEngine::Construct() {
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
+ LOG(LS_VERBOSE) << "WebRtcVoiceEngine::WebRtcVoiceEngine";
+
signal_thread_checker_.DetachFromThread();
std::memset(&default_agc_config_, 0, sizeof(default_agc_config_));
- SetTraceFilter(log_filter_);
- LOG(LS_VERBOSE) << "WebRtcVoiceEngine::WebRtcVoiceEngine";
- SetTraceOptions("");
- if (tracing_->SetTraceCallback(this) == -1) {
- LOG_RTCERR0(SetTraceCallback);
- }
+
+ webrtc::Trace::set_level_filter(kDefaultTraceFilter);
+ webrtc::Trace::SetTraceCallback(this);
// Load our audio codec list.
ConstructCodecs();
@@ -533,8 +511,7 @@
adm_->Release();
adm_ = NULL;
}
-
- tracing_->SetTraceCallback(NULL);
+ webrtc::Trace::SetTraceCallback(nullptr);
}
bool WebRtcVoiceEngine::Init(rtc::Thread* worker_thread) {
@@ -554,20 +531,12 @@
bool WebRtcVoiceEngine::InitInternal() {
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
// Temporarily turn logging level up for the Init call
- int old_filter = log_filter_;
- int extended_filter = log_filter_ | SeverityToFilter(rtc::LS_INFO);
- SetTraceFilter(extended_filter);
- SetTraceOptions("");
-
- // Init WebRtc VoiceEngine.
+ webrtc::Trace::set_level_filter(kElevatedTraceFilter);
if (voe_wrapper_->base()->Init(adm_) == -1) {
LOG_RTCERR0_EX(Init, voe_wrapper_->error());
- SetTraceFilter(old_filter);
return false;
}
-
- SetTraceFilter(old_filter);
- SetTraceOptions(log_options_);
+ webrtc::Trace::set_level_filter(kDefaultTraceFilter);
// Log the VoiceEngine version info
char buffer[1024] = "";
@@ -1142,78 +1111,11 @@
return rtp_header_extensions_;
}
-void WebRtcVoiceEngine::SetLogging(int min_sev, const char* filter) {
- RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
- // if min_sev == -1, we keep the current log level.
- if (min_sev >= 0) {
- SetTraceFilter(SeverityToFilter(min_sev));
- }
- log_options_ = filter;
- SetTraceOptions(initialized_ ? log_options_ : "");
-}
-
int WebRtcVoiceEngine::GetLastEngineError() {
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
return voe_wrapper_->error();
}
-void WebRtcVoiceEngine::SetTraceFilter(int filter) {
- RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
- log_filter_ = filter;
- tracing_->SetTraceFilter(filter);
-}
-
-// We suppport three different logging settings for VoiceEngine:
-// 1. Observer callback that goes into talk diagnostic logfile.
-// Use --logfile and --loglevel
-//
-// 2. Encrypted VoiceEngine log for debugging VoiceEngine.
-// Use --voice_loglevel --voice_logfilter "tracefile file_name"
-//
-// 3. EC log and dump for debugging QualityEngine.
-// Use --voice_loglevel --voice_logfilter "recordEC file_name"
-//
-// For more details see: "https://sites.google.com/a/google.com/wavelet/Home/
-// Magic-Flute--RTC-Engine-/Magic-Flute-Command-Line-Parameters"
-void WebRtcVoiceEngine::SetTraceOptions(const std::string& options) {
- RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
- // Set encrypted trace file.
- std::vector<std::string> opts;
- rtc::tokenize(options, ' ', '"', '"', &opts);
- std::vector<std::string>::iterator tracefile =
- std::find(opts.begin(), opts.end(), "tracefile");
- if (tracefile != opts.end() && ++tracefile != opts.end()) {
- // Write encrypted debug output (at same loglevel) to file
- // EncryptedTraceFile no longer supported.
- if (tracing_->SetTraceFile(tracefile->c_str()) == -1) {
- LOG_RTCERR1(SetTraceFile, *tracefile);
- }
- }
-
- // Allow trace options to override the trace filter. We default
- // it to log_filter_ (as a translation of libjingle log levels)
- // elsewhere, but this allows clients to explicitly set webrtc
- // log levels.
- std::vector<std::string>::iterator tracefilter =
- std::find(opts.begin(), opts.end(), "tracefilter");
- if (tracefilter != opts.end() && ++tracefilter != opts.end()) {
- if (!tracing_->SetTraceFilter(rtc::FromString<int>(*tracefilter))) {
- LOG_RTCERR1(SetTraceFilter, *tracefilter);
- }
- }
-
- // Set AEC dump file
- std::vector<std::string>::iterator recordEC =
- std::find(opts.begin(), opts.end(), "recordEC");
- if (recordEC != opts.end()) {
- ++recordEC;
- if (recordEC != opts.end())
- StartAecDump(recordEC->c_str());
- else
- StopAecDump();
- }
-}
-
void WebRtcVoiceEngine::Print(webrtc::TraceLevel level, const char* trace,
int length) {
// Note: This callback can happen on any thread!
@@ -1809,7 +1711,7 @@
// Set Opus internal DTX.
LOG(LS_INFO) << "Attempt to "
- << GetEnableString(enable_opus_dtx)
+ << (enable_opus_dtx ? "enable" : "disable")
<< " Opus DTX on channel "
<< channel;
if (engine()->voe()->codec()->SetOpusDtx(channel, enable_opus_dtx)) {
diff --git a/talk/media/webrtc/webrtcvoiceengine.h b/talk/media/webrtc/webrtcvoiceengine.h
index c26aa06..9c7f7bb 100644
--- a/talk/media/webrtc/webrtcvoiceengine.h
+++ b/talk/media/webrtc/webrtcvoiceengine.h
@@ -39,8 +39,6 @@
#include "talk/session/media/channel.h"
#include "webrtc/audio_state.h"
#include "webrtc/base/buffer.h"
-#include "webrtc/base/byteorder.h"
-#include "webrtc/base/logging.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/base/stream.h"
#include "webrtc/base/thread_checker.h"
@@ -52,7 +50,6 @@
class AudioDeviceModule;
class AudioRenderer;
-class VoETraceWrapper;
class VoEWrapper;
class WebRtcVoiceMediaChannel;
@@ -64,7 +61,7 @@
public:
WebRtcVoiceEngine();
// Dependency injection for testing.
- WebRtcVoiceEngine(VoEWrapper* voe_wrapper, VoETraceWrapper* tracing);
+ explicit WebRtcVoiceEngine(VoEWrapper* voe_wrapper);
~WebRtcVoiceEngine();
bool Init(rtc::Thread* worker_thread);
void Terminate();
@@ -86,8 +83,6 @@
const std::vector<RtpHeaderExtension>& rtp_header_extensions() const;
- void SetLogging(int min_sev, const char* filter);
-
// For tracking WebRtc channels. Needed because we have to pause them
// all when switching devices.
// May only be called by WebRtcVoiceMediaChannel.
@@ -122,8 +117,6 @@
void ConstructCodecs();
bool GetVoeCodec(int index, webrtc::CodecInst* codec);
bool InitInternal();
- void SetTraceFilter(int filter);
- void SetTraceOptions(const std::string& options);
// Every option that is "set" will be applied. Every option not "set" will be
// ignored. This allows us to selectively turn on and off different options
// easily at any time.
@@ -140,19 +133,14 @@
void StartAecDump(const std::string& filename);
int CreateVoEChannel();
- static const int kDefaultLogSeverity = rtc::LS_WARNING;
-
rtc::ThreadChecker signal_thread_checker_;
rtc::ThreadChecker worker_thread_checker_;
// The primary instance of WebRtc VoiceEngine.
rtc::scoped_ptr<VoEWrapper> voe_wrapper_;
- rtc::scoped_ptr<VoETraceWrapper> tracing_;
rtc::scoped_refptr<webrtc::AudioState> audio_state_;
// The external audio device manager
webrtc::AudioDeviceModule* adm_ = nullptr;
- int log_filter_;
- std::string log_options_;
bool is_dumping_aec_ = false;
std::vector<AudioCodec> codecs_;
std::vector<RtpHeaderExtension> rtp_header_extensions_;
diff --git a/talk/media/webrtc/webrtcvoiceengine_unittest.cc b/talk/media/webrtc/webrtcvoiceengine_unittest.cc
index 6309833..b52f6fc 100644
--- a/talk/media/webrtc/webrtcvoiceengine_unittest.cc
+++ b/talk/media/webrtc/webrtcvoiceengine_unittest.cc
@@ -75,17 +75,6 @@
engine) { // volume
}
};
-
-class FakeVoETraceWrapper : public cricket::VoETraceWrapper {
- public:
- int SetTraceFilter(const unsigned int filter) override {
- filter_ = filter;
- return 0;
- }
- int SetTraceFile(const char* fileNameUTF8) override { return 0; }
- int SetTraceCallback(webrtc::TraceCallback* callback) override { return 0; }
- unsigned int filter_;
-};
} // namespace
class WebRtcVoiceEngineTestFake : public testing::Test {
@@ -93,8 +82,7 @@
WebRtcVoiceEngineTestFake()
: call_(webrtc::Call::Config()),
voe_(kAudioCodecs, arraysize(kAudioCodecs)),
- trace_wrapper_(new FakeVoETraceWrapper()),
- engine_(new FakeVoEWrapper(&voe_), trace_wrapper_),
+ engine_(new FakeVoEWrapper(&voe_)),
channel_(nullptr) {
send_parameters_.codecs.push_back(kPcmuCodec);
recv_parameters_.codecs.push_back(kPcmuCodec);
@@ -417,7 +405,6 @@
protected:
cricket::FakeCall call_;
cricket::FakeWebRtcVoiceEngine voe_;
- FakeVoETraceWrapper* trace_wrapper_;
cricket::WebRtcVoiceEngine engine_;
cricket::VoiceMediaChannel* channel_;
@@ -2324,25 +2311,6 @@
EXPECT_EQ(44100u, playout_sample_rate);
}
-TEST_F(WebRtcVoiceEngineTestFake, TraceFilterViaTraceOptions) {
- EXPECT_TRUE(SetupEngineWithSendStream());
- engine_.SetLogging(rtc::LS_INFO, "");
- EXPECT_EQ(
- // Info:
- webrtc::kTraceStateInfo | webrtc::kTraceInfo |
- // Warning:
- webrtc::kTraceTerseInfo | webrtc::kTraceWarning |
- // Error:
- webrtc::kTraceError | webrtc::kTraceCritical,
- static_cast<int>(trace_wrapper_->filter_));
- // Now set it explicitly
- std::string filter =
- "tracefilter " + rtc::ToString(webrtc::kTraceDefault);
- engine_.SetLogging(rtc::LS_VERBOSE, filter.c_str());
- EXPECT_EQ(static_cast<unsigned int>(webrtc::kTraceDefault),
- trace_wrapper_->filter_);
-}
-
// Test that we can set the outgoing SSRC properly.
// SSRC is set in SetupEngine by calling AddSendStream.
TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
diff --git a/talk/session/media/channelmanager.cc b/talk/session/media/channelmanager.cc
index e7e1cd4..9a402f6 100644
--- a/talk/session/media/channelmanager.cc
+++ b/talk/session/media/channelmanager.cc
@@ -500,26 +500,6 @@
return ret;
}
-void ChannelManager::SetVoiceLogging(int level, const char* filter) {
- if (initialized_) {
- worker_thread_->Invoke<void>(
- Bind(&MediaEngineInterface::SetVoiceLogging,
- media_engine_.get(), level, filter));
- } else {
- media_engine_->SetVoiceLogging(level, filter);
- }
-}
-
-void ChannelManager::SetVideoLogging(int level, const char* filter) {
- if (initialized_) {
- worker_thread_->Invoke<void>(
- Bind(&MediaEngineInterface::SetVideoLogging,
- media_engine_.get(), level, filter));
- } else {
- media_engine_->SetVideoLogging(level, filter);
- }
-}
-
std::vector<cricket::VideoFormat> ChannelManager::GetSupportedFormats(
VideoCapturer* capturer) const {
ASSERT(capturer != NULL);
diff --git a/talk/session/media/channelmanager.h b/talk/session/media/channelmanager.h
index 6312e61..d333dea 100644
--- a/talk/session/media/channelmanager.h
+++ b/talk/session/media/channelmanager.h
@@ -137,10 +137,6 @@
// Starts/stops the local microphone and enables polling of the input level.
bool capturing() const { return capturing_; }
- // Configures the logging output of the mediaengine(s).
- void SetVoiceLogging(int level, const char* filter);
- void SetVideoLogging(int level, const char* filter);
-
// Gets capturer's supported formats in a thread safe manner
std::vector<cricket::VideoFormat> GetSupportedFormats(
VideoCapturer* capturer) const;
diff --git a/talk/session/media/channelmanager_unittest.cc b/talk/session/media/channelmanager_unittest.cc
index fa6aa2c..e8fb516 100644
--- a/talk/session/media/channelmanager_unittest.cc
+++ b/talk/session/media/channelmanager_unittest.cc
@@ -250,33 +250,6 @@
EXPECT_EQ(60, level);
}
-// Test that logging options set before Init are applied properly,
-// and retained even after Init.
-TEST_F(ChannelManagerTest, SetLoggingBeforeInit) {
- cm_->SetVoiceLogging(rtc::LS_INFO, "test-voice");
- cm_->SetVideoLogging(rtc::LS_VERBOSE, "test-video");
- EXPECT_EQ(rtc::LS_INFO, fme_->voice_loglevel());
- EXPECT_STREQ("test-voice", fme_->voice_logfilter().c_str());
- EXPECT_EQ(rtc::LS_VERBOSE, fme_->video_loglevel());
- EXPECT_STREQ("test-video", fme_->video_logfilter().c_str());
- EXPECT_TRUE(cm_->Init());
- EXPECT_EQ(rtc::LS_INFO, fme_->voice_loglevel());
- EXPECT_STREQ("test-voice", fme_->voice_logfilter().c_str());
- EXPECT_EQ(rtc::LS_VERBOSE, fme_->video_loglevel());
- EXPECT_STREQ("test-video", fme_->video_logfilter().c_str());
-}
-
-// Test that logging options set after Init are applied properly.
-TEST_F(ChannelManagerTest, SetLogging) {
- EXPECT_TRUE(cm_->Init());
- cm_->SetVoiceLogging(rtc::LS_INFO, "test-voice");
- cm_->SetVideoLogging(rtc::LS_VERBOSE, "test-video");
- EXPECT_EQ(rtc::LS_INFO, fme_->voice_loglevel());
- EXPECT_STREQ("test-voice", fme_->voice_logfilter().c_str());
- EXPECT_EQ(rtc::LS_VERBOSE, fme_->video_loglevel());
- EXPECT_STREQ("test-video", fme_->video_logfilter().c_str());
-}
-
TEST_F(ChannelManagerTest, SetVideoRtxEnabled) {
std::vector<VideoCodec> codecs;
const VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0);