Revert "Revert "Enables PeerConnectionFactory using external fec controller""

This reverts commit 00733015fa.

Reason for revert: The reason for a downstream test failure on the original commit and a workaround has been found. Solution is to keep a PeerConnectionFactory constructor implementation as the same as before.

Original change's description:
> Revert "Enables PeerConnectionFactory using external fec controller"
>
> This reverts commit 4f07bdb255.
>
> Reason for revert: Speculatively reverting, because downstream test is now hitting "PeerConnectionFactory.initialize was not called before creating a PeerConnectionFactory" error, even though it did call initialize. I don't see how any change in this CL could cause that, but it's the only CL on the blamelist, and it does modify PeerConnectionFactory.java
>
> Original change's description:
> > Enables PeerConnectionFactory using external fec controller
> >
> > Bug: webrtc:8799
> > Change-Id: Ieb2cf6163b9a83844ab9ed4822b4a7f1db4c24b8
> > Reviewed-on: https://webrtc-review.googlesource.com/43961
> > Commit-Queue: Ying Wang <yinwa@webrtc.org>
> > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
> > Reviewed-by: Niels Moller <nisse@webrtc.org>
> > Reviewed-by: Sami Kalliomäki <sakal@webrtc.org>
> > Cr-Commit-Position: refs/heads/master@{#22038}
>
> TBR=sakal@webrtc.org,kwiberg@webrtc.org,nisse@webrtc.org,stefan@webrtc.org,yinwa@webrtc.org
>
> Change-Id: I95868c35d6f9973e0ebf563814cd71d0fcbd433d
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: webrtc:8799
> Reviewed-on: https://webrtc-review.googlesource.com/54080
> Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org>
> Commit-Queue: Taylor Brandstetter <deadbeef@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#22040}

TBR=deadbeef@webrtc.org,sakal@webrtc.org,kwiberg@webrtc.org,nisse@webrtc.org,stefan@webrtc.org,yinwa@webrtc.org

Bug: webrtc:8799
Change-Id: If9f3292bfcc739782967530c49f006d0abbc38a8
Reviewed-on: https://webrtc-review.googlesource.com/55400
Commit-Queue: Ying Wang <yinwa@webrtc.org>
Reviewed-by: Ying Wang <yinwa@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22100}
This commit is contained in:
Ying Wang 2018-02-20 12:50:27 +01:00 committed by Commit Bot
parent 439f0bc69a
commit 0dd1b0a4b2
24 changed files with 314 additions and 97 deletions

View file

@ -101,6 +101,7 @@ rtc_static_library("libjingle_peerconnection_api") {
":array_view", ":array_view",
":audio_options_api", ":audio_options_api",
":callfactory_api", ":callfactory_api",
":fec_controller_api",
":libjingle_logging_api", ":libjingle_logging_api",
":optional", ":optional",
":rtc_stats_api", ":rtc_stats_api",
@ -211,8 +212,8 @@ rtc_source_set("fec_controller_api") {
] ]
deps = [ deps = [
"../common_video:common_video", "..:webrtc_common",
"../modules:module_api", "../modules:module_fec_api",
] ]
} }

View file

@ -11,10 +11,11 @@
#ifndef API_FEC_CONTROLLER_H_ #ifndef API_FEC_CONTROLLER_H_
#define API_FEC_CONTROLLER_H_ #define API_FEC_CONTROLLER_H_
#include <memory>
#include <vector> #include <vector>
#include "common_video/include/video_frame.h" #include "common_types.h" // NOLINT(build/include)
#include "modules/include/module_common_types.h" #include "modules/include/module_fec_types.h"
namespace webrtc { namespace webrtc {
// TODO(yinwa): work in progress. API in class FecController should not be // TODO(yinwa): work in progress. API in class FecController should not be
@ -73,11 +74,18 @@ class FecController {
int64_t round_trip_time_ms) = 0; int64_t round_trip_time_ms) = 0;
// Informs of encoded output. // Informs of encoded output.
virtual void UpdateWithEncodedData(const EncodedImage& encoded_image) = 0; virtual void UpdateWithEncodedData(size_t encoded_image_length,
FrameType encoded_image_frametype) = 0;
// Returns whether this FEC Controller needs Loss Vector Mask as input. // Returns whether this FEC Controller needs Loss Vector Mask as input.
virtual bool UseLossVectorMask() = 0; virtual bool UseLossVectorMask() = 0;
}; };
class FecControllerFactoryInterface {
public:
virtual std::unique_ptr<FecController> CreateFecController() = 0;
virtual ~FecControllerFactoryInterface() = default;
};
} // namespace webrtc } // namespace webrtc
#endif // API_FEC_CONTROLLER_H_ #endif // API_FEC_CONTROLLER_H_

View file

@ -83,6 +83,7 @@
#include "api/call/callfactoryinterface.h" #include "api/call/callfactoryinterface.h"
#include "api/datachannelinterface.h" #include "api/datachannelinterface.h"
#include "api/dtmfsenderinterface.h" #include "api/dtmfsenderinterface.h"
#include "api/fec_controller.h"
#include "api/jsep.h" #include "api/jsep.h"
#include "api/mediastreaminterface.h" #include "api/mediastreaminterface.h"
#include "api/rtcerror.h" #include "api/rtcerror.h"
@ -1296,6 +1297,27 @@ rtc::scoped_refptr<PeerConnectionFactoryInterface> CreatePeerConnectionFactory(
rtc::scoped_refptr<AudioMixer> audio_mixer, rtc::scoped_refptr<AudioMixer> audio_mixer,
rtc::scoped_refptr<AudioProcessing> audio_processing); rtc::scoped_refptr<AudioProcessing> audio_processing);
// Create a new instance of PeerConnectionFactoryInterface with optional
// external audio mixer, audio processing, and fec controller modules.
//
// If |audio_mixer| is null, an internal audio mixer will be created and used.
// If |audio_processing| is null, an internal audio processing module will be
// created and used.
// If |fec_controller_factory| is null, an internal fec controller module will
// be created and used.
rtc::scoped_refptr<PeerConnectionFactoryInterface> CreatePeerConnectionFactory(
rtc::Thread* network_thread,
rtc::Thread* worker_thread,
rtc::Thread* signaling_thread,
AudioDeviceModule* default_adm,
rtc::scoped_refptr<AudioEncoderFactory> audio_encoder_factory,
rtc::scoped_refptr<AudioDecoderFactory> audio_decoder_factory,
cricket::WebRtcVideoEncoderFactory* video_encoder_factory,
cricket::WebRtcVideoDecoderFactory* video_decoder_factory,
rtc::scoped_refptr<AudioMixer> audio_mixer,
rtc::scoped_refptr<AudioProcessing> audio_processing,
std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory);
// Create a new instance of PeerConnectionFactoryInterface with optional video // Create a new instance of PeerConnectionFactoryInterface with optional video
// codec factories. These video factories represents all video codecs, i.e. no // codec factories. These video factories represents all video codecs, i.e. no
// extra internal video codecs will be added. // extra internal video codecs will be added.
@ -1385,6 +1407,16 @@ CreateModularPeerConnectionFactory(
std::unique_ptr<CallFactoryInterface> call_factory, std::unique_ptr<CallFactoryInterface> call_factory,
std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory); std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory);
rtc::scoped_refptr<PeerConnectionFactoryInterface>
CreateModularPeerConnectionFactory(
rtc::Thread* network_thread,
rtc::Thread* worker_thread,
rtc::Thread* signaling_thread,
std::unique_ptr<cricket::MediaEngineInterface> media_engine,
std::unique_ptr<CallFactoryInterface> call_factory,
std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory,
std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory);
} // namespace webrtc } // namespace webrtc
#endif // API_PEERCONNECTIONINTERFACE_H_ #endif // API_PEERCONNECTIONINTERFACE_H_

View file

@ -408,6 +408,9 @@ Call* Call::Create(
return new internal::Call(config, std::move(transport_send)); return new internal::Call(config, std::move(transport_send));
} }
// This method here to avoid subclasses has to implement this method.
// Call perf test will use Internal::Call::CreateVideoSendStream() to inject
// FecController.
VideoSendStream* Call::CreateVideoSendStream( VideoSendStream* Call::CreateVideoSendStream(
VideoSendStream::Config config, VideoSendStream::Config config,
VideoEncoderConfig encoder_config, VideoEncoderConfig encoder_config,
@ -723,14 +726,7 @@ void Call::DestroyAudioReceiveStream(
delete audio_receive_stream; delete audio_receive_stream;
} }
webrtc::VideoSendStream* Call::CreateVideoSendStream( // This method can be used for Call tests with external fec controller factory.
webrtc::VideoSendStream::Config config,
VideoEncoderConfig encoder_config) {
return CreateVideoSendStream(
std::move(config), std::move(encoder_config),
rtc::MakeUnique<FecControllerDefault>(Clock::GetRealTimeClock()));
}
webrtc::VideoSendStream* Call::CreateVideoSendStream( webrtc::VideoSendStream* Call::CreateVideoSendStream(
webrtc::VideoSendStream::Config config, webrtc::VideoSendStream::Config config,
VideoEncoderConfig encoder_config, VideoEncoderConfig encoder_config,
@ -749,6 +745,7 @@ webrtc::VideoSendStream* Call::CreateVideoSendStream(
// the call has already started. // the call has already started.
// Copy ssrcs from |config| since |config| is moved. // Copy ssrcs from |config| since |config| is moved.
std::vector<uint32_t> ssrcs = config.rtp.ssrcs; std::vector<uint32_t> ssrcs = config.rtp.ssrcs;
VideoSendStream* send_stream = new VideoSendStream( VideoSendStream* send_stream = new VideoSendStream(
num_cpu_cores_, module_process_thread_.get(), &worker_queue_, num_cpu_cores_, module_process_thread_.get(), &worker_queue_,
call_stats_.get(), transport_send_.get(), bitrate_allocator_.get(), call_stats_.get(), transport_send_.get(), bitrate_allocator_.get(),
@ -770,6 +767,17 @@ webrtc::VideoSendStream* Call::CreateVideoSendStream(
return send_stream; return send_stream;
} }
webrtc::VideoSendStream* Call::CreateVideoSendStream(
webrtc::VideoSendStream::Config config,
VideoEncoderConfig encoder_config) {
std::unique_ptr<FecController> fec_controller =
config_.fec_controller_factory
? config_.fec_controller_factory->CreateFecController()
: rtc::MakeUnique<FecControllerDefault>(Clock::GetRealTimeClock());
return CreateVideoSendStream(std::move(config), std::move(encoder_config),
std::move(fec_controller));
}
void Call::DestroyVideoSendStream(webrtc::VideoSendStream* send_stream) { void Call::DestroyVideoSendStream(webrtc::VideoSendStream* send_stream) {
TRACE_EVENT0("webrtc", "Call::DestroyVideoSendStream"); TRACE_EVENT0("webrtc", "Call::DestroyVideoSendStream");
RTC_DCHECK(send_stream != nullptr); RTC_DCHECK(send_stream != nullptr);

View file

@ -109,6 +109,9 @@ struct CallConfig {
// RtcEventLog to use for this call. Required. // RtcEventLog to use for this call. Required.
// Use webrtc::RtcEventLog::CreateNull() for a null implementation. // Use webrtc::RtcEventLog::CreateNull() for a null implementation.
RtcEventLog* event_log = nullptr; RtcEventLog* event_log = nullptr;
// FecController to use for this call.
FecControllerFactoryInterface* fec_controller_factory = nullptr;
}; };
// A Call instance can contain several send and/or receive streams. All streams // A Call instance can contain several send and/or receive streams. All streams

View file

@ -49,6 +49,7 @@ rtc_source_set("module_api") {
] ]
deps = [ deps = [
":module_api_public", ":module_api_public",
":module_fec_api",
"..:webrtc_common", "..:webrtc_common",
"../:typedefs", "../:typedefs",
"../api:libjingle_peerconnection_api", "../api:libjingle_peerconnection_api",
@ -62,6 +63,13 @@ rtc_source_set("module_api") {
] ]
} }
rtc_source_set("module_fec_api") {
visibility = [ "*" ]
sources = [
"include/module_fec_types.h",
]
}
if (rtc_include_tests) { if (rtc_include_tests) {
modules_tests_resources = [ modules_tests_resources = [
"../resources/audio_coding/testfile32kHz.pcm", "../resources/audio_coding/testfile32kHz.pcm",

View file

@ -25,6 +25,7 @@
#include "api/video/video_rotation.h" #include "api/video/video_rotation.h"
#include "common_types.h" // NOLINT(build/include) #include "common_types.h" // NOLINT(build/include)
#include "modules/include/module_common_types_public.h" #include "modules/include/module_common_types_public.h"
#include "modules/include/module_fec_types.h"
#include "modules/video_coding/codecs/h264/include/h264_globals.h" #include "modules/video_coding/codecs/h264/include/h264_globals.h"
#include "modules/video_coding/codecs/vp8/include/vp8_globals.h" #include "modules/video_coding/codecs/vp8/include/vp8_globals.h"
#include "modules/video_coding/codecs/vp9/include/vp9_globals.h" #include "modules/video_coding/codecs/vp9/include/vp9_globals.h"
@ -265,22 +266,6 @@ struct RTCPVoIPMetric {
uint16_t JBabsMax; uint16_t JBabsMax;
}; };
// Types for the FEC packet masks. The type |kFecMaskRandom| is based on a
// random loss model. The type |kFecMaskBursty| is based on a bursty/consecutive
// loss model. The packet masks are defined in
// modules/rtp_rtcp/fec_private_tables_random(bursty).h
enum FecMaskType {
kFecMaskRandom,
kFecMaskBursty,
};
// Struct containing forward error correction settings.
struct FecProtectionParams {
int fec_rate;
int max_fec_frames;
FecMaskType fec_mask_type;
};
// Interface used by the CallStats class to distribute call statistics. // Interface used by the CallStats class to distribute call statistics.
// Callbacks will be triggered as soon as the class has been registered to a // Callbacks will be triggered as soon as the class has been registered to a
// CallStats object using RegisterStatsObserver. // CallStats object using RegisterStatsObserver.

View file

@ -0,0 +1,34 @@
/*
* Copyright (c) 2018 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 MODULES_INCLUDE_MODULE_FEC_TYPES_H_
#define MODULES_INCLUDE_MODULE_FEC_TYPES_H_
namespace webrtc {
// Types for the FEC packet masks. The type |kFecMaskRandom| is based on a
// random loss model. The type |kFecMaskBursty| is based on a bursty/consecutive
// loss model. The packet masks are defined in
// modules/rtp_rtcp/fec_private_tables_random(bursty).h
enum FecMaskType {
kFecMaskRandom,
kFecMaskBursty,
};
// Struct containing forward error correction settings.
struct FecProtectionParams {
int fec_rate;
int max_fec_frames;
FecMaskType fec_mask_type;
};
} // namespace webrtc
#endif // MODULES_INCLUDE_MODULE_FEC_TYPES_H_

View file

@ -145,11 +145,12 @@ void FecControllerDefault::SetProtectionMethod(bool enable_fec,
loss_prot_logic_->SetMethod(method); loss_prot_logic_->SetMethod(method);
} }
void FecControllerDefault::UpdateWithEncodedData( void FecControllerDefault::UpdateWithEncodedData(
const EncodedImage& encoded_image) { const size_t encoded_image_length,
const size_t encoded_length = encoded_image._length; const FrameType encoded_image_frametype) {
const size_t encoded_length = encoded_image_length;
CritScope lock(&crit_sect_); CritScope lock(&crit_sect_);
if (encoded_length > 0) { if (encoded_length > 0) {
const bool delta_frame = encoded_image._frameType != kVideoFrameKey; const bool delta_frame = encoded_image_frametype != kVideoFrameKey;
if (max_payload_size_ > 0 && encoded_length > 0) { if (max_payload_size_ > 0 && encoded_length > 0) {
const float min_packets_per_frame = const float min_packets_per_frame =
encoded_length / static_cast<float>(max_payload_size_); encoded_length / static_cast<float>(max_payload_size_);

View file

@ -39,7 +39,8 @@ class FecControllerDefault : public FecController {
uint8_t fraction_lost, uint8_t fraction_lost,
std::vector<bool> loss_mask_vector, std::vector<bool> loss_mask_vector,
int64_t round_trip_time_ms) override; int64_t round_trip_time_ms) override;
void UpdateWithEncodedData(const EncodedImage& encoded_image) override; void UpdateWithEncodedData(const size_t encoded_image_length,
const FrameType encoded_image_frametype) override;
bool UseLossVectorMask() override { return false; } bool UseLossVectorMask() override { return false; }
private: private:

View file

@ -412,7 +412,8 @@ EncodedImageCallback::Result VCMEncodedFrameCallback::OnEncodedImage(
return result; return result;
if (media_opt_) { if (media_opt_) {
media_opt_->UpdateWithEncodedData(image_copy); media_opt_->UpdateWithEncodedData(image_copy._length,
image_copy._frameType);
if (internal_source_) { if (internal_source_) {
// Signal to encoder to drop next frame. // Signal to encoder to drop next frame.
result.drop_next_frame = media_opt_->DropFrame(); result.drop_next_frame = media_opt_->DropFrame();

View file

@ -90,11 +90,12 @@ uint32_t MediaOptimization::InputFrameRateInternal() {
} }
void MediaOptimization::UpdateWithEncodedData( void MediaOptimization::UpdateWithEncodedData(
const EncodedImage& encoded_image) { const size_t encoded_image_length,
size_t encoded_length = encoded_image._length; const FrameType encoded_image_frametype) {
size_t encoded_length = encoded_image_length;
rtc::CritScope lock(&crit_sect_); rtc::CritScope lock(&crit_sect_);
if (encoded_length > 0) { if (encoded_length > 0) {
const bool delta_frame = encoded_image._frameType != kVideoFrameKey; const bool delta_frame = encoded_image_frametype != kVideoFrameKey;
frame_dropper_->Fill(encoded_length, delta_frame); frame_dropper_->Fill(encoded_length, delta_frame);
} }
} }

View file

@ -51,7 +51,8 @@ class MediaOptimization {
// Informs Media Optimization of encoded output. // Informs Media Optimization of encoded output.
// TODO(perkj): Deprecate SetEncodingData once its not used for stats in // TODO(perkj): Deprecate SetEncodingData once its not used for stats in
// VideoStreamEncoder. // VideoStreamEncoder.
void UpdateWithEncodedData(const EncodedImage& encoded_image); void UpdateWithEncodedData(const size_t encoded_image_length,
const FrameType encoded_image_frametype);
// InputFrameRate 0 = no frame rate estimate available. // InputFrameRate 0 = no frame rate estimate available.
uint32_t InputFrameRate(); uint32_t InputFrameRate();

View file

@ -181,6 +181,7 @@ rtc_static_library("peerconnection") {
":rtc_pc_base", ":rtc_pc_base",
"..:webrtc_common", "..:webrtc_common",
"../api:call_api", "../api:call_api",
"../api:fec_controller_api",
"../api:libjingle_peerconnection_api", "../api:libjingle_peerconnection_api",
"../api:optional", "../api:optional",
"../api:rtc_stats_api", "../api:rtc_stats_api",

View file

@ -69,6 +69,40 @@ rtc::scoped_refptr<PeerConnectionFactoryInterface> CreatePeerConnectionFactory(
} }
#endif #endif
rtc::scoped_refptr<PeerConnectionFactoryInterface> CreatePeerConnectionFactory(
rtc::Thread* network_thread,
rtc::Thread* worker_thread,
rtc::Thread* signaling_thread,
AudioDeviceModule* default_adm,
rtc::scoped_refptr<AudioEncoderFactory> audio_encoder_factory,
rtc::scoped_refptr<AudioDecoderFactory> audio_decoder_factory,
cricket::WebRtcVideoEncoderFactory* video_encoder_factory,
cricket::WebRtcVideoDecoderFactory* video_decoder_factory,
rtc::scoped_refptr<AudioMixer> audio_mixer,
rtc::scoped_refptr<AudioProcessing> audio_processing,
std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory) {
rtc::scoped_refptr<AudioProcessing> audio_processing_use = audio_processing;
if (!audio_processing_use) {
audio_processing_use = AudioProcessingBuilder().Create();
}
std::unique_ptr<cricket::MediaEngineInterface> media_engine(
cricket::WebRtcMediaEngineFactory::Create(
default_adm, audio_encoder_factory, audio_decoder_factory,
video_encoder_factory, video_decoder_factory, audio_mixer,
audio_processing_use));
std::unique_ptr<CallFactoryInterface> call_factory = CreateCallFactory();
std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory =
CreateRtcEventLogFactory();
return CreateModularPeerConnectionFactory(
network_thread, worker_thread, signaling_thread, std::move(media_engine),
std::move(call_factory), std::move(event_log_factory),
std::move(fec_controller_factory));
}
rtc::scoped_refptr<PeerConnectionFactoryInterface> CreatePeerConnectionFactory( rtc::scoped_refptr<PeerConnectionFactoryInterface> CreatePeerConnectionFactory(
rtc::Thread* network_thread, rtc::Thread* network_thread,
rtc::Thread* worker_thread, rtc::Thread* worker_thread,

View file

@ -12,6 +12,7 @@
#include <utility> #include <utility>
#include "api/fec_controller.h"
#include "api/mediaconstraintsinterface.h" #include "api/mediaconstraintsinterface.h"
#include "api/mediastreamproxy.h" #include "api/mediastreamproxy.h"
#include "api/mediastreamtrackproxy.h" #include "api/mediastreamtrackproxy.h"
@ -52,11 +53,25 @@ CreateModularPeerConnectionFactory(
std::unique_ptr<cricket::MediaEngineInterface> media_engine, std::unique_ptr<cricket::MediaEngineInterface> media_engine,
std::unique_ptr<CallFactoryInterface> call_factory, std::unique_ptr<CallFactoryInterface> call_factory,
std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory) { std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory) {
return CreateModularPeerConnectionFactory(
network_thread, worker_thread, signaling_thread, std::move(media_engine),
std::move(call_factory), std::move(event_log_factory), nullptr);
}
rtc::scoped_refptr<PeerConnectionFactoryInterface>
CreateModularPeerConnectionFactory(
rtc::Thread* network_thread,
rtc::Thread* worker_thread,
rtc::Thread* signaling_thread,
std::unique_ptr<cricket::MediaEngineInterface> media_engine,
std::unique_ptr<CallFactoryInterface> call_factory,
std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory,
std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory) {
rtc::scoped_refptr<PeerConnectionFactory> pc_factory( rtc::scoped_refptr<PeerConnectionFactory> pc_factory(
new rtc::RefCountedObject<PeerConnectionFactory>( new rtc::RefCountedObject<PeerConnectionFactory>(
network_thread, worker_thread, signaling_thread, network_thread, worker_thread, signaling_thread,
std::move(media_engine), std::move(call_factory), std::move(media_engine), std::move(call_factory),
std::move(event_log_factory))); std::move(event_log_factory), std::move(fec_controller_factory)));
// Call Initialize synchronously but make sure it is executed on // Call Initialize synchronously but make sure it is executed on
// |signaling_thread|. // |signaling_thread|.
@ -78,13 +93,30 @@ PeerConnectionFactory::PeerConnectionFactory(
std::unique_ptr<cricket::MediaEngineInterface> media_engine, std::unique_ptr<cricket::MediaEngineInterface> media_engine,
std::unique_ptr<webrtc::CallFactoryInterface> call_factory, std::unique_ptr<webrtc::CallFactoryInterface> call_factory,
std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory) std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory)
: PeerConnectionFactory(network_thread,
worker_thread,
signaling_thread,
std::move(media_engine),
std::move(call_factory),
std::move(event_log_factory),
nullptr) {}
PeerConnectionFactory::PeerConnectionFactory(
rtc::Thread* network_thread,
rtc::Thread* worker_thread,
rtc::Thread* signaling_thread,
std::unique_ptr<cricket::MediaEngineInterface> media_engine,
std::unique_ptr<webrtc::CallFactoryInterface> call_factory,
std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory,
std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory)
: wraps_current_thread_(false), : wraps_current_thread_(false),
network_thread_(network_thread), network_thread_(network_thread),
worker_thread_(worker_thread), worker_thread_(worker_thread),
signaling_thread_(signaling_thread), signaling_thread_(signaling_thread),
media_engine_(std::move(media_engine)), media_engine_(std::move(media_engine)),
call_factory_(std::move(call_factory)), call_factory_(std::move(call_factory)),
event_log_factory_(std::move(event_log_factory)) { event_log_factory_(std::move(event_log_factory)),
fec_controller_factory_(std::move(fec_controller_factory)) {
if (!network_thread_) { if (!network_thread_) {
owned_network_thread_ = rtc::Thread::CreateWithSocketServer(); owned_network_thread_ = rtc::Thread::CreateWithSocketServer();
owned_network_thread_->SetName("pc_network_thread", nullptr); owned_network_thread_->SetName("pc_network_thread", nullptr);
@ -355,6 +387,8 @@ std::unique_ptr<Call> PeerConnectionFactory::CreateCall_w(
call_config.bitrate_config.start_bitrate_bps = kStartBandwidthBps; call_config.bitrate_config.start_bitrate_bps = kStartBandwidthBps;
call_config.bitrate_config.max_bitrate_bps = kMaxBandwidthBps; call_config.bitrate_config.max_bitrate_bps = kMaxBandwidthBps;
call_config.fec_controller_factory = fec_controller_factory_.get();
return std::unique_ptr<Call>(call_factory_->CreateCall(call_config)); return std::unique_ptr<Call>(call_factory_->CreateCall(call_config));
} }

View file

@ -109,6 +109,14 @@ class PeerConnectionFactory : public PeerConnectionFactoryInterface {
std::unique_ptr<cricket::MediaEngineInterface> media_engine, std::unique_ptr<cricket::MediaEngineInterface> media_engine,
std::unique_ptr<webrtc::CallFactoryInterface> call_factory, std::unique_ptr<webrtc::CallFactoryInterface> call_factory,
std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory); std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory);
PeerConnectionFactory(
rtc::Thread* network_thread,
rtc::Thread* worker_thread,
rtc::Thread* signaling_thread,
std::unique_ptr<cricket::MediaEngineInterface> media_engine,
std::unique_ptr<webrtc::CallFactoryInterface> call_factory,
std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory,
std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory);
virtual ~PeerConnectionFactory(); virtual ~PeerConnectionFactory();
private: private:
@ -128,6 +136,7 @@ class PeerConnectionFactory : public PeerConnectionFactoryInterface {
std::unique_ptr<cricket::MediaEngineInterface> media_engine_; std::unique_ptr<cricket::MediaEngineInterface> media_engine_;
std::unique_ptr<webrtc::CallFactoryInterface> call_factory_; std::unique_ptr<webrtc::CallFactoryInterface> call_factory_;
std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory_; std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory_;
std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory_;
}; };
} // namespace webrtc } // namespace webrtc

View file

@ -642,6 +642,7 @@ rtc_android_library("libjingle_peerconnection_java") {
"api/org/webrtc/EglBase.java", "api/org/webrtc/EglBase.java",
"api/org/webrtc/EglRenderer.java", "api/org/webrtc/EglRenderer.java",
"api/org/webrtc/EncodedImage.java", "api/org/webrtc/EncodedImage.java",
"api/org/webrtc/FecControllerFactoryFactoryInterface.java",
"api/org/webrtc/FileVideoCapturer.java", "api/org/webrtc/FileVideoCapturer.java",
"api/org/webrtc/GlRectDrawer.java", "api/org/webrtc/GlRectDrawer.java",
"api/org/webrtc/GlShader.java", "api/org/webrtc/GlShader.java",

View file

@ -0,0 +1,22 @@
/*
* Copyright 2018 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.
*/
package org.webrtc;
/**
* Factory for creating webrtc::FecControllerFactory instances.
*/
public interface FecControllerFactoryFactoryInterface {
/**
* Dynamically allocates a webrtc::FecControllerFactory instance and returns a pointer to it.
* The caller takes ownership of the object.
*/
public long createNative();
}

View file

@ -124,6 +124,55 @@ public class PeerConnectionFactory {
} }
} }
public static class Builder {
private Options options;
private VideoEncoderFactory encoderFactory;
private VideoDecoderFactory decoderFactory;
private AudioProcessingFactory audioProcessingFactory;
private FecControllerFactoryFactoryInterface fecControllerFactoryFactory;
private Builder() {}
public Builder setOptions(Options options) {
this.options = options;
return this;
}
public Builder setVideoEncoderFactory(VideoEncoderFactory encoderFactory) {
this.encoderFactory = encoderFactory;
return this;
}
public Builder setVideoDecoderFactory(VideoDecoderFactory decoderFactory) {
this.decoderFactory = decoderFactory;
return this;
}
public Builder setAudioProcessingFactory(AudioProcessingFactory audioProcessingFactory) {
if (audioProcessingFactory == null) {
throw new NullPointerException(
"PeerConnectionFactory builder does not accept a null AudioProcessingFactory.");
}
this.audioProcessingFactory = audioProcessingFactory;
return this;
}
public Builder setFecControllerFactoryFactoryInterface(
FecControllerFactoryFactoryInterface fecControllerFactoryFactory) {
this.fecControllerFactoryFactory = fecControllerFactoryFactory;
return this;
}
public PeerConnectionFactory createPeerConnectionFactory() {
return new PeerConnectionFactory(options, encoderFactory, decoderFactory,
audioProcessingFactory, fecControllerFactoryFactory);
}
}
public static Builder builder() {
return new Builder();
}
/** /**
* Loads and initializes WebRTC. This must be called at least once before creating a * Loads and initializes WebRTC. This must be called at least once before creating a
* PeerConnectionFactory. Replaces all the old initialization methods. Must not be called while * PeerConnectionFactory. Replaces all the old initialization methods. Must not be called while
@ -191,28 +240,36 @@ public class PeerConnectionFactory {
// Note: initializeAndroidGlobals must be called at least once before // Note: initializeAndroidGlobals must be called at least once before
// constructing a PeerConnectionFactory. // constructing a PeerConnectionFactory.
@Deprecated
public PeerConnectionFactory(Options options) { public PeerConnectionFactory(Options options) {
this(options, null /* encoderFactory */, null /* decoderFactory */); this(options, null /* encoderFactory */, null /* decoderFactory */);
} }
@Deprecated
public PeerConnectionFactory( public PeerConnectionFactory(
Options options, VideoEncoderFactory encoderFactory, VideoDecoderFactory decoderFactory) { Options options, VideoEncoderFactory encoderFactory, VideoDecoderFactory decoderFactory) {
checkInitializeHasBeenCalled(); checkInitializeHasBeenCalled();
nativeFactory = nativeCreatePeerConnectionFactory(options, encoderFactory, decoderFactory); nativeFactory =
nativeCreatePeerConnectionFactory(options, encoderFactory, decoderFactory, 0, 0);
if (nativeFactory == 0) { if (nativeFactory == 0) {
throw new RuntimeException("Failed to initialize PeerConnectionFactory!"); throw new RuntimeException("Failed to initialize PeerConnectionFactory!");
} }
} }
@Deprecated
public PeerConnectionFactory(Options options, VideoEncoderFactory encoderFactory, public PeerConnectionFactory(Options options, VideoEncoderFactory encoderFactory,
VideoDecoderFactory decoderFactory, AudioProcessingFactory audioProcessingFactory) { VideoDecoderFactory decoderFactory, AudioProcessingFactory audioProcessingFactory) {
this(options, encoderFactory, decoderFactory, audioProcessingFactory,
null /* fecControllerFactoryFactory */);
}
private PeerConnectionFactory(Options options, VideoEncoderFactory encoderFactory,
VideoDecoderFactory decoderFactory, AudioProcessingFactory audioProcessingFactory,
FecControllerFactoryFactoryInterface fecControllerFactoryFactory) {
checkInitializeHasBeenCalled(); checkInitializeHasBeenCalled();
if (audioProcessingFactory == null) { nativeFactory = nativeCreatePeerConnectionFactory(options, encoderFactory, decoderFactory,
throw new NullPointerException( audioProcessingFactory == null ? 0 : audioProcessingFactory.createNative(),
"PeerConnectionFactory constructor does not accept a null AudioProcessingFactory."); fecControllerFactoryFactory == null ? 0 : fecControllerFactoryFactory.createNative());
}
nativeFactory = nativeCreatePeerConnectionFactoryWithAudioProcessing(
options, encoderFactory, decoderFactory, audioProcessingFactory.createNative());
if (nativeFactory == 0) { if (nativeFactory == 0) {
throw new RuntimeException("Failed to initialize PeerConnectionFactory!"); throw new RuntimeException("Failed to initialize PeerConnectionFactory!");
} }
@ -405,11 +462,9 @@ public class PeerConnectionFactory {
private static native void nativeShutdownInternalTracer(); private static native void nativeShutdownInternalTracer();
private static native boolean nativeStartInternalTracingCapture(String tracingFilename); private static native boolean nativeStartInternalTracingCapture(String tracingFilename);
private static native void nativeStopInternalTracingCapture(); private static native void nativeStopInternalTracingCapture();
private static native long nativeCreatePeerConnectionFactory( private static native long nativeCreatePeerConnectionFactory(Options options,
Options options, VideoEncoderFactory encoderFactory, VideoDecoderFactory decoderFactory);
private static native long nativeCreatePeerConnectionFactoryWithAudioProcessing(Options options,
VideoEncoderFactory encoderFactory, VideoDecoderFactory decoderFactory, VideoEncoderFactory encoderFactory, VideoDecoderFactory decoderFactory,
long nativeAudioProcessor); long nativeAudioProcessor, long nativeFecControllerFactory);
private static native long nativeCreatePeerConnection(long factory, private static native long nativeCreatePeerConnection(long factory,
PeerConnection.RTCConfiguration rtcConfig, MediaConstraints constraints, long nativeObserver); PeerConnection.RTCConfiguration rtcConfig, MediaConstraints constraints, long nativeObserver);
private static native long nativeCreateLocalMediaStream(long factory, String label); private static native long nativeCreateLocalMediaStream(long factory, String label);

View file

@ -172,7 +172,8 @@ jlong CreatePeerConnectionFactoryForJava(
const JavaParamRef<jobject>& joptions, const JavaParamRef<jobject>& joptions,
const JavaParamRef<jobject>& jencoder_factory, const JavaParamRef<jobject>& jencoder_factory,
const JavaParamRef<jobject>& jdecoder_factory, const JavaParamRef<jobject>& jdecoder_factory,
rtc::scoped_refptr<AudioProcessing> audio_processor) { rtc::scoped_refptr<AudioProcessing> audio_processor,
std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory) {
// talk/ assumes pretty widely that the current Thread is ThreadManager'd, but // talk/ assumes pretty widely that the current Thread is ThreadManager'd, but
// ThreadManager only WrapCurrentThread()s the thread where it is first // ThreadManager only WrapCurrentThread()s the thread where it is first
// created. Since the semantics around when auto-wrapping happens in // created. Since the semantics around when auto-wrapping happens in
@ -269,7 +270,7 @@ jlong CreatePeerConnectionFactoryForJava(
CreateModularPeerConnectionFactory( CreateModularPeerConnectionFactory(
network_thread.get(), worker_thread.get(), signaling_thread.get(), network_thread.get(), worker_thread.get(), signaling_thread.get(),
std::move(media_engine), std::move(call_factory), std::move(media_engine), std::move(call_factory),
std::move(rtc_event_log_factory))); std::move(rtc_event_log_factory), std::move(fec_controller_factory)));
RTC_CHECK(factory) << "Failed to create the peer connection factory; " RTC_CHECK(factory) << "Failed to create the peer connection factory; "
<< "WebRTC/libjingle init likely failed on this device"; << "WebRTC/libjingle init likely failed on this device";
// TODO(honghaiz): Maybe put the options as the argument of // TODO(honghaiz): Maybe put the options as the argument of
@ -286,29 +287,22 @@ jlong CreatePeerConnectionFactoryForJava(
} }
static jlong JNI_PeerConnectionFactory_CreatePeerConnectionFactory( static jlong JNI_PeerConnectionFactory_CreatePeerConnectionFactory(
JNIEnv* jni,
const JavaParamRef<jclass>&,
const JavaParamRef<jobject>& joptions,
const JavaParamRef<jobject>& jencoder_factory,
const JavaParamRef<jobject>& jdecoder_factory) {
return CreatePeerConnectionFactoryForJava(jni, joptions, jencoder_factory,
jdecoder_factory,
CreateAudioProcessing());
}
static jlong
JNI_PeerConnectionFactory_CreatePeerConnectionFactoryWithAudioProcessing(
JNIEnv* jni, JNIEnv* jni,
const JavaParamRef<jclass>&, const JavaParamRef<jclass>&,
const JavaParamRef<jobject>& joptions, const JavaParamRef<jobject>& joptions,
const JavaParamRef<jobject>& jencoder_factory, const JavaParamRef<jobject>& jencoder_factory,
const JavaParamRef<jobject>& jdecoder_factory, const JavaParamRef<jobject>& jdecoder_factory,
jlong native_audio_processor) { jlong native_audio_processor,
jlong native_fec_controller_factory) {
rtc::scoped_refptr<AudioProcessing> audio_processor = rtc::scoped_refptr<AudioProcessing> audio_processor =
reinterpret_cast<AudioProcessing*>(native_audio_processor); reinterpret_cast<AudioProcessing*>(native_audio_processor);
RTC_DCHECK(audio_processor); std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory(
return CreatePeerConnectionFactoryForJava(jni, joptions, jencoder_factory, reinterpret_cast<FecControllerFactoryInterface*>(
jdecoder_factory, audio_processor); native_fec_controller_factory));
return CreatePeerConnectionFactoryForJava(
jni, joptions, jencoder_factory, jdecoder_factory,
audio_processor ? audio_processor : CreateAudioProcessing(),
std::move(fec_controller_factory));
} }
static void JNI_PeerConnectionFactory_FreeFactory(JNIEnv*, static void JNI_PeerConnectionFactory_FreeFactory(JNIEnv*,

View file

@ -1087,9 +1087,9 @@ VideoQualityTest::VideoQualityTest()
} }
VideoQualityTest::VideoQualityTest( VideoQualityTest::VideoQualityTest(
std::unique_ptr<FecController> fec_controller) std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory)
: VideoQualityTest() { : VideoQualityTest() {
fec_controller_ = std::move(fec_controller); fec_controller_factory_ = std::move(fec_controller_factory);
} }
VideoQualityTest::Params::Params() VideoQualityTest::Params::Params()
@ -1827,16 +1827,17 @@ void VideoQualityTest::CreateVideoStreams() {
RTC_DCHECK(video_send_streams_.empty()); RTC_DCHECK(video_send_streams_.empty());
RTC_DCHECK(video_receive_streams_.empty()); RTC_DCHECK(video_receive_streams_.empty());
RTC_DCHECK_EQ(video_send_configs_.size(), num_video_streams_); RTC_DCHECK_EQ(video_send_configs_.size(), num_video_streams_);
// We currently only support testing external fec controllers with a single // We currently only support testing external fec controllers with a single
// VideoSendStream. // VideoSendStream.
if (fec_controller_.get()) { if (fec_controller_factory_.get()) {
RTC_DCHECK_LE(video_send_configs_.size(), 1); RTC_DCHECK_LE(video_send_configs_.size(), 1);
} }
for (size_t i = 0; i < video_send_configs_.size(); ++i) { for (size_t i = 0; i < video_send_configs_.size(); ++i) {
if (fec_controller_.get()) { if (fec_controller_factory_.get()) {
video_send_streams_.push_back(sender_call_->CreateVideoSendStream( video_send_streams_.push_back(sender_call_->CreateVideoSendStream(
video_send_configs_[i].Copy(), video_encoder_configs_[i].Copy(), video_send_configs_[i].Copy(), video_encoder_configs_[i].Copy(),
std::move(fec_controller_))); fec_controller_factory_->CreateFecController()));
} else { } else {
video_send_streams_.push_back(sender_call_->CreateVideoSendStream( video_send_streams_.push_back(sender_call_->CreateVideoSendStream(
video_send_configs_[i].Copy(), video_encoder_configs_[i].Copy())); video_send_configs_[i].Copy(), video_encoder_configs_[i].Copy()));
@ -1850,24 +1851,6 @@ void VideoQualityTest::CreateVideoStreams() {
AssociateFlexfecStreamsWithVideoStreams(); AssociateFlexfecStreamsWithVideoStreams();
} }
void VideoQualityTest::CreateVideoStreamsWithProtectionBitrateCalculator(
std::unique_ptr<FecController> fec_controller) {
RTC_DCHECK(video_send_streams_.empty());
RTC_DCHECK(video_receive_streams_.empty());
RTC_DCHECK_EQ(video_send_configs_.size(), num_video_streams_);
for (size_t i = 0; i < video_send_configs_.size(); ++i) {
video_send_streams_.push_back(sender_call_->CreateVideoSendStream(
video_send_configs_[i].Copy(), video_encoder_configs_[i].Copy(),
std::move(fec_controller)));
}
for (size_t i = 0; i < video_receive_configs_.size(); ++i) {
video_receive_streams_.push_back(receiver_call_->CreateVideoReceiveStream(
video_receive_configs_[i].Copy()));
}
AssociateFlexfecStreamsWithVideoStreams();
}
void VideoQualityTest::DestroyStreams() { void VideoQualityTest::DestroyStreams() {
CallTest::DestroyStreams(); CallTest::DestroyStreams();

View file

@ -96,7 +96,8 @@ class VideoQualityTest : public test::CallTest {
}; };
VideoQualityTest(); VideoQualityTest();
explicit VideoQualityTest(std::unique_ptr<FecController> fec_controller); explicit VideoQualityTest(
std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory);
void RunWithAnalyzer(const Params& params); void RunWithAnalyzer(const Params& params);
void RunWithRenderers(const Params& params); void RunWithRenderers(const Params& params);
@ -112,7 +113,7 @@ class VideoQualityTest : public test::CallTest {
protected: protected:
std::map<uint8_t, webrtc::MediaType> payload_type_map_; std::map<uint8_t, webrtc::MediaType> payload_type_map_;
std::unique_ptr<FecController> fec_controller_; std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory_;
// No-op implementation to be able to instantiate this class from non-TEST_F // No-op implementation to be able to instantiate this class from non-TEST_F
// locations. // locations.
@ -129,8 +130,6 @@ class VideoQualityTest : public test::CallTest {
// Helper methods for setting up the call. // Helper methods for setting up the call.
void CreateVideoStreams(); void CreateVideoStreams();
void CreateVideoStreamsWithProtectionBitrateCalculator(
std::unique_ptr<FecController> fec_controller);
void DestroyStreams(); void DestroyStreams();
void CreateCapturers(); void CreateCapturers();
std::unique_ptr<test::FrameGenerator> CreateFrameGenerator(size_t video_idx); std::unique_ptr<test::FrameGenerator> CreateFrameGenerator(size_t video_idx);

View file

@ -1115,7 +1115,8 @@ EncodedImageCallback::Result VideoSendStreamImpl::OnEncodedImage(
check_encoder_activity_task_->UpdateEncoderActivity(); check_encoder_activity_task_->UpdateEncoderActivity();
} }
fec_controller_->UpdateWithEncodedData(encoded_image); fec_controller_->UpdateWithEncodedData(encoded_image._length,
encoded_image._frameType);
EncodedImageCallback::Result result = payload_router_.OnEncodedImage( EncodedImageCallback::Result result = payload_router_.OnEncodedImage(
encoded_image, codec_specific_info, fragmentation); encoded_image, codec_specific_info, fragmentation);