Remove WebRtcVideoEngine.
Leaves a stub file for talk/media/webrtc/webrtcvideoengine.cc until
build files in Chromium have been modified.
BUG=1695,4566
R=mflodman@webrtc.org, pthatcher@webrtc.org
Review URL: https://webrtc-codereview.appspot.com/48339004
Cr-Commit-Position: refs/heads/master@{#9148}
diff --git a/talk/libjingle.gyp b/talk/libjingle.gyp
index bac42cc..fdef906 100755
--- a/talk/libjingle.gyp
+++ b/talk/libjingle.gyp
@@ -488,8 +488,6 @@
'media/webrtc/webrtcvideocapturer.h',
'media/webrtc/webrtcvideodecoderfactory.h',
'media/webrtc/webrtcvideoencoderfactory.h',
- 'media/webrtc/webrtcvideoengine.cc',
- 'media/webrtc/webrtcvideoengine.h',
'media/webrtc/webrtcvideoengine2.cc',
'media/webrtc/webrtcvideoengine2.h',
'media/webrtc/webrtcvideoframe.cc',
diff --git a/talk/libjingle_tests.gyp b/talk/libjingle_tests.gyp
index 246fa3b..3ca2f1f 100755
--- a/talk/libjingle_tests.gyp
+++ b/talk/libjingle_tests.gyp
@@ -107,7 +107,6 @@
# Disabled because some tests fail.
# TODO(ronghuawu): Reenable these tests.
# 'media/devices/devicemanager_unittest.cc',
- 'media/webrtc/webrtcvideoengine_unittest.cc',
'media/webrtc/webrtcvideoengine2_unittest.cc',
'media/webrtc/webrtcvoiceengine_unittest.cc',
],
diff --git a/talk/media/base/mediaengine.cc b/talk/media/base/mediaengine.cc
index 23c9929..9be590c 100644
--- a/talk/media/base/mediaengine.cc
+++ b/talk/media/base/mediaengine.cc
@@ -49,20 +49,6 @@
return old_function;
}
-// TODO(pthatcher): Remove this method and require all the users of
-// media engines to choose one explictly, or at least remove the
-// default behavior and require calling SetCreateFunction explictly.
-MediaEngineInterface* MediaEngineFactory::Create() {
- if (create_function_) {
- return create_function_();
- }
-#if defined(HAVE_WEBRTC_VOICE) && defined(HAVE_WEBRTC_VIDEO)
- return WebRtcMediaEngineFactory::Create();
-#else
- return new NullMediaEngine();
-#endif // HAVE_WEBRTC_VIDEO && HAVE_WEBRTC_VOICE
-}
-
}; // namespace cricket
#endif // DISABLE_MEDIA_ENGINE_FACTORY
diff --git a/talk/media/webrtc/constants.h b/talk/media/webrtc/constants.h
index b1a0cd8..ff73faa 100755
--- a/talk/media/webrtc/constants.h
+++ b/talk/media/webrtc/constants.h
@@ -33,19 +33,12 @@
extern const int kVideoMtu;
extern const int kVideoRtpBufferSize;
-extern const char kVp8CodecName[];
-extern const char kVp9CodecName[];
extern const char kH264CodecName[];
-extern const int kDefaultVideoMaxWidth;
-extern const int kDefaultVideoMaxHeight;
-extern const int kDefaultVideoMaxFramerate;
extern const int kMinVideoBitrate;
extern const int kStartVideoBitrate;
extern const int kMaxVideoBitrate;
-extern const int kCpuMonitorPeriodMs;
-
} // namespace cricket
#endif // TALK_MEDIA_WEBRTC_CONSTANTS_H_
diff --git a/talk/media/webrtc/dummyinstantiation.cc b/talk/media/webrtc/dummyinstantiation.cc
index 7d27967..7442831 100644
--- a/talk/media/webrtc/dummyinstantiation.cc
+++ b/talk/media/webrtc/dummyinstantiation.cc
@@ -25,13 +25,8 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "talk/media/webrtc/fakewebrtcvideoengine.h"
#include "talk/media/webrtc/fakewebrtcvoiceengine.h"
static void EnsureAPIMatch() {
new cricket::FakeWebRtcVoiceEngine(NULL, 0);
- new cricket::FakeWebRtcVideoDecoder();
- new cricket::FakeWebRtcVideoEncoder();
- new cricket::FakeWebRtcVideoEngine(NULL, 0);
- new cricket::FakeWebRtcVideoEngine::Capturer();
}
diff --git a/talk/media/webrtc/fakewebrtcvideoengine.h b/talk/media/webrtc/fakewebrtcvideoengine.h
index e3a2304..bfe22c4 100644
--- a/talk/media/webrtc/fakewebrtcvideoengine.h
+++ b/talk/media/webrtc/fakewebrtcvideoengine.h
@@ -263,1103 +263,6 @@
bool encoders_have_internal_sources_;
};
-// Information associated with an external encoder.
-struct ExternalEncoderInfo {
- bool internal_source;
-};
-
-class FakeWebRtcVideoEngine
- : public webrtc::ViEBase,
- public webrtc::ViECodec,
- public webrtc::ViECapture,
- public webrtc::ViENetwork,
- public webrtc::ViERender,
- public webrtc::ViERTP_RTCP,
- public webrtc::ViEImageProcess,
- public webrtc::ViEExternalCodec {
- public:
- struct Channel {
- Channel()
- : capture_id_(-1),
- original_channel_id_(-1),
- has_renderer_(false),
- render_started_(false),
- send(false),
- receive_(false),
- can_transmit_(true),
- remote_rtx_ssrc_(-1),
- rtcp_status_(webrtc::kRtcpNone),
- key_frame_request_method_(webrtc::kViEKeyFrameRequestNone),
- tmmbr_(false),
- remb_contribute_(false),
- remb_bw_partition_(false),
- rtp_offset_send_id_(-1),
- rtp_offset_receive_id_(-1),
- rtp_absolute_send_time_send_id_(-1),
- rtp_absolute_send_time_receive_id_(-1),
- rtp_video_rotation_send_id_(-1),
- rtp_video_rotation_receive_id_(-1),
- sender_target_delay_(0),
- receiver_target_delay_(0),
- transmission_smoothing_(false),
- nack_(false),
- hybrid_nack_fec_(false),
- send_video_bitrate_(0),
- send_fec_bitrate_(0),
- send_nack_bitrate_(0),
- send_bandwidth_(0),
- receive_bandwidth_(0),
- reserved_transmit_bitrate_bps_(0),
- suspend_below_min_bitrate_(false),
- overuse_observer_(NULL),
- last_recvd_payload_type_(-1) {
- ssrcs_[0] = 0; // default ssrc.
- memset(&send_codec, 0, sizeof(send_codec));
- memset(&overuse_options_, 0, sizeof(overuse_options_));
- }
- int capture_id_;
- int original_channel_id_;
- bool has_renderer_;
- bool render_started_;
- bool send;
- bool receive_;
- bool can_transmit_;
- std::map<int, int> ssrcs_;
- std::map<int, int> rtx_ssrcs_;
- int remote_rtx_ssrc_;
- // Mapping rtx_send_payload_types_[rtx] = associated.
- std::map<int, int> rtx_send_payload_types_;
- // Mapping rtx_recv_payload_types_[rtx] = associated.
- std::map<int, int> rtx_recv_payload_types_;
- std::string cname_;
- webrtc::ViERTCPMode rtcp_status_;
- webrtc::ViEKeyFrameRequestMethod key_frame_request_method_;
- bool tmmbr_;
- bool remb_contribute_; // This channel contributes to the remb report.
- bool remb_bw_partition_; // This channel is allocated part of total bw.
- int rtp_offset_send_id_;
- int rtp_offset_receive_id_;
- int rtp_absolute_send_time_send_id_;
- int rtp_absolute_send_time_receive_id_;
- int rtp_video_rotation_send_id_;
- int rtp_video_rotation_receive_id_;
- int sender_target_delay_;
- int receiver_target_delay_;
- bool transmission_smoothing_;
- bool nack_;
- bool hybrid_nack_fec_;
- std::vector<webrtc::VideoCodec> recv_codecs;
- std::set<unsigned int> ext_decoder_pl_types_;
- std::map<unsigned int, ExternalEncoderInfo> ext_encoders_;
- webrtc::VideoCodec send_codec;
- unsigned int send_video_bitrate_;
- unsigned int send_fec_bitrate_;
- unsigned int send_nack_bitrate_;
- unsigned int send_bandwidth_;
- unsigned int receive_bandwidth_;
- // Bandwidth to deduct from estimated uplink capacity.
- unsigned int reserved_transmit_bitrate_bps_;
- bool suspend_below_min_bitrate_;
- webrtc::CpuOveruseObserver* overuse_observer_;
- webrtc::CpuOveruseOptions overuse_options_;
- int last_recvd_payload_type_;
- };
- class Capturer : public webrtc::ViEExternalCapture {
- public:
- Capturer() : channel_id_(-1), denoising_(false),
- last_capture_time_(0), incoming_frame_num_(0) { }
- int channel_id() const { return channel_id_; }
- void set_channel_id(int channel_id) { channel_id_ = channel_id; }
- bool denoising() const { return denoising_; }
- void set_denoising(bool denoising) { denoising_ = denoising; }
- int64 last_capture_time() const { return last_capture_time_; }
- int incoming_frame_num() const { return incoming_frame_num_; }
-
- // From ViEExternalCapture
- void IncomingFrame(const webrtc::I420VideoFrame& frame) override {
- last_capture_time_ = frame.render_time_ms();
- ++incoming_frame_num_;
- }
-
- private:
- int channel_id_;
- bool denoising_;
- int64 last_capture_time_;
- int incoming_frame_num_;
- };
-
- FakeWebRtcVideoEngine(const cricket::VideoCodec* const* codecs,
- int num_codecs)
- : inited_(false),
- last_channel_(kViEChannelIdBase - 1),
- fail_create_channel_(false),
- last_capturer_(kViECaptureIdBase - 1),
- fail_alloc_capturer_(false),
- codecs_(codecs),
- num_codecs_(num_codecs),
- num_set_send_codecs_(0) {
- }
-
- ~FakeWebRtcVideoEngine() {
- ASSERT(0 == channels_.size());
- ASSERT(0 == capturers_.size());
- }
- bool IsInited() const { return inited_; }
-
- int GetLastChannel() const { return last_channel_; }
- int GetChannelFromLocalSsrc(int local_ssrc) const {
- // ssrcs_[0] is the default local ssrc.
- for (std::map<int, Channel*>::const_iterator iter = channels_.begin();
- iter != channels_.end(); ++iter) {
- if (local_ssrc == iter->second->ssrcs_[0]) {
- return iter->first;
- }
- }
- return -1;
- }
-
- int GetNumChannels() const { return static_cast<int>(channels_.size()); }
- bool IsChannel(int channel) const {
- return (channels_.find(channel) != channels_.end());
- }
- void set_fail_create_channel(bool fail_create_channel) {
- fail_create_channel_ = fail_create_channel;
- }
-
- int GetLastCapturer() const { return last_capturer_; }
- int GetNumCapturers() const { return static_cast<int>(capturers_.size()); }
- int GetIncomingFrameNum(int channel_id) const {
- for (std::map<int, Capturer*>::const_iterator iter = capturers_.begin();
- iter != capturers_.end(); ++iter) {
- Capturer* capturer = iter->second;
- if (capturer->channel_id() == channel_id) {
- return capturer->incoming_frame_num();
- }
- }
- return -1;
- }
- void set_fail_alloc_capturer(bool fail_alloc_capturer) {
- fail_alloc_capturer_ = fail_alloc_capturer;
- }
- int GetNumSetSendCodecs() const { return num_set_send_codecs_; }
-
- int GetCaptureId(int channel) const {
- WEBRTC_ASSERT_CHANNEL(channel);
- return channels_.find(channel)->second->capture_id_;
- }
- int GetOriginalChannelId(int channel) const {
- WEBRTC_ASSERT_CHANNEL(channel);
- return channels_.find(channel)->second->original_channel_id_;
- }
- bool GetHasRenderer(int channel) const {
- WEBRTC_ASSERT_CHANNEL(channel);
- return channels_.find(channel)->second->has_renderer_;
- }
- bool GetRenderStarted(int channel) const {
- WEBRTC_ASSERT_CHANNEL(channel);
- return channels_.find(channel)->second->render_started_;
- }
- bool GetSend(int channel) const {
- WEBRTC_ASSERT_CHANNEL(channel);
- return channels_.find(channel)->second->send;
- }
- bool GetReceive(int channel) const {
- WEBRTC_ASSERT_CHANNEL(channel);
- return channels_.find(channel)->second->receive_;
- }
- int GetCaptureChannelId(int capture_id) const {
- WEBRTC_ASSERT_CAPTURER(capture_id);
- return capturers_.find(capture_id)->second->channel_id();
- }
- bool GetCaptureDenoising(int capture_id) const {
- WEBRTC_ASSERT_CAPTURER(capture_id);
- return capturers_.find(capture_id)->second->denoising();
- }
- int64 GetCaptureLastTimestamp(int capture_id) const {
- WEBRTC_ASSERT_CAPTURER(capture_id);
- return capturers_.find(capture_id)->second->last_capture_time();
- }
- webrtc::ViERTCPMode GetRtcpStatus(int channel) const {
- WEBRTC_ASSERT_CHANNEL(channel);
- return channels_.find(channel)->second->rtcp_status_;
- }
- webrtc::ViEKeyFrameRequestMethod GetKeyFrameRequestMethod(int channel) const {
- WEBRTC_ASSERT_CHANNEL(channel);
- return channels_.find(channel)->second->key_frame_request_method_;
- }
- bool GetTmmbrStatus(int channel) const {
- WEBRTC_ASSERT_CHANNEL(channel);
- return channels_.find(channel)->second->tmmbr_;
- }
- bool GetRembStatusBwPartition(int channel) const {
- WEBRTC_ASSERT_CHANNEL(channel);
- return channels_.find(channel)->second->remb_bw_partition_;
- }
- bool GetRembStatusContribute(int channel) const {
- WEBRTC_ASSERT_CHANNEL(channel);
- return channels_.find(channel)->second->remb_contribute_;
- }
- int GetSendRtpExtensionId(int channel, const std::string& extension) {
- WEBRTC_ASSERT_CHANNEL(channel);
- if (extension == kRtpTimestampOffsetHeaderExtension) {
- return channels_.find(channel)->second->rtp_offset_send_id_;
- } else if (extension == kRtpAbsoluteSenderTimeHeaderExtension) {
- return channels_.find(channel)->second->rtp_absolute_send_time_send_id_;
- } else if (extension == kRtpVideoRotationHeaderExtension) {
- return channels_.find(channel)->second->rtp_video_rotation_send_id_;
- }
- return -1;
- }
- int GetReceiveRtpExtensionId(int channel, const std::string& extension) {
- WEBRTC_ASSERT_CHANNEL(channel);
- if (extension == kRtpTimestampOffsetHeaderExtension) {
- return channels_.find(channel)->second->rtp_offset_receive_id_;
- } else if (extension == kRtpAbsoluteSenderTimeHeaderExtension) {
- return
- channels_.find(channel)->second->rtp_absolute_send_time_receive_id_;
- } else if (extension == kRtpVideoRotationHeaderExtension) {
- return channels_.find(channel)->second->rtp_video_rotation_receive_id_;
- }
- return -1;
- }
- bool GetTransmissionSmoothingStatus(int channel) {
- WEBRTC_ASSERT_CHANNEL(channel);
- return channels_.find(channel)->second->transmission_smoothing_;
- }
- int GetSenderTargetDelay(int channel) {
- WEBRTC_ASSERT_CHANNEL(channel);
- return channels_.find(channel)->second->sender_target_delay_;
- }
- int GetReceiverTargetDelay(int channel) {
- WEBRTC_ASSERT_CHANNEL(channel);
- return channels_.find(channel)->second->receiver_target_delay_;
- }
- bool GetNackStatus(int channel) const {
- WEBRTC_ASSERT_CHANNEL(channel);
- return channels_.find(channel)->second->nack_;
- }
- bool GetHybridNackFecStatus(int channel) const {
- WEBRTC_ASSERT_CHANNEL(channel);
- return channels_.find(channel)->second->hybrid_nack_fec_;
- }
- int GetNumSsrcs(int channel) const {
- WEBRTC_ASSERT_CHANNEL(channel);
- return static_cast<int>(
- channels_.find(channel)->second->ssrcs_.size());
- }
- int GetNumRtxSsrcs(int channel) const {
- WEBRTC_ASSERT_CHANNEL(channel);
- return static_cast<int>(
- channels_.find(channel)->second->rtx_ssrcs_.size());
- }
- bool GetIsTransmitting(int channel) const {
- WEBRTC_ASSERT_CHANNEL(channel);
- return channels_.find(channel)->second->can_transmit_;
- }
- webrtc::CpuOveruseObserver* GetCpuOveruseObserver(int channel) const {
- WEBRTC_ASSERT_CHANNEL(channel);
- return channels_.find(channel)->second->overuse_observer_;
- }
- webrtc::CpuOveruseOptions GetCpuOveruseOptions(int channel) const {
- WEBRTC_ASSERT_CHANNEL(channel);
- return channels_.find(channel)->second->overuse_options_;
- }
- int GetSsrc(int channel, int idx) const {
- WEBRTC_ASSERT_CHANNEL(channel);
- if (channels_.find(channel)->second->ssrcs_.find(idx) ==
- channels_.find(channel)->second->ssrcs_.end()) {
- return -1;
- }
- return channels_.find(channel)->second->ssrcs_[idx];
- }
- int GetRtxSsrc(int channel, int idx) const {
- WEBRTC_ASSERT_CHANNEL(channel);
- if (channels_.find(channel)->second->rtx_ssrcs_.find(idx) ==
- channels_.find(channel)->second->rtx_ssrcs_.end()) {
- return -1;
- }
- return channels_.find(channel)->second->rtx_ssrcs_[idx];
- }
- bool ReceiveCodecRegistered(int channel,
- const webrtc::VideoCodec& codec) const {
- WEBRTC_ASSERT_CHANNEL(channel);
- const std::vector<webrtc::VideoCodec>& codecs =
- channels_.find(channel)->second->recv_codecs;
- return std::find(codecs.begin(), codecs.end(), codec) != codecs.end();
- };
- bool ExternalDecoderRegistered(int channel,
- unsigned int pl_type) const {
- WEBRTC_ASSERT_CHANNEL(channel);
- return channels_.find(channel)->second->
- ext_decoder_pl_types_.count(pl_type) != 0;
- };
- int GetNumExternalDecoderRegistered(int channel) const {
- WEBRTC_ASSERT_CHANNEL(channel);
- return static_cast<int>(
- channels_.find(channel)->second->ext_decoder_pl_types_.size());
- };
- bool ExternalEncoderRegistered(int channel,
- unsigned int pl_type) const {
- WEBRTC_ASSERT_CHANNEL(channel);
- return channels_.find(channel)->second->ext_encoders_.count(pl_type) != 0;
- };
- int GetNumExternalEncoderRegistered(int channel) const {
- WEBRTC_ASSERT_CHANNEL(channel);
- return static_cast<int>(
- channels_.find(channel)->second->ext_encoders_.size());
- };
- bool ExternalEncoderHasInternalSource(int channel,
- unsigned int pl_type) const {
- WEBRTC_ASSERT_CHANNEL(channel);
- ASSERT(channels_.find(channel)->second->ext_encoders_.count(pl_type) != 0);
- return channels_.find(channel)
- ->second->ext_encoders_[pl_type]
- .internal_source;
- };
- int GetTotalNumExternalEncoderRegistered() const {
- std::map<int, Channel*>::const_iterator it;
- int total_num_registered = 0;
- for (it = channels_.begin(); it != channels_.end(); ++it)
- total_num_registered +=
- static_cast<int>(it->second->ext_encoders_.size());
- return total_num_registered;
- }
- void SetSendBitrates(int channel, unsigned int video_bitrate,
- unsigned int fec_bitrate, unsigned int nack_bitrate) {
- WEBRTC_ASSERT_CHANNEL(channel);
- channels_[channel]->send_video_bitrate_ = video_bitrate;
- channels_[channel]->send_fec_bitrate_ = fec_bitrate;
- channels_[channel]->send_nack_bitrate_ = nack_bitrate;
- }
- void SetSendBandwidthEstimate(int channel, unsigned int send_bandwidth) {
- WEBRTC_ASSERT_CHANNEL(channel);
- channels_[GetOriginalChannelId(channel)]->send_bandwidth_ = send_bandwidth;
- }
- void SetReceiveBandwidthEstimate(int channel,
- unsigned int receive_bandwidth) {
- WEBRTC_ASSERT_CHANNEL(channel);
- channels_[GetOriginalChannelId(channel)]->receive_bandwidth_ =
- receive_bandwidth;
- }
- std::vector<int> GetRtxSendPayloadTypes(int channel) {
- std::vector<int> rtx_payload_types;
- if (channels_.find(channel) == channels_.end())
- return rtx_payload_types;
-
- for (const auto& payload_type :
- channels_[channel]->rtx_send_payload_types_) {
- rtx_payload_types.push_back(payload_type.first);
- }
- return rtx_payload_types;
- }
- std::vector<int> GetRtxRecvPayloadTypes(int channel) {
- std::vector<int> rtx_payload_types;
- if (channels_.find(channel) == channels_.end())
- return rtx_payload_types;
-
- for (const auto& payload_type :
- channels_[channel]->rtx_recv_payload_types_) {
- rtx_payload_types.push_back(payload_type.first);
- }
- return rtx_payload_types;
- }
- int GetRemoteRtxSsrc(int channel) {
- WEBRTC_CHECK_CHANNEL(channel);
- return channels_.find(channel)->second->remote_rtx_ssrc_;
- }
- bool GetSuspendBelowMinBitrateStatus(int channel) {
- WEBRTC_ASSERT_CHANNEL(channel);
- return channels_.find(channel)->second->suspend_below_min_bitrate_;
- }
- int GetLastRecvdPayloadType(int channel) const {
- WEBRTC_CHECK_CHANNEL(channel);
- return channels_.find(channel)->second->last_recvd_payload_type_;
- }
- unsigned int GetReservedTransmitBitrate(int channel) {
- WEBRTC_ASSERT_CHANNEL(channel);
- return channels_.find(channel)->second->reserved_transmit_bitrate_bps_;
- }
-
- WEBRTC_STUB(Release, ());
-
- // webrtc::ViEBase
- WEBRTC_FUNC(Init, ()) {
- inited_ = true;
- return 0;
- };
- WEBRTC_STUB(SetVoiceEngine, (webrtc::VoiceEngine*));
- WEBRTC_FUNC(CreateChannel, (int& channel)) { // NOLINT
- if (fail_create_channel_) {
- return -1;
- }
- if (kViEChannelIdMax == last_channel_) {
- return -1;
- }
- Channel* ch = new Channel();
- ++last_channel_;
- // The original channel of the first channel in a group refers to itself
- // for code simplicity.
- ch->original_channel_id_ = last_channel_;
- channels_[last_channel_] = ch;
- channel = last_channel_;
- return 0;
- };
- WEBRTC_FUNC(CreateChannel, (int& channel, int original_channel)) {
- WEBRTC_CHECK_CHANNEL(original_channel);
- if (CreateChannel(channel) != 0) {
- return -1;
- }
- channels_[channel]->original_channel_id_ = original_channel;
- return 0;
- }
- WEBRTC_STUB(CreateChannelWithoutDefaultEncoder, (int&, int original_channel));
- webrtc::ChannelGroup* GetChannelGroup(int channel_id) override {
- return nullptr;
- }
- webrtc::ViEChannel* GetChannel(int channel_id) override { return nullptr; }
- webrtc::ViEEncoder* GetEncoder(int channel_id) override { return nullptr; }
- webrtc::ViESharedData* shared_data() override { return nullptr; }
-
- WEBRTC_FUNC(CreateReceiveChannel, (int& channel, int original_channel)) {
- return CreateChannel(channel, original_channel);
- }
- WEBRTC_FUNC(DeleteChannel, (const int channel)) {
- WEBRTC_CHECK_CHANNEL(channel);
- // Make sure we deregister all the decoders before deleting a channel.
- EXPECT_EQ(0, GetNumExternalDecoderRegistered(channel));
- delete channels_[channel];
- channels_.erase(channel);
- return 0;
- }
- WEBRTC_FUNC(RegisterCpuOveruseObserver,
- (int channel, webrtc::CpuOveruseObserver* observer)) {
- WEBRTC_CHECK_CHANNEL(channel);
- channels_[channel]->overuse_observer_ = observer;
- return 0;
- }
- WEBRTC_STUB(GetCpuOveruseMetrics, (int, webrtc::CpuOveruseMetrics*));
- WEBRTC_VOID_STUB(RegisterCpuOveruseMetricsObserver,
- (int, webrtc::CpuOveruseMetricsObserver*));
- WEBRTC_FUNC(SetCpuOveruseOptions,
- (int channel, const webrtc::CpuOveruseOptions& options)) {
- WEBRTC_CHECK_CHANNEL(channel);
- channels_[channel]->overuse_options_ = options;
- return 0;
- }
- WEBRTC_STUB(ConnectAudioChannel, (const int, const int));
- WEBRTC_STUB(DisconnectAudioChannel, (const int));
- WEBRTC_FUNC(StartSend, (const int channel)) {
- WEBRTC_CHECK_CHANNEL(channel);
- channels_[channel]->send = true;
- return 0;
- }
- WEBRTC_FUNC(StopSend, (const int channel)) {
- WEBRTC_CHECK_CHANNEL(channel);
- channels_[channel]->send = false;
- return 0;
- }
- WEBRTC_FUNC(StartReceive, (const int channel)) {
- WEBRTC_CHECK_CHANNEL(channel);
- channels_[channel]->receive_ = true;
- return 0;
- }
- WEBRTC_FUNC(StopReceive, (const int channel)) {
- WEBRTC_CHECK_CHANNEL(channel);
- channels_[channel]->receive_ = false;
- return 0;
- }
- WEBRTC_STUB(GetVersion, (char version[1024]));
- WEBRTC_STUB(LastError, ());
- WEBRTC_VOID_STUB(RegisterSendStatisticsProxy,
- (int, webrtc::SendStatisticsProxy*));
-
- WEBRTC_VOID_STUB(RegisterReceiveStatisticsProxy,
- (int, webrtc::ReceiveStatisticsProxy*));
-
- // webrtc::ViECodec
- WEBRTC_FUNC_CONST(NumberOfCodecs, ()) {
- return num_codecs_;
- };
- WEBRTC_FUNC_CONST(GetCodec, (const unsigned char list_number,
- webrtc::VideoCodec& out_codec)) {
- if (list_number >= NumberOfCodecs()) {
- return -1;
- }
- memset(&out_codec, 0, sizeof(out_codec));
- const cricket::VideoCodec& c(*codecs_[list_number]);
- if ("I420" == c.name) {
- out_codec.codecType = webrtc::kVideoCodecI420;
- } else if ("VP8" == c.name) {
- out_codec.codecType = webrtc::kVideoCodecVP8;
- } else if ("red" == c.name) {
- out_codec.codecType = webrtc::kVideoCodecRED;
- } else if ("ulpfec" == c.name) {
- out_codec.codecType = webrtc::kVideoCodecULPFEC;
- } else {
- out_codec.codecType = webrtc::kVideoCodecUnknown;
- }
- rtc::strcpyn(out_codec.plName, sizeof(out_codec.plName),
- c.name.c_str());
- out_codec.plType = c.id;
- out_codec.width = c.width;
- out_codec.height = c.height;
- out_codec.startBitrate = kStartVideoBitrate;
- out_codec.maxBitrate = kMaxVideoBitrate;
- out_codec.minBitrate = kMinVideoBitrate;
- out_codec.maxFramerate = c.framerate;
- return 0;
- };
- WEBRTC_FUNC(SetSendCodec, (const int channel,
- const webrtc::VideoCodec& codec)) {
- WEBRTC_CHECK_CHANNEL(channel);
- channels_[channel]->send_codec = codec;
- ++num_set_send_codecs_;
- return 0;
- };
- WEBRTC_FUNC_CONST(GetSendCodec, (const int channel,
- webrtc::VideoCodec& codec)) { // NOLINT
- WEBRTC_CHECK_CHANNEL(channel);
- codec = channels_.find(channel)->second->send_codec;
- return 0;
- };
- WEBRTC_FUNC(SetReceiveCodec, (const int channel,
- const webrtc::VideoCodec& codec)) { // NOLINT
- WEBRTC_CHECK_CHANNEL(channel);
- channels_[channel]->recv_codecs.push_back(codec);
- return 0;
- };
- WEBRTC_STUB_CONST(GetReceiveCodec, (const int, webrtc::VideoCodec&));
- WEBRTC_STUB_CONST(GetCodecConfigParameters, (const int,
- unsigned char*, unsigned char&));
- WEBRTC_STUB(SetImageScaleStatus, (const int, const bool));
- WEBRTC_STUB_CONST(GetSendCodecStastistics, (const int,
- unsigned int&, unsigned int&));
- WEBRTC_STUB_CONST(GetReceiveCodecStastistics, (const int,
- unsigned int&, unsigned int&));
- WEBRTC_STUB_CONST(GetReceiveSideDelay, (const int video_channel,
- int* delay_ms));
- virtual uint32_t GetLastObservedBitrateBps(int channel) const override {
- return 0;
- }
- WEBRTC_FUNC_CONST(GetCodecTargetBitrate, (const int channel,
- unsigned int* codec_target_bitrate)) {
- WEBRTC_CHECK_CHANNEL(channel);
-
- std::map<int, Channel*>::const_iterator it = channels_.find(channel);
- if (it->second->send) {
- // Assume the encoder produces the expected rate.
- *codec_target_bitrate = it->second->send_video_bitrate_;
- } else {
- *codec_target_bitrate = 0;
- }
- return 0;
- }
- virtual unsigned int GetDiscardedPackets(const int channel) const {
- return 0;
- }
-
- WEBRTC_STUB(SetKeyFrameRequestCallbackStatus, (const int, const bool));
- WEBRTC_STUB(SetSignalKeyPacketLossStatus, (const int, const bool,
- const bool));
- WEBRTC_STUB(RegisterEncoderObserver, (const int,
- webrtc::ViEEncoderObserver&));
- WEBRTC_STUB(DeregisterEncoderObserver, (const int));
- WEBRTC_STUB(RegisterDecoderObserver, (const int,
- webrtc::ViEDecoderObserver&));
- WEBRTC_STUB(DeregisterDecoderObserver, (const int));
- WEBRTC_STUB(SendKeyFrame, (const int));
- WEBRTC_STUB(WaitForFirstKeyFrame, (const int, const bool));
- WEBRTC_STUB(StartDebugRecording, (int, const char*));
- WEBRTC_STUB(StopDebugRecording, (int));
- WEBRTC_VOID_FUNC(SuspendBelowMinBitrate, (int channel)) {
- WEBRTC_ASSERT_CHANNEL(channel);
- channels_[channel]->suspend_below_min_bitrate_ = true;
- }
-
- // webrtc::ViECapture
- WEBRTC_STUB(NumberOfCaptureDevices, ());
- WEBRTC_STUB(GetCaptureDevice, (unsigned int, char*,
- const unsigned int, char*, const unsigned int));
- WEBRTC_STUB(AllocateCaptureDevice, (const char*, const unsigned int, int&));
- WEBRTC_FUNC(AllocateExternalCaptureDevice,
- (int& capture_id, webrtc::ViEExternalCapture*& capture)) {
- if (fail_alloc_capturer_) {
- return -1;
- }
- if (kViECaptureIdMax == last_capturer_) {
- return -1;
- }
- Capturer* cap = new Capturer();
- capturers_[++last_capturer_] = cap;
- capture_id = last_capturer_;
- capture = cap;
- return 0;
- }
- WEBRTC_STUB(AllocateCaptureDevice, (webrtc::VideoCaptureModule&, int&));
- WEBRTC_FUNC(ReleaseCaptureDevice, (const int capture_id)) {
- WEBRTC_CHECK_CAPTURER(capture_id);
- delete capturers_[capture_id];
- capturers_.erase(capture_id);
- return 0;
- }
- WEBRTC_FUNC(ConnectCaptureDevice, (const int capture_id,
- const int channel)) {
- WEBRTC_CHECK_CHANNEL(channel);
- WEBRTC_CHECK_CAPTURER(capture_id);
- channels_[channel]->capture_id_ = capture_id;
- capturers_[capture_id]->set_channel_id(channel);
- return 0;
- }
- WEBRTC_FUNC(DisconnectCaptureDevice, (const int channel)) {
- WEBRTC_CHECK_CHANNEL(channel);
- int capture_id = channels_[channel]->capture_id_;
- WEBRTC_CHECK_CAPTURER(capture_id);
- channels_[channel]->capture_id_ = -1;
- capturers_[capture_id]->set_channel_id(-1);
- return 0;
- }
- WEBRTC_STUB(StartCapture, (const int, const webrtc::CaptureCapability&));
- WEBRTC_STUB(StopCapture, (const int));
- WEBRTC_STUB(SetVideoRotation, (const int, const webrtc::VideoRotation));
- WEBRTC_STUB(SetCaptureDelay, (const int, const unsigned int));
- WEBRTC_STUB(NumberOfCapabilities, (const char*, const unsigned int));
- WEBRTC_STUB(GetCaptureCapability, (const char*, const unsigned int,
- const unsigned int, webrtc::CaptureCapability&));
- WEBRTC_STUB(ShowCaptureSettingsDialogBox, (const char*, const unsigned int,
- const char*, void*, const unsigned int, const unsigned int));
- WEBRTC_STUB(GetOrientation, (const char*, webrtc::VideoRotation&));
- WEBRTC_STUB(EnableBrightnessAlarm, (const int, const bool));
- WEBRTC_STUB(RegisterObserver, (const int, webrtc::ViECaptureObserver&));
- WEBRTC_STUB(DeregisterObserver, (const int));
-
- // webrtc::ViENetwork
- WEBRTC_VOID_STUB(SetBitrateConfig, (int, int, int, int));
- WEBRTC_VOID_FUNC(SetNetworkTransmissionState, (const int channel,
- const bool is_transmitting)) {
- WEBRTC_ASSERT_CHANNEL(channel);
- channels_[channel]->can_transmit_ = is_transmitting;
- }
- WEBRTC_STUB(RegisterSendTransport, (const int, webrtc::Transport&));
- WEBRTC_STUB(DeregisterSendTransport, (const int));
-
- WEBRTC_FUNC(ReceivedRTPPacket, (const int channel,
- const void* packet,
- const size_t length,
- const webrtc::PacketTime& packet_time)) {
- WEBRTC_ASSERT_CHANNEL(channel);
- ASSERT(length > 1);
- uint8_t payload_type = static_cast<const uint8_t*>(packet)[1] & 0x7F;
- channels_[channel]->last_recvd_payload_type_ = payload_type;
- return 0;
- }
-
- WEBRTC_STUB(ReceivedRTCPPacket, (const int, const void*, const size_t));
- // Not using WEBRTC_STUB due to bool return value
- virtual bool IsIPv6Enabled(int channel) { return true; }
- WEBRTC_STUB(SetMTU, (int, unsigned int));
- WEBRTC_STUB(ReceivedBWEPacket, (const int, int64_t, size_t,
- const webrtc::RTPHeader&));
-
- // webrtc::ViERender
- WEBRTC_STUB(RegisterVideoRenderModule, (webrtc::VideoRender&));
- WEBRTC_STUB(DeRegisterVideoRenderModule, (webrtc::VideoRender&));
- WEBRTC_STUB(AddRenderer, (const int, void*, const unsigned int, const float,
- const float, const float, const float));
- WEBRTC_FUNC(RemoveRenderer, (const int render_id)) {
- if (IsCapturerId(render_id)) {
- WEBRTC_CHECK_CAPTURER(render_id);
- return 0;
- } else if (IsChannelId(render_id)) {
- WEBRTC_CHECK_CHANNEL(render_id);
- channels_[render_id]->has_renderer_ = false;
- return 0;
- }
- return -1;
- }
- WEBRTC_FUNC(StartRender, (const int render_id)) {
- if (IsCapturerId(render_id)) {
- WEBRTC_CHECK_CAPTURER(render_id);
- return 0;
- } else if (IsChannelId(render_id)) {
- WEBRTC_CHECK_CHANNEL(render_id);
- channels_[render_id]->render_started_ = true;
- return 0;
- }
- return -1;
- }
- WEBRTC_FUNC(StopRender, (const int render_id)) {
- if (IsCapturerId(render_id)) {
- WEBRTC_CHECK_CAPTURER(render_id);
- return 0;
- } else if (IsChannelId(render_id)) {
- WEBRTC_CHECK_CHANNEL(render_id);
- channels_[render_id]->render_started_ = false;
- return 0;
- }
- return -1;
- }
- WEBRTC_STUB(SetExpectedRenderDelay, (int render_id, int render_delay));
- WEBRTC_STUB(ConfigureRender, (int, const unsigned int, const float,
- const float, const float, const float));
- WEBRTC_FUNC(AddRenderer, (const int render_id,
- webrtc::RawVideoType video_type,
- webrtc::ExternalRenderer* renderer)) {
- if (IsCapturerId(render_id)) {
- WEBRTC_CHECK_CAPTURER(render_id);
- return 0;
- } else if (IsChannelId(render_id)) {
- WEBRTC_CHECK_CHANNEL(render_id);
- channels_[render_id]->has_renderer_ = true;
- return 0;
- }
- return -1;
- }
-
- // webrtc::ViERTP_RTCP
- WEBRTC_FUNC(SetLocalSSRC, (const int channel,
- const unsigned int ssrc,
- const webrtc::StreamType usage,
- const unsigned char idx)) {
- WEBRTC_CHECK_CHANNEL(channel);
- switch (usage) {
- case webrtc::kViEStreamTypeNormal:
- channels_[channel]->ssrcs_[idx] = ssrc;
- break;
- case webrtc::kViEStreamTypeRtx:
- channels_[channel]->rtx_ssrcs_[idx] = ssrc;
- break;
- default:
- return -1;
- }
- return 0;
- }
-
- WEBRTC_FUNC_CONST(SetRemoteSSRCType, (const int channel,
- const webrtc::StreamType usage, const unsigned int ssrc)) {
- WEBRTC_CHECK_CHANNEL(channel);
- if (usage == webrtc::kViEStreamTypeRtx) {
- channels_.find(channel)->second->remote_rtx_ssrc_ = ssrc;
- return 0;
- }
- return -1;
- }
-
- WEBRTC_FUNC_CONST(GetLocalSSRC, (const int channel,
- unsigned int& ssrc)) {
- // ssrcs_[0] is the default local ssrc.
- WEBRTC_CHECK_CHANNEL(channel);
- ssrc = channels_.find(channel)->second->ssrcs_[0];
- return 0;
- }
- WEBRTC_STUB_CONST(GetRemoteSSRC, (const int, unsigned int&));
- WEBRTC_STUB_CONST(GetRemoteCSRCs, (const int, unsigned int*));
-
- WEBRTC_FUNC(SetRtxSendPayloadType,
- (const int channel,
- const uint8 payload_type,
- const uint8 associated_payload_type)) {
- WEBRTC_CHECK_CHANNEL(channel);
- assert(payload_type >= 0);
- assert(associated_payload_type >= 0);
- channels_[channel]->rtx_send_payload_types_[payload_type] =
- associated_payload_type;
- return 0;
- }
-
- WEBRTC_FUNC(SetRtxReceivePayloadType,
- (const int channel,
- const uint8 payload_type,
- const uint8 associated_payload_type)) {
- WEBRTC_CHECK_CHANNEL(channel);
- assert(payload_type >= 0);
- assert(associated_payload_type >= 0);
- channels_[channel]->rtx_recv_payload_types_[payload_type] =
- associated_payload_type;
- return 0;
- }
-
- WEBRTC_STUB(SetStartSequenceNumber, (const int, unsigned short));
- WEBRTC_FUNC(SetRTCPStatus,
- (const int channel, const webrtc::ViERTCPMode mode)) {
- WEBRTC_CHECK_CHANNEL(channel);
- channels_[channel]->rtcp_status_ = mode;
- return 0;
- }
- WEBRTC_STUB_CONST(GetRTCPStatus, (const int, webrtc::ViERTCPMode&));
- WEBRTC_FUNC(SetRTCPCName, (const int channel,
- const char rtcp_cname[KMaxRTCPCNameLength])) {
- WEBRTC_CHECK_CHANNEL(channel);
- channels_[channel]->cname_.assign(rtcp_cname);
- return 0;
- }
- WEBRTC_FUNC_CONST(GetRTCPCName, (const int channel,
- char rtcp_cname[KMaxRTCPCNameLength])) {
- WEBRTC_CHECK_CHANNEL(channel);
- rtc::strcpyn(rtcp_cname, KMaxRTCPCNameLength,
- channels_.find(channel)->second->cname_.c_str());
- return 0;
- }
- WEBRTC_STUB_CONST(GetRemoteRTCPCName, (const int, char*));
- WEBRTC_STUB(SendApplicationDefinedRTCPPacket, (const int, const unsigned char,
- unsigned int, const char*, unsigned short));
- WEBRTC_FUNC(SetNACKStatus, (const int channel, const bool enable)) {
- WEBRTC_CHECK_CHANNEL(channel);
- channels_[channel]->nack_ = enable;
- channels_[channel]->hybrid_nack_fec_ = false;
- return 0;
- }
- WEBRTC_STUB(SetFECStatus, (const int, const bool, const unsigned char,
- const unsigned char));
- WEBRTC_FUNC(SetHybridNACKFECStatus, (const int channel, const bool enable,
- const unsigned char red_type, const unsigned char fec_type)) {
- WEBRTC_CHECK_CHANNEL(channel);
- if (red_type == fec_type ||
- red_type == channels_[channel]->send_codec.plType ||
- fec_type == channels_[channel]->send_codec.plType) {
- return -1;
- }
- channels_[channel]->nack_ = false;
- channels_[channel]->hybrid_nack_fec_ = enable;
- return 0;
- }
- WEBRTC_FUNC(SetKeyFrameRequestMethod,
- (const int channel,
- const webrtc::ViEKeyFrameRequestMethod method)) {
- WEBRTC_CHECK_CHANNEL(channel);
- channels_[channel]->key_frame_request_method_ = method;
- return 0;
- }
- WEBRTC_FUNC(SetSenderBufferingMode, (int channel, int target_delay)) {
- WEBRTC_CHECK_CHANNEL(channel);
- channels_[channel]->sender_target_delay_ = target_delay;
- return 0;
- }
- WEBRTC_FUNC(SetReceiverBufferingMode, (int channel, int target_delay)) {
- WEBRTC_CHECK_CHANNEL(channel);
- channels_[channel]->receiver_target_delay_ = target_delay;
- return 0;
- }
- // |Send| and |receive| are stored locally in variables that more clearly
- // explain what they mean.
- WEBRTC_FUNC(SetRembStatus, (int channel, bool send, bool receive)) {
- WEBRTC_CHECK_CHANNEL(channel);
- channels_[channel]->remb_contribute_ = receive;
- channels_[channel]->remb_bw_partition_ = send;
- return 0;
- }
- WEBRTC_FUNC(SetTMMBRStatus, (const int channel, const bool enable)) {
- WEBRTC_CHECK_CHANNEL(channel);
- channels_[channel]->tmmbr_ = enable;
- return 0;
- }
- WEBRTC_FUNC(SetSendTimestampOffsetStatus, (int channel, bool enable,
- int id)) {
- WEBRTC_CHECK_CHANNEL(channel);
- channels_[channel]->rtp_offset_send_id_ = enable? id : -1;
- return 0;
- }
- WEBRTC_FUNC(SetReceiveTimestampOffsetStatus, (int channel, bool enable,
- int id)) {
- WEBRTC_CHECK_CHANNEL(channel);
- channels_[channel]->rtp_offset_receive_id_ = enable? id : -1;
- return 0;
- }
- WEBRTC_FUNC(SetSendAbsoluteSendTimeStatus, (int channel, bool enable,
- int id)) {
- WEBRTC_CHECK_CHANNEL(channel);
- channels_[channel]->rtp_absolute_send_time_send_id_ = enable? id : -1;
- return 0;
- }
- WEBRTC_FUNC(SetReceiveAbsoluteSendTimeStatus, (int channel, bool enable,
- int id)) {
- WEBRTC_CHECK_CHANNEL(channel);
- channels_[channel]->rtp_absolute_send_time_receive_id_ = enable? id : -1;
- return 0;
- }
- WEBRTC_FUNC(SetSendVideoRotationStatus, (int channel, bool enable, int id)) {
- WEBRTC_CHECK_CHANNEL(channel);
- channels_[channel]->rtp_video_rotation_send_id_ = enable? id : -1;
- return 0;
- }
- WEBRTC_FUNC(SetReceiveVideoRotationStatus,
- (int channel, bool enable, int id)) {
- WEBRTC_CHECK_CHANNEL(channel);
- channels_[channel]->rtp_video_rotation_receive_id_ = enable? id : -1;
- return 0;
- }
- WEBRTC_STUB(SetRtcpXrRrtrStatus, (int, bool));
- WEBRTC_FUNC(SetTransmissionSmoothingStatus, (int channel, bool enable)) {
- WEBRTC_CHECK_CHANNEL(channel);
- channels_[channel]->transmission_smoothing_ = enable;
- return 0;
- }
- WEBRTC_FUNC(SetReservedTransmitBitrate, (int channel,
- unsigned int reserved_transmit_bitrate_bps)) {
- WEBRTC_CHECK_CHANNEL(channel);
- channels_[channel]->reserved_transmit_bitrate_bps_ =
- reserved_transmit_bitrate_bps;
- return 0;
- }
- WEBRTC_STUB_CONST(GetSendRtcpPacketTypeCounter, (int,
- webrtc::RtcpPacketTypeCounter*));
- WEBRTC_STUB_CONST(GetReceiveRtcpPacketTypeCounter, (int,
- webrtc::RtcpPacketTypeCounter*));
- WEBRTC_STUB_CONST(GetReceivedRTCPStatistics, (const int, unsigned short&,
- unsigned int&, unsigned int&, unsigned int&, int64_t&));
- WEBRTC_STUB_CONST(GetSentRTCPStatistics, (const int, unsigned short&,
- unsigned int&, unsigned int&, unsigned int&, int64_t&));
- WEBRTC_STUB_CONST(GetRTPStatistics, (const int, size_t&, unsigned int&,
- size_t&, unsigned int&));
- WEBRTC_STUB_CONST(GetReceiveChannelRtcpStatistics, (const int,
- webrtc::RtcpStatistics&, int64_t&));
- WEBRTC_STUB_CONST(GetSendChannelRtcpStatistics, (const int,
- webrtc::RtcpStatistics&, int64_t&));
- WEBRTC_STUB_CONST(GetRtpStatistics, (const int, webrtc::StreamDataCounters&,
- webrtc::StreamDataCounters&));
- WEBRTC_FUNC_CONST(GetBandwidthUsage, (const int channel,
- unsigned int& total_bitrate, unsigned int& video_bitrate,
- unsigned int& fec_bitrate, unsigned int& nack_bitrate)) {
- WEBRTC_CHECK_CHANNEL(channel);
- std::map<int, Channel*>::const_iterator it = channels_.find(channel);
- if (it->second->send) {
- video_bitrate = it->second->send_video_bitrate_;
- fec_bitrate = it->second->send_fec_bitrate_;
- nack_bitrate = it->second->send_nack_bitrate_;
- total_bitrate = video_bitrate + fec_bitrate + nack_bitrate;
- } else {
- total_bitrate = 0;
- video_bitrate = 0;
- fec_bitrate = 0;
- nack_bitrate = 0;
- }
- return 0;
- }
- WEBRTC_FUNC_CONST(GetEstimatedSendBandwidth, (const int channel,
- unsigned int* send_bandwidth_estimate)) {
- WEBRTC_CHECK_CHANNEL(channel);
- std::map<int, Channel*>::const_iterator it = channels_.find(channel);
- // Assume the current video, fec and nack bitrate sums up to our estimate.
- if (it->second->send) {
- it = channels_.find(GetOriginalChannelId(channel));
- *send_bandwidth_estimate = it->second->send_bandwidth_;
- } else {
- *send_bandwidth_estimate = 0;
- }
- return 0;
- }
- WEBRTC_FUNC_CONST(GetEstimatedReceiveBandwidth, (const int channel,
- unsigned int* receive_bandwidth_estimate)) {
- WEBRTC_CHECK_CHANNEL(channel);
- std::map<int, Channel*>::const_iterator it = channels_.find(channel);
- if (it->second->receive_) {
- it = channels_.find(GetOriginalChannelId(channel));
- *receive_bandwidth_estimate = it->second->receive_bandwidth_;
- } else {
- *receive_bandwidth_estimate = 0;
- }
- return 0;
- }
- WEBRTC_STUB(RegisterSendChannelRtcpStatisticsCallback,
- (int, webrtc::RtcpStatisticsCallback*));
- WEBRTC_STUB(DeregisterSendChannelRtcpStatisticsCallback,
- (int, webrtc::RtcpStatisticsCallback*));
- WEBRTC_STUB(RegisterReceiveChannelRtcpStatisticsCallback,
- (int, webrtc::RtcpStatisticsCallback*));
- WEBRTC_STUB(DeregisterReceiveChannelRtcpStatisticsCallback,
- (int, webrtc::RtcpStatisticsCallback*));
- WEBRTC_STUB(RegisterSendChannelRtpStatisticsCallback,
- (int, webrtc::StreamDataCountersCallback*));
- WEBRTC_STUB(DeregisterSendChannelRtpStatisticsCallback,
- (int, webrtc::StreamDataCountersCallback*));
- WEBRTC_STUB(RegisterReceiveChannelRtpStatisticsCallback,
- (int, webrtc::StreamDataCountersCallback*));
- WEBRTC_STUB(DeregisterReceiveChannelRtpStatisticsCallback,
- (int, webrtc::StreamDataCountersCallback*));
- WEBRTC_STUB(RegisterSendBitrateObserver,
- (int, webrtc::BitrateStatisticsObserver*));
- WEBRTC_STUB(DeregisterSendBitrateObserver,
- (int, webrtc::BitrateStatisticsObserver*));
- WEBRTC_STUB(RegisterSendFrameCountObserver,
- (int, webrtc::FrameCountObserver*));
- WEBRTC_STUB(DeregisterSendFrameCountObserver,
- (int, webrtc::FrameCountObserver*));
- WEBRTC_STUB(RegisterRtcpPacketTypeCounterObserver,
- (int, webrtc::RtcpPacketTypeCounterObserver*));
-
- WEBRTC_STUB(StartRTPDump, (const int, const char*, webrtc::RTPDirections));
- WEBRTC_STUB(StopRTPDump, (const int, webrtc::RTPDirections));
- WEBRTC_STUB(RegisterRTPObserver, (const int, webrtc::ViERTPObserver&));
- WEBRTC_STUB(DeregisterRTPObserver, (const int));
-
- // webrtc::ViEImageProcess
- WEBRTC_STUB(RegisterCaptureEffectFilter, (const int,
- webrtc::ViEEffectFilter&));
- WEBRTC_STUB(DeregisterCaptureEffectFilter, (const int));
- WEBRTC_STUB(RegisterSendEffectFilter, (const int,
- webrtc::ViEEffectFilter&));
- WEBRTC_STUB(DeregisterSendEffectFilter, (const int));
- WEBRTC_STUB(RegisterRenderEffectFilter, (const int,
- webrtc::ViEEffectFilter&));
- WEBRTC_STUB(DeregisterRenderEffectFilter, (const int));
- WEBRTC_STUB(EnableDeflickering, (const int, const bool));
- WEBRTC_FUNC(EnableDenoising, (const int capture_id, const bool denoising)) {
- WEBRTC_CHECK_CAPTURER(capture_id);
- capturers_[capture_id]->set_denoising(denoising);
- return 0;
- }
- WEBRTC_STUB(EnableColorEnhancement, (const int, const bool));
- // webrtc::ViEExternalCodec
- WEBRTC_FUNC(RegisterExternalSendCodec,
- (const int channel,
- const unsigned char pl_type,
- webrtc::VideoEncoder*,
- bool internal_source)) {
- WEBRTC_CHECK_CHANNEL(channel);
- ExternalEncoderInfo info;
- info.internal_source = internal_source;
- channels_[channel]->ext_encoders_[pl_type] = info;
- return 0;
- }
- WEBRTC_FUNC(DeRegisterExternalSendCodec,
- (const int channel, const unsigned char pl_type)) {
- WEBRTC_CHECK_CHANNEL(channel);
- channels_[channel]->ext_encoders_.erase(pl_type);
- return 0;
- }
- WEBRTC_FUNC(RegisterExternalReceiveCodec,
- (const int channel, const unsigned char pl_type, webrtc::VideoDecoder*,
- bool, int)) {
- WEBRTC_CHECK_CHANNEL(channel);
- channels_[channel]->ext_decoder_pl_types_.insert(pl_type);
- return 0;
- }
- WEBRTC_FUNC(DeRegisterExternalReceiveCodec,
- (const int channel, const unsigned char pl_type)) {
- WEBRTC_CHECK_CHANNEL(channel);
- channels_[channel]->ext_decoder_pl_types_.erase(pl_type);
- return 0;
- }
-
- private:
- bool IsChannelId(int id) const {
- return (id >= kViEChannelIdBase && id <= kViEChannelIdMax);
- }
- bool IsCapturerId(int id) const {
- return (id >= kViECaptureIdBase && id <= kViECaptureIdMax);
- }
-
- bool inited_;
- int last_channel_;
- std::map<int, Channel*> channels_;
- bool fail_create_channel_;
- int last_capturer_;
- std::map<int, Capturer*> capturers_;
- bool fail_alloc_capturer_;
- const cricket::VideoCodec* const* codecs_;
- int num_codecs_;
- int num_set_send_codecs_; // how many times we call SetSendCodec().
-};
-
} // namespace cricket
#endif // TALK_MEDIA_WEBRTC_FAKEWEBRTCVIDEOENGINE_H_
diff --git a/talk/media/webrtc/webrtcmediaengine.cc b/talk/media/webrtc/webrtcmediaengine.cc
index 37705e2..ca36f73 100644
--- a/talk/media/webrtc/webrtcmediaengine.cc
+++ b/talk/media/webrtc/webrtcmediaengine.cc
@@ -28,27 +28,11 @@
#if defined(LIBPEERCONNECTION_LIB) || defined(LIBPEERCONNECTION_IMPLEMENTATION)
#include "talk/media/webrtc/webrtcmediaengine.h"
-#include "talk/media/webrtc/webrtcvideoengine.h"
#include "talk/media/webrtc/webrtcvideoengine2.h"
#include "talk/media/webrtc/webrtcvoiceengine.h"
-#include "webrtc/system_wrappers/interface/field_trial.h"
namespace cricket {
-class WebRtcMediaEngine
- : public CompositeMediaEngine<WebRtcVoiceEngine, WebRtcVideoEngine> {
- public:
- WebRtcMediaEngine() {}
- WebRtcMediaEngine(webrtc::AudioDeviceModule* adm,
- webrtc::AudioDeviceModule* adm_sc,
- WebRtcVideoEncoderFactory* encoder_factory,
- WebRtcVideoDecoderFactory* decoder_factory) {
- voice_.SetAudioDeviceModule(adm, adm_sc);
- video_.SetExternalEncoderFactory(encoder_factory);
- video_.SetExternalDecoderFactory(decoder_factory);
- }
-};
-
class WebRtcMediaEngine2
: public CompositeMediaEngine<WebRtcVoiceEngine, WebRtcVideoEngine2> {
public:
@@ -70,10 +54,6 @@
webrtc::AudioDeviceModule* adm_sc,
cricket::WebRtcVideoEncoderFactory* encoder_factory,
cricket::WebRtcVideoDecoderFactory* decoder_factory) {
- if (webrtc::field_trial::FindFullName("WebRTC-NewVideoAPI") == "Disabled") {
- return new cricket::WebRtcMediaEngine(adm, adm_sc, encoder_factory,
- decoder_factory);
- }
return new cricket::WebRtcMediaEngine2(adm, adm_sc, encoder_factory,
decoder_factory);
}
@@ -85,12 +65,6 @@
namespace cricket {
-// Used by ChannelManager when no media engine is passed in to it
-// explicitly (acts as a default).
-MediaEngineInterface* WebRtcMediaEngineFactory::Create() {
- return new cricket::WebRtcMediaEngine();
-}
-
// Used by PeerConnectionFactory to create a media engine passed into
// ChannelManager.
MediaEngineInterface* WebRtcMediaEngineFactory::Create(
diff --git a/talk/media/webrtc/webrtcvideoengine.cc b/talk/media/webrtc/webrtcvideoengine.cc
index 5c41c43..6ff09a3 100644
--- a/talk/media/webrtc/webrtcvideoengine.cc
+++ b/talk/media/webrtc/webrtcvideoengine.cc
@@ -1,4246 +1 @@
-/*
- * libjingle
- * Copyright 2004 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifdef HAVE_WEBRTC_VIDEO
-#include "talk/media/webrtc/webrtcvideoengine.h"
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <math.h>
-#include <algorithm>
-#include <set>
-
-#include "talk/media/base/constants.h"
-#include "talk/media/base/rtputils.h"
-#include "talk/media/base/streamparams.h"
-#include "talk/media/base/videoadapter.h"
-#include "talk/media/base/videocapturer.h"
-#include "talk/media/base/videorenderer.h"
-#include "talk/media/devices/filevideocapturer.h"
-#include "talk/media/webrtc/constants.h"
-#include "talk/media/webrtc/simulcast.h"
-#include "talk/media/webrtc/webrtcpassthroughrender.h"
-#include "talk/media/webrtc/webrtcvideocapturer.h"
-#include "talk/media/webrtc/webrtcvideodecoderfactory.h"
-#include "talk/media/webrtc/webrtcvideoencoderfactory.h"
-#include "talk/media/webrtc/webrtcvideoframe.h"
-#include "talk/media/webrtc/webrtcvie.h"
-#include "talk/media/webrtc/webrtcvoe.h"
-#include "talk/media/webrtc/webrtcvoiceengine.h"
-#include "webrtc/base/basictypes.h"
-#include "webrtc/base/buffer.h"
-#include "webrtc/base/byteorder.h"
-#include "webrtc/base/checks.h"
-#include "webrtc/base/common.h"
-#include "webrtc/base/cpumonitor.h"
-#include "webrtc/base/logging.h"
-#include "webrtc/base/stringutils.h"
-#include "webrtc/base/thread.h"
-#include "webrtc/base/timeutils.h"
-#include "webrtc/experiments.h"
-#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
-#include "webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.h"
-#include "webrtc/modules/video_coding/codecs/vp8/vp8_factory.h"
-#include "webrtc/system_wrappers/interface/field_trial.h"
-
-namespace {
-
-cricket::VideoFormat CreateVideoFormat(int width, int height, int framerate) {
- return cricket::VideoFormat(
- width,
- height,
- cricket::VideoFormat::FpsToInterval(framerate),
- cricket::FOURCC_ANY);
-}
-
-cricket::VideoFormat VideoFormatFromCodec(const cricket::VideoCodec& codec) {
- return CreateVideoFormat(codec.width, codec.height, codec.framerate);
-}
-
-cricket::VideoFormat VideoFormatFromVieCodec(const webrtc::VideoCodec& codec) {
- return CreateVideoFormat(codec.width, codec.height, codec.maxFramerate);
-}
-
-template <class T>
-void Clamp(cricket::Settable<T>* box, T min, T max) {
- T val;
- if (!box->Get(&val)) {
- return;
- }
- if (val < min) {
- box->Set(min);
- return;
- }
- if (val > max) {
- box->Set(max);
- return;
- }
-}
-
-template <class T>
-bool Changed(cricket::Settable<T> proposed,
- cricket::Settable<T> original) {
- return proposed.IsSet() && proposed != original;
-}
-
-template <class T>
-bool Changed(cricket::Settable<T> proposed,
- cricket::Settable<T> original,
- T* value) {
- return proposed.Get(value) && proposed != original;
-}
-
-// Wrap cricket::WebRtcVideoEncoderFactory as a webrtc::VideoEncoderFactory.
-class EncoderFactoryAdapter : public webrtc::VideoEncoderFactory {
- public:
- // EncoderFactoryAdapter doesn't take ownership of |factory|, which is owned
- // by e.g. PeerConnectionFactory.
- explicit EncoderFactoryAdapter(cricket::WebRtcVideoEncoderFactory* factory)
- : factory_(factory) {}
- virtual ~EncoderFactoryAdapter() {}
-
- // Implement webrtc::VideoEncoderFactory.
- webrtc::VideoEncoder* Create() override {
- return factory_->CreateVideoEncoder(webrtc::kVideoCodecVP8);
- }
-
- void Destroy(webrtc::VideoEncoder* encoder) override {
- return factory_->DestroyVideoEncoder(encoder);
- }
-
- private:
- cricket::WebRtcVideoEncoderFactory* factory_;
-};
-
-} // namespace
-
-namespace cricket {
-
-// Constants defined in talk/media/webrtc/constants.h
-// TODO(pbos): Move these to a separate constants.cc file.
-const int kVideoMtu = 1200;
-const int kVideoRtpBufferSize = 65536;
-
-// TODO(ronghuawu): Change to 640x360.
-const int kMinVideoBitrate = 30;
-const int kStartVideoBitrate = 300;
-const int kMaxVideoBitrate = 2000;
-
-const int kCpuMonitorPeriodMs = 2000; // 2 seconds.
-
-// TODO(pthatcher): Figure out what the proper value here is, or if we
-// can just remove this altogether.
-static const int kDefaultRenderDelayMs = 100;
-
-static const int kDefaultLogSeverity = rtc::LS_WARNING;
-
-static const int kDefaultNumberOfTemporalLayers = 1; // 1:1
-
-static const int kChannelIdUnset = -1;
-static const uint32 kDefaultChannelSsrcKey = 0;
-static const uint32 kSsrcUnset = 0;
-
-static bool BitrateIsSet(int value) {
- return value > kAutoBandwidth;
-}
-
-static int GetBitrate(int value, int deflt) {
- return BitrateIsSet(value) ? value : deflt;
-}
-
-// Static allocation of payload type values for external video codec.
-static int GetExternalVideoPayloadType(size_t index) {
- static const int kExternalVideoPayloadTypeBase = 120;
- index += kExternalVideoPayloadTypeBase;
- ASSERT(index < 128);
- return static_cast<int>(index);
-}
-
-static void LogMultiline(rtc::LoggingSeverity sev, char* text) {
- const char* delim = "\r\n";
- // TODO(fbarchard): Fix strtok lint warning.
- for (char* tok = strtok(text, delim); tok; tok = strtok(NULL, delim)) {
- LOG_V(sev) << tok;
- }
-}
-
-// Severity is an integer because it comes is assumed to be from command line.
-static 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;
-}
-
-static const bool kNotSending = false;
-
-// Default video dscp value.
-// See http://tools.ietf.org/html/rfc2474 for details
-// See also http://tools.ietf.org/html/draft-jennings-rtcweb-qos-00
-static const rtc::DiffServCodePoint kVideoDscpValue =
- rtc::DSCP_AF41;
-
-void AddDefaultFeedbackParams(VideoCodec* codec) {
- codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamCcm, kRtcpFbCcmParamFir));
- codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kParamValueEmpty));
- codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kRtcpFbNackParamPli));
- codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamRemb, kParamValueEmpty));
-}
-
-static VideoCodec MakeVideoCodecWithDefaultFeedbackParams(int payload_type,
- const char* name) {
- VideoCodec codec(payload_type, name, kDefaultVideoMaxWidth,
- kDefaultVideoMaxHeight, kDefaultVideoMaxFramerate, 0);
- AddDefaultFeedbackParams(&codec);
- return codec;
-}
-
-bool CodecIsInternallySupported(const std::string& codec_name) {
- if (CodecNamesEq(codec_name, kVp8CodecName)) {
- return true;
- }
- if (CodecNamesEq(codec_name, kVp9CodecName)) {
- const std::string group_name =
- webrtc::field_trial::FindFullName("WebRTC-SupportVP9");
- return group_name == "Enabled" || group_name == "EnabledByFlag";
- }
- return false;
-}
-
-std::vector<VideoCodec> DefaultVideoCodecList() {
- std::vector<VideoCodec> codecs;
- if (CodecIsInternallySupported(kVp9CodecName)) {
- codecs.push_back(MakeVideoCodecWithDefaultFeedbackParams(kDefaultVp9PlType,
- kVp9CodecName));
- // TODO(andresp): Add rtx codec for vp9 and verify it works.
- }
- codecs.push_back(MakeVideoCodecWithDefaultFeedbackParams(kDefaultVp8PlType,
- kVp8CodecName));
- codecs.push_back(
- VideoCodec::CreateRtxCodec(kDefaultRtxVp8PlType, kDefaultVp8PlType));
- codecs.push_back(VideoCodec(kDefaultRedPlType, kRedCodecName));
- codecs.push_back(VideoCodec(kDefaultUlpfecType, kUlpfecCodecName));
- return codecs;
-}
-
-WebRtcSimulcastEncoderFactory::WebRtcSimulcastEncoderFactory(
- cricket::WebRtcVideoEncoderFactory* factory)
- : factory_(factory) {
-}
-
-WebRtcSimulcastEncoderFactory::~WebRtcSimulcastEncoderFactory() {
-}
-
-bool WebRtcSimulcastEncoderFactory::UseSimulcastEncoderFactory(
- const std::vector<WebRtcVideoEncoderFactory::VideoCodec>& codecs) {
- // If any codec is VP8, use the simulcast factory. If asked to create a
- // non-VP8 codec, we'll just return a contained factory encoder directly.
- for (const auto& codec: codecs) {
- if (codec.type == webrtc::kVideoCodecVP8) {
- return true;
- }
- }
- return false;
-}
-
-webrtc::VideoEncoder* WebRtcSimulcastEncoderFactory::CreateVideoEncoder(
- webrtc::VideoCodecType type) {
- ASSERT(factory_ != NULL);
- // If it's a codec type we can simulcast, create a wrapped encoder.
- if (type == webrtc::kVideoCodecVP8) {
- return new webrtc::SimulcastEncoderAdapter(
- new EncoderFactoryAdapter(factory_));
- }
- webrtc::VideoEncoder* encoder = factory_->CreateVideoEncoder(type);
- if (encoder) {
- non_simulcast_encoders_.push_back(encoder);
- }
- return encoder;
-}
-
-const std::vector<WebRtcVideoEncoderFactory::VideoCodec>&
-WebRtcSimulcastEncoderFactory::codecs() const {
- return factory_->codecs();
-}
-
-bool WebRtcSimulcastEncoderFactory::EncoderTypeHasInternalSource(
- webrtc::VideoCodecType type) const {
- return factory_->EncoderTypeHasInternalSource(type);
-}
-
-void WebRtcSimulcastEncoderFactory::DestroyVideoEncoder(
- webrtc::VideoEncoder* encoder) {
- // Check first to see if the encoder wasn't wrapped in a
- // SimulcastEncoderAdapter. In that case, ask the factory to destroy it.
- if (std::remove(non_simulcast_encoders_.begin(),
- non_simulcast_encoders_.end(), encoder) !=
- non_simulcast_encoders_.end()) {
- factory_->DestroyVideoEncoder(encoder);
- return;
- }
-
- // Otherwise, SimulcastEncoderAdapter can be deleted directly, and will call
- // DestroyVideoEncoder on the factory for individual encoder instances.
- delete encoder;
-}
-
-struct FlushBlackFrameData : public rtc::MessageData {
- FlushBlackFrameData(uint32 s, int64 t, int i)
- : ssrc(s), timestamp(t), interval(i) {
- }
- uint32 ssrc;
- int64 timestamp;
- int interval;
-};
-
-class WebRtcRenderAdapter : public webrtc::ExternalRenderer {
- public:
- WebRtcRenderAdapter(VideoRenderer* renderer, int channel_id)
- : renderer_(renderer),
- channel_id_(channel_id),
- width_(0),
- height_(0),
- capture_start_rtp_time_stamp_(-1),
- capture_start_ntp_time_ms_(0) {
- }
-
- virtual ~WebRtcRenderAdapter() {
- }
-
- void SetRenderer(VideoRenderer* renderer) {
- rtc::CritScope cs(&crit_);
- renderer_ = renderer;
- // FrameSizeChange may have already been called when renderer was not set.
- // If so we should call SetSize here.
- // TODO(ronghuawu): Add unit test for this case. Didn't do it now
- // because the WebRtcRenderAdapter is currently hiding in cc file. No
- // good way to get access to it from the unit test.
- if (width_ > 0 && height_ > 0 && renderer_) {
- if (!renderer_->SetSize(width_, height_, 0)) {
- LOG(LS_ERROR)
- << "WebRtcRenderAdapter (channel " << channel_id_
- << ") SetRenderer failed to SetSize to: "
- << width_ << "x" << height_;
- }
- }
- }
-
- // Implementation of webrtc::ExternalRenderer.
- virtual int FrameSizeChange(unsigned int width, unsigned int height,
- unsigned int /*number_of_streams*/) {
- rtc::CritScope cs(&crit_);
- width_ = width;
- height_ = height;
- LOG(LS_INFO) << "WebRtcRenderAdapter (channel " << channel_id_
- << ") frame size changed to: "
- << width << "x" << height;
- if (!renderer_) {
- LOG(LS_VERBOSE) << "WebRtcRenderAdapter (channel " << channel_id_
- << ") the renderer has not been set. "
- << "SetSize will be called later in SetRenderer.";
- return 0;
- }
- return renderer_->SetSize(width_, height_, 0) ? 0 : -1;
- }
-
- virtual int DeliverFrame(unsigned char* buffer,
- size_t buffer_size,
- uint32_t rtp_time_stamp,
- int64_t ntp_time_ms,
- int64_t render_time,
- void* handle) {
- CHECK(false) << "All frames should be delivered as I420 frames through "
- "DeliverI420Frame.";
- return 0;
- }
-
- virtual int DeliverI420Frame(const webrtc::I420VideoFrame& webrtc_frame) {
- rtc::CritScope cs(&crit_);
- const int64_t elapsed_time_ms = ElapsedTimeMs(webrtc_frame.timestamp());
- UpdateFrameStats(elapsed_time_ms, webrtc_frame.ntp_time_ms());
- if (!renderer_) {
- return 0;
- }
-
- WebRtcVideoFrame cricket_frame(
- webrtc_frame.video_frame_buffer(),
- elapsed_time_ms * rtc::kNumNanosecsPerMillisec,
- webrtc_frame.render_time_ms() * rtc::kNumNanosecsPerMillisec,
- webrtc_frame.rotation());
- return renderer_->RenderFrame(&cricket_frame) ? 0 : -1;
- }
-
- virtual bool IsTextureSupported() { return true; }
-
- unsigned int width() {
- rtc::CritScope cs(&crit_);
- return width_;
- }
-
- unsigned int height() {
- rtc::CritScope cs(&crit_);
- return height_;
- }
-
- int framerate() {
- rtc::CritScope cs(&crit_);
- return static_cast<int>(frame_rate_tracker_.units_second());
- }
-
- VideoRenderer* renderer() {
- rtc::CritScope cs(&crit_);
- return renderer_;
- }
-
- int64 capture_start_ntp_time_ms() {
- rtc::CritScope cs(&crit_);
- return capture_start_ntp_time_ms_;
- }
-
- private:
- int64_t ElapsedTimeMs(uint32_t rtp_time_stamp) {
- if (capture_start_rtp_time_stamp_ < 0) {
- capture_start_rtp_time_stamp_ = rtp_time_stamp;
- }
- const int kVideoCodecClockratekHz = cricket::kVideoCodecClockrate / 1000;
- return (rtp_ts_wraparound_handler_.Unwrap(rtp_time_stamp) -
- capture_start_rtp_time_stamp_) / kVideoCodecClockratekHz;
- }
-
- void UpdateFrameStats(int64_t elapsed_time_ms, int64_t ntp_time_ms) {
- if (ntp_time_ms > 0) {
- capture_start_ntp_time_ms_ = ntp_time_ms - elapsed_time_ms;
- }
- frame_rate_tracker_.Update(1);
- }
-
- rtc::CriticalSection crit_;
- VideoRenderer* renderer_;
- int channel_id_;
- unsigned int width_;
- unsigned int height_;
- rtc::RateTracker frame_rate_tracker_;
- rtc::TimestampWrapAroundHandler rtp_ts_wraparound_handler_;
- int64 capture_start_rtp_time_stamp_;
- int64 capture_start_ntp_time_ms_;
-};
-
-class WebRtcDecoderObserver : public webrtc::ViEDecoderObserver {
- public:
- explicit WebRtcDecoderObserver()
- : framerate_(0),
- bitrate_(0),
- decode_ms_(0),
- max_decode_ms_(0),
- current_delay_ms_(0),
- target_delay_ms_(0),
- jitter_buffer_ms_(0),
- min_playout_delay_ms_(0),
- render_delay_ms_(0) {}
-
- // virtual functions from VieDecoderObserver.
- virtual void IncomingCodecChanged(const int video_channel_id,
- const webrtc::VideoCodec& videoCodec) {}
- virtual void IncomingRate(const int video_channel_id,
- const unsigned int framerate,
- const unsigned int bitrate) {
- rtc::CritScope cs(&crit_);
- framerate_ = framerate;
- bitrate_ = bitrate;
- }
-
- virtual void DecoderTiming(int decode_ms,
- int max_decode_ms,
- int current_delay_ms,
- int target_delay_ms,
- int jitter_buffer_ms,
- int min_playout_delay_ms,
- int render_delay_ms) {
- rtc::CritScope cs(&crit_);
- decode_ms_ = decode_ms;
- max_decode_ms_ = max_decode_ms;
- current_delay_ms_ = current_delay_ms;
- target_delay_ms_ = target_delay_ms;
- jitter_buffer_ms_ = jitter_buffer_ms;
- min_playout_delay_ms_ = min_playout_delay_ms;
- render_delay_ms_ = render_delay_ms;
- }
-
- virtual void RequestNewKeyFrame(const int video_channel_id) {}
-
- // Populate |rinfo| based on previously-set data in |*this|.
- void ExportTo(VideoReceiverInfo* rinfo) {
- rtc::CritScope cs(&crit_);
- rinfo->framerate_rcvd = framerate_;
- rinfo->decode_ms = decode_ms_;
- rinfo->max_decode_ms = max_decode_ms_;
- rinfo->current_delay_ms = current_delay_ms_;
- rinfo->target_delay_ms = target_delay_ms_;
- rinfo->jitter_buffer_ms = jitter_buffer_ms_;
- rinfo->min_playout_delay_ms = min_playout_delay_ms_;
- rinfo->render_delay_ms = render_delay_ms_;
- }
-
- private:
- mutable rtc::CriticalSection crit_;
- int framerate_;
- int bitrate_;
- int decode_ms_;
- int max_decode_ms_;
- int current_delay_ms_;
- int target_delay_ms_;
- int jitter_buffer_ms_;
- int min_playout_delay_ms_;
- int render_delay_ms_;
-};
-
-class WebRtcEncoderObserver : public webrtc::ViEEncoderObserver {
- public:
- explicit WebRtcEncoderObserver()
- : framerate_(0), bitrate_(0), suspended_(false) {}
-
- // virtual functions from VieEncoderObserver.
- virtual void OutgoingRate(const int video_channel_id,
- const unsigned int framerate,
- const unsigned int bitrate) {
- rtc::CritScope cs(&crit_);
- framerate_ = framerate;
- bitrate_ = bitrate;
- }
-
- virtual void SuspendChange(int video_channel_id, bool is_suspended) {
- rtc::CritScope cs(&crit_);
- suspended_ = is_suspended;
- }
-
- int framerate() const {
- rtc::CritScope cs(&crit_);
- return framerate_;
- }
- int bitrate() const {
- rtc::CritScope cs(&crit_);
- return bitrate_;
- }
- bool suspended() const {
- rtc::CritScope cs(&crit_);
- return suspended_;
- }
-
- private:
- mutable rtc::CriticalSection crit_;
- int framerate_;
- int bitrate_;
- bool suspended_;
-};
-
-struct CapturedFrameInfo {
- CapturedFrameInfo()
- : width(0),
- height(0),
- screencast(false),
- elapsed_time(-1),
- timestamp(-1) {}
- CapturedFrameInfo(size_t width,
- size_t height,
- bool screencast,
- int64_t elapsed_time,
- int64_t timestamp)
- : width(width),
- height(height),
- screencast(screencast),
- elapsed_time(elapsed_time),
- timestamp(timestamp) {}
-
- size_t width;
- size_t height;
- bool screencast;
-
- int64_t elapsed_time;
- int64_t timestamp;
-};
-
-class WebRtcLocalStreamInfo {
- public:
- WebRtcLocalStreamInfo() : time_stamp_(-1) {}
- int64 time_stamp() const {
- rtc::CritScope cs(&crit_);
- return time_stamp_;
- }
- int framerate() {
- rtc::CritScope cs(&crit_);
- return static_cast<int>(rate_tracker_.units_second());
- }
-
- void UpdateFrame(const VideoFrame* frame) {
- rtc::CritScope cs(&crit_);
- time_stamp_ = frame->GetTimeStamp();
- rate_tracker_.Update(1);
- }
-
- private:
- mutable rtc::CriticalSection crit_;
- int64 time_stamp_;
- rtc::RateTracker rate_tracker_;
-
- DISALLOW_COPY_AND_ASSIGN(WebRtcLocalStreamInfo);
-};
-
-// WebRtcVideoChannelRecvInfo is a container class with members such as renderer
-// and a decoder observer that is used by receive channels.
-// It must exist as long as the receive channel is connected to renderer or a
-// decoder observer in this class and methods in the class should only be called
-// from the worker thread.
-class WebRtcVideoChannelRecvInfo {
- public:
- typedef std::map<int, webrtc::VideoDecoder*> DecoderMap; // Key: payload type
- explicit WebRtcVideoChannelRecvInfo(int channel_id)
- : channel_id_(channel_id), render_adapter_(NULL, channel_id) {}
- int channel_id() { return channel_id_; }
- void SetRenderer(VideoRenderer* renderer) {
- render_adapter_.SetRenderer(renderer);
- }
- WebRtcRenderAdapter* render_adapter() { return &render_adapter_; }
- WebRtcDecoderObserver* decoder_observer() { return &decoder_observer_; }
- void RegisterDecoder(int pl_type, webrtc::VideoDecoder* decoder) {
- ASSERT(!IsDecoderRegistered(pl_type));
- registered_decoders_[pl_type] = decoder;
- }
- bool IsDecoderRegistered(int pl_type) {
- return registered_decoders_.count(pl_type) != 0;
- }
- const DecoderMap& registered_decoders() {
- return registered_decoders_;
- }
- void ClearRegisteredDecoders() {
- registered_decoders_.clear();
- }
-
- private:
- int channel_id_; // Webrtc video channel number.
- // Renderer for this channel.
- WebRtcRenderAdapter render_adapter_;
- WebRtcDecoderObserver decoder_observer_;
- DecoderMap registered_decoders_;
-};
-
-class WebRtcOveruseObserver : public webrtc::CpuOveruseObserver {
- public:
- explicit WebRtcOveruseObserver(CoordinatedVideoAdapter* video_adapter)
- : video_adapter_(video_adapter),
- enabled_(false) {
- }
-
- // TODO(mflodman): Consider sending resolution as part of event, to let
- // adapter know what resolution the request is based on. Helps eliminate stale
- // data, race conditions.
- void OveruseDetected() override {
- rtc::CritScope cs(&crit_);
- if (!enabled_) {
- return;
- }
-
- video_adapter_->OnCpuResolutionRequest(CoordinatedVideoAdapter::DOWNGRADE);
- }
-
- void NormalUsage() override {
- rtc::CritScope cs(&crit_);
- if (!enabled_) {
- return;
- }
-
- video_adapter_->OnCpuResolutionRequest(CoordinatedVideoAdapter::UPGRADE);
- }
-
- void Enable(bool enable) {
- LOG(LS_INFO) << "WebRtcOveruseObserver enable: " << enable;
- rtc::CritScope cs(&crit_);
- enabled_ = enable;
- }
-
- bool enabled() const { return enabled_; }
-
- private:
- CoordinatedVideoAdapter* video_adapter_;
- bool enabled_;
- rtc::CriticalSection crit_;
-};
-
-
-class WebRtcVideoChannelSendInfo : public sigslot::has_slots<> {
- public:
- typedef std::map<int, webrtc::VideoEncoder*> EncoderMap; // Key: payload type
-
- enum AdaptFormatType {
- // This is how we make SetSendStreamFormat take precedence over
- // SetSendCodecs.
- kAdaptFormatTypeNone = 0, // Unset
- kAdaptFormatTypeCodec = 1, // From SetSendCodec
- kAdaptFormatTypeStream = 2, // From SetStreamFormat
- };
-
- WebRtcVideoChannelSendInfo(int channel_id, int capture_id,
- webrtc::ViEExternalCapture* external_capture,
- rtc::CpuMonitor* cpu_monitor)
- : channel_id_(channel_id),
- capture_id_(capture_id),
- sending_(false),
- muted_(false),
- video_capturer_(NULL),
- external_capture_(external_capture),
- cpu_monitor_(cpu_monitor),
- old_adaptation_changes_(0),
- adapt_format_type_(kAdaptFormatTypeNone) {
- }
-
- int channel_id() const { return channel_id_; }
- int capture_id() const { return capture_id_; }
- void set_sending(bool sending) { sending_ = sending; }
- bool sending() const { return sending_; }
- void set_send_params(const VideoSendParams& send_params) {
- send_params_ = send_params;
- }
- const VideoSendParams& send_params() const {
- return send_params_;
- }
- const Settable<CapturedFrameInfo>& last_captured_frame_info() const {
- return last_captured_frame_info_;
- }
- void set_muted(bool on) {
- // TODO(asapersson): add support.
- muted_ = on;
- }
- bool muted() {return muted_; }
-
- WebRtcEncoderObserver* encoder_observer() { return &encoder_observer_; }
- webrtc::ViEExternalCapture* external_capture() { return external_capture_; }
- const VideoFormat& adapt_format() const { return adapt_format_; }
- AdaptFormatType adapt_format_type() const { return adapt_format_type_; }
- bool adapt_format_set() const {
- return adapt_format_type() != kAdaptFormatTypeNone;
- }
-
- // Returns true if the last captured frame info changed.
- void SetLastCapturedFrameInfo(
- const VideoFrame* frame, bool screencast, bool* changed) {
- CapturedFrameInfo last;
- *changed =
- !(last_captured_frame_info_.Get(&last) &&
- frame->GetWidth() == last.width &&
- frame->GetHeight() == last.height && screencast == last.screencast);
-
- last_captured_frame_info_.Set(
- CapturedFrameInfo(frame->GetWidth(), frame->GetHeight(), screencast,
- frame->GetElapsedTime(), frame->GetTimeStamp()));
- }
-
- // Tells the video adapter to adapt down to a given format. The
- // type indicates where the format came from, where different types
- // have slightly different behavior and priority.
- void SetAdaptFormat(const VideoFormat& format, AdaptFormatType type) {
- if (type < adapt_format_type_) {
- // Formats from SetSendStream format are higher priority than
- // ones from SetSendCodecs wich is higher priority than not
- // being set. If something lower-prioirty comes in, just ignore
- // it.
- return;
- }
-
- // TODO(pthatcher): Use the adapter for all max size enforcement,
- // both codec-based and SetSendStreamFormat-based. For now, we
- // can't do that without fixing a lot of unit tests.
- if (video_adapter() && type == kAdaptFormatTypeStream) {
- video_adapter()->OnOutputFormatRequest(format);
- }
-
- adapt_format_ = format;
- adapt_format_type_ = type;
- }
-
- int CurrentAdaptReason() const {
- if (!video_adapter()) {
- return CoordinatedVideoAdapter::ADAPTREASON_NONE;
- }
- return video_adapter()->adapt_reason();
- }
- int AdaptChanges() const {
- if (!video_adapter()) {
- return old_adaptation_changes_;
- }
- return old_adaptation_changes_ + video_adapter()->adaptation_changes();
- }
-
- void set_stream_params(const StreamParams& sp) {
- send_params_.stream = sp;
- }
- const StreamParams& stream_params() const { return send_params_.stream; }
- // A default send channel can be non-active if a stream hasn't been
- // added yet, or if all streams have been removed (at which point,
- // Deactive is called).
- bool IsActive() {
- return stream_params().first_ssrc() != 0;
- }
- void Deactivate() {
- send_params_.stream = StreamParams();
- }
-
- WebRtcLocalStreamInfo* local_stream_info() {
- return &local_stream_info_;
- }
- VideoCapturer* video_capturer() {
- return video_capturer_;
- }
- void set_video_capturer(VideoCapturer* video_capturer,
- ViEWrapper* vie_wrapper) {
- if (video_capturer == video_capturer_) {
- return;
- }
-
- CoordinatedVideoAdapter* old_video_adapter = video_adapter();
- if (old_video_adapter) {
- // Get adaptation changes from old video adapter.
- old_adaptation_changes_ += old_video_adapter->adaptation_changes();
- // Disconnect signals from old video adapter.
- SignalCpuAdaptationUnable.disconnect(old_video_adapter);
- if (cpu_monitor_) {
- cpu_monitor_->SignalUpdate.disconnect(old_video_adapter);
- }
- }
-
- video_capturer_ = video_capturer;
-
- vie_wrapper->base()->RegisterCpuOveruseObserver(channel_id_, NULL);
- if (!video_capturer) {
- overuse_observer_.reset();
- return;
- }
-
- CoordinatedVideoAdapter* adapter = video_adapter();
- ASSERT(adapter && "Video adapter should not be null here.");
-
- // TODO(pthatcher): Use the adapter for all max size enforcement,
- // both codec-based and SetSendStreamFormat-based. For now, we
- // can't do that without fixing a lot of unit tests.
- if (adapt_format_type_ == kAdaptFormatTypeStream) {
- adapter->OnOutputFormatRequest(adapt_format_);
- }
-
- UpdateAdapterCpuOptions();
-
- overuse_observer_.reset(new WebRtcOveruseObserver(adapter));
- vie_wrapper->base()->RegisterCpuOveruseObserver(channel_id_,
- overuse_observer_.get());
- // (Dis)connect the video adapter from the cpu monitor as appropriate.
- SetCpuOveruseDetection(
- video_options_.cpu_overuse_detection.GetWithDefaultIfUnset(false));
-
- SignalCpuAdaptationUnable.repeat(adapter->SignalCpuAdaptationUnable);
- }
-
- CoordinatedVideoAdapter* video_adapter() {
- if (!video_capturer_) {
- return NULL;
- }
- return video_capturer_->video_adapter();
- }
- const CoordinatedVideoAdapter* video_adapter() const {
- if (!video_capturer_) {
- return NULL;
- }
- return video_capturer_->video_adapter();
- }
-
- void ApplyCpuOptions(const VideoOptions& video_options) {
- bool cpu_overuse_detection_changed =
- video_options.cpu_overuse_detection.IsSet() &&
- (video_options.cpu_overuse_detection.GetWithDefaultIfUnset(false) !=
- video_options_.cpu_overuse_detection.GetWithDefaultIfUnset(false));
- // Use video_options_.SetAll() instead of assignment so that unset value in
- // video_options will not overwrite the previous option value.
- video_options_.SetAll(video_options);
- UpdateAdapterCpuOptions();
- if (cpu_overuse_detection_changed) {
- SetCpuOveruseDetection(
- video_options_.cpu_overuse_detection.GetWithDefaultIfUnset(false));
- }
- }
-
- void UpdateAdapterCpuOptions() {
- if (!video_capturer_) {
- return;
- }
-
- bool cpu_smoothing, adapt_third;
- float low, med, high;
- bool cpu_adapt =
- video_options_.adapt_input_to_cpu_usage.GetWithDefaultIfUnset(false);
- bool cpu_overuse_detection =
- video_options_.cpu_overuse_detection.GetWithDefaultIfUnset(false);
-
- // TODO(thorcarpenter): Have VideoAdapter be responsible for setting
- // all these video options.
- CoordinatedVideoAdapter* video_adapter = video_capturer_->video_adapter();
- if (video_options_.adapt_input_to_cpu_usage.IsSet() ||
- video_options_.cpu_overuse_detection.IsSet()) {
- video_adapter->set_cpu_adaptation(cpu_adapt || cpu_overuse_detection);
- }
- if (video_options_.adapt_cpu_with_smoothing.Get(&cpu_smoothing)) {
- video_adapter->set_cpu_smoothing(cpu_smoothing);
- }
- if (video_options_.process_adaptation_threshhold.Get(&med)) {
- video_adapter->set_process_threshold(med);
- }
- if (video_options_.system_low_adaptation_threshhold.Get(&low)) {
- video_adapter->set_low_system_threshold(low);
- }
- if (video_options_.system_high_adaptation_threshhold.Get(&high)) {
- video_adapter->set_high_system_threshold(high);
- }
- if (video_options_.video_adapt_third.Get(&adapt_third)) {
- video_adapter->set_scale_third(adapt_third);
- }
- }
-
- void SetCpuOveruseDetection(bool enable) {
- if (overuse_observer_) {
- overuse_observer_->Enable(enable);
- }
-
- // The video adapter is signaled by overuse detection if enabled; otherwise
- // it will be signaled by cpu monitor.
- CoordinatedVideoAdapter* adapter = video_adapter();
- if (adapter) {
- if (cpu_monitor_) {
- if (enable) {
- cpu_monitor_->SignalUpdate.disconnect(adapter);
- } else {
- cpu_monitor_->SignalUpdate.connect(
- adapter, &CoordinatedVideoAdapter::OnCpuLoadUpdated);
- }
- }
- }
- }
-
- void ProcessFrame(const VideoFrame& original_frame, bool mute,
- VideoFrame** processed_frame) {
- if (!mute) {
- *processed_frame = original_frame.Copy(); // Shallow copy.
- } else {
- // Cache a black frame of the same dimensions as original_frame.
- if (black_frame_.GetWidth() != original_frame.GetWidth() ||
- black_frame_.GetHeight() != original_frame.GetHeight()) {
- black_frame_.InitToBlack(static_cast<int>(original_frame.GetWidth()),
- static_cast<int>(original_frame.GetHeight()),
- 1, 1,
- original_frame.GetElapsedTime(),
- original_frame.GetTimeStamp());
- }
- *processed_frame = black_frame_.Copy(); // Shallow copy.
- (*processed_frame)->SetElapsedTime(original_frame.GetElapsedTime());
- (*processed_frame)->SetTimeStamp(original_frame.GetTimeStamp());
- }
- local_stream_info_.UpdateFrame(*processed_frame);
- }
- void RegisterEncoder(int pl_type, webrtc::VideoEncoder* encoder) {
- ASSERT(!IsEncoderRegistered(pl_type));
- registered_encoders_[pl_type] = encoder;
- }
- bool IsEncoderRegistered(int pl_type) {
- return registered_encoders_.count(pl_type) != 0;
- }
- const EncoderMap& registered_encoders() {
- return registered_encoders_;
- }
- void ClearRegisteredEncoders() {
- registered_encoders_.clear();
- }
-
- sigslot::repeater0<> SignalCpuAdaptationUnable;
-
- private:
- int channel_id_;
- int capture_id_;
- VideoSendParams send_params_;
- // TODO(pthatcher): Merge CapturedFrameInfo and LocalStreamInfo.
- Settable<CapturedFrameInfo> last_captured_frame_info_;
- bool sending_;
- bool muted_;
- VideoCapturer* video_capturer_;
- WebRtcEncoderObserver encoder_observer_;
- webrtc::ViEExternalCapture* external_capture_;
- EncoderMap registered_encoders_;
-
- WebRtcLocalStreamInfo local_stream_info_;
-
- rtc::CpuMonitor* cpu_monitor_;
- rtc::scoped_ptr<WebRtcOveruseObserver> overuse_observer_;
-
- int old_adaptation_changes_;
-
- VideoOptions video_options_;
-
- VideoFormat adapt_format_;
- AdaptFormatType adapt_format_type_;
- WebRtcVideoFrame black_frame_; // Cached frame for mute.
-};
-
-static bool GetCpuOveruseOptions(const VideoOptions& options,
- webrtc::CpuOveruseOptions* overuse_options) {
- int underuse_threshold = 0;
- int overuse_threshold = 0;
- if (!options.cpu_underuse_threshold.Get(&underuse_threshold) ||
- !options.cpu_overuse_threshold.Get(&overuse_threshold)) {
- return false;
- }
- if (underuse_threshold <= 0 || overuse_threshold <= 0) {
- return false;
- }
- // Valid thresholds.
- bool encode_usage =
- options.cpu_overuse_encode_usage.GetWithDefaultIfUnset(false);
- overuse_options->enable_capture_jitter_method = !encode_usage;
- overuse_options->enable_encode_usage_method = encode_usage;
- if (encode_usage) {
- // Use method based on encode usage.
- overuse_options->low_encode_usage_threshold_percent = underuse_threshold;
- overuse_options->high_encode_usage_threshold_percent = overuse_threshold;
-
- // Set optional thresholds, if configured.
- int underuse_rsd_threshold = 0;
- if (options.cpu_underuse_encode_rsd_threshold.Get(
- &underuse_rsd_threshold)) {
- overuse_options->low_encode_time_rsd_threshold = underuse_rsd_threshold;
- }
- int overuse_rsd_threshold = 0;
- if (options.cpu_overuse_encode_rsd_threshold.Get(&overuse_rsd_threshold)) {
- overuse_options->high_encode_time_rsd_threshold = overuse_rsd_threshold;
- }
- } else {
- // Use default method based on capture jitter.
- overuse_options->low_capture_jitter_threshold_ms =
- static_cast<float>(underuse_threshold);
- overuse_options->high_capture_jitter_threshold_ms =
- static_cast<float>(overuse_threshold);
- }
- return true;
-}
-
-WebRtcVideoEngine::WebRtcVideoEngine(WebRtcVoiceEngine* voice_engine)
- : voice_engine_(voice_engine), trace_callback_(voice_engine) {
- Construct(new ViEWrapper(), new ViETraceWrapper(), voice_engine,
- new rtc::CpuMonitor(NULL));
-}
-
-WebRtcVideoEngine::WebRtcVideoEngine(WebRtcVoiceEngine* voice_engine,
- ViEWrapper* vie_wrapper,
- rtc::CpuMonitor* cpu_monitor)
- : voice_engine_(voice_engine), trace_callback_(voice_engine) {
- Construct(vie_wrapper, new ViETraceWrapper(), voice_engine, cpu_monitor);
-}
-
-WebRtcVideoEngine::WebRtcVideoEngine(WebRtcVoiceEngine* voice_engine,
- ViEWrapper* vie_wrapper,
- ViETraceWrapper* tracing,
- rtc::CpuMonitor* cpu_monitor)
- : voice_engine_(voice_engine), trace_callback_(voice_engine) {
- Construct(vie_wrapper, tracing, voice_engine, cpu_monitor);
-}
-
-void WebRtcVideoEngine::Construct(ViEWrapper* vie_wrapper,
- ViETraceWrapper* tracing,
- WebRtcVoiceEngine* voice_engine,
- rtc::CpuMonitor* cpu_monitor) {
- LOG(LS_INFO) << "WebRtcVideoEngine::WebRtcVideoEngine";
- worker_thread_ = NULL;
- vie_wrapper_.reset(vie_wrapper);
- vie_wrapper_base_initialized_ = false;
- tracing_.reset(tracing);
- initialized_ = false;
- SetTraceFilter(SeverityToFilter(kDefaultLogSeverity));
- render_module_.reset(new WebRtcPassthroughRender());
- capture_started_ = false;
- decoder_factory_ = NULL;
- encoder_factory_ = NULL;
- cpu_monitor_.reset(cpu_monitor);
-
- SetTraceOptions("");
- if (tracing_->SetTraceCallback(&trace_callback_) != 0) {
- LOG_RTCERR1(SetTraceCallback, &trace_callback_);
- }
-
- default_video_codec_list_ = DefaultVideoCodecList();
-
- // Set default quality levels for our supported codecs. We override them here
- // if we know your cpu performance is low, and they can be updated explicitly
- // by calling SetDefaultCodec. For example by a flute preference setting, or
- // by the server with a jec in response to our reported system info.
- CHECK(SetDefaultCodec(default_video_codec_list_.front()))
- << "Failed to initialize list of supported codec types.";
-
- // Consider jitter, packet loss, etc when rendering. This will
- // theoretically make rendering more smooth.
- EnableTimedRender();
-
- // Load our RTP Header extensions.
- rtp_header_extensions_.push_back(
- RtpHeaderExtension(kRtpTimestampOffsetHeaderExtension,
- kRtpTimestampOffsetHeaderExtensionDefaultId));
- rtp_header_extensions_.push_back(
- RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension,
- kRtpAbsoluteSenderTimeHeaderExtensionDefaultId));
- rtp_header_extensions_.push_back(
- RtpHeaderExtension(kRtpVideoRotationHeaderExtension,
- kRtpVideoRotationHeaderExtensionDefaultId));
-}
-
-WebRtcVideoEngine::~WebRtcVideoEngine() {
- LOG(LS_INFO) << "WebRtcVideoEngine::~WebRtcVideoEngine";
- if (initialized_) {
- Terminate();
- }
-
- tracing_->SetTraceCallback(NULL);
- // Test to see if the media processor was deregistered properly.
- ASSERT(SignalMediaFrame.is_empty());
-}
-
-bool WebRtcVideoEngine::Init(rtc::Thread* worker_thread) {
- LOG(LS_INFO) << "WebRtcVideoEngine::Init";
- worker_thread_ = worker_thread;
- ASSERT(worker_thread_ != NULL);
-
- cpu_monitor_->set_thread(worker_thread_);
- if (!cpu_monitor_->Start(kCpuMonitorPeriodMs)) {
- LOG(LS_ERROR) << "Failed to start CPU monitor.";
- cpu_monitor_.reset();
- }
-
- bool result = InitVideoEngine();
- if (result) {
- LOG(LS_INFO) << "VideoEngine Init done";
- } else {
- LOG(LS_ERROR) << "VideoEngine Init failed, releasing";
- Terminate();
- }
- return result;
-}
-
-bool WebRtcVideoEngine::InitVideoEngine() {
- LOG(LS_INFO) << "WebRtcVideoEngine::InitVideoEngine";
-
- // Init WebRTC VideoEngine.
- if (!vie_wrapper_base_initialized_) {
- if (vie_wrapper_->base()->Init() != 0) {
- LOG_RTCERR0(Init);
- return false;
- }
- vie_wrapper_base_initialized_ = true;
- }
-
- // Log the VoiceEngine version info.
- char buffer[1024] = "";
- if (vie_wrapper_->base()->GetVersion(buffer) != 0) {
- LOG_RTCERR0(GetVersion);
- return false;
- }
-
- LOG(LS_INFO) << "WebRtc VideoEngine Version:";
- LogMultiline(rtc::LS_INFO, buffer);
-
- // Hook up to VoiceEngine for sync purposes, if supplied.
- if (!voice_engine_) {
- LOG(LS_WARNING) << "NULL voice engine";
- } else if ((vie_wrapper_->base()->SetVoiceEngine(
- voice_engine_->voe()->engine())) != 0) {
- LOG_RTCERR0(SetVoiceEngine);
- return false;
- }
-
- // Register our custom render module.
- if (vie_wrapper_->render()->RegisterVideoRenderModule(
- *render_module_.get()) != 0) {
- LOG_RTCERR0(RegisterVideoRenderModule);
- return false;
- }
-
- initialized_ = true;
- return true;
-}
-
-void WebRtcVideoEngine::Terminate() {
- LOG(LS_INFO) << "WebRtcVideoEngine::Terminate";
- initialized_ = false;
-
- if (vie_wrapper_->render()->DeRegisterVideoRenderModule(
- *render_module_.get()) != 0) {
- LOG_RTCERR0(DeRegisterVideoRenderModule);
- }
-
- if (vie_wrapper_->base()->SetVoiceEngine(NULL) != 0) {
- LOG_RTCERR0(SetVoiceEngine);
- }
-
- if (cpu_monitor_.get()) {
- cpu_monitor_->Stop();
- }
-}
-
-int WebRtcVideoEngine::GetCapabilities() {
- return VIDEO_RECV | VIDEO_SEND;
-}
-
-bool WebRtcVideoEngine::SetDefaultEncoderConfig(
- const VideoEncoderConfig& config) {
- return SetDefaultCodec(config.max_codec);
-}
-
-// SetDefaultCodec may be called while the capturer is running. For example, a
-// test call is started in a page with QVGA default codec, and then a real call
-// is started in another page with VGA default codec. This is the corner case
-// and happens only when a session is started. We ignore this case currently.
-bool WebRtcVideoEngine::SetDefaultCodec(const VideoCodec& codec) {
- if (!RebuildCodecList(codec)) {
- LOG(LS_WARNING) << "Failed to RebuildCodecList";
- return false;
- }
-
- ASSERT(!video_codecs_.empty());
- default_codec_format_ = VideoFormatFromCodec(video_codecs_[0]);
-
- return true;
-}
-
-WebRtcVideoMediaChannel* WebRtcVideoEngine::CreateChannel(
- VoiceMediaChannel* voice_channel) {
- return CreateChannel(VideoOptions(), voice_channel);
-}
-
-WebRtcVideoMediaChannel* WebRtcVideoEngine::CreateChannel(
- const VideoOptions& options,
- VoiceMediaChannel* voice_channel) {
- WebRtcVideoMediaChannel* channel =
- new WebRtcVideoMediaChannel(this, voice_channel);
- if (!channel->Init()) {
- delete channel;
- return NULL;
- }
-
- if (!channel->SetOptions(options)) {
- LOG(LS_WARNING) << "Failed to set options while creating channel.";
- }
- return channel;
-}
-
-const std::vector<VideoCodec>& WebRtcVideoEngine::codecs() const {
- return video_codecs_;
-}
-
-const std::vector<RtpHeaderExtension>&
-WebRtcVideoEngine::rtp_header_extensions() const {
- return rtp_header_extensions_;
-}
-
-void WebRtcVideoEngine::SetLogging(int min_sev, const char* filter) {
- // if min_sev == -1, we keep the current log level.
- if (min_sev >= 0) {
- SetTraceFilter(SeverityToFilter(min_sev));
- }
- SetTraceOptions(filter);
-}
-
-int WebRtcVideoEngine::GetLastEngineError() {
- return vie_wrapper_->error();
-}
-
-// Checks to see whether we comprehend and could receive a particular codec
-bool WebRtcVideoEngine::FindCodec(const VideoCodec& in) {
- if (encoder_factory_) {
- const std::vector<WebRtcVideoEncoderFactory::VideoCodec>& codecs =
- encoder_factory_->codecs();
- for (size_t j = 0; j < codecs.size(); ++j) {
- VideoCodec codec(GetExternalVideoPayloadType(j), codecs[j].name, 0, 0, 0,
- 0);
- if (codec.Matches(in))
- return true;
- }
- }
- for (size_t j = 0; j != default_video_codec_list_.size(); ++j) {
- if (default_video_codec_list_[j].Matches(in)) {
- return true;
- }
- }
-
- return false;
-}
-
-// Given the requested codec, returns true if we can send that codec type and
-// updates out with the best quality we could send for that codec.
-// TODO(ronghuawu): Remove |current| from the interface.
-bool WebRtcVideoEngine::CanSendCodec(const VideoCodec& requested,
- const VideoCodec& /* current */,
- VideoCodec* out) {
- if (!out) {
- return false;
- }
-
- std::vector<VideoCodec>::const_iterator local_max;
- for (local_max = video_codecs_.begin();
- local_max < video_codecs_.end();
- ++local_max) {
- // First match codecs by payload type
- if (!requested.Matches(*local_max)) {
- continue;
- }
-
- out->id = requested.id;
- out->name = requested.name;
- out->preference = requested.preference;
- out->params = requested.params;
- out->framerate = std::min(requested.framerate, local_max->framerate);
- out->width = 0;
- out->height = 0;
- out->params = requested.params;
- out->feedback_params = requested.feedback_params;
-
- if (0 == requested.width && 0 == requested.height) {
- // Special case with resolution 0. The channel should not send frames.
- return true;
- } else if (0 == requested.width || 0 == requested.height) {
- // 0xn and nx0 are invalid resolutions.
- return false;
- }
-
- // Reduce the requested size by /= 2 until it's width under
- // |local_max->width|.
- out->width = requested.width;
- out->height = requested.height;
- while (out->width > local_max->width) {
- out->width /= 2;
- out->height /= 2;
- }
-
- if (out->width > 0 && out->height > 0) {
- return true;
- }
- }
- return false;
-}
-
-static void ConvertToCricketVideoCodec(
- const webrtc::VideoCodec& in_codec, VideoCodec* out_codec) {
- out_codec->id = in_codec.plType;
- out_codec->name = in_codec.plName;
- out_codec->width = in_codec.width;
- out_codec->height = in_codec.height;
- out_codec->framerate = in_codec.maxFramerate;
- if (BitrateIsSet(in_codec.minBitrate)) {
- out_codec->SetParam(kCodecParamMinBitrate, in_codec.minBitrate);
- }
- if (BitrateIsSet(in_codec.maxBitrate)) {
- out_codec->SetParam(kCodecParamMaxBitrate, in_codec.maxBitrate);
- }
- if (BitrateIsSet(in_codec.startBitrate)) {
- out_codec->SetParam(kCodecParamStartBitrate, in_codec.startBitrate);
- }
- if (in_codec.qpMax) {
- out_codec->SetParam(kCodecParamMaxQuantization, in_codec.qpMax);
- }
-}
-
-bool WebRtcVideoEngine::ConvertFromCricketVideoCodec(
- const VideoCodec& in_codec, webrtc::VideoCodec* out_codec) {
- bool found = false;
- int ncodecs = vie_wrapper_->codec()->NumberOfCodecs();
- for (int i = 0; i < ncodecs; ++i) {
- if (vie_wrapper_->codec()->GetCodec(i, *out_codec) == 0 &&
- _stricmp(in_codec.name.c_str(), out_codec->plName) == 0) {
- found = true;
- break;
- }
- }
-
- // If not found, check if this is supported by external encoder factory.
- if (!found && encoder_factory_) {
- const std::vector<WebRtcVideoEncoderFactory::VideoCodec>& codecs =
- encoder_factory_->codecs();
- for (size_t i = 0; i < codecs.size(); ++i) {
- if (_stricmp(in_codec.name.c_str(), codecs[i].name.c_str()) == 0) {
- out_codec->codecType = codecs[i].type;
- out_codec->plType = GetExternalVideoPayloadType(i);
- rtc::strcpyn(out_codec->plName, sizeof(out_codec->plName),
- codecs[i].name.c_str(), codecs[i].name.length());
- found = true;
- break;
- }
- }
- }
-
- // Is this an RTX codec? Handled separately here since webrtc doesn't handle
- // them as webrtc::VideoCodec internally.
- if (!found && _stricmp(in_codec.name.c_str(), kRtxCodecName) == 0) {
- rtc::strcpyn(out_codec->plName, sizeof(out_codec->plName),
- in_codec.name.c_str(), in_codec.name.length());
- out_codec->plType = in_codec.id;
- found = true;
- }
-
- if (!found) {
- LOG(LS_ERROR) << "invalid codec type";
- return false;
- }
-
- if (in_codec.id != 0)
- out_codec->plType = in_codec.id;
-
- if (in_codec.width != 0)
- out_codec->width = in_codec.width;
-
- if (in_codec.height != 0)
- out_codec->height = in_codec.height;
-
- if (in_codec.framerate != 0)
- out_codec->maxFramerate = in_codec.framerate;
-
- // Convert bitrate parameters.
- int max_bitrate = -1;
- int min_bitrate = -1;
- int start_bitrate = -1;
-
- in_codec.GetParam(kCodecParamMinBitrate, &min_bitrate);
- in_codec.GetParam(kCodecParamMaxBitrate, &max_bitrate);
- in_codec.GetParam(kCodecParamStartBitrate, &start_bitrate);
-
-
- out_codec->minBitrate = min_bitrate;
- out_codec->startBitrate = start_bitrate;
- out_codec->maxBitrate = max_bitrate;
-
- // Convert general codec parameters.
- int max_quantization = 0;
- if (in_codec.GetParam(kCodecParamMaxQuantization, &max_quantization)) {
- if (max_quantization < 0) {
- return false;
- }
- out_codec->qpMax = max_quantization;
- }
- return true;
-}
-
-void WebRtcVideoEngine::RegisterChannel(WebRtcVideoMediaChannel *channel) {
- rtc::CritScope cs(&channels_crit_);
- channels_.push_back(channel);
-}
-
-void WebRtcVideoEngine::UnregisterChannel(WebRtcVideoMediaChannel *channel) {
- rtc::CritScope cs(&channels_crit_);
- channels_.erase(std::remove(channels_.begin(), channels_.end(), channel),
- channels_.end());
-}
-
-bool WebRtcVideoEngine::EnableTimedRender() {
- if (initialized_) {
- LOG(LS_WARNING) << "EnableTimedRender can not be called after Init";
- return false;
- }
- render_module_.reset(webrtc::VideoRender::CreateVideoRender(0, NULL,
- false, webrtc::kRenderExternal));
- return true;
-}
-
-void WebRtcVideoEngine::SetTraceFilter(int filter) {
- tracing_->SetTraceFilter(filter);
-}
-
-// See https://sites.google.com/a/google.com/wavelet/
-// Home/Magic-Flute--RTC-Engine-/Magic-Flute-Command-Line-Parameters
-// for all supported command line setttings.
-void WebRtcVideoEngine::SetTraceOptions(const std::string& options) {
- // Set WebRTC 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 WebRTC debug output (at same loglevel) to file
- if (tracing_->SetTraceFile(tracefile->c_str()) == -1) {
- LOG_RTCERR1(SetTraceFile, *tracefile);
- }
- }
-}
-
-// Rebuilds the codec list to be only those that are less intensive
-// than the specified codec. Prefers internal codec over external with
-// higher preference field.
-bool WebRtcVideoEngine::RebuildCodecList(const VideoCodec& in_codec) {
- if (!FindCodec(in_codec))
- return false;
-
- video_codecs_.clear();
-
- std::set<std::string> internal_codec_names;
- for (size_t i = 0; i != default_video_codec_list_.size(); ++i) {
- VideoCodec codec = default_video_codec_list_[i];
- codec.width = in_codec.width;
- codec.height = in_codec.height;
- codec.framerate = in_codec.framerate;
- video_codecs_.push_back(codec);
-
- internal_codec_names.insert(codec.name);
- }
-
- if (encoder_factory_) {
- const std::vector<WebRtcVideoEncoderFactory::VideoCodec>& codecs =
- encoder_factory_->codecs();
- for (size_t i = 0; i < codecs.size(); ++i) {
- bool is_internal_codec = internal_codec_names.find(codecs[i].name) !=
- internal_codec_names.end();
- if (!is_internal_codec) {
- VideoCodec codec(
- GetExternalVideoPayloadType(i),
- codecs[i].name,
- codecs[i].max_width,
- codecs[i].max_height,
- codecs[i].max_fps,
- // Use negative preference on external codec to ensure the internal
- // codec is preferred.
- static_cast<int>(0 - i));
- AddDefaultFeedbackParams(&codec);
- video_codecs_.push_back(codec);
- }
- }
- }
- return true;
-}
-
-int WebRtcVideoEngine::GetNumOfChannels() {
- rtc::CritScope cs(&channels_crit_);
- return static_cast<int>(channels_.size());
-}
-
-void WebRtcVideoEngine::TraceCallbackImpl::Print(
- webrtc::TraceLevel level, const char* trace, int length) {
- rtc::LoggingSeverity sev = rtc::LS_VERBOSE;
- if (level == webrtc::kTraceError || level == webrtc::kTraceCritical)
- sev = rtc::LS_ERROR;
- else if (level == webrtc::kTraceWarning)
- sev = rtc::LS_WARNING;
- else if (level == webrtc::kTraceStateInfo || level == webrtc::kTraceInfo)
- sev = rtc::LS_INFO;
- else if (level == webrtc::kTraceTerseInfo)
- sev = rtc::LS_INFO;
-
- // Skip past boilerplate prefix text
- if (length < 72) {
- std::string msg(trace, length);
- LOG(LS_ERROR) << "Malformed webrtc log message: ";
- LOG_V(sev) << msg;
- } else {
- std::string msg(trace + 71, length - 72);
- if (!voice_engine_ || !voice_engine_->ShouldIgnoreTrace(msg)) {
- LOG_V(sev) << "webrtc: " << msg;
- }
- }
-}
-
-webrtc::VideoDecoder* WebRtcVideoEngine::CreateExternalDecoder(
- webrtc::VideoCodecType type) {
- if (!decoder_factory_) {
- return NULL;
- }
- return decoder_factory_->CreateVideoDecoder(type);
-}
-
-void WebRtcVideoEngine::DestroyExternalDecoder(webrtc::VideoDecoder* decoder) {
- ASSERT(decoder_factory_ != NULL);
- if (!decoder_factory_)
- return;
- decoder_factory_->DestroyVideoDecoder(decoder);
-}
-
-webrtc::VideoEncoder* WebRtcVideoEngine::CreateExternalEncoder(
- webrtc::VideoCodecType type,
- bool* internal_source) {
- ASSERT(internal_source != NULL);
- if (!encoder_factory_) {
- return NULL;
- }
- *internal_source = encoder_factory_->EncoderTypeHasInternalSource(type);
- return encoder_factory_->CreateVideoEncoder(type);
-}
-
-void WebRtcVideoEngine::DestroyExternalEncoder(webrtc::VideoEncoder* encoder) {
- ASSERT(encoder_factory_ != NULL);
- if (!encoder_factory_)
- return;
- encoder_factory_->DestroyVideoEncoder(encoder);
-}
-
-bool WebRtcVideoEngine::IsExternalEncoderCodecType(
- webrtc::VideoCodecType type) const {
- if (!encoder_factory_)
- return false;
- const std::vector<WebRtcVideoEncoderFactory::VideoCodec>& codecs =
- encoder_factory_->codecs();
- std::vector<WebRtcVideoEncoderFactory::VideoCodec>::const_iterator it;
- for (it = codecs.begin(); it != codecs.end(); ++it) {
- if (it->type == type)
- return true;
- }
- return false;
-}
-
-void WebRtcVideoEngine::SetExternalDecoderFactory(
- WebRtcVideoDecoderFactory* decoder_factory) {
- decoder_factory_ = decoder_factory;
-}
-
-void WebRtcVideoEngine::SetExternalEncoderFactory(
- WebRtcVideoEncoderFactory* encoder_factory) {
- if (encoder_factory_ == encoder_factory)
- return;
-
- // No matter what happens we shouldn't hold on to a stale
- // WebRtcSimulcastEncoderFactory.
- simulcast_encoder_factory_.reset();
-
- if (encoder_factory) {
- const std::vector<WebRtcVideoEncoderFactory::VideoCodec>& codecs =
- encoder_factory->codecs();
- if (WebRtcSimulcastEncoderFactory::UseSimulcastEncoderFactory(codecs)) {
- simulcast_encoder_factory_.reset(
- new WebRtcSimulcastEncoderFactory(encoder_factory));
- encoder_factory = simulcast_encoder_factory_.get();
- }
- }
-
- encoder_factory_ = encoder_factory;
-
- // Rebuild codec list while reapplying the current default codec format.
- VideoCodec max_codec = default_video_codec_list_[0];
- max_codec.width = video_codecs_[0].width;
- max_codec.height = video_codecs_[0].height;
- max_codec.framerate = video_codecs_[0].framerate;
- if (!RebuildCodecList(max_codec)) {
- LOG(LS_ERROR) << "Failed to initialize list of supported codec types";
- }
-}
-
-// WebRtcVideoMediaChannel
-
-WebRtcVideoMediaChannel::WebRtcVideoMediaChannel(
- WebRtcVideoEngine* engine,
- VoiceMediaChannel* channel)
- : engine_(engine),
- voice_channel_(channel),
- default_channel_id_(kChannelIdUnset),
- nack_enabled_(true),
- remb_enabled_(false),
- render_started_(false),
- first_receive_ssrc_(kSsrcUnset),
- receiver_report_ssrc_(kSsrcUnset),
- num_unsignalled_recv_channels_(0),
- send_red_type_(-1),
- send_fec_type_(-1),
- sending_(false),
- ratio_w_(0),
- ratio_h_(0) {
- engine->RegisterChannel(this);
-}
-
-bool WebRtcVideoMediaChannel::Init() {
- const uint32 ssrc_key = 0;
- bool result = CreateChannel(ssrc_key, MD_SENDRECV, &default_channel_id_);
- if (!result) {
- return false;
- }
- if (voice_channel_) {
- WebRtcVoiceMediaChannel* voice_channel =
- static_cast<WebRtcVoiceMediaChannel*>(voice_channel_);
- if (!voice_channel->SetupSharedBandwidthEstimation(
- engine()->vie()->engine(), default_channel_id_)) {
- return false;
- }
- }
- return true;
-}
-
-WebRtcVideoMediaChannel::~WebRtcVideoMediaChannel() {
- Terminate();
-}
-
-void WebRtcVideoMediaChannel::Terminate() {
- SetSend(false);
- SetRender(false);
-
- while (!send_channels_.empty()) {
- if (!DeleteSendChannel(send_channels_.begin()->first)) {
- LOG(LS_ERROR) << "Unable to delete channel with ssrc key "
- << send_channels_.begin()->first;
- ASSERT(false);
- break;
- }
- }
-
- // Remove all receive streams and the default channel.
- while (!recv_channels_.empty()) {
- RemoveRecvStreamInternal(recv_channels_.begin()->first);
- }
-
- // Unregister the channel from the engine.
- engine()->UnregisterChannel(this);
- if (worker_thread()) {
- worker_thread()->Clear(this);
- }
-}
-
-bool WebRtcVideoMediaChannel::SetRecvCodecs(
- const std::vector<VideoCodec>& codecs) {
- receive_codecs_.clear();
- associated_payload_types_.clear();
- for (std::vector<VideoCodec>::const_iterator iter = codecs.begin();
- iter != codecs.end(); ++iter) {
- if (engine()->FindCodec(*iter)) {
- webrtc::VideoCodec wcodec;
- if (engine()->ConvertFromCricketVideoCodec(*iter, &wcodec)) {
- receive_codecs_.push_back(wcodec);
- int apt;
- if (iter->GetParam(cricket::kCodecParamAssociatedPayloadType, &apt)) {
- if (!IsValidRtpPayloadType(apt))
- return false;
- associated_payload_types_[wcodec.plType] = apt;
- }
- }
- } else {
- LOG(LS_INFO) << "Unknown codec " << iter->name;
- return false;
- }
- }
-
- for (RecvChannelMap::iterator it = recv_channels_.begin();
- it != recv_channels_.end(); ++it) {
- if (!SetReceiveCodecs(it->second))
- return false;
- }
- return true;
-}
-
-bool WebRtcVideoMediaChannel::SetSendCodecs(
- const std::vector<VideoCodec>& codecs) {
- // Match with local video codec list.
- std::vector<webrtc::VideoCodec> send_codecs;
- VideoCodec checked_codec;
- VideoCodec dummy_current; // Will be ignored by CanSendCodec.
- std::map<int, int> primary_rtx_pt_mapping;
- bool nack_enabled = nack_enabled_;
- bool remb_enabled = remb_enabled_;
- for (std::vector<VideoCodec>::const_iterator iter = codecs.begin();
- iter != codecs.end(); ++iter) {
- if (_stricmp(iter->name.c_str(), kRedCodecName) == 0) {
- send_red_type_ = iter->id;
- } else if (_stricmp(iter->name.c_str(), kUlpfecCodecName) == 0) {
- send_fec_type_ = iter->id;
- } else if (_stricmp(iter->name.c_str(), kRtxCodecName) == 0) {
- int rtx_type = iter->id;
- int rtx_primary_type = -1;
- if (iter->GetParam(kCodecParamAssociatedPayloadType, &rtx_primary_type)) {
- if (!IsValidRtpPayloadType(rtx_primary_type))
- return false;
- primary_rtx_pt_mapping[rtx_primary_type] = rtx_type;
- }
- } else if (engine()->CanSendCodec(*iter, dummy_current, &checked_codec)) {
- webrtc::VideoCodec wcodec;
- if (engine()->ConvertFromCricketVideoCodec(checked_codec, &wcodec)) {
- if (send_codecs.empty()) {
- nack_enabled = HasNack(checked_codec);
- remb_enabled = HasRemb(checked_codec);
- }
- send_codecs.push_back(wcodec);
- }
- } else {
- LOG(LS_WARNING) << "Unknown codec " << iter->name;
- }
- }
-
- // Fail if we don't have a match.
- if (send_codecs.empty()) {
- LOG(LS_WARNING) << "No matching codecs available";
- return false;
- }
-
- // Recv protection.
- // Do not update if the status is same as previously configured.
- if (nack_enabled_ != nack_enabled) {
- for (RecvChannelMap::iterator it = recv_channels_.begin();
- it != recv_channels_.end(); ++it) {
- int channel_id = it->second->channel_id();
- if (!SetNackFec(channel_id, send_red_type_, send_fec_type_,
- nack_enabled)) {
- return false;
- }
- if (engine_->vie()->rtp()->SetRembStatus(channel_id,
- kNotSending,
- remb_enabled_) != 0) {
- LOG_RTCERR3(SetRembStatus, channel_id, kNotSending, remb_enabled_);
- return false;
- }
- }
- nack_enabled_ = nack_enabled;
- }
-
- // Send settings.
- // Do not update if the status is same as previously configured.
- if (remb_enabled_ != remb_enabled) {
- for (SendChannelMap::iterator iter = send_channels_.begin();
- iter != send_channels_.end(); ++iter) {
- int channel_id = iter->second->channel_id();
- if (!SetNackFec(channel_id, send_red_type_, send_fec_type_,
- nack_enabled_)) {
- return false;
- }
- if (engine_->vie()->rtp()->SetRembStatus(channel_id,
- remb_enabled,
- remb_enabled) != 0) {
- LOG_RTCERR3(SetRembStatus, channel_id, remb_enabled, remb_enabled);
- return false;
- }
- }
- remb_enabled_ = remb_enabled;
- }
-
- // Select the first matched codec.
- webrtc::VideoCodec& codec(send_codecs[0]);
-
- // TODO(changbin): Add support for more than on RTX payload type. Currently
- // using only one to interop with previous versions of Chrome.
- std::map<int, int>::const_iterator rtx_it =
- primary_rtx_pt_mapping.find(codec.plType);
- if (rtx_it != primary_rtx_pt_mapping.end()) {
- send_rtx_associated_types_[rtx_it->second] = rtx_it->first;
- }
-
- if (BitrateIsSet(codec.minBitrate) && BitrateIsSet(codec.maxBitrate) &&
- codec.minBitrate > codec.maxBitrate) {
- // TODO(pthatcher): This behavior contradicts other behavior in
- // this file which will cause min > max to push the min down to
- // the max. There are unit tests for both behaviors. We should
- // pick one and do that.
- LOG(LS_INFO) << "Rejecting codec with min bitrate ("
- << codec.minBitrate << ") larger than max ("
- << codec.maxBitrate << "). ";
- return false;
- }
-
- if (!SetSendCodec(codec)) {
- return false;
- }
-
- LogSendCodecChange("SetSendCodecs()");
-
- return true;
-}
-
-bool WebRtcVideoMediaChannel::MaybeRegisterExternalEncoder(
- WebRtcVideoChannelSendInfo* send_channel,
- const webrtc::VideoCodec& codec) {
- // Codec type not supported or encoder already registered, so
- // nothing to do.
- if (!engine()->IsExternalEncoderCodecType(codec.codecType) ||
- send_channel->IsEncoderRegistered(codec.plType)) {
- return true;
- }
-
- bool internal_source;
- webrtc::VideoEncoder* encoder =
- engine()->CreateExternalEncoder(codec.codecType, &internal_source);
- if (!encoder) {
- // No external encoder created, so nothing to do.
- return true;
- }
-
- const int channel_id = send_channel->channel_id();
- if (engine()->vie()->ext_codec()->RegisterExternalSendCodec(
- channel_id, codec.plType, encoder, internal_source) != 0) {
- LOG_RTCERR2(RegisterExternalSendCodec, channel_id, codec.plName);
- engine()->DestroyExternalEncoder(encoder);
- return false;
- }
-
- send_channel->RegisterEncoder(codec.plType, encoder);
- return true;
-}
-
-bool WebRtcVideoMediaChannel::GetSendCodec(VideoCodec* send_codec) {
- if (!send_codec_) {
- return false;
- }
- ConvertToCricketVideoCodec(*send_codec_, send_codec);
- return true;
-}
-
-bool WebRtcVideoMediaChannel::SetSendStreamFormat(uint32 ssrc,
- const VideoFormat& format) {
- WebRtcVideoChannelSendInfo* send_channel = GetSendChannelBySsrc(ssrc);
- if (!send_channel) {
- LOG(LS_ERROR) << "The specified ssrc " << ssrc << " is not in use.";
- return false;
- }
-
- send_channel->SetAdaptFormat(
- format, WebRtcVideoChannelSendInfo::kAdaptFormatTypeStream);
- return true;
-}
-
-bool WebRtcVideoMediaChannel::SetRender(bool render) {
- if (render == render_started_) {
- return true; // no action required
- }
-
- bool ret = true;
- for (RecvChannelMap::iterator it = recv_channels_.begin();
- it != recv_channels_.end(); ++it) {
- if (render) {
- if (engine()->vie()->render()->StartRender(
- it->second->channel_id()) != 0) {
- LOG_RTCERR1(StartRender, it->second->channel_id());
- ret = false;
- }
- } else {
- if (engine()->vie()->render()->StopRender(
- it->second->channel_id()) != 0) {
- LOG_RTCERR1(StopRender, it->second->channel_id());
- ret = false;
- }
- }
- }
- if (ret) {
- render_started_ = render;
- }
-
- return ret;
-}
-
-bool WebRtcVideoMediaChannel::SetSend(bool send) {
- if (!HasReadySendChannels() && send) {
- LOG(LS_ERROR) << "No stream added";
- return false;
- }
- if (send == sending()) {
- return true; // No action required.
- }
-
- if (send) {
- // We've been asked to start sending.
- // SetSendCodecs must have been called already.
- if (!send_codec_) {
- return false;
- }
- // Start send now.
- if (!StartSend()) {
- return false;
- }
- } else {
- // We've been asked to stop sending.
- if (!StopSend()) {
- return false;
- }
- }
- sending_ = send;
-
- return true;
-}
-
-bool WebRtcVideoMediaChannel::AddSendStream(const StreamParams& sp) {
- if (sp.first_ssrc() == 0) {
- LOG(LS_ERROR) << "AddSendStream with 0 ssrc is not supported.";
- return false;
- }
-
- LOG(LS_INFO) << "AddSendStream " << sp.ToString();
-
- if (!IsOneSsrcStream(sp) && !IsSimulcastStream(sp)) {
- LOG(LS_ERROR) << "AddSendStream: bad local stream parameters";
- return false;
- }
-
- uint32 ssrc_key;
- if (!CreateSendChannelSsrcKey(sp.first_ssrc(), &ssrc_key)) {
- LOG(LS_ERROR) << "Trying to register duplicate ssrc: " << sp.first_ssrc();
- return false;
- }
- // If the default channel is already used for sending create a new channel
- // otherwise use the default channel for sending.
- int channel_id = kChannelIdUnset;
- if (!DefaultSendChannelIsActive()) {
- channel_id = default_channel_id_;
- } else {
- if (!CreateChannel(ssrc_key, MD_SEND, &channel_id)) {
- LOG(LS_ERROR) << "AddSendStream: unable to create channel";
- return false;
- }
- }
-
- WebRtcVideoChannelSendInfo* send_channel = GetSendChannelBySsrcKey(ssrc_key);
- // If there are multiple send SSRCs, we can only set the first one here, and
- // the rest of the SSRC(s) need to be set after SetSendCodec has been called
- if (!SetLimitedNumberOfSendSsrcs(channel_id, sp, 1)) {
- return false;
- }
-
- // Set RTCP CName.
- if (engine()->vie()->rtp()->SetRTCPCName(channel_id,
- sp.cname.c_str()) != 0) {
- LOG_RTCERR2(SetRTCPCName, channel_id, sp.cname.c_str());
- return false;
- }
-
- // Use the SSRC of the default channel in the RTCP receiver reports.
- if (IsDefaultChannelId(channel_id)) {
- SetReceiverReportSsrc(sp.first_ssrc());
- }
-
- if (send_codec_) {
- send_channel->SetAdaptFormat(
- VideoFormatFromVieCodec(*send_codec_),
- WebRtcVideoChannelSendInfo::kAdaptFormatTypeCodec);
-
- VideoSendParams send_params;
- send_params.codec = *send_codec_;
- send_params.stream = sp;
- if (!SetSendParams(send_channel, send_params)) {
- return false;
- }
- LogSendCodecChange("AddStream()");
- } else {
- // Save the stream params for later, when we have a codec.
- send_channel->set_stream_params(sp);
- }
-
- if (sending_) {
- return StartSend(send_channel);
- }
- return true;
-}
-
-bool WebRtcVideoMediaChannel::RemoveSendStream(uint32 ssrc) {
- if (ssrc == 0) {
- LOG(LS_ERROR) << "RemoveSendStream with 0 ssrc is not supported.";
- return false;
- }
-
- uint32 ssrc_key;
- if (!GetSendChannelSsrcKey(ssrc, &ssrc_key)) {
- LOG(LS_WARNING) << "Try to remove stream with ssrc " << ssrc
- << " which doesn't exist.";
- return false;
- }
- WebRtcVideoChannelSendInfo* send_channel = GetSendChannelBySsrcKey(ssrc_key);
- int channel_id = send_channel->channel_id();
- if (IsDefaultChannelId(channel_id) && !send_channel->IsActive()) {
- // Default channel will still exist. However, there is no stream
- // to remove.
- return false;
- }
- if (sending_) {
- StopSend(send_channel);
- }
-
- const WebRtcVideoChannelSendInfo::EncoderMap& encoder_map =
- send_channel->registered_encoders();
- for (WebRtcVideoChannelSendInfo::EncoderMap::const_iterator it =
- encoder_map.begin(); it != encoder_map.end(); ++it) {
- if (engine()->vie()->ext_codec()->DeRegisterExternalSendCodec(
- channel_id, it->first) != 0) {
- LOG_RTCERR1(DeregisterEncoderObserver, channel_id);
- }
- engine()->DestroyExternalEncoder(it->second);
- }
- send_channel->ClearRegisteredEncoders();
-
- // The receive channels depend on the default channel, recycle it instead.
- if (IsDefaultChannelId(channel_id)) {
- SetCapturer(GetDefaultSendChannelSsrc(), NULL);
- send_channel->Deactivate();
- } else {
- return DeleteSendChannel(ssrc_key);
- }
- return true;
-}
-
-bool WebRtcVideoMediaChannel::AddRecvStream(const StreamParams& sp) {
- if (sp.first_ssrc() == 0) {
- LOG(LS_ERROR) << "AddRecvStream with 0 ssrc is not supported.";
- return false;
- }
-
- // TODO(zhurunz) Remove this once BWE works properly across different send
- // and receive channels.
- // Reuse default channel for recv stream in 1:1 call.
- if (!ConferenceModeIsEnabled() && first_receive_ssrc_ == kSsrcUnset) {
- LOG(LS_INFO) << "Recv stream " << sp.first_ssrc()
- << " reuse default channel #"
- << default_channel_id_;
- first_receive_ssrc_ = sp.first_ssrc();
- if (!MaybeSetRtxSsrc(sp, default_channel_id_)) {
- return false;
- }
- if (render_started_) {
- if (engine()->vie()->render()->StartRender(default_channel_id_) !=0) {
- LOG_RTCERR1(StartRender, default_channel_id_);
- }
- }
- return true;
- }
-
- int channel_id = kChannelIdUnset;
- uint32 ssrc = sp.first_ssrc();
- WebRtcVideoChannelRecvInfo* recv_channel = GetRecvChannelBySsrc(ssrc);
- if (!recv_channel && first_receive_ssrc_ != ssrc) {
- // TODO(perkj): Implement recv media from multiple media SSRCs per stream.
- // NOTE: We have two SSRCs per stream when RTX is enabled.
- if (!IsOneSsrcStream(sp)) {
- LOG(LS_ERROR) << "WebRtcVideoMediaChannel supports one primary SSRC per"
- << " stream and one FID SSRC per primary SSRC.";
- return false;
- }
-
- // Create a new channel for receiving video data.
- // In order to get the bandwidth estimation work fine for
- // receive only channels, we connect all receiving channels
- // to our master send channel.
- if (!CreateChannel(sp.first_ssrc(), MD_RECV, &channel_id)) {
- return false;
- }
- } else {
- // Already exists.
- if (first_receive_ssrc_ == ssrc) {
- return false;
- }
- // Early receive added channel.
- channel_id = recv_channel->channel_id();
- }
-
- if (!MaybeSetRtxSsrc(sp, channel_id)) {
- return false;
- }
-
- LOG(LS_INFO) << "New video stream " << sp.first_ssrc()
- << " registered to VideoEngine channel #"
- << channel_id << " and connected to channel #"
- << default_channel_id_;
- return true;
-}
-
-bool WebRtcVideoMediaChannel::MaybeSetRtxSsrc(const StreamParams& sp,
- int channel_id) {
- uint32 rtx_ssrc;
- bool has_rtx = sp.GetFidSsrc(sp.first_ssrc(), &rtx_ssrc);
- if (has_rtx) {
- LOG(LS_INFO) << "Setting rtx ssrc " << rtx_ssrc << " for stream "
- << sp.first_ssrc();
- if (engine()->vie()->rtp()->SetRemoteSSRCType(
- channel_id, webrtc::kViEStreamTypeRtx, rtx_ssrc) != 0) {
- LOG_RTCERR3(SetRemoteSSRCType, channel_id, webrtc::kViEStreamTypeRtx,
- rtx_ssrc);
- return false;
- }
- rtx_to_primary_ssrc_[rtx_ssrc] = sp.first_ssrc();
- }
- return true;
-}
-
-bool WebRtcVideoMediaChannel::RemoveRecvStream(uint32 ssrc) {
- if (ssrc == 0) {
- LOG(LS_ERROR) << "RemoveRecvStream with 0 ssrc is not supported.";
- return false;
- }
- return RemoveRecvStreamInternal(ssrc);
-}
-
-bool WebRtcVideoMediaChannel::RemoveRecvStreamInternal(uint32 ssrc) {
- // First remove the RTX SSRC mapping, to include this step even if exiting in
- // the default receive channel logic below.
- SsrcMap::iterator rtx_it = rtx_to_primary_ssrc_.begin();
- while (rtx_it != rtx_to_primary_ssrc_.end()) {
- if (rtx_it->second == ssrc) {
- rtx_to_primary_ssrc_.erase(rtx_it++);
- } else {
- ++rtx_it;
- }
- }
-
- WebRtcVideoChannelRecvInfo* recv_channel = GetRecvChannelBySsrc(ssrc);
- if (!recv_channel) {
- // TODO(perkj): Remove this once BWE works properly across different send
- // and receive channels.
- // The default channel is reused for recv stream in 1:1 call.
- if (first_receive_ssrc_ == ssrc) {
- first_receive_ssrc_ = kSsrcUnset;
- // Need to stop the renderer and remove it since the render window can be
- // deleted after this.
- if (render_started_) {
- if (engine()->vie()->render()->StopRender(default_channel_id_) !=0) {
- LOG_RTCERR1(StopRender, recv_channel->channel_id());
- }
- }
- GetDefaultRecvChannel()->SetRenderer(NULL);
- return true;
- }
- return false;
- }
-
- int channel_id = recv_channel->channel_id();
- if (engine()->vie()->render()->RemoveRenderer(channel_id) != 0) {
- LOG_RTCERR1(RemoveRenderer, channel_id);
- }
-
- if (engine()->vie()->network()->DeregisterSendTransport(channel_id) !=0) {
- LOG_RTCERR1(DeRegisterSendTransport, channel_id);
- }
-
- if (engine()->vie()->codec()->DeregisterDecoderObserver(
- channel_id) != 0) {
- LOG_RTCERR1(DeregisterDecoderObserver, channel_id);
- }
-
- const WebRtcVideoChannelRecvInfo::DecoderMap& decoder_map =
- recv_channel->registered_decoders();
- for (WebRtcVideoChannelRecvInfo::DecoderMap::const_iterator it =
- decoder_map.begin(); it != decoder_map.end(); ++it) {
- if (engine()->vie()->ext_codec()->DeRegisterExternalReceiveCodec(
- channel_id, it->first) != 0) {
- LOG_RTCERR1(DeregisterDecoderObserver, channel_id);
- }
- engine()->DestroyExternalDecoder(it->second);
- }
- recv_channel->ClearRegisteredDecoders();
-
- LOG(LS_INFO) << "Removing video stream " << ssrc
- << " with VideoEngine channel #"
- << channel_id;
- bool ret = true;
- if (engine()->vie()->base()->DeleteChannel(channel_id) == -1) {
- LOG_RTCERR1(DeleteChannel, channel_id);
- ret = false;
- }
- // Delete the WebRtcVideoChannelRecvInfo pointed to by it->second.
- delete recv_channel;
- recv_channels_.erase(ssrc);
- return ret;
-}
-
-bool WebRtcVideoMediaChannel::StartSend() {
- bool success = true;
- for (SendChannelMap::iterator iter = send_channels_.begin();
- iter != send_channels_.end(); ++iter) {
- WebRtcVideoChannelSendInfo* send_channel = iter->second;
- if (!StartSend(send_channel)) {
- success = false;
- }
- }
- return success;
-}
-
-bool WebRtcVideoMediaChannel::StartSend(
- WebRtcVideoChannelSendInfo* send_channel) {
- const int channel_id = send_channel->channel_id();
- if (engine()->vie()->base()->StartSend(channel_id) != 0) {
- LOG_RTCERR1(StartSend, channel_id);
- return false;
- }
-
- send_channel->set_sending(true);
- return true;
-}
-
-bool WebRtcVideoMediaChannel::StopSend() {
- bool success = true;
- for (SendChannelMap::iterator iter = send_channels_.begin();
- iter != send_channels_.end(); ++iter) {
- WebRtcVideoChannelSendInfo* send_channel = iter->second;
- if (!StopSend(send_channel)) {
- success = false;
- }
- }
- return success;
-}
-
-bool WebRtcVideoMediaChannel::StopSend(
- WebRtcVideoChannelSendInfo* send_channel) {
- const int channel_id = send_channel->channel_id();
- if (engine()->vie()->base()->StopSend(channel_id) != 0) {
- LOG_RTCERR1(StopSend, channel_id);
- return false;
- }
- send_channel->set_sending(false);
- return true;
-}
-
-bool WebRtcVideoMediaChannel::SendIntraFrame() {
- bool success = true;
- for (SendChannelMap::iterator iter = send_channels_.begin();
- iter != send_channels_.end();
- ++iter) {
- WebRtcVideoChannelSendInfo* send_channel = iter->second;
- const int channel_id = send_channel->channel_id();
- if (engine()->vie()->codec()->SendKeyFrame(channel_id) != 0) {
- LOG_RTCERR1(SendKeyFrame, channel_id);
- success = false;
- }
- }
- return success;
-}
-
-bool WebRtcVideoMediaChannel::HasReadySendChannels() {
- return !send_channels_.empty() &&
- ((send_channels_.size() > 1) || DefaultSendChannelIsActive());
-}
-
-bool WebRtcVideoMediaChannel::DefaultSendChannelIsActive() {
- return GetDefaultSendChannel() && GetDefaultSendChannel()->IsActive();
-}
-
-bool WebRtcVideoMediaChannel::GetSendChannelSsrcKey(uint32 local_ssrc,
- uint32* ssrc_key) {
- *ssrc_key = kDefaultChannelSsrcKey;
- // If a send channel is not ready to send it will not have local_ssrc
- // registered to it.
- if (!HasReadySendChannels()) {
- return false;
- }
- // The default channel is stored with ssrc key
- // kDefaultChannelSsrcKey. The ssrc key therefore does not match the
- // SSRC associated with the default channel. Check if the SSRC
- // provided corresponds to the default channel's SSRC.
- if (local_ssrc == GetDefaultSendChannelSsrc()) {
- return true;
- }
- if (!GetSendChannelBySsrcKey(local_ssrc)) {
- // If a stream has multiple ssrcs, the local_ssrc could be any of
- // them, but we use the first one (StreamParams::first_ssrc()) as
- // the key.
- for (SendChannelMap::iterator iter = send_channels_.begin();
- iter != send_channels_.end(); ++iter) {
- WebRtcVideoChannelSendInfo* send_channel = iter->second;
- if (send_channel->stream_params().has_ssrc(local_ssrc)) {
- *ssrc_key = iter->first;
- return true;
- }
- }
- return false;
- }
- // The ssrc key was found in the above std::map::find call. This
- // means that the ssrc is the ssrc key.
- *ssrc_key = local_ssrc;
- return true;
-}
-
-WebRtcVideoChannelSendInfo* WebRtcVideoMediaChannel::GetDefaultSendChannel() {
- return GetSendChannelBySsrcKey(kDefaultChannelSsrcKey);
-}
-
-WebRtcVideoChannelSendInfo* WebRtcVideoMediaChannel::GetSendChannelBySsrcKey(
- uint32 ssrc_key) {
- std::map<uint32, WebRtcVideoChannelSendInfo *>::iterator iter =
- send_channels_.find(ssrc_key);
- if (iter == send_channels_.end()) {
- return NULL;
- }
- return iter->second;
-}
-
-WebRtcVideoChannelSendInfo* WebRtcVideoMediaChannel::GetSendChannelBySsrc(
- uint32 local_ssrc) {
- uint32 ssrc_key;
- if (!GetSendChannelSsrcKey(local_ssrc, &ssrc_key)) {
- return NULL;
- }
- return send_channels_[ssrc_key];
-}
-
-bool WebRtcVideoMediaChannel::CreateSendChannelSsrcKey(uint32 local_ssrc,
- uint32* ssrc_key) {
- if (GetSendChannelSsrcKey(local_ssrc, ssrc_key)) {
- // If there is an ssrc key corresponding to |local_ssrc|, the SSRC
- // is already in use. SSRCs need to be unique in a session and at
- // this point a duplicate SSRC has been detected.
- return false;
- }
- if (!DefaultSendChannelIsActive()) {
- // |ssrc_key| should be kDefaultChannelSsrcKey here as the default
- // channel should be re-used whenever it is not used.
- *ssrc_key = kDefaultChannelSsrcKey;
- return true;
- }
- // SSRC is currently not in use and the default channel is already
- // in use. Use the SSRC as ssrc_key since it is supposed to be
- // unique in a session.
- *ssrc_key = local_ssrc;
- return true;
-}
-
-int WebRtcVideoMediaChannel::GetSendChannelNum(VideoCapturer* capturer) {
- int num = 0;
- for (SendChannelMap::iterator iter = send_channels_.begin();
- iter != send_channels_.end(); ++iter) {
- WebRtcVideoChannelSendInfo* send_channel = iter->second;
- if (send_channel->video_capturer() == capturer) {
- ++num;
- }
- }
- return num;
-}
-
-uint32 WebRtcVideoMediaChannel::GetDefaultSendChannelSsrc() {
- return GetDefaultSendChannel()->stream_params().first_ssrc();
-}
-
-bool WebRtcVideoMediaChannel::DeleteSendChannel(uint32 ssrc_key) {
- WebRtcVideoChannelSendInfo* send_channel = GetSendChannelBySsrcKey(ssrc_key);
- if (!send_channel) {
- return false;
- }
- MaybeDisconnectCapturer(send_channel->video_capturer());
- send_channel->set_video_capturer(NULL, engine()->vie());
-
- int channel_id = send_channel->channel_id();
- int capture_id = send_channel->capture_id();
- if (engine()->vie()->codec()->DeregisterEncoderObserver(
- channel_id) != 0) {
- LOG_RTCERR1(DeregisterEncoderObserver, channel_id);
- }
-
- // Destroy the external capture interface.
- if (engine()->vie()->capture()->DisconnectCaptureDevice(
- channel_id) != 0) {
- LOG_RTCERR1(DisconnectCaptureDevice, channel_id);
- }
- if (engine()->vie()->capture()->ReleaseCaptureDevice(
- capture_id) != 0) {
- LOG_RTCERR1(ReleaseCaptureDevice, capture_id);
- }
-
- // The default channel is stored in both |send_channels_| and
- // |recv_channels_|. To make sure it is only deleted once from vie let the
- // delete call happen when tearing down |recv_channels_| and not here.
- if (!IsDefaultChannelId(channel_id)) {
- engine_->vie()->base()->DeleteChannel(channel_id);
- }
- delete send_channel;
- send_channels_.erase(ssrc_key);
- return true;
-}
-
-WebRtcVideoChannelRecvInfo* WebRtcVideoMediaChannel::GetDefaultRecvChannel() {
- return GetRecvChannelBySsrc(kDefaultChannelSsrcKey);
-}
-
-WebRtcVideoChannelRecvInfo* WebRtcVideoMediaChannel::GetRecvChannelBySsrc(
- uint32 ssrc) {
- if (recv_channels_.find(ssrc) == recv_channels_.end()) {
- return NULL;
- }
- return recv_channels_[ssrc];
-}
-
-bool WebRtcVideoMediaChannel::RemoveCapturer(uint32 ssrc) {
- WebRtcVideoChannelSendInfo* send_channel = GetSendChannelBySsrc(ssrc);
- if (!send_channel) {
- return false;
- }
- VideoCapturer* capturer = send_channel->video_capturer();
- if (!capturer) {
- return false;
- }
- MaybeDisconnectCapturer(capturer);
- send_channel->set_video_capturer(NULL, engine()->vie());
- const int64 timestamp = send_channel->local_stream_info()->time_stamp();
- if (send_codec_) {
- QueueBlackFrame(ssrc, timestamp,
- VideoFormat::FpsToInterval(send_codec_->maxFramerate));
- }
- return true;
-}
-
-bool WebRtcVideoMediaChannel::SetRenderer(uint32 ssrc,
- VideoRenderer* renderer) {
- WebRtcVideoChannelRecvInfo* recv_channel = GetRecvChannelBySsrc(ssrc);
- if (!recv_channel) {
- // TODO(perkj): Remove this once BWE works properly across different send
- // and receive channels.
- // The default channel is reused for recv stream in 1:1 call.
- if (first_receive_ssrc_ == ssrc && GetDefaultRecvChannel()) {
- LOG(LS_INFO) << "SetRenderer " << ssrc
- << " reuse default channel #"
- << default_channel_id_;
- GetDefaultRecvChannel()->SetRenderer(renderer);
- return true;
- }
- return false;
- }
-
- recv_channel->SetRenderer(renderer);
- return true;
-}
-
-bool WebRtcVideoMediaChannel::GetStats(VideoMediaInfo* info) {
- // Get sender statistics and build VideoSenderInfo.
- unsigned int total_bitrate_sent = 0;
- unsigned int video_bitrate_sent = 0;
- unsigned int fec_bitrate_sent = 0;
- unsigned int nack_bitrate_sent = 0;
- unsigned int estimated_send_bandwidth = 0;
- unsigned int target_enc_bitrate = 0;
- if (send_codec_) {
- for (SendChannelMap::const_iterator iter = send_channels_.begin();
- iter != send_channels_.end(); ++iter) {
- WebRtcVideoChannelSendInfo* send_channel = iter->second;
- const int channel_id = send_channel->channel_id();
- VideoSenderInfo sinfo;
- if (!send_channel->IsActive()) {
- // This should only happen if the default vie channel is not in use.
- // This can happen if no streams have ever been added or the stream
- // corresponding to the default channel has been removed. Note that
- // there may be non-default vie channels in use when this happen so
- // asserting send_channels_.size() == 1 is not correct and neither is
- // breaking out of the loop.
- ASSERT(channel_id == default_channel_id_);
- continue;
- }
- size_t bytes_sent, bytes_recv;
- unsigned int packets_sent, packets_recv;
- if (engine_->vie()->rtp()->GetRTPStatistics(channel_id, bytes_sent,
- packets_sent, bytes_recv,
- packets_recv) != 0) {
- LOG_RTCERR1(GetRTPStatistics, default_channel_id_);
- continue;
- }
- WebRtcLocalStreamInfo* channel_stream_info =
- send_channel->local_stream_info();
-
- const StreamParams& sp = send_channel->stream_params();
- for (size_t i = 0; i < sp.ssrcs.size(); ++i) {
- sinfo.add_ssrc(sp.ssrcs[i]);
- }
- sinfo.codec_name = send_codec_->plName;
- sinfo.bytes_sent = bytes_sent;
- sinfo.packets_sent = packets_sent;
- sinfo.packets_cached = -1;
- sinfo.packets_lost = -1;
- sinfo.fraction_lost = -1;
- sinfo.rtt_ms = -1;
-
- VideoCapturer* video_capturer = send_channel->video_capturer();
- if (video_capturer) {
- VideoFormat last_captured_frame_format;
- video_capturer->GetStats(&sinfo.adapt_frame_drops,
- &sinfo.effects_frame_drops,
- &sinfo.capturer_frame_time,
- &last_captured_frame_format);
- sinfo.input_frame_width = last_captured_frame_format.width;
- sinfo.input_frame_height = last_captured_frame_format.height;
- } else {
- sinfo.input_frame_width = 0;
- sinfo.input_frame_height = 0;
- }
-
- webrtc::VideoCodec vie_codec;
- if (!video_capturer || video_capturer->IsMuted()) {
- sinfo.send_frame_width = 0;
- sinfo.send_frame_height = 0;
- } else if (engine()->vie()->codec()->GetSendCodec(channel_id,
- vie_codec) == 0) {
- sinfo.send_frame_width = vie_codec.width;
- sinfo.send_frame_height = vie_codec.height;
- } else {
- sinfo.send_frame_width = -1;
- sinfo.send_frame_height = -1;
- LOG_RTCERR1(GetSendCodec, channel_id);
- }
- sinfo.framerate_input = channel_stream_info->framerate();
- sinfo.framerate_sent = send_channel->encoder_observer()->framerate();
- sinfo.nominal_bitrate = send_channel->encoder_observer()->bitrate();
- if (send_codec_) {
- sinfo.preferred_bitrate = GetBitrate(
- send_codec_->maxBitrate, kMaxVideoBitrate);
- }
- sinfo.adapt_reason = send_channel->CurrentAdaptReason();
- sinfo.adapt_changes = send_channel->AdaptChanges();
-
- webrtc::CpuOveruseMetrics metrics;
- engine()->vie()->base()->GetCpuOveruseMetrics(channel_id, &metrics);
- sinfo.avg_encode_ms = metrics.avg_encode_time_ms;
- sinfo.encode_usage_percent = metrics.encode_usage_percent;
-
- webrtc::RtcpPacketTypeCounter rtcp_counter;
- if (engine()->vie()->rtp()->GetSendRtcpPacketTypeCounter(
- channel_id, &rtcp_counter) == 0) {
- sinfo.firs_rcvd = rtcp_counter.fir_packets;
- sinfo.plis_rcvd = rtcp_counter.pli_packets;
- sinfo.nacks_rcvd = rtcp_counter.nack_packets;
- } else {
- sinfo.firs_rcvd = -1;
- sinfo.plis_rcvd = -1;
- sinfo.nacks_rcvd = -1;
- LOG_RTCERR1(GetRtcpPacketTypeCounters, channel_id);
- }
-
- // Get received RTCP statistics for the sender (reported by the remote
- // client in a RTCP packet), if available.
- // It's not a fatal error if we can't, since RTCP may not have arrived
- // yet.
- webrtc::RtcpStatistics outgoing_stream_rtcp_stats;
- int64_t outgoing_stream_rtt_ms;
-
- if (engine_->vie()->rtp()->GetSendChannelRtcpStatistics(
- channel_id,
- outgoing_stream_rtcp_stats,
- outgoing_stream_rtt_ms) == 0) {
- // Convert Q8 to float.
- sinfo.packets_lost = outgoing_stream_rtcp_stats.cumulative_lost;
- sinfo.fraction_lost = static_cast<float>(
- outgoing_stream_rtcp_stats.fraction_lost) / (1 << 8);
- sinfo.rtt_ms = outgoing_stream_rtt_ms;
- }
- info->senders.push_back(sinfo);
-
- unsigned int channel_total_bitrate_sent = 0;
- unsigned int channel_video_bitrate_sent = 0;
- unsigned int channel_fec_bitrate_sent = 0;
- unsigned int channel_nack_bitrate_sent = 0;
- if (engine_->vie()->rtp()->GetBandwidthUsage(
- channel_id, channel_total_bitrate_sent, channel_video_bitrate_sent,
- channel_fec_bitrate_sent, channel_nack_bitrate_sent) == 0) {
- total_bitrate_sent += channel_total_bitrate_sent;
- video_bitrate_sent += channel_video_bitrate_sent;
- fec_bitrate_sent += channel_fec_bitrate_sent;
- nack_bitrate_sent += channel_nack_bitrate_sent;
- } else {
- LOG_RTCERR1(GetBandwidthUsage, channel_id);
- }
-
- unsigned int target_enc_stream_bitrate = 0;
- if (engine_->vie()->codec()->GetCodecTargetBitrate(
- channel_id, &target_enc_stream_bitrate) == 0) {
- target_enc_bitrate += target_enc_stream_bitrate;
- } else {
- LOG_RTCERR1(GetCodecTargetBitrate, channel_id);
- }
- }
- if (!send_channels_.empty()) {
- // GetEstimatedSendBandwidth returns the estimated bandwidth for all video
- // engine channels in a channel group. Any valid channel id will do as it
- // is only used to access the right group of channels.
- const int channel_id = send_channels_.begin()->second->channel_id();
- // Get the send bandwidth available for this MediaChannel.
- if (engine_->vie()->rtp()->GetEstimatedSendBandwidth(
- channel_id, &estimated_send_bandwidth) != 0) {
- LOG_RTCERR1(GetEstimatedSendBandwidth, channel_id);
- }
- }
- } else {
- LOG(LS_WARNING) << "GetStats: sender information not ready.";
- }
-
- // Get the SSRC and stats for each receiver, based on our own calculations.
- for (RecvChannelMap::const_iterator it = recv_channels_.begin();
- it != recv_channels_.end(); ++it) {
- WebRtcVideoChannelRecvInfo* channel = it->second;
-
- unsigned int ssrc = 0;
- // Get receiver statistics and build VideoReceiverInfo, if we have data.
- // Skip the default channel (ssrc == 0).
- if (engine_->vie()->rtp()->GetRemoteSSRC(
- channel->channel_id(), ssrc) != 0 ||
- ssrc == 0)
- continue;
-
- webrtc::StreamDataCounters sent;
- webrtc::StreamDataCounters received;
- if (engine_->vie()->rtp()->GetRtpStatistics(channel->channel_id(),
- sent, received) != 0) {
- LOG_RTCERR1(GetRTPStatistics, channel->channel_id());
- return false;
- }
- VideoReceiverInfo rinfo;
- rinfo.add_ssrc(ssrc);
- rinfo.bytes_rcvd = received.transmitted.payload_bytes;
- rinfo.packets_rcvd = received.transmitted.packets;
- rinfo.packets_lost = -1;
- rinfo.packets_concealed = -1;
- rinfo.fraction_lost = -1; // from SentRTCP
- rinfo.frame_width = channel->render_adapter()->width();
- rinfo.frame_height = channel->render_adapter()->height();
- int fps = channel->render_adapter()->framerate();
- rinfo.framerate_decoded = fps;
- rinfo.framerate_output = fps;
- rinfo.capture_start_ntp_time_ms =
- channel->render_adapter()->capture_start_ntp_time_ms();
- channel->decoder_observer()->ExportTo(&rinfo);
-
- webrtc::RtcpPacketTypeCounter rtcp_counter;
- if (engine()->vie()->rtp()->GetReceiveRtcpPacketTypeCounter(
- channel->channel_id(), &rtcp_counter) == 0) {
- rinfo.firs_sent = rtcp_counter.fir_packets;
- rinfo.plis_sent = rtcp_counter.pli_packets;
- rinfo.nacks_sent = rtcp_counter.nack_packets;
- } else {
- rinfo.firs_sent = -1;
- rinfo.plis_sent = -1;
- rinfo.nacks_sent = -1;
- LOG_RTCERR1(GetRtcpPacketTypeCounters, channel->channel_id());
- }
-
- // Get our locally created statistics of the received RTP stream.
- webrtc::RtcpStatistics incoming_stream_rtcp_stats;
- int64_t incoming_stream_rtt_ms;
- if (engine_->vie()->rtp()->GetReceiveChannelRtcpStatistics(
- channel->channel_id(),
- incoming_stream_rtcp_stats,
- incoming_stream_rtt_ms) == 0) {
- // Convert Q8 to float.
- rinfo.packets_lost = incoming_stream_rtcp_stats.cumulative_lost;
- rinfo.fraction_lost = static_cast<float>(
- incoming_stream_rtcp_stats.fraction_lost) / (1 << 8);
- }
- info->receivers.push_back(rinfo);
- }
- unsigned int estimated_recv_bandwidth = 0;
- if (!recv_channels_.empty()) {
- // GetEstimatedReceiveBandwidth returns the estimated bandwidth for all
- // video engine channels in a channel group. Any valid channel id will do as
- // it is only used to access the right group of channels.
- const int channel_id = recv_channels_.begin()->second->channel_id();
- // Gets the estimated receive bandwidth for the MediaChannel.
- if (engine_->vie()->rtp()->GetEstimatedReceiveBandwidth(
- channel_id, &estimated_recv_bandwidth) != 0) {
- LOG_RTCERR1(GetEstimatedReceiveBandwidth, channel_id);
- }
- }
-
- // Build BandwidthEstimationInfo.
- // TODO(zhurunz): Add real unittest for this.
- BandwidthEstimationInfo bwe;
- engine_->vie()->rtp()->GetPacerQueuingDelayMs(
- GetDefaultRecvChannel()->channel_id(), &bwe.bucket_delay);
-
- // Calculations done above per send/receive stream.
- bwe.actual_enc_bitrate = video_bitrate_sent;
- bwe.transmit_bitrate = total_bitrate_sent;
- bwe.retransmit_bitrate = nack_bitrate_sent;
- bwe.available_send_bandwidth = estimated_send_bandwidth;
- bwe.available_recv_bandwidth = estimated_recv_bandwidth;
- bwe.target_enc_bitrate = target_enc_bitrate;
-
- info->bw_estimations.push_back(bwe);
-
- return true;
-}
-
-bool WebRtcVideoMediaChannel::SetCapturer(uint32 ssrc,
- VideoCapturer* capturer) {
- ASSERT(ssrc != 0);
- if (!capturer) {
- return RemoveCapturer(ssrc);
- }
- WebRtcVideoChannelSendInfo* send_channel = GetSendChannelBySsrc(ssrc);
- if (!send_channel) {
- return false;
- }
- VideoCapturer* old_capturer = send_channel->video_capturer();
- MaybeDisconnectCapturer(old_capturer);
-
- send_channel->set_video_capturer(capturer, engine()->vie());
- MaybeConnectCapturer(capturer);
- if (!capturer->IsScreencast() && ratio_w_ != 0 && ratio_h_ != 0) {
- capturer->UpdateAspectRatio(ratio_w_, ratio_h_);
- }
- const int64 timestamp = send_channel->local_stream_info()->time_stamp();
- if (send_codec_) {
- QueueBlackFrame(ssrc, timestamp,
- VideoFormat::FpsToInterval(send_codec_->maxFramerate));
- }
-
- capturer->SetApplyRotation(
- !FindHeaderExtension(send_extensions_, kRtpVideoRotationHeaderExtension));
-
- return true;
-}
-
-bool WebRtcVideoMediaChannel::RequestIntraFrame() {
- // There is no API exposed to application to request a key frame
- // ViE does this internally when there are errors from decoder
- return false;
-}
-
-void WebRtcVideoMediaChannel::OnPacketReceived(
- rtc::Buffer* packet, const rtc::PacketTime& packet_time) {
- // Pick which channel to send this packet to. If this packet doesn't match
- // any multiplexed streams, just send it to the default channel. Otherwise,
- // send it to the specific decoder instance for that stream.
- uint32 ssrc = 0;
- if (!GetRtpSsrc(packet->data(), packet->size(), &ssrc))
- return;
- int processing_channel_id = GetRecvChannelId(ssrc);
- if (processing_channel_id == kChannelIdUnset) {
- // Allocate an unsignalled recv channel for processing in conference mode.
- if (!ConferenceModeIsEnabled()) {
- // If we can't find or allocate one, use the default.
- processing_channel_id = default_channel_id_;
- } else if (!CreateUnsignalledRecvChannel(ssrc, &processing_channel_id)) {
- // If we can't create an unsignalled recv channel, drop the packet in
- // conference mode.
- return;
- }
- }
-
- engine()->vie()->network()->ReceivedRTPPacket(
- processing_channel_id, packet->data(), packet->size(),
- webrtc::PacketTime(packet_time.timestamp, packet_time.not_before));
-}
-
-void WebRtcVideoMediaChannel::OnRtcpReceived(
- rtc::Buffer* packet, const rtc::PacketTime& packet_time) {
-// Sending channels need all RTCP packets with feedback information.
-// Even sender reports can contain attached report blocks.
-// Receiving channels need sender reports in order to create
-// correct receiver reports.
-
- uint32 ssrc = 0;
- if (!GetRtcpSsrc(packet->data(), packet->size(), &ssrc)) {
- LOG(LS_WARNING) << "Failed to parse SSRC from received RTCP packet";
- return;
- }
- int type = 0;
- if (!GetRtcpType(packet->data(), packet->size(), &type)) {
- LOG(LS_WARNING) << "Failed to parse type from received RTCP packet";
- return;
- }
-
- // If it is a sender report, find the channel that is listening.
- if (type == kRtcpTypeSR) {
- int recv_channel_id = GetRecvChannelId(ssrc);
- if (recv_channel_id != kChannelIdUnset && !IsDefaultChannelId(recv_channel_id)) {
- engine_->vie()->network()->ReceivedRTCPPacket(
- recv_channel_id, packet->data(), packet->size());
- }
- }
- // SR may continue RR and any RR entry may correspond to any one of the send
- // channels. So all RTCP packets must be forwarded all send channels. ViE
- // will filter out RR internally.
- for (SendChannelMap::iterator iter = send_channels_.begin();
- iter != send_channels_.end(); ++iter) {
- WebRtcVideoChannelSendInfo* send_channel = iter->second;
- int channel_id = send_channel->channel_id();
- engine_->vie()->network()->ReceivedRTCPPacket(channel_id, packet->data(),
- packet->size());
- }
-}
-
-void WebRtcVideoMediaChannel::OnReadyToSend(bool ready) {
- SetNetworkTransmissionState(ready);
-}
-
-bool WebRtcVideoMediaChannel::MuteStream(uint32 ssrc, bool muted) {
- WebRtcVideoChannelSendInfo* send_channel = GetSendChannelBySsrc(ssrc);
- if (!send_channel) {
- LOG(LS_ERROR) << "The specified ssrc " << ssrc << " is not in use.";
- return false;
- }
- send_channel->set_muted(muted);
- return true;
-}
-
-bool WebRtcVideoMediaChannel::SetRecvRtpHeaderExtensions(
- const std::vector<RtpHeaderExtension>& extensions) {
- if (receive_extensions_ == extensions) {
- return true;
- }
-
- const RtpHeaderExtension* offset_extension =
- FindHeaderExtension(extensions, kRtpTimestampOffsetHeaderExtension);
- const RtpHeaderExtension* send_time_extension =
- FindHeaderExtension(extensions, kRtpAbsoluteSenderTimeHeaderExtension);
- const RtpHeaderExtension* cvo_extension =
- FindHeaderExtension(extensions, kRtpVideoRotationHeaderExtension);
-
- // Loop through all receive channels and enable/disable the extensions.
- for (RecvChannelMap::iterator channel_it = recv_channels_.begin();
- channel_it != recv_channels_.end(); ++channel_it) {
- int channel_id = channel_it->second->channel_id();
- if (!SetHeaderExtension(
- &webrtc::ViERTP_RTCP::SetReceiveTimestampOffsetStatus, channel_id,
- offset_extension)) {
- return false;
- }
- if (!SetHeaderExtension(
- &webrtc::ViERTP_RTCP::SetReceiveAbsoluteSendTimeStatus, channel_id,
- send_time_extension)) {
- return false;
- }
- if (!SetHeaderExtension(&webrtc::ViERTP_RTCP::SetReceiveVideoRotationStatus,
- channel_id, cvo_extension)) {
- return false;
- }
- }
-
- receive_extensions_ = extensions;
- return true;
-}
-
-bool WebRtcVideoMediaChannel::SetSendRtpHeaderExtensions(
- const std::vector<RtpHeaderExtension>& extensions) {
- if (send_extensions_ == extensions) {
- return true;
- }
-
- const RtpHeaderExtension* offset_extension =
- FindHeaderExtension(extensions, kRtpTimestampOffsetHeaderExtension);
- const RtpHeaderExtension* send_time_extension =
- FindHeaderExtension(extensions, kRtpAbsoluteSenderTimeHeaderExtension);
- const RtpHeaderExtension* cvo_extension =
- FindHeaderExtension(extensions, kRtpVideoRotationHeaderExtension);
-
- // Loop through all send channels and enable/disable the extensions.
- for (SendChannelMap::iterator channel_it = send_channels_.begin();
- channel_it != send_channels_.end(); ++channel_it) {
- int channel_id = channel_it->second->channel_id();
- if (!SetHeaderExtension(
- &webrtc::ViERTP_RTCP::SetSendTimestampOffsetStatus, channel_id,
- offset_extension)) {
- return false;
- }
- if (!SetHeaderExtension(
- &webrtc::ViERTP_RTCP::SetSendAbsoluteSendTimeStatus, channel_id,
- send_time_extension)) {
- return false;
- }
- if (!SetHeaderExtension(&webrtc::ViERTP_RTCP::SetSendVideoRotationStatus,
- channel_id, cvo_extension)) {
- return false;
- }
- }
-
- if (send_time_extension) {
- // For video RTP packets, we would like to update AbsoluteSendTimeHeader
- // Extension closer to the network, @ socket level before sending.
- // Pushing the extension id to socket layer.
- MediaChannel::SetOption(NetworkInterface::ST_RTP,
- rtc::Socket::OPT_RTP_SENDTIME_EXTN_ID,
- send_time_extension->id);
- }
-
- // For now assume that all streams want the same CVO setting.
- // TODO(guoweis): Remove the need for this assumption.
- for (const auto& kv : send_channels_) {
- if (kv.second->video_capturer()) {
- kv.second->video_capturer()->SetApplyRotation(!cvo_extension);
- }
- }
-
- send_extensions_ = extensions;
- return true;
-}
-
-int WebRtcVideoMediaChannel::GetRtpSendTimeExtnId() const {
- const RtpHeaderExtension* send_time_extension = FindHeaderExtension(
- send_extensions_, kRtpAbsoluteSenderTimeHeaderExtension);
- if (send_time_extension) {
- return send_time_extension->id;
- }
- return -1;
-}
-
-bool WebRtcVideoMediaChannel::SetMaxSendBandwidth(int bps) {
- LOG(LS_INFO) << "WebRtcVideoMediaChannel::SetMaxSendBandwidth";
-
- if (!send_codec_) {
- LOG(LS_INFO) << "The send codec has not been set up yet";
- return true;
- }
-
- webrtc::VideoCodec new_codec = *send_codec_;
- if (BitrateIsSet(bps)) {
- new_codec.maxBitrate = bps / 1000;
- }
- if (!SetSendCodec(new_codec)) {
- return false;
- }
- LogSendCodecChange("SetMaxSendBandwidth()");
-
- return true;
-}
-
-bool WebRtcVideoMediaChannel::SetOptions(const VideoOptions &options) {
- // Always accept options that are unchanged.
- if (options_ == options) {
- return true;
- }
-
- // Save the options, to be interpreted where appropriate.
- // Use options_.SetAll() instead of assignment so that unset value in options
- // will not overwrite the previous option value.
- VideoOptions original = options_;
- options_.SetAll(options);
-
- Clamp(&options_.system_low_adaptation_threshhold, 0.0f, 1.0f);
- Clamp(&options_.system_high_adaptation_threshhold, 0.0f, 1.0f);
-
- bool use_simulcast_adapter;
- if (options.use_simulcast_adapter.Get(&use_simulcast_adapter) &&
- options.use_simulcast_adapter != original.use_simulcast_adapter) {
- webrtc::VP8EncoderFactoryConfig::set_use_simulcast_adapter(
- use_simulcast_adapter);
- }
-
- // Set CPU options and codec options for all send channels.
- for (SendChannelMap::iterator iter = send_channels_.begin();
- iter != send_channels_.end(); ++iter) {
- WebRtcVideoChannelSendInfo* send_channel = iter->second;
- send_channel->ApplyCpuOptions(options_);
-
- if (send_codec_) {
- VideoSendParams send_params = send_channel->send_params();
-
- bool conference_mode_turned_off = (
- original.conference_mode.IsSet() &&
- options.conference_mode.IsSet() &&
- original.conference_mode.GetWithDefaultIfUnset(false) &&
- !options.conference_mode.GetWithDefaultIfUnset(false));
- if (conference_mode_turned_off) {
- // This is a special case for turning conference mode off.
- // Max bitrate should go back to the default maximum value instead
- // of the current maximum.
- send_params.codec.maxBitrate = kAutoBandwidth;
- }
-
- // TODO(pthatcher): Remove this. We don't need 4 ways to set bitrates.
- int new_start_bitrate;
- if (options.video_start_bitrate.Get(&new_start_bitrate)) {
- send_params.codec.startBitrate = new_start_bitrate;
- }
-
- if (!SetSendParams(send_channel, send_params)) {
- return false;
- }
- LogSendCodecChange("SetOptions()");
- }
- }
-
-
- int buffer_latency;
- if (Changed(options.buffered_mode_latency,
- original.buffered_mode_latency,
- &buffer_latency)) {
- LOG(LS_INFO) << "Buffer latency is " << buffer_latency;
- for (SendChannelMap::iterator it = send_channels_.begin();
- it != send_channels_.end(); ++it) {
- if (engine()->vie()->rtp()->SetSenderBufferingMode(
- it->second->channel_id(), buffer_latency) != 0) {
- LOG_RTCERR2(SetSenderBufferingMode, it->second->channel_id(),
- buffer_latency);
- }
- }
- for (RecvChannelMap::iterator it = recv_channels_.begin();
- it != recv_channels_.end(); ++it) {
- if (engine()->vie()->rtp()->SetReceiverBufferingMode(
- it->second->channel_id(), buffer_latency) != 0) {
- LOG_RTCERR2(SetReceiverBufferingMode, it->second->channel_id(),
- buffer_latency);
- }
- }
- }
-
- bool dscp_enabled;
- if (Changed(options.dscp, original.dscp, &dscp_enabled)) {
- rtc::DiffServCodePoint dscp = rtc::DSCP_DEFAULT;
- if (dscp_enabled) {
- dscp = kVideoDscpValue;
- }
- LOG(LS_INFO) << "DSCP is " << dscp;
- if (MediaChannel::SetDscp(dscp) != 0) {
- LOG(LS_WARNING) << "Failed to set DSCP settings for video channel";
- }
- }
-
- bool suspend_below_min_bitrate;
- if (Changed(options.suspend_below_min_bitrate,
- original.suspend_below_min_bitrate,
- &suspend_below_min_bitrate)) {
- if (suspend_below_min_bitrate) {
- LOG(LS_INFO) << "Suspend below min bitrate enabled.";
- for (SendChannelMap::iterator it = send_channels_.begin();
- it != send_channels_.end(); ++it) {
- engine()->vie()->codec()->SuspendBelowMinBitrate(
- it->second->channel_id());
- }
- } else {
- LOG(LS_WARNING) << "Cannot disable video suspension once it is enabled";
- }
- }
-
- webrtc::CpuOveruseOptions overuse_options;
- if (GetCpuOveruseOptions(options_, &overuse_options)) {
- for (SendChannelMap::iterator it = send_channels_.begin();
- it != send_channels_.end(); ++it) {
- if (engine()->vie()->base()->SetCpuOveruseOptions(
- it->second->channel_id(), overuse_options) != 0) {
- LOG_RTCERR1(SetCpuOveruseOptions, it->second->channel_id());
- }
- }
- }
- return true;
-}
-
-void WebRtcVideoMediaChannel::SetInterface(NetworkInterface* iface) {
- MediaChannel::SetInterface(iface);
- // Set the RTP recv/send buffer to a bigger size
- MediaChannel::SetOption(NetworkInterface::ST_RTP,
- rtc::Socket::OPT_RCVBUF,
- kVideoRtpBufferSize);
-
- // Speculative change to increase the outbound socket buffer size.
- // In b/15152257, we are seeing a significant number of packets discarded
- // due to lack of socket buffer space, although it's not yet clear what the
- // ideal value should be.
- MediaChannel::SetOption(NetworkInterface::ST_RTP,
- rtc::Socket::OPT_SNDBUF,
- kVideoRtpBufferSize);
-}
-
-void WebRtcVideoMediaChannel::UpdateAspectRatio(int ratio_w, int ratio_h) {
- ASSERT(ratio_w != 0);
- ASSERT(ratio_h != 0);
- ratio_w_ = ratio_w;
- ratio_h_ = ratio_h;
- // For now assume that all streams want the same aspect ratio.
- // TODO(hellner): remove the need for this assumption.
- for (SendChannelMap::iterator iter = send_channels_.begin();
- iter != send_channels_.end(); ++iter) {
- WebRtcVideoChannelSendInfo* send_channel = iter->second;
- VideoCapturer* capturer = send_channel->video_capturer();
- if (capturer) {
- capturer->UpdateAspectRatio(ratio_w, ratio_h);
- }
- }
-}
-
-bool WebRtcVideoMediaChannel::GetRenderer(uint32 ssrc,
- VideoRenderer** renderer) {
- WebRtcVideoChannelRecvInfo* recv_channel = GetRecvChannelBySsrc(ssrc);
- if (!recv_channel) {
- if (first_receive_ssrc_ == ssrc && GetDefaultRecvChannel()) {
- LOG(LS_INFO) << " GetRenderer " << ssrc
- << " reuse default renderer #"
- << default_channel_id_;
- *renderer = GetDefaultRecvChannel()->render_adapter()->renderer();
- return true;
- }
- return false;
- }
-
- *renderer = recv_channel->render_adapter()->renderer();
- return true;
-}
-
-bool WebRtcVideoMediaChannel::GetVideoAdapter(
- uint32 ssrc, CoordinatedVideoAdapter** video_adapter) {
- WebRtcVideoChannelSendInfo* send_channel = GetSendChannelBySsrc(ssrc);
- if (!send_channel) {
- return false;
- }
- *video_adapter = send_channel->video_adapter();
- return true;
-}
-
-void WebRtcVideoMediaChannel::SendFrame(VideoCapturer* capturer,
- const VideoFrame* frame) {
- // If the |capturer| is registered to any send channel, then send the frame
- // to those send channels.
- bool capturer_is_channel_owned = false;
- for (SendChannelMap::iterator iter = send_channels_.begin();
- iter != send_channels_.end(); ++iter) {
- WebRtcVideoChannelSendInfo* send_channel = iter->second;
- if (send_channel->video_capturer() == capturer) {
- SendFrame(send_channel, frame, capturer->IsScreencast());
- capturer_is_channel_owned = true;
- }
- }
- if (capturer_is_channel_owned) {
- return;
- }
-
- // TODO(hellner): Remove below for loop once the captured frame no longer
- // come from the engine, i.e. the engine no longer owns a capturer.
- for (SendChannelMap::iterator iter = send_channels_.begin();
- iter != send_channels_.end(); ++iter) {
- WebRtcVideoChannelSendInfo* send_channel = iter->second;
- if (!send_channel->video_capturer()) {
- SendFrame(send_channel, frame, capturer->IsScreencast());
- }
- }
-}
-
-bool WebRtcVideoMediaChannel::SendFrame(
- WebRtcVideoChannelSendInfo* send_channel,
- const VideoFrame* frame,
- bool is_screencast) {
- if (!send_channel) {
- return false;
- }
-
- bool changed;
- send_channel->SetLastCapturedFrameInfo(frame, is_screencast, &changed);
-
- if (!send_codec_) {
- // Send codec has not been set. No reason to process the frame any further.
- return false;
- }
-
- // TODO(pthatcher): Move drop logic to adapter.
- // If the frame should be dropped.
- if (send_channel->adapt_format_set() &&
- send_channel->adapt_format().width == 0 &&
- send_channel->adapt_format().height == 0) {
- return true;
- }
-
- if (changed) {
- // If the last captured frame info changed, then calling
- // SetSendParams will update to the latest resolution.
- VideoSendParams send_params = send_channel->send_params();
- // Note: We must copy the send_params because otherwise the memory
- // checker will complain.
- if (!SetSendParams(send_channel, send_params)) {
- LOG(LS_ERROR) << "SetSendParams from SendFrame failed with "
- << frame->GetWidth() << "x" << frame->GetHeight()
- << " screencast? " << is_screencast;
- return false;
- }
- LogSendCodecChange("Captured frame size changed");
- }
-
- const VideoFrame* frame_out = frame;
- rtc::scoped_ptr<VideoFrame> processed_frame;
- // TODO(hellner): Remove the need for disabling mute when screencasting.
- const bool mute = (send_channel->muted() && !is_screencast);
- send_channel->ProcessFrame(*frame_out, mute, processed_frame.use());
- if (processed_frame) {
- frame_out = processed_frame.get();
- }
-
- webrtc::I420VideoFrame webrtc_frame(frame_out->GetVideoFrameBuffer(), 0, 0,
- frame_out->GetVideoRotation());
- int64 timestamp_ntp_ms = 0;
- // TODO(justinlin): Reenable after Windows issues with clock drift are fixed.
- // Currently reverted to old behavior of discarding capture timestamp.
-#if 0
- static const int kTimestampDeltaInSecondsForWarning = 2;
-
- // If the frame timestamp is 0, we will use the deliver time.
- const int64 frame_timestamp = frame->GetTimeStamp();
- if (frame_timestamp != 0) {
- if (abs(time(NULL) - frame_timestamp / rtc::kNumNanosecsPerSec) >
- kTimestampDeltaInSecondsForWarning) {
- LOG(LS_WARNING) << "Frame timestamp differs by more than "
- << kTimestampDeltaInSecondsForWarning << " seconds from "
- << "current Unix timestamp.";
- }
-
- timestamp_ntp_ms =
- rtc::UnixTimestampNanosecsToNtpMillisecs(frame_timestamp);
- }
-#endif
- webrtc_frame.set_ntp_time_ms(timestamp_ntp_ms);
- send_channel->external_capture()->IncomingFrame(webrtc_frame);
- return true;
-}
-
-bool WebRtcVideoMediaChannel::CreateChannel(uint32 ssrc_key,
- MediaDirection direction,
- int* channel_id) {
- // There are 3 types of channels. Sending only, receiving only and
- // sending and receiving. The sending and receiving channel is the
- // default channel and there is only one. All other channels that
- // are created are associated with the default channel which must
- // exist. The default channel id is stored in
- // |default_channel_id_|. All channels need to know about the
- // default channel to properly handle remb which is why there are
- // different ViE create channel calls. For this channel the local
- // and remote ssrc_key is kDefaultChannelSsrcKey. However, it may
- // have a non-zero local and/or remote ssrc depending on if it is
- // currently sending and/or receiving.
- if ((default_channel_id_ == kChannelIdUnset || direction == MD_SENDRECV) &&
- (!send_channels_.empty() || !recv_channels_.empty())) {
- ASSERT(false);
- return false;
- }
-
- *channel_id = kChannelIdUnset;
- if (direction == MD_RECV) {
- // All rec channels are associated with default_channel_id_.
- if (engine_->vie()->base()->CreateReceiveChannel(*channel_id,
- default_channel_id_) != 0) {
- LOG_RTCERR2(CreateReceiveChannel, *channel_id, default_channel_id_);
- return false;
- }
- } else if (direction == MD_SEND) {
- if (engine_->vie()->base()->CreateChannel(*channel_id,
- default_channel_id_) != 0) {
- LOG_RTCERR2(CreateChannel, *channel_id, default_channel_id_);
- return false;
- }
- } else {
- ASSERT(direction == MD_SENDRECV);
- if (engine_->vie()->base()->CreateChannel(*channel_id) != 0) {
- LOG_RTCERR1(CreateChannel, *channel_id);
- return false;
- }
- }
- if (!ConfigureChannel(*channel_id, direction, ssrc_key)) {
- engine_->vie()->base()->DeleteChannel(*channel_id);
- *channel_id = kChannelIdUnset;
- return false;
- }
-
- return true;
-}
-
-bool WebRtcVideoMediaChannel::CreateUnsignalledRecvChannel(
- uint32 ssrc_key, int* out_channel_id) {
- int unsignalled_recv_channel_limit =
- options_.unsignalled_recv_stream_limit.GetWithDefaultIfUnset(
- kNumDefaultUnsignalledVideoRecvStreams);
- if (num_unsignalled_recv_channels_ >= unsignalled_recv_channel_limit) {
- return false;
- }
- if (!CreateChannel(ssrc_key, MD_RECV, out_channel_id)) {
- return false;
- }
- // TODO(tvsriram): Support dynamic sizing of unsignalled recv channels.
- num_unsignalled_recv_channels_++;
- return true;
-}
-
-bool WebRtcVideoMediaChannel::ConfigureChannel(int channel_id,
- MediaDirection direction,
- uint32 ssrc_key) {
- const bool receiving = (direction == MD_RECV) || (direction == MD_SENDRECV);
- const bool sending = (direction == MD_SEND) || (direction == MD_SENDRECV);
- // Register external transport.
- if (engine_->vie()->network()->RegisterSendTransport(
- channel_id, *this) != 0) {
- LOG_RTCERR1(RegisterSendTransport, channel_id);
- return false;
- }
-
- // Set MTU.
- if (engine_->vie()->network()->SetMTU(channel_id, kVideoMtu) != 0) {
- LOG_RTCERR2(SetMTU, channel_id, kVideoMtu);
- return false;
- }
- // Turn on RTCP and loss feedback reporting.
- if (engine()->vie()->rtp()->SetRTCPStatus(
- channel_id, webrtc::kRtcpCompound_RFC4585) != 0) {
- LOG_RTCERR2(SetRTCPStatus, channel_id, webrtc::kRtcpCompound_RFC4585);
- return false;
- }
- // Enable pli as key frame request method.
- if (engine_->vie()->rtp()->SetKeyFrameRequestMethod(
- channel_id, webrtc::kViEKeyFrameRequestPliRtcp) != 0) {
- LOG_RTCERR2(SetKeyFrameRequestMethod,
- channel_id, webrtc::kViEKeyFrameRequestPliRtcp);
- return false;
- }
- if (!SetNackFec(channel_id, send_red_type_, send_fec_type_, nack_enabled_)) {
- // Logged in SetNackFec. Don't spam the logs.
- return false;
- }
- // Note that receiving must always be configured before sending to ensure
- // that send and receive channel is configured correctly (ConfigureReceiving
- // assumes no sending).
- if (receiving) {
- if (!ConfigureReceiving(channel_id, ssrc_key)) {
- return false;
- }
- }
- if (sending) {
- if (!ConfigureSending(channel_id, ssrc_key)) {
- return false;
- }
- }
-
- // Start receiving for both receive and send channels so that we get incoming
- // RTP (if receiving) as well as RTCP feedback (if sending).
- if (engine()->vie()->base()->StartReceive(channel_id) != 0) {
- LOG_RTCERR1(StartReceive, channel_id);
- return false;
- }
-
- return true;
-}
-
-bool WebRtcVideoMediaChannel::ConfigureReceiving(int channel_id,
- uint32 remote_ssrc) {
- // Make sure that an SSRC isn't registered more than once.
- if (GetRecvChannelBySsrc(remote_ssrc)) {
- return false;
- }
- // Connect the voice channel, if there is one.
- // TODO(perkj): The A/V is synched by the receiving channel. So we need to
- // know the SSRC of the remote audio channel in order to fetch the correct
- // webrtc VoiceEngine channel. For now- only sync the default channel used
- // in 1-1 calls.
- if (remote_ssrc == kDefaultChannelSsrcKey && voice_channel_) {
- WebRtcVoiceMediaChannel* voice_channel =
- static_cast<WebRtcVoiceMediaChannel*>(voice_channel_);
- if (engine_->vie()->base()->ConnectAudioChannel(
- default_channel_id_, voice_channel->voe_channel()) != 0) {
- LOG_RTCERR2(ConnectAudioChannel, channel_id,
- voice_channel->voe_channel());
- LOG(LS_WARNING) << "A/V not synchronized";
- // Not a fatal error.
- }
- }
-
- rtc::scoped_ptr<WebRtcVideoChannelRecvInfo> channel_info(
- new WebRtcVideoChannelRecvInfo(channel_id));
-
- // Install a render adapter.
- if (engine_->vie()->render()->AddRenderer(channel_id,
- webrtc::kVideoI420, channel_info->render_adapter()) != 0) {
- LOG_RTCERR3(AddRenderer, channel_id, webrtc::kVideoI420,
- channel_info->render_adapter());
- return false;
- }
-
- if (engine()->vie()->render()->SetExpectedRenderDelay(
- channel_id, kDefaultRenderDelayMs)) {
- LOG_RTCERR2(SetExpectedRenderDelay,
- channel_id, kDefaultRenderDelayMs);
- }
-
- if (engine_->vie()->rtp()->SetRembStatus(channel_id,
- kNotSending,
- remb_enabled_) != 0) {
- LOG_RTCERR3(SetRembStatus, channel_id, kNotSending, remb_enabled_);
- return false;
- }
-
- if (!SetHeaderExtension(&webrtc::ViERTP_RTCP::SetReceiveTimestampOffsetStatus,
- channel_id, receive_extensions_, kRtpTimestampOffsetHeaderExtension)) {
- return false;
- }
- if (!SetHeaderExtension(
- &webrtc::ViERTP_RTCP::SetReceiveAbsoluteSendTimeStatus, channel_id,
- receive_extensions_, kRtpAbsoluteSenderTimeHeaderExtension)) {
- return false;
- }
- if (!SetHeaderExtension(&webrtc::ViERTP_RTCP::SetReceiveVideoRotationStatus,
- channel_id, receive_extensions_,
- kRtpVideoRotationHeaderExtension)) {
- return false;
- }
-
- if (receiver_report_ssrc_ != kSsrcUnset) {
- if (engine()->vie()->rtp()->SetLocalSSRC(
- channel_id, receiver_report_ssrc_) == -1) {
- LOG_RTCERR2(SetLocalSSRC, channel_id, receiver_report_ssrc_);
- return false;
- }
- }
-
- // Disable color enhancement since it is a bit too aggressive.
- if (engine()->vie()->image()->EnableColorEnhancement(channel_id,
- false) != 0) {
- LOG_RTCERR1(EnableColorEnhancement, channel_id);
- return false;
- }
-
- if (!SetReceiveCodecs(channel_info.get())) {
- return false;
- }
-
- int buffer_latency =
- options_.buffered_mode_latency.GetWithDefaultIfUnset(
- cricket::kBufferedModeDisabled);
- if (buffer_latency != cricket::kBufferedModeDisabled) {
- if (engine()->vie()->rtp()->SetReceiverBufferingMode(
- channel_id, buffer_latency) != 0) {
- LOG_RTCERR2(SetReceiverBufferingMode, channel_id, buffer_latency);
- }
- }
-
- if (render_started_) {
- if (engine_->vie()->render()->StartRender(channel_id) != 0) {
- LOG_RTCERR1(StartRender, channel_id);
- return false;
- }
- }
-
- // Register decoder observer for incoming framerate and bitrate.
- if (engine()->vie()->codec()->RegisterDecoderObserver(
- channel_id, *channel_info->decoder_observer()) != 0) {
- LOG_RTCERR1(RegisterDecoderObserver, channel_info->decoder_observer());
- return false;
- }
-
- recv_channels_[remote_ssrc] = channel_info.release();
- return true;
-}
-
-bool WebRtcVideoMediaChannel::ConfigureSending(int channel_id,
- uint32 local_ssrc_key) {
- // The ssrc key can be zero or correspond to an SSRC.
- // Make sure the default channel isn't configured more than once.
- if (local_ssrc_key == kDefaultChannelSsrcKey && GetDefaultSendChannel()) {
- return false;
- }
- // Make sure that the SSRC is not already in use.
- uint32 dummy_key;
- if (GetSendChannelSsrcKey(local_ssrc_key, &dummy_key)) {
- return false;
- }
- int vie_capture = 0;
- webrtc::ViEExternalCapture* external_capture = NULL;
- // Register external capture.
- if (engine()->vie()->capture()->AllocateExternalCaptureDevice(
- vie_capture, external_capture) != 0) {
- LOG_RTCERR0(AllocateExternalCaptureDevice);
- return false;
- }
-
- // Connect external capture.
- if (engine()->vie()->capture()->ConnectCaptureDevice(
- vie_capture, channel_id) != 0) {
- LOG_RTCERR2(ConnectCaptureDevice, vie_capture, channel_id);
- return false;
- }
-
- // Set up a new send channel.
- rtc::scoped_ptr<WebRtcVideoChannelSendInfo> send_channel(
- new WebRtcVideoChannelSendInfo(channel_id, vie_capture,
- external_capture,
- engine()->cpu_monitor()));
- send_channel->ApplyCpuOptions(options_);
- send_channel->SignalCpuAdaptationUnable.connect(this,
- &WebRtcVideoMediaChannel::OnCpuAdaptationUnable);
-
- webrtc::CpuOveruseOptions overuse_options;
- if (GetCpuOveruseOptions(options_, &overuse_options)) {
- if (engine()->vie()->base()->SetCpuOveruseOptions(channel_id,
- overuse_options) != 0) {
- LOG_RTCERR1(SetCpuOveruseOptions, channel_id);
- }
- }
-
- // Register encoder observer for outgoing framerate and bitrate.
- if (engine()->vie()->codec()->RegisterEncoderObserver(
- channel_id, *send_channel->encoder_observer()) != 0) {
- LOG_RTCERR1(RegisterEncoderObserver, send_channel->encoder_observer());
- return false;
- }
-
- if (!SetHeaderExtension(&webrtc::ViERTP_RTCP::SetSendTimestampOffsetStatus,
- channel_id, send_extensions_, kRtpTimestampOffsetHeaderExtension)) {
- return false;
- }
-
- if (!SetHeaderExtension(&webrtc::ViERTP_RTCP::SetSendAbsoluteSendTimeStatus,
- channel_id, send_extensions_, kRtpAbsoluteSenderTimeHeaderExtension)) {
- return false;
- }
-
- if (!SetHeaderExtension(&webrtc::ViERTP_RTCP::SetSendVideoRotationStatus,
- channel_id, send_extensions_,
- kRtpVideoRotationHeaderExtension)) {
- return false;
- }
-
- if (engine()->vie()->rtp()->SetTransmissionSmoothingStatus(channel_id,
- true) != 0) {
- LOG_RTCERR2(SetTransmissionSmoothingStatus, channel_id, true);
- return false;
- }
-
- int buffer_latency =
- options_.buffered_mode_latency.GetWithDefaultIfUnset(
- cricket::kBufferedModeDisabled);
- if (buffer_latency != cricket::kBufferedModeDisabled) {
- if (engine()->vie()->rtp()->SetSenderBufferingMode(
- channel_id, buffer_latency) != 0) {
- LOG_RTCERR2(SetSenderBufferingMode, channel_id, buffer_latency);
- }
- }
-
- if (options_.suspend_below_min_bitrate.GetWithDefaultIfUnset(false)) {
- engine()->vie()->codec()->SuspendBelowMinBitrate(channel_id);
- }
-
- // The remb status direction correspond to the RTP stream (and not the RTCP
- // stream). I.e. if send remb is enabled it means it is receiving remote
- // rembs and should use them to estimate bandwidth. Receive remb mean that
- // remb packets will be generated and that the channel should be included in
- // it. If remb is enabled all channels are allowed to contribute to the remb
- // but only receive channels will ever end up actually contributing. This
- // keeps the logic simple.
- if (engine_->vie()->rtp()->SetRembStatus(channel_id,
- remb_enabled_,
- remb_enabled_) != 0) {
- LOG_RTCERR3(SetRembStatus, channel_id, remb_enabled_, remb_enabled_);
- return false;
- }
- if (!SetNackFec(channel_id, send_red_type_, send_fec_type_, nack_enabled_)) {
- // Logged in SetNackFec. Don't spam the logs.
- return false;
- }
-
- send_channels_[local_ssrc_key] = send_channel.release();
-
- return true;
-}
-
-bool WebRtcVideoMediaChannel::SetNackFec(int channel_id,
- int red_payload_type,
- int fec_payload_type,
- bool nack_enabled) {
- bool enable = (red_payload_type != -1 && fec_payload_type != -1 &&
- !ConferenceModeIsEnabled());
- if (enable) {
- if (engine_->vie()->rtp()->SetHybridNACKFECStatus(
- channel_id, nack_enabled, red_payload_type, fec_payload_type) != 0) {
- LOG_RTCERR4(SetHybridNACKFECStatus, channel_id, nack_enabled,
- red_payload_type, fec_payload_type);
- return false;
- }
- LOG(LS_INFO) << "Hybrid NACK/FEC enabled for channel " << channel_id;
- } else {
- if (engine_->vie()->rtp()->SetNACKStatus(channel_id, nack_enabled) != 0) {
- LOG_RTCERR1(SetNACKStatus, channel_id);
- return false;
- }
- std::string enabled = nack_enabled ? "enabled" : "disabled";
- LOG(LS_INFO) << "NACK " << enabled << " for channel " << channel_id;
- }
- return true;
-}
-
-bool WebRtcVideoMediaChannel::SetSendCodec(const webrtc::VideoCodec& codec) {
- bool ret_val = true;
- for (SendChannelMap::iterator iter = send_channels_.begin();
- iter != send_channels_.end(); ++iter) {
- WebRtcVideoChannelSendInfo* send_channel = iter->second;
- ret_val = SetSendCodec(send_channel, codec) && ret_val;
- }
- if (ret_val) {
- // All SetSendCodec calls were successful. Update the global state
- // accordingly.
- send_codec_.reset(new webrtc::VideoCodec(codec));
- } else {
- // At least one SetSendCodec call failed, rollback.
- for (SendChannelMap::iterator iter = send_channels_.begin();
- iter != send_channels_.end(); ++iter) {
- WebRtcVideoChannelSendInfo* send_channel = iter->second;
- if (send_codec_) {
- SetSendCodec(send_channel, *send_codec_);
- }
- }
- }
- return ret_val;
-}
-
-bool WebRtcVideoMediaChannel::SetSendCodec(
- WebRtcVideoChannelSendInfo* send_channel,
- const webrtc::VideoCodec& codec) {
- if (!send_channel) {
- return false;
- }
-
- send_channel->SetAdaptFormat(
- VideoFormatFromVieCodec(codec),
- WebRtcVideoChannelSendInfo::kAdaptFormatTypeCodec);
-
- VideoSendParams send_params = send_channel->send_params();
- send_params.codec = codec;
- return SetSendParams(send_channel, send_params);
-}
-
-static std::string ToString(webrtc::VideoCodecComplexity complexity) {
- switch (complexity) {
- case webrtc::kComplexityNormal:
- return "normal";
- case webrtc::kComplexityHigh:
- return "high";
- case webrtc::kComplexityHigher:
- return "higher";
- case webrtc::kComplexityMax:
- return "max";
- default:
- return "unknown";
- }
-}
-
-static std::string ToString(webrtc::VP8ResilienceMode resilience) {
- switch (resilience) {
- case webrtc::kResilienceOff:
- return "off";
- case webrtc::kResilientStream:
- return "stream";
- case webrtc::kResilientFrames:
- return "frames";
- default:
- return "unknown";
- }
-}
-
-void WebRtcVideoMediaChannel::LogSendCodecChange(const std::string& reason) {
- webrtc::VideoCodec vie_codec;
- if (engine()->vie()->codec()->GetSendCodec(default_channel_id_, vie_codec) != 0) {
- LOG_RTCERR1(GetSendCodec, default_channel_id_);
- return;
- }
-
- LOG(LS_INFO) << reason << " : selected video codec "
- << vie_codec.plName << "/"
- << vie_codec.width << "x" << vie_codec.height << "x"
- << static_cast<int>(vie_codec.maxFramerate) << "fps"
- << "@" << vie_codec.maxBitrate << "kbps"
- << " (min=" << vie_codec.minBitrate << "kbps,"
- << " start=" << vie_codec.startBitrate << "kbps)";
- LOG(LS_INFO) << "Video max quantization: " << vie_codec.qpMax;
- if (webrtc::kVideoCodecVP8 == vie_codec.codecType) {
- LOG(LS_INFO) << "VP8 number of temporal layers: "
- << static_cast<int>(
- vie_codec.codecSpecific.VP8.numberOfTemporalLayers);
- LOG(LS_INFO) << "VP8 options : "
- << "picture loss indication = "
- << vie_codec.codecSpecific.VP8.pictureLossIndicationOn
- << ", feedback mode = "
- << vie_codec.codecSpecific.VP8.feedbackModeOn
- << ", complexity = "
- << ToString(vie_codec.codecSpecific.VP8.complexity)
- << ", resilience = "
- << ToString(vie_codec.codecSpecific.VP8.resilience)
- << ", denoising = "
- << vie_codec.codecSpecific.VP8.denoisingOn
- << ", error concealment = "
- << vie_codec.codecSpecific.VP8.errorConcealmentOn
- << ", automatic resize = "
- << vie_codec.codecSpecific.VP8.automaticResizeOn
- << ", frame dropping = "
- << vie_codec.codecSpecific.VP8.frameDroppingOn
- << ", key frame interval = "
- << vie_codec.codecSpecific.VP8.keyFrameInterval;
- }
-
- for (const auto& kv : send_rtx_associated_types_) {
- LOG(LS_INFO) << "RTX payload type: " << kv.first
- << ", associated payload type:" << kv.second;
- }
-
- LogSimulcastSubstreams(vie_codec);
-}
-
-bool WebRtcVideoMediaChannel::SetReceiveCodecs(
- WebRtcVideoChannelRecvInfo* info) {
- int red_type = -1;
- int fec_type = -1;
- int channel_id = info->channel_id();
- // Build a map from payload types to video codecs so that we easily can find
- // out if associated payload types are referring to valid codecs.
- std::map<int, webrtc::VideoCodec*> pt_to_codec;
- for (std::vector<webrtc::VideoCodec>::iterator it = receive_codecs_.begin();
- it != receive_codecs_.end(); ++it) {
- pt_to_codec[it->plType] = &(*it);
- }
- for (std::vector<webrtc::VideoCodec>::iterator it = receive_codecs_.begin();
- it != receive_codecs_.end(); ++it) {
- if (it->codecType == webrtc::kVideoCodecRED) {
- red_type = it->plType;
- } else if (it->codecType == webrtc::kVideoCodecULPFEC) {
- fec_type = it->plType;
- }
- // If this is an RTX codec we have to verify that it is associated with
- // a valid video codec which we have RTX support for.
- if (_stricmp(it->plName, kRtxCodecName) == 0) {
- std::map<int, int>::iterator apt_it =
- associated_payload_types_.find(it->plType);
- bool valid_apt = false;
- if (apt_it != associated_payload_types_.end()) {
- std::map<int, webrtc::VideoCodec*>::iterator codec_it =
- pt_to_codec.find(apt_it->second);
- valid_apt = codec_it != pt_to_codec.end();
- }
- if (!valid_apt) {
- LOG(LS_ERROR) << "The RTX codec isn't associated with a known and "
- "supported payload type";
- return false;
- }
- if (engine()->vie()->rtp()->SetRtxReceivePayloadType(
- channel_id, it->plType, apt_it->second) != 0) {
- LOG_RTCERR2(SetRtxReceivePayloadType, channel_id,
- static_cast<int>(it->plType));
- return false;
- }
- continue;
- }
- if (engine()->vie()->codec()->SetReceiveCodec(channel_id, *it) != 0) {
- LOG_RTCERR2(SetReceiveCodec, channel_id, it->plName);
- return false;
- }
- if (!info->IsDecoderRegistered(it->plType) &&
- it->codecType != webrtc::kVideoCodecRED &&
- it->codecType != webrtc::kVideoCodecULPFEC) {
- webrtc::VideoDecoder* decoder =
- engine()->CreateExternalDecoder(it->codecType);
- if (decoder) {
- if (engine()->vie()->ext_codec()->RegisterExternalReceiveCodec(
- channel_id, it->plType, decoder) == 0) {
- info->RegisterDecoder(it->plType, decoder);
- } else {
- LOG_RTCERR2(RegisterExternalReceiveCodec, channel_id, it->plName);
- engine()->DestroyExternalDecoder(decoder);
- }
- }
- }
- }
- return true;
-}
-
-int WebRtcVideoMediaChannel::GetRecvChannelId(uint32 ssrc) {
- if (ssrc == first_receive_ssrc_) {
- return default_channel_id_;
- }
- int recv_channel_id = kChannelIdUnset;
- WebRtcVideoChannelRecvInfo* recv_channel = GetRecvChannelBySsrc(ssrc);
- if (!recv_channel) {
- // Check if we have an RTX stream registered on this SSRC.
- SsrcMap::iterator rtx_it = rtx_to_primary_ssrc_.find(ssrc);
- if (rtx_it != rtx_to_primary_ssrc_.end()) {
- if (rtx_it->second == first_receive_ssrc_) {
- recv_channel_id = default_channel_id_;
- } else {
- recv_channel = GetRecvChannelBySsrc(rtx_it->second);
- ASSERT(recv_channel != NULL);
- recv_channel_id = recv_channel->channel_id();
- }
- }
- } else {
- recv_channel_id = recv_channel->channel_id();
- }
- return recv_channel_id;
-}
-
-bool WebRtcVideoMediaChannel::SetSendParams(
- WebRtcVideoChannelSendInfo* send_channel,
- const VideoSendParams& send_params) {
- ASSERT(engine()->worker_thread()->IsCurrent());
- const int channel_id = send_channel->channel_id();
-
- MaybeRegisterExternalEncoder(send_channel, send_params.codec);
-
- CapturedFrameInfo frame;
- if (!send_channel->last_captured_frame_info().Get(&frame)) {
- // When we don't have a frame yet, configure the encoder with a
- // QCIF (176x144) frame (to ensure HW encoder can be initialized).
- // This gives us low memory usage but also makes it so configuration
- // errors are discovered at the time we apply the settings rather than
- // when we get the first frame (waiting for the first frame to know
- // that you gave a bad codec parameter could make debugging hard).
- frame.width = 176;
- frame.height = 144;
-
- // TODO(pthatcher): Evaluate the risk of not setting up an encoder
- // at all until we have a frame. Once we feel it's worth the
- // risk, we can do something like this:
- // send_channel->set_send_params(send_params);
- // return true;
- }
-
- // TODO(pthatcher): This checking of the max height and width is
- // only needed because some unit tests bypass the VideoAdapter, and
- // others expect behavior from the adapter different than what it
- // actually does. We should fix the tests and remove this block.
- VideoFormat max = send_channel->adapt_format();
- size_t max_width = static_cast<size_t>(max.width);
- size_t max_height = static_cast<size_t>(max.height);
- if ((!frame.screencast &&
- (frame.width > max_width || frame.height > max_height))) {
- frame.width = max_width;
- frame.height = max_height;
- }
-
- webrtc::VideoCodec codec;
- ConfigureVieCodecFromSendParams(channel_id, send_params, frame, &codec);
- // TODO(pthatcher): Figure out a clean way to configure the max
- // framerate and sanitize the bitrates inside of
- // ConfigureVieCodecFromSendParams.
- codec.maxFramerate = max.framerate();
- SanitizeBitrates(channel_id, &codec);
-
- // Get current vie codec.
- webrtc::VideoCodec current;
- if (engine()->vie()->codec()->GetSendCodec(channel_id, current) != 0) {
- LOG_RTCERR1(GetSendCodec, channel_id);
- return false;
- }
-
- if (current != codec) {
- if (engine()->vie()->codec()->SetSendCodec(channel_id, codec) != 0) {
- LOG_RTCERR1(SetSendCodec, channel_id);
- return false;
- }
- }
-
- if (frame.screencast) {
- int screencast_min_bitrate =
- options_.screencast_min_bitrate.GetWithDefaultIfUnset(0);
- engine()->vie()->rtp()->SetMinTransmitBitrate(channel_id,
- screencast_min_bitrate);
- } else {
- // In case of switching from screencast to regular capture, set
- // min bitrate padding and pacer back to defaults.
- engine()->vie()->rtp()->SetMinTransmitBitrate(channel_id, 0);
- }
- engine()->vie()->rtp()->SetTransmissionSmoothingStatus(channel_id, true);
-
- // If the set of SSRCs isn't populated, then don't apply them. If we
- // do, we'll cause a bug where adding a stream, then removing a
- // stream, then re-adding a stream with the same primary SSRC will
- // cause the sequence numbers to change and confuse the receiver due
- // to jumping SRTP sequence numbers.
- if (send_params.stream.first_ssrc() != 0) {
- if (!SetSendSsrcs(channel_id, send_params.stream, codec)) {
- return false;
- }
- }
-
- // NOTE: SetRtxSendPayloadType must be called after all SSRCs are
- // configured. Otherwise ssrc's configured after this point will use
- // the primary PT for RTX.
- for (const auto& kv : send_rtx_associated_types_) {
- if (engine()->vie()->rtp()->SetRtxSendPayloadType(channel_id, kv.first,
- kv.second) != 0) {
- LOG_RTCERR3(SetRtxSendPayloadType, channel_id, kv.first, kv.second);
- return false;
- }
- }
-
- send_channel->set_send_params(send_params);
- return true;
-}
-
-bool WebRtcVideoMediaChannel::ConfigureVieCodecFromSendParams(
- int channel_id,
- const VideoSendParams& send_params,
- const CapturedFrameInfo& last_captured_frame_info,
- webrtc::VideoCodec* codec_out) {
- webrtc::VideoCodec codec = send_params.codec;
-
- codec.width = static_cast<int>(last_captured_frame_info.width);
- codec.height = static_cast<int>(last_captured_frame_info.height);
- codec.targetBitrate = 0;
- if (codec.codecType == webrtc::kVideoCodecVP8) {
- codec.codecSpecific.VP8.numberOfTemporalLayers =
- kDefaultNumberOfTemporalLayers;
- codec.codecSpecific.VP8.resilience = webrtc::kResilienceOff;
- }
-
- if (last_captured_frame_info.screencast) {
- codec.mode = webrtc::kScreensharing;
- if (codec.codecType == webrtc::kVideoCodecVP8) {
- codec.codecSpecific.VP8.denoisingOn = false;
- codec.codecSpecific.VP8.automaticResizeOn = false;
- codec.codecSpecific.VP8.frameDroppingOn = false;
- }
- } else {
- codec.mode = webrtc::kRealtimeVideo;
- if (codec.codecType == webrtc::kVideoCodecVP8) {
- // TODO(pthatcher): Pass in options in VideoSendParams.
- codec.codecSpecific.VP8.denoisingOn =
- options_.video_noise_reduction.GetWithDefaultIfUnset(true);
- codec.codecSpecific.VP8.automaticResizeOn = true;
- codec.codecSpecific.VP8.frameDroppingOn = true;
- }
- }
-
- if (webrtc::kVideoCodecVP8 == codec.codecType) {
- ConfigureSimulcastTemporalLayers(
- kDefaultNumberOfTemporalLayers, &codec);
- if (IsSimulcastStream(send_params.stream)) {
- codec.codecSpecific.VP8.automaticResizeOn = false;
- // TODO(pthatcher): Pass in options in VideoSendParams.
- VideoOptions options;
- GetOptions(&options);
- if (ConferenceModeIsEnabled()) {
- ConfigureSimulcastCodec(send_params.stream, options, &codec);
- }
- }
-
- if (last_captured_frame_info.screencast) {
- // Use existing bitrate if not in conference mode.
- if (ConferenceModeIsEnabled()) {
- ConfigureConferenceModeScreencastCodec(&codec);
- }
-
- DisableSimulcastCodec(&codec);
- }
- }
-
- *codec_out = codec;
- return true;
-}
-
-void WebRtcVideoMediaChannel::SanitizeBitrates(
- int channel_id, webrtc::VideoCodec* codec) {
- codec->minBitrate = GetBitrate(codec->minBitrate, kMinVideoBitrate);
- codec->startBitrate = GetBitrate(codec->startBitrate, kStartVideoBitrate);
- codec->maxBitrate = GetBitrate(codec->maxBitrate, kMaxVideoBitrate);
-
- if (codec->minBitrate > codec->maxBitrate) {
- LOG(LS_INFO) << "Decreasing codec min bitrate to the max ("
- << codec->maxBitrate << ") because the min ("
- << codec->minBitrate << ") exceeds the max.";
- codec->minBitrate = codec->maxBitrate;
- }
- if (codec->startBitrate < codec->minBitrate) {
- LOG(LS_INFO) << "Increasing codec start bitrate to the min ("
- << codec->minBitrate << ") because the start ("
- << codec->startBitrate << ") is less than the min.";
- codec->startBitrate = codec->minBitrate;
- } else if (codec->startBitrate > codec->maxBitrate) {
- LOG(LS_INFO) << "Decreasing codec start bitrate to the max ("
- << codec->maxBitrate << ") because the start ("
- << codec->startBitrate << ") exceeds the max.";
- codec->startBitrate = codec->maxBitrate;
- }
-
- // Use a previous target bitrate, if there is one.
- unsigned int current_target_bitrate = 0;
- if (engine()->vie()->codec()->GetCodecTargetBitrate(
- channel_id, ¤t_target_bitrate) == 0) {
- // Convert to kbps.
- current_target_bitrate /= 1000;
- if (current_target_bitrate > codec->maxBitrate) {
- current_target_bitrate = codec->maxBitrate;
- }
- if (current_target_bitrate > codec->startBitrate) {
- codec->startBitrate = current_target_bitrate;
- }
- }
-
- // Make sure the start bitrate is larger than lowest layer's min bitrate.
- if (codec->numberOfSimulcastStreams > 1 &&
- codec->startBitrate < codec->simulcastStream[0].minBitrate) {
- codec->startBitrate = codec->simulcastStream[0].minBitrate;
- }
-}
-
-void WebRtcVideoMediaChannel::OnMessage(rtc::Message* msg) {
- FlushBlackFrameData* data = static_cast<FlushBlackFrameData*>(msg->pdata);
- FlushBlackFrame(data->ssrc, data->timestamp, data->interval);
- delete data;
-}
-
-int WebRtcVideoMediaChannel::SendPacket(int channel, const void* data,
- size_t len) {
- rtc::Buffer packet(reinterpret_cast<const uint8_t*>(data), len,
- kMaxRtpPacketLen);
- return MediaChannel::SendPacket(&packet) ? static_cast<int>(len) : -1;
-}
-
-int WebRtcVideoMediaChannel::SendRTCPPacket(int channel,
- const void* data,
- size_t len) {
- rtc::Buffer packet(reinterpret_cast<const uint8_t*>(data), len,
- kMaxRtpPacketLen);
- return MediaChannel::SendRtcp(&packet) ? static_cast<int>(len) : -1;
-}
-
-void WebRtcVideoMediaChannel::QueueBlackFrame(uint32 ssrc, int64 timestamp,
- int interval) {
- if (timestamp) {
- FlushBlackFrameData* black_frame_data = new FlushBlackFrameData(
- ssrc, timestamp, interval);
- const int delay_ms = static_cast<int>(
- 2 * interval * rtc::kNumMillisecsPerSec / rtc::kNumNanosecsPerSec);
- worker_thread()->PostDelayed(delay_ms, this, 0, black_frame_data);
- }
-}
-
-void WebRtcVideoMediaChannel::FlushBlackFrame(
- uint32 ssrc, int64 timestamp, int timestamp_delta) {
- WebRtcVideoChannelSendInfo* send_channel = GetSendChannelBySsrc(ssrc);
- if (!send_channel) {
- return;
- }
-
- CapturedFrameInfo last_frame_info;
- if (!send_channel->last_captured_frame_info().Get(&last_frame_info))
- return;
-
- if (last_frame_info.timestamp == timestamp) {
- WebRtcVideoFrame black_frame;
- if (!black_frame.InitToBlack(static_cast<int>(last_frame_info.width),
- static_cast<int>(last_frame_info.height), 1, 1,
- last_frame_info.elapsed_time + timestamp_delta,
- last_frame_info.timestamp + timestamp_delta) ||
- !SendFrame(send_channel, &black_frame, last_frame_info.screencast)) {
- LOG(LS_ERROR) << "Failed to send black frame.";
- }
- }
-}
-
-void WebRtcVideoMediaChannel::OnCpuAdaptationUnable() {
- // ssrc is hardcoded to 0. This message is based on a system wide issue,
- // so finding which ssrc caused it doesn't matter.
- SignalMediaError(0, VideoMediaChannel::ERROR_REC_CPU_MAX_CANT_DOWNGRADE);
-}
-
-void WebRtcVideoMediaChannel::SetNetworkTransmissionState(
- bool is_transmitting) {
- LOG(LS_INFO) << "SetNetworkTransmissionState: " << is_transmitting;
- for (SendChannelMap::iterator iter = send_channels_.begin();
- iter != send_channels_.end(); ++iter) {
- WebRtcVideoChannelSendInfo* send_channel = iter->second;
- int channel_id = send_channel->channel_id();
- engine_->vie()->network()->SetNetworkTransmissionState(channel_id,
- is_transmitting);
- }
-}
-
-bool WebRtcVideoMediaChannel::SetHeaderExtension(ExtensionSetterFunction setter,
- int channel_id, const RtpHeaderExtension* extension) {
- bool enable = false;
- int id = 0;
- if (extension) {
- enable = true;
- id = extension->id;
- }
- if ((engine_->vie()->rtp()->*setter)(channel_id, enable, id) != 0) {
- LOG_RTCERR4(*setter, extension->uri, channel_id, enable, id);
- return false;
- }
- return true;
-}
-
-bool WebRtcVideoMediaChannel::SetHeaderExtension(ExtensionSetterFunction setter,
- int channel_id, const std::vector<RtpHeaderExtension>& extensions,
- const char header_extension_uri[]) {
- const RtpHeaderExtension* extension = FindHeaderExtension(extensions,
- header_extension_uri);
- return SetHeaderExtension(setter, channel_id, extension);
-}
-
-bool WebRtcVideoMediaChannel::SetPrimaryAndRtxSsrcs(
- int channel_id, int idx, uint32 primary_ssrc,
- const StreamParams& sp) {
- LOG(LS_INFO) << "Set primary ssrc " << primary_ssrc
- << " on channel " << channel_id << " idx " << idx;
- if (engine()->vie()->rtp()->SetLocalSSRC(
- channel_id, primary_ssrc, webrtc::kViEStreamTypeNormal, idx) != 0) {
- LOG_RTCERR4(SetLocalSSRC,
- channel_id, primary_ssrc, webrtc::kViEStreamTypeNormal, idx);
- return false;
- }
-
- uint32 rtx_ssrc = 0;
- if (sp.GetFidSsrc(primary_ssrc, &rtx_ssrc)) {
- LOG(LS_INFO) << "Set rtx ssrc " << rtx_ssrc
- << " on channel " << channel_id << " idx " << idx;
- if (engine()->vie()->rtp()->SetLocalSSRC(
- channel_id, rtx_ssrc, webrtc::kViEStreamTypeRtx, idx) != 0) {
- LOG_RTCERR4(SetLocalSSRC,
- channel_id, rtx_ssrc, webrtc::kViEStreamTypeRtx, idx);
- return false;
- }
- }
- return true;
-}
-
-bool WebRtcVideoMediaChannel::SetLimitedNumberOfSendSsrcs(
- int channel_id, const StreamParams& sp, size_t limit) {
- const SsrcGroup* sim_group = sp.get_ssrc_group(kSimSsrcGroupSemantics);
- if (!sim_group || limit == 1) {
- return SetPrimaryAndRtxSsrcs(channel_id, 0, sp.first_ssrc(), sp);
- }
-
- std::vector<uint32> ssrcs = sim_group->ssrcs;
- for (size_t i = 0; i < ssrcs.size() && i < limit; ++i) {
- if (!SetPrimaryAndRtxSsrcs(channel_id, static_cast<int>(i), ssrcs[i], sp)) {
- return false;
- }
- }
- return true;
-}
-
-bool WebRtcVideoMediaChannel::SetSendSsrcs(int channel_id,
- const StreamParams& sp,
- const webrtc::VideoCodec& codec) {
- size_t limit = codec.numberOfSimulcastStreams;
- return SetLimitedNumberOfSendSsrcs(channel_id, sp, limit);
-}
-
-void WebRtcVideoMediaChannel::MaybeConnectCapturer(VideoCapturer* capturer) {
- if (capturer && GetSendChannelNum(capturer) == 1) {
- capturer->SignalVideoFrame.connect(this,
- &WebRtcVideoMediaChannel::SendFrame);
- }
-}
-
-void WebRtcVideoMediaChannel::MaybeDisconnectCapturer(VideoCapturer* capturer) {
- if (capturer && GetSendChannelNum(capturer) == 1) {
- capturer->SignalVideoFrame.disconnect(this);
- }
-}
-
-void WebRtcVideoMediaChannel::SetReceiverReportSsrc(uint32 ssrc) {
- for (RecvChannelMap::const_iterator it = recv_channels_.begin();
- it != recv_channels_.end(); ++it) {
- int channel_id = it->second->channel_id();
- if (engine()->vie()->rtp()->SetLocalSSRC(channel_id, ssrc) != 0) {
- LOG_RTCERR2(SetLocalSSRC, channel_id, ssrc);
- ASSERT(false);
- }
- }
- receiver_report_ssrc_ = ssrc;
-}
-
-} // namespace cricket
-
-#endif // HAVE_WEBRTC_VIDEO
+// TODO(pbos): Remove this file when it's no longer built in Chromium.
diff --git a/talk/media/webrtc/webrtcvideoengine.h b/talk/media/webrtc/webrtcvideoengine.h
deleted file mode 100644
index f48d779..0000000
--- a/talk/media/webrtc/webrtcvideoengine.h
+++ /dev/null
@@ -1,548 +0,0 @@
-/*
- * libjingle
- * Copyright 2004 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_MEDIA_WEBRTCVIDEOENGINE_H_
-#define TALK_MEDIA_WEBRTCVIDEOENGINE_H_
-
-#include <map>
-#include <vector>
-
-#include "talk/media/base/codec.h"
-#include "talk/media/base/videocommon.h"
-#include "talk/media/webrtc/webrtccommon.h"
-#include "talk/media/webrtc/webrtcexport.h"
-#include "talk/media/webrtc/webrtcvideoencoderfactory.h"
-#include "talk/session/media/channel.h"
-#include "webrtc/base/scoped_ptr.h"
-#include "webrtc/video_engine/include/vie_base.h"
-
-#if !defined(LIBPEERCONNECTION_LIB) && \
- !defined(LIBPEERCONNECTION_IMPLEMENTATION)
-// If you hit this, then you've tried to include this header from outside
-// a shared library. An instance of this class must only be created from
-// within the library that actually implements it.
-#error "Bogus include."
-#endif
-
-namespace webrtc {
-class VideoCaptureModule;
-class VideoDecoder;
-class VideoEncoder;
-class VideoRender;
-class ViEExternalCapture;
-class ViERTP_RTCP;
-}
-
-namespace rtc {
-class CpuMonitor;
-} // namespace rtc
-
-namespace cricket {
-
-class CoordinatedVideoAdapter;
-class ViETraceWrapper;
-class ViEWrapper;
-class VideoCapturer;
-class VideoFrame;
-class VideoProcessor;
-class VideoRenderer;
-class VoiceMediaChannel;
-class WebRtcDecoderObserver;
-class WebRtcEncoderObserver;
-class WebRtcLocalStreamInfo;
-class WebRtcRenderAdapter;
-class WebRtcVideoChannelRecvInfo;
-class WebRtcVideoChannelSendInfo;
-class WebRtcVideoDecoderFactory;
-class WebRtcVideoEncoderFactory;
-class WebRtcVideoMediaChannel;
-class WebRtcVoiceEngine;
-
-struct CapturedFrame;
-struct Device;
-
-// This set of methods is declared here for the sole purpose of sharing code
-// between webrtc video engine v1 and v2.
-std::vector<VideoCodec> DefaultVideoCodecList();
-bool CodecIsInternallySupported(const std::string& codec_name);
-void AddDefaultFeedbackParams(VideoCodec* codec);
-
-class WebRtcVideoEngine : public sigslot::has_slots<> {
- public:
- // Creates the WebRtcVideoEngine with internal VideoCaptureModule.
- explicit WebRtcVideoEngine(WebRtcVoiceEngine* voice_engine);
- // For testing purposes. Allows the WebRtcVoiceEngine,
- // ViEWrapper and CpuMonitor to be mocks.
- // TODO(juberti): Remove the 3-arg ctor once fake tracing is implemented.
- WebRtcVideoEngine(WebRtcVoiceEngine* voice_engine,
- ViEWrapper* vie_wrapper,
- rtc::CpuMonitor* cpu_monitor);
- WebRtcVideoEngine(WebRtcVoiceEngine* voice_engine,
- ViEWrapper* vie_wrapper,
- ViETraceWrapper* tracing,
- rtc::CpuMonitor* cpu_monitor);
- virtual ~WebRtcVideoEngine();
-
- // Basic video engine implementation.
- bool Init(rtc::Thread* worker_thread);
- void Terminate();
-
- int GetCapabilities();
- bool SetDefaultEncoderConfig(const VideoEncoderConfig& config);
-
- // TODO(pbos): Remove when all call sites use VideoOptions.
- virtual WebRtcVideoMediaChannel* CreateChannel(
- VoiceMediaChannel* voice_channel);
- virtual WebRtcVideoMediaChannel* CreateChannel(
- const VideoOptions& options,
- VoiceMediaChannel* voice_channel);
-
- 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
- // that |decoder_factory| outlives the video engine.
- void SetExternalDecoderFactory(WebRtcVideoDecoderFactory* decoder_factory);
- // Set a WebRtcVideoEncoderFactory for external encoding. Video engine does
- // not take the ownership of |encoder_factory|. The caller needs to make sure
- // that |encoder_factory| outlives the video engine.
- virtual void SetExternalEncoderFactory(
- WebRtcVideoEncoderFactory* encoder_factory);
- // Enable the render module with timing control.
- bool EnableTimedRender();
-
- // Returns an external decoder for the given codec type. The return value
- // can be NULL if decoder factory is not given or it does not support the
- // codec type. The caller takes the ownership of the returned object.
- webrtc::VideoDecoder* CreateExternalDecoder(webrtc::VideoCodecType type);
- // Releases the decoder instance created by CreateExternalDecoder().
- void DestroyExternalDecoder(webrtc::VideoDecoder* decoder);
-
- // Returns an external encoder for the given codec type. The return value
- // can be NULL if encoder factory is not given or it does not support the
- // codec type. The caller takes the ownership of the returned object.
- // On success, |internal_source| is set to true if the encoder has an internal
- // frame source, meaning that it doesn't expect/require frames through the
- // normal camera pipeline. See ViEExternalCodec::RegisterExternalSendCodec for
- // more information.
- webrtc::VideoEncoder* CreateExternalEncoder(webrtc::VideoCodecType type,
- bool* internal_source);
- // Releases the encoder instance created by CreateExternalEncoder().
- void DestroyExternalEncoder(webrtc::VideoEncoder* encoder);
-
- // Returns true if the codec type is supported by the external encoder.
- bool IsExternalEncoderCodecType(webrtc::VideoCodecType type) const;
-
- // Functions called by WebRtcVideoMediaChannel.
- rtc::Thread* worker_thread() { return worker_thread_; }
- ViEWrapper* vie() { return vie_wrapper_.get(); }
- const VideoFormat& default_codec_format() const {
- return default_codec_format_;
- }
- int GetLastEngineError();
- bool FindCodec(const VideoCodec& in);
- bool CanSendCodec(const VideoCodec& in, const VideoCodec& current,
- VideoCodec* out);
- void RegisterChannel(WebRtcVideoMediaChannel* channel);
- void UnregisterChannel(WebRtcVideoMediaChannel* channel);
- bool ConvertFromCricketVideoCodec(const VideoCodec& in_codec,
- webrtc::VideoCodec* out_codec);
- int GetNumOfChannels();
-
- rtc::CpuMonitor* cpu_monitor() { return cpu_monitor_.get(); }
-
- protected:
- class TraceCallbackImpl : public webrtc::TraceCallback {
- public:
- TraceCallbackImpl(WebRtcVoiceEngine* voice_engine)
- : voice_engine_(voice_engine) {}
- ~TraceCallbackImpl() override {}
-
- private:
- void Print(webrtc::TraceLevel level, const char* trace,
- int length) override;
-
- WebRtcVoiceEngine* const voice_engine_;
- };
-
- bool initialized() const {
- return initialized_;
- }
-
- // When a video processor registers with the engine.
- // SignalMediaFrame will be invoked for every video frame.
- // See videoprocessor.h for param reference.
- sigslot::signal3<uint32, VideoFrame*, bool*> SignalMediaFrame;
-
- private:
- typedef std::vector<WebRtcVideoMediaChannel*> VideoChannels;
-
- void Construct(ViEWrapper* vie_wrapper,
- ViETraceWrapper* tracing,
- WebRtcVoiceEngine* voice_engine,
- rtc::CpuMonitor* cpu_monitor);
- bool SetDefaultCodec(const VideoCodec& codec);
- bool RebuildCodecList(const VideoCodec& max_codec);
- void SetTraceFilter(int filter);
- void SetTraceOptions(const std::string& options);
- bool InitVideoEngine();
- bool VerifyApt(const VideoCodec& in, int expected_apt) const;
-
- rtc::Thread* worker_thread_;
- rtc::scoped_ptr<ViEWrapper> vie_wrapper_;
- bool vie_wrapper_base_initialized_;
- rtc::scoped_ptr<ViETraceWrapper> tracing_;
- WebRtcVoiceEngine* const voice_engine_;
- rtc::scoped_ptr<webrtc::VideoRender> render_module_;
- rtc::scoped_ptr<WebRtcVideoEncoderFactory> simulcast_encoder_factory_;
- WebRtcVideoEncoderFactory* encoder_factory_;
- WebRtcVideoDecoderFactory* decoder_factory_;
- std::vector<VideoCodec> video_codecs_;
- std::vector<VideoCodec> default_video_codec_list_;
- std::vector<RtpHeaderExtension> rtp_header_extensions_;
- VideoFormat default_codec_format_;
- TraceCallbackImpl trace_callback_;
-
- bool initialized_;
- rtc::CriticalSection channels_crit_;
- VideoChannels channels_;
-
- bool capture_started_;
-
- rtc::scoped_ptr<rtc::CpuMonitor> cpu_monitor_;
-};
-
-struct CapturedFrameInfo;
-
-// TODO(pthatcher): Add VideoOptions.
-struct VideoSendParams {
- webrtc::VideoCodec codec;
- StreamParams stream;
-};
-
-class WebRtcVideoMediaChannel : public rtc::MessageHandler,
- public VideoMediaChannel,
- public webrtc::Transport {
- public:
- WebRtcVideoMediaChannel(WebRtcVideoEngine* engine,
- VoiceMediaChannel* voice_channel);
- virtual ~WebRtcVideoMediaChannel();
- bool Init();
-
- WebRtcVideoEngine* engine() { return engine_; }
- VoiceMediaChannel* voice_channel() { return voice_channel_; }
- bool sending() const { return sending_; }
-
- // Public for testing purpose.
- uint32 GetDefaultSendChannelSsrc();
- int GetDefaultChannelId() const { return default_channel_id_; }
-
- // VideoMediaChannel implementation
- bool SetRecvCodecs(const std::vector<VideoCodec>& codecs) override;
- bool SetSendCodecs(const std::vector<VideoCodec>& codecs) override;
- bool GetSendCodec(VideoCodec* send_codec) override;
- bool SetSendStreamFormat(uint32 ssrc, const VideoFormat& format) override;
- bool SetRender(bool render) override;
- bool SetSend(bool send) override;
-
- bool AddSendStream(const StreamParams& sp) override;
- bool RemoveSendStream(uint32 ssrc) override;
- bool AddRecvStream(const StreamParams& sp) override;
- bool RemoveRecvStream(uint32 ssrc) override;
- bool SetRenderer(uint32 ssrc, VideoRenderer* renderer) override;
- bool GetStats(VideoMediaInfo* info) override;
- bool SetCapturer(uint32 ssrc, VideoCapturer* capturer) override;
- bool SendIntraFrame() override;
- bool RequestIntraFrame() override;
-
- void OnPacketReceived(rtc::Buffer* packet,
- const rtc::PacketTime& packet_time) override;
- void OnRtcpReceived(rtc::Buffer* packet,
- const rtc::PacketTime& packet_time) override;
- void OnReadyToSend(bool ready) override;
- bool MuteStream(uint32 ssrc, bool on) override;
- bool SetRecvRtpHeaderExtensions(
- const std::vector<RtpHeaderExtension>& extensions) override;
- bool SetSendRtpHeaderExtensions(
- const std::vector<RtpHeaderExtension>& extensions) override;
- int GetRtpSendTimeExtnId() const override;
- bool SetMaxSendBandwidth(int bps) override;
- bool SetOptions(const VideoOptions& options) override;
- bool GetOptions(VideoOptions* options) const override {
- *options = options_;
- return true;
- }
- void SetInterface(NetworkInterface* iface) override;
- void UpdateAspectRatio(int ratio_w, int ratio_h) override;
-
- // Public functions for use by tests and other specialized code.
- uint32 send_ssrc() const { return 0; }
- bool GetRenderer(uint32 ssrc, VideoRenderer** renderer);
- bool GetVideoAdapter(uint32 ssrc, CoordinatedVideoAdapter** video_adapter);
- void SendFrame(VideoCapturer* capturer, const VideoFrame* frame);
- bool SendFrame(WebRtcVideoChannelSendInfo* channel_info,
- const VideoFrame* frame, bool is_screencast);
-
- // Thunk functions for use with HybridVideoEngine
- void OnLocalFrame(VideoCapturer* capturer, const VideoFrame* frame) {
- SendFrame(0u, frame, capturer->IsScreencast());
- }
- void OnLocalFrameFormat(VideoCapturer* capturer, const VideoFormat* format) {
- }
-
- // rtc::MessageHandler:
- void OnMessage(rtc::Message* msg) override;
-
- protected:
- void Terminate();
- int GetLastEngineError() { return engine()->GetLastEngineError(); }
-
- // webrtc::Transport:
- int SendPacket(int channel, const void* data, size_t len) override;
- int SendRTCPPacket(int channel, const void* data, size_t len) override;
-
- bool ConferenceModeIsEnabled() const {
- return options_.conference_mode.GetWithDefaultIfUnset(false);
- }
-
- // We take lots of things as input from applications (packaged in
- // params), but ViE wants lots of those packed instead as a
- // webrtc::VideoCodec. This is where we convert between the inputs
- // we get from the applications and the input to give to ViE. We
- // also configure the codec differently depending on the latest
- // frame that we have received (in particular, depending on the
- // resolution and whether the it was a screencast frame or not).
- virtual bool ConfigureVieCodecFromSendParams(
- int channel_id,
- const VideoSendParams& send_params,
- const CapturedFrameInfo& last_captured_frame_info,
- webrtc::VideoCodec* codec);
- // Checks the current bitrate estimate and modifies the bitrates
- // accordingly, including converting kAutoBandwidth to the correct defaults.
- virtual void SanitizeBitrates(
- int channel_id, webrtc::VideoCodec* video_codec);
- virtual void LogSendCodecChange(const std::string& reason);
- bool SetPrimaryAndRtxSsrcs(
- int channel_id, int idx, uint32 primary_ssrc,
- const StreamParams& send_params);
- bool SetLimitedNumberOfSendSsrcs(
- int channel_id, const StreamParams& send_params, size_t limit);
- virtual bool SetSendSsrcs(
- int channel_id, const StreamParams& send_params,
- const webrtc::VideoCodec& codec);
-
- private:
- typedef std::map<uint32, WebRtcVideoChannelRecvInfo*> RecvChannelMap;
- typedef std::map<uint32, WebRtcVideoChannelSendInfo*> SendChannelMap;
- typedef std::map<uint32, uint32> SsrcMap;
- typedef int (webrtc::ViERTP_RTCP::* ExtensionSetterFunction)(int, bool, int);
-
- enum MediaDirection { MD_RECV, MD_SEND, MD_SENDRECV };
-
- // Creates and initializes a ViE channel. When successful
- // |channel_id| will contain the new channel's ID. If |receiving| is
- // true |ssrc| is the remote ssrc. If |sending| is true the ssrc is
- // local ssrc. If both |receiving| and |sending| is true the ssrc
- // must be kDefaultChannelSsrcKey and the channel will be created as
- // a default channel. The ssrc must be different for receive
- // channels and it must be different for send channels. If the same
- // SSRC is being used for creating channel more than once, this
- // function will fail returning false.
- bool CreateChannel(uint32 ssrc_key, MediaDirection direction,
- int* channel_id);
- bool CreateUnsignalledRecvChannel(uint32 ssrc_key, int* channel_id);
- bool ConfigureChannel(int channel_id, MediaDirection direction,
- uint32 ssrc_key);
- bool ConfigureReceiving(int channel_id, uint32 remote_ssrc_key);
- bool ConfigureSending(int channel_id, uint32 local_ssrc_key);
- bool SetNackFec(int channel_id, int red_payload_type, int fec_payload_type,
- bool nack_enabled);
- bool SetSendCodec(const webrtc::VideoCodec& codec);
- bool SetSendCodec(WebRtcVideoChannelSendInfo* send_channel,
- const webrtc::VideoCodec& codec);
- bool SetSendParams(WebRtcVideoChannelSendInfo* send_channel,
- const VideoSendParams& params);
-
- // Prepares the channel with channel id |info->channel_id()| to receive all
- // codecs in |receive_codecs_| and start receive packets.
- bool SetReceiveCodecs(WebRtcVideoChannelRecvInfo* info);
- // Returns the channel ID that receives the stream with SSRC |ssrc|.
- int GetRecvChannelId(uint32 ssrc);
- bool MaybeSetRtxSsrc(const StreamParams& sp, int channel_id);
- // Create and register an external endcoder if it's possible to do
- // so and one isn't already registered.
- bool MaybeRegisterExternalEncoder(
- WebRtcVideoChannelSendInfo* send_channel,
- const webrtc::VideoCodec& codec);
- // Helper function for starting the sending of media on all channels or
- // |channel_id|. Note that these two function do not change |sending_|.
- bool StartSend();
- bool StartSend(WebRtcVideoChannelSendInfo* send_channel);
- // Helper function for stop the sending of media on all channels or
- // |channel_id|. Note that these two function do not change |sending_|.
- bool StopSend();
- bool StopSend(WebRtcVideoChannelSendInfo* send_channel);
- bool SendIntraFrame(int channel_id);
-
- bool HasReadySendChannels();
- bool DefaultSendChannelIsActive();
-
- // Returns the ssrc key corresponding to the provided local SSRC in
- // |ssrc_key|. The return value is true upon success. If the local
- // ssrc correspond to that of the default channel the key is
- // kDefaultChannelSsrcKey. For all other channels the returned ssrc
- // key will be the same as the local ssrc. If a stream has more
- // than one ssrc, the first (corresponding to
- // StreamParams::first_ssrc()) is used as the key.
- bool GetSendChannelSsrcKey(uint32 local_ssrc, uint32* ssrc_key);
- WebRtcVideoChannelSendInfo* GetDefaultSendChannel();
- WebRtcVideoChannelSendInfo* GetSendChannelBySsrcKey(uint32 ssrc_key);
- WebRtcVideoChannelSendInfo* GetSendChannelBySsrc(uint32 local_ssrc);
- // Creates a new unique ssrc key that can be used for inserting a
- // new send channel into |send_channels_|
- bool CreateSendChannelSsrcKey(uint32 local_ssrc, uint32* ssrc_key);
- // Get the number of the send channels |capturer| registered with.
- int GetSendChannelNum(VideoCapturer* capturer);
-
- bool IsDefaultChannelId(int channel_id) const {
- return channel_id == default_channel_id_;
- }
- bool DeleteSendChannel(uint32 ssrc_key);
-
- WebRtcVideoChannelRecvInfo* GetDefaultRecvChannel();
- WebRtcVideoChannelRecvInfo* GetRecvChannelBySsrc(uint32 ssrc);
-
- bool RemoveCapturer(uint32 ssrc);
-
- rtc::MessageQueue* worker_thread() { return engine_->worker_thread(); }
- void QueueBlackFrame(uint32 ssrc, int64 timestamp, int interval);
- void FlushBlackFrame(uint32 ssrc, int64 timestamp, int interval);
-
- void SetNetworkTransmissionState(bool is_transmitting);
-
- bool SetHeaderExtension(ExtensionSetterFunction setter, int channel_id,
- const RtpHeaderExtension* extension);
- bool SetHeaderExtension(ExtensionSetterFunction setter, int channel_id,
- const std::vector<RtpHeaderExtension>& extensions,
- const char header_extension_uri[]);
-
- // Signal when cpu adaptation has no further scope to adapt.
- void OnCpuAdaptationUnable();
-
- // Connect |capturer| to WebRtcVideoMediaChannel if it is only registered
- // to one send channel, i.e. the first send channel.
- void MaybeConnectCapturer(VideoCapturer* capturer);
- // Disconnect |capturer| from WebRtcVideoMediaChannel if it is only registered
- // to one send channel, i.e. the last send channel.
- void MaybeDisconnectCapturer(VideoCapturer* capturer);
-
- bool RemoveRecvStreamInternal(uint32 ssrc);
-
- // Set the ssrc to use for RTCP receiver reports.
- void SetReceiverReportSsrc(uint32 ssrc);
-
- // Global state.
- WebRtcVideoEngine* engine_;
- VoiceMediaChannel* voice_channel_;
- int default_channel_id_;
- bool nack_enabled_;
- // Receiver Estimated Max Bitrate
- bool remb_enabled_;
- VideoOptions options_;
-
- // Global recv side state.
- // Note the default channel (default_channel_id_), i.e. the send channel
- // corresponding to all the receive channels (this must be done for REMB to
- // work properly), resides in both recv_channels_ and send_channels_ with the
- // ssrc key kDefaultChannelSsrcKey.
- RecvChannelMap recv_channels_; // Contains all receive channels.
- // A map from the SSRCs on which RTX packets are received to the media SSRCs
- // the RTX packets are associated with. RTX packets will be delivered to the
- // streams matching the primary SSRC.
- SsrcMap rtx_to_primary_ssrc_;
- std::vector<webrtc::VideoCodec> receive_codecs_;
- // A map from codec payload types to their associated payload types, if any.
- // TODO(holmer): This is a temporary solution until webrtc::VideoCodec has
- // an associated payload type member, when it does we can rely on
- // receive_codecs_.
- std::map<int, int> associated_payload_types_;
- bool render_started_;
- uint32 first_receive_ssrc_;
- uint32 receiver_report_ssrc_;
- std::vector<RtpHeaderExtension> receive_extensions_;
- int num_unsignalled_recv_channels_;
-
- // Global send side state.
- SendChannelMap send_channels_;
- rtc::scoped_ptr<webrtc::VideoCodec> send_codec_;
- // A map from RTX payload types to their associated payload types.
- std::map<int, int> send_rtx_associated_types_;
- int send_red_type_;
- int send_fec_type_;
- bool sending_;
- std::vector<RtpHeaderExtension> send_extensions_;
-
- // The aspect ratio that the channel desires. 0 means there is no desired
- // aspect ratio
- int ratio_w_;
- int ratio_h_;
-};
-
-// An encoder factory that wraps Create requests for simulcastable codec types
-// with a webrtc::SimulcastEncoderAdapter. Non simulcastable codec type
-// requests are just passed through to the contained encoder factory.
-// Exposed here for code to be shared with WebRtcVideoEngine2, not to be used
-// externally.
-class WebRtcSimulcastEncoderFactory
- : public cricket::WebRtcVideoEncoderFactory {
- public:
- // WebRtcSimulcastEncoderFactory doesn't take ownership of |factory|, which is
- // owned by e.g. PeerConnectionFactory.
- explicit WebRtcSimulcastEncoderFactory(
- cricket::WebRtcVideoEncoderFactory* factory);
- virtual ~WebRtcSimulcastEncoderFactory();
-
- static bool UseSimulcastEncoderFactory(const std::vector<VideoCodec>& codecs);
-
- webrtc::VideoEncoder* CreateVideoEncoder(
- webrtc::VideoCodecType type) override;
- const std::vector<VideoCodec>& codecs() const override;
- bool EncoderTypeHasInternalSource(webrtc::VideoCodecType type) const override;
- void DestroyVideoEncoder(webrtc::VideoEncoder* encoder) override;
-
- private:
- cricket::WebRtcVideoEncoderFactory* factory_;
- // A list of encoders that were created without being wrapped in a
- // SimulcastEncoderAdapter.
- std::vector<webrtc::VideoEncoder*> non_simulcast_encoders_;
-};
-
-} // namespace cricket
-
-#endif // TALK_MEDIA_WEBRTCVIDEOENGINE_H_
diff --git a/talk/media/webrtc/webrtcvideoengine2.cc b/talk/media/webrtc/webrtcvideoengine2.cc
index eee67fa..93bd447 100644
--- a/talk/media/webrtc/webrtcvideoengine2.cc
+++ b/talk/media/webrtc/webrtcvideoengine2.cc
@@ -32,19 +32,20 @@
#include <set>
#include <string>
-#include "libyuv/convert_from.h"
#include "talk/media/base/videocapturer.h"
#include "talk/media/base/videorenderer.h"
#include "talk/media/webrtc/constants.h"
#include "talk/media/webrtc/simulcast.h"
#include "talk/media/webrtc/webrtcvideocapturer.h"
-#include "talk/media/webrtc/webrtcvideoengine.h"
+#include "talk/media/webrtc/webrtcvideoencoderfactory.h"
#include "talk/media/webrtc/webrtcvideoframe.h"
#include "talk/media/webrtc/webrtcvoiceengine.h"
#include "webrtc/base/buffer.h"
#include "webrtc/base/logging.h"
#include "webrtc/base/stringutils.h"
#include "webrtc/call.h"
+#include "webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.h"
+#include "webrtc/system_wrappers/interface/field_trial.h"
#include "webrtc/system_wrappers/interface/trace_event.h"
#include "webrtc/video_decoder.h"
#include "webrtc/video_encoder.h"
@@ -55,6 +56,126 @@
namespace cricket {
namespace {
+
+// Wrap cricket::WebRtcVideoEncoderFactory as a webrtc::VideoEncoderFactory.
+class EncoderFactoryAdapter : public webrtc::VideoEncoderFactory {
+ public:
+ // EncoderFactoryAdapter doesn't take ownership of |factory|, which is owned
+ // by e.g. PeerConnectionFactory.
+ explicit EncoderFactoryAdapter(cricket::WebRtcVideoEncoderFactory* factory)
+ : factory_(factory) {}
+ virtual ~EncoderFactoryAdapter() {}
+
+ // Implement webrtc::VideoEncoderFactory.
+ webrtc::VideoEncoder* Create() override {
+ return factory_->CreateVideoEncoder(webrtc::kVideoCodecVP8);
+ }
+
+ void Destroy(webrtc::VideoEncoder* encoder) override {
+ return factory_->DestroyVideoEncoder(encoder);
+ }
+
+ private:
+ cricket::WebRtcVideoEncoderFactory* const factory_;
+};
+
+// An encoder factory that wraps Create requests for simulcastable codec types
+// with a webrtc::SimulcastEncoderAdapter. Non simulcastable codec type
+// requests are just passed through to the contained encoder factory.
+class WebRtcSimulcastEncoderFactory
+ : public cricket::WebRtcVideoEncoderFactory {
+ public:
+ // WebRtcSimulcastEncoderFactory doesn't take ownership of |factory|, which is
+ // owned by e.g. PeerConnectionFactory.
+ explicit WebRtcSimulcastEncoderFactory(
+ cricket::WebRtcVideoEncoderFactory* factory)
+ : factory_(factory) {}
+
+ static bool UseSimulcastEncoderFactory(
+ const std::vector<VideoCodec>& codecs) {
+ // If any codec is VP8, use the simulcast factory. If asked to create a
+ // non-VP8 codec, we'll just return a contained factory encoder directly.
+ for (const auto& codec : codecs) {
+ if (codec.type == webrtc::kVideoCodecVP8) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ webrtc::VideoEncoder* CreateVideoEncoder(
+ webrtc::VideoCodecType type) override {
+ ASSERT(factory_ != NULL);
+ // If it's a codec type we can simulcast, create a wrapped encoder.
+ if (type == webrtc::kVideoCodecVP8) {
+ return new webrtc::SimulcastEncoderAdapter(
+ new EncoderFactoryAdapter(factory_));
+ }
+ webrtc::VideoEncoder* encoder = factory_->CreateVideoEncoder(type);
+ if (encoder) {
+ non_simulcast_encoders_.push_back(encoder);
+ }
+ return encoder;
+ }
+
+ const std::vector<VideoCodec>& codecs() const override {
+ return factory_->codecs();
+ }
+
+ bool EncoderTypeHasInternalSource(
+ webrtc::VideoCodecType type) const override {
+ return factory_->EncoderTypeHasInternalSource(type);
+ }
+
+ void DestroyVideoEncoder(webrtc::VideoEncoder* encoder) override {
+ // Check first to see if the encoder wasn't wrapped in a
+ // SimulcastEncoderAdapter. In that case, ask the factory to destroy it.
+ if (std::remove(non_simulcast_encoders_.begin(),
+ non_simulcast_encoders_.end(),
+ encoder) != non_simulcast_encoders_.end()) {
+ factory_->DestroyVideoEncoder(encoder);
+ return;
+ }
+
+ // Otherwise, SimulcastEncoderAdapter can be deleted directly, and will call
+ // DestroyVideoEncoder on the factory for individual encoder instances.
+ delete encoder;
+ }
+
+ private:
+ cricket::WebRtcVideoEncoderFactory* factory_;
+ // A list of encoders that were created without being wrapped in a
+ // SimulcastEncoderAdapter.
+ std::vector<webrtc::VideoEncoder*> non_simulcast_encoders_;
+};
+
+bool CodecIsInternallySupported(const std::string& codec_name) {
+ if (CodecNamesEq(codec_name, kVp8CodecName)) {
+ return true;
+ }
+ if (CodecNamesEq(codec_name, kVp9CodecName)) {
+ const std::string group_name =
+ webrtc::field_trial::FindFullName("WebRTC-SupportVP9");
+ return group_name == "Enabled" || group_name == "EnabledByFlag";
+ }
+ return false;
+}
+
+void AddDefaultFeedbackParams(VideoCodec* codec) {
+ codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamCcm, kRtcpFbCcmParamFir));
+ codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kParamValueEmpty));
+ codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kRtcpFbNackParamPli));
+ codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamRemb, kParamValueEmpty));
+}
+
+static VideoCodec MakeVideoCodecWithDefaultFeedbackParams(int payload_type,
+ const char* name) {
+ VideoCodec codec(payload_type, name, kDefaultVideoMaxWidth,
+ kDefaultVideoMaxHeight, kDefaultVideoMaxFramerate, 0);
+ AddDefaultFeedbackParams(&codec);
+ return codec;
+}
+
static std::string CodecVectorToString(const std::vector<VideoCodec>& codecs) {
std::stringstream out;
out << '{';
@@ -179,6 +300,15 @@
}
} // namespace
+// Constants defined in talk/media/webrtc/constants.h
+// TODO(pbos): Move these to a separate constants.cc file.
+const int kMinVideoBitrate = 30;
+const int kStartVideoBitrate = 300;
+const int kMaxVideoBitrate = 2000;
+
+const int kVideoMtu = 1200;
+const int kVideoRtpBufferSize = 65536;
+
// This constant is really an on/off, lower-level configurable NACK history
// duration hasn't been implemented.
static const int kNackHistoryMs = 1000;
@@ -193,6 +323,22 @@
const int kStartBandwidthBps = 300000;
const int kMaxBandwidthBps = 2000000;
+std::vector<VideoCodec> DefaultVideoCodecList() {
+ std::vector<VideoCodec> codecs;
+ if (CodecIsInternallySupported(kVp9CodecName)) {
+ codecs.push_back(MakeVideoCodecWithDefaultFeedbackParams(kDefaultVp9PlType,
+ kVp9CodecName));
+ // TODO(andresp): Add rtx codec for vp9 and verify it works.
+ }
+ codecs.push_back(MakeVideoCodecWithDefaultFeedbackParams(kDefaultVp8PlType,
+ kVp8CodecName));
+ codecs.push_back(
+ VideoCodec::CreateRtxCodec(kDefaultRtxVp8PlType, kDefaultVp8PlType));
+ codecs.push_back(VideoCodec(kDefaultRedPlType, kRedCodecName));
+ codecs.push_back(VideoCodec(kDefaultUlpfecType, kUlpfecCodecName));
+ return codecs;
+}
+
static bool FindFirstMatchingCodec(const std::vector<VideoCodec>& codecs,
const VideoCodec& requested_codec,
VideoCodec* matching_codec) {
diff --git a/talk/media/webrtc/webrtcvideoengine2.h b/talk/media/webrtc/webrtcvideoengine2.h
index b6b9764..a0fde8f 100644
--- a/talk/media/webrtc/webrtcvideoengine2.h
+++ b/talk/media/webrtc/webrtcvideoengine2.h
@@ -75,6 +75,9 @@
struct CapturedFrame;
struct Device;
+// Exposed here for unittests.
+std::vector<VideoCodec> DefaultVideoCodecList();
+
class UnsignalledSsrcHandler {
public:
enum Action {
diff --git a/talk/media/webrtc/webrtcvideoengine2_unittest.cc b/talk/media/webrtc/webrtcvideoengine2_unittest.cc
index 7bcab55..6811155 100644
--- a/talk/media/webrtc/webrtcvideoengine2_unittest.cc
+++ b/talk/media/webrtc/webrtcvideoengine2_unittest.cc
@@ -35,7 +35,6 @@
#include "talk/media/webrtc/fakewebrtcvideoengine.h"
#include "talk/media/webrtc/simulcast.h"
#include "talk/media/webrtc/webrtcvideochannelfactory.h"
-#include "talk/media/webrtc/webrtcvideoengine.h"
#include "talk/media/webrtc/webrtcvideoengine2.h"
#include "talk/media/webrtc/webrtcvoiceengine.h"
#include "webrtc/base/arraysize.h"
diff --git a/talk/media/webrtc/webrtcvideoengine_unittest.cc b/talk/media/webrtc/webrtcvideoengine_unittest.cc
deleted file mode 100644
index 60e7e36..0000000
--- a/talk/media/webrtc/webrtcvideoengine_unittest.cc
+++ /dev/null
@@ -1,4644 +0,0 @@
-/*
- * libjingle
- * Copyright 2004 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <algorithm>
-#include "talk/media/base/constants.h"
-#include "talk/media/base/fakenetworkinterface.h"
-#include "talk/media/base/fakevideorenderer.h"
-#include "talk/media/base/mediachannel.h"
-#include "talk/media/base/testutils.h"
-#include "talk/media/base/videoadapter.h"
-#include "talk/media/base/videoengine_unittest.h"
-#include "talk/media/webrtc/fakewebrtcvideoengine.h"
-#include "talk/media/webrtc/simulcast.h"
-#include "talk/media/webrtc/webrtcvideoengine.h"
-#include "talk/media/webrtc/webrtcvideoframe.h"
-#include "talk/media/webrtc/webrtcvoiceengine.h"
-#include "talk/session/media/mediasession.h"
-#include "webrtc/base/fakecpumonitor.h"
-#include "webrtc/base/gunit.h"
-#include "webrtc/base/logging.h"
-#include "webrtc/base/scoped_ptr.h"
-#include "webrtc/base/stream.h"
-#include "webrtc/system_wrappers/interface/trace.h"
-
-// Tests for the WebRtcVideoEngine/VideoChannel code.
-
-using cricket::kRtpTimestampOffsetHeaderExtension;
-using cricket::kRtpAbsoluteSenderTimeHeaderExtension;
-using cricket::kRtpVideoRotationHeaderExtension;
-
-static const cricket::VideoCodec kVP8Codec720p(100, "VP8", 1280, 720, 30, 0);
-static const cricket::VideoCodec kVP8Codec360p(100, "VP8", 640, 360, 30, 0);
-static const cricket::VideoCodec kVP8Codec270p(100, "VP8", 480, 270, 30, 0);
-
-static const cricket::VideoCodec kVP8Codec(100, "VP8", 640, 400, 30, 0);
-static const cricket::VideoCodec kH264Codec(127, "H264", 640, 400, 30, 0);
-static const cricket::VideoCodec kRedCodec(101, "red", 0, 0, 0, 0);
-static const cricket::VideoCodec kUlpFecCodec(102, "ulpfec", 0, 0, 0, 0);
-static const cricket::VideoCodec* const kVideoCodecs[] = {
- &kVP8Codec,
- &kRedCodec,
- &kUlpFecCodec
-};
-
-static const unsigned int kStartBandwidthKbps = 300;
-static const unsigned int kMinBandwidthKbps = 30;
-static const unsigned int kMaxBandwidthKbps = 2000;
-
-static const uint32 kSsrcs1[] = {1};
-static const uint32 kSsrcs2[] = {1, 2};
-static const uint32 kSsrcs3[] = {1, 2, 3};
-static const uint32 kRtxSsrcs1[] = {4};
-static const uint32 kRtxSsrcs3[] = {4, 5, 6};
-
-static const int kPayloadTypes1[] = {96};
-static const int kPayloadTypes2[] = {96, 97};
-
-class FakeViEWrapper : public cricket::ViEWrapper {
- public:
- explicit FakeViEWrapper(cricket::FakeWebRtcVideoEngine* engine)
- : cricket::ViEWrapper(engine, // base
- engine, // codec
- engine, // capture
- engine, // network
- engine, // render
- engine, // rtp
- engine, // image
- engine) { // external decoder
- }
-};
-
-// Test fixture to test WebRtcVideoEngine with a fake webrtc::VideoEngine.
-// Useful for testing failure paths.
-class WebRtcVideoEngineTestFake : public testing::Test,
- public sigslot::has_slots<> {
- public:
- WebRtcVideoEngineTestFake()
- : vie_(kVideoCodecs, ARRAY_SIZE(kVideoCodecs)),
- cpu_monitor_(new rtc::FakeCpuMonitor(
- rtc::Thread::Current())),
- engine_(NULL, // cricket::WebRtcVoiceEngine
- new FakeViEWrapper(&vie_), cpu_monitor_),
- channel_(NULL),
- voice_channel_(NULL),
- last_error_(cricket::VideoMediaChannel::ERROR_NONE) {
- }
- bool SetupEngine() {
- bool result = engine_.Init(rtc::Thread::Current());
- if (result) {
- channel_ = engine_.CreateChannel(cricket::VideoOptions(), voice_channel_);
- channel_->SignalMediaError.connect(this,
- &WebRtcVideoEngineTestFake::OnMediaError);
- result = (channel_ != NULL);
- }
- return result;
- }
- void OnMediaError(uint32 ssrc, cricket::VideoMediaChannel::Error error) {
- last_error_ = error;
- }
- bool SendI420Frame(int width, int height) {
- if (NULL == channel_) {
- return false;
- }
- cricket::WebRtcVideoFrame frame;
- if (!frame.InitToBlack(width, height, 1, 1, 0, 0)) {
- return false;
- }
- cricket::FakeVideoCapturer capturer;
- channel_->SendFrame(&capturer, &frame);
- return true;
- }
- bool SendI420ScreencastFrame(int width, int height) {
- return SendI420ScreencastFrameWithTimestamp(width, height, 0);
- }
- bool SendI420ScreencastFrameWithTimestamp(
- int width, int height, int64 timestamp) {
- if (NULL == channel_) {
- return false;
- }
- cricket::WebRtcVideoFrame frame;
- if (!frame.InitToBlack(width, height, 1, 1, 0, 0)) {
- return false;
- }
- cricket::FakeVideoCapturer capturer;
- capturer.SetScreencast(true);
- channel_->SendFrame(&capturer, &frame);
- return true;
- }
- void TestSetSendRtpHeaderExtensions(const std::string& ext) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
-
- // Verify extensions are off by default.
- EXPECT_EQ(-1, vie_.GetSendRtpExtensionId(channel_num, ext));
-
- // Enable extension.
- const int id = 1;
- std::vector<cricket::RtpHeaderExtension> extensions;
- extensions.push_back(cricket::RtpHeaderExtension(ext, id));
-
- // Verify the send extension id.
- EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
- EXPECT_EQ(id, vie_.GetSendRtpExtensionId(channel_num, ext));
- // Verify call with same set of extensions returns true.
- EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
- EXPECT_EQ(id, vie_.GetSendRtpExtensionId(channel_num, ext));
-
- // Add a new send stream and verify the extension is set.
- // The first send stream to occupy the default channel.
- EXPECT_TRUE(
- channel_->AddSendStream(cricket::StreamParams::CreateLegacy(123)));
- EXPECT_TRUE(
- channel_->AddSendStream(cricket::StreamParams::CreateLegacy(234)));
- int new_send_channel_num = vie_.GetLastChannel();
- EXPECT_NE(channel_num, new_send_channel_num);
- EXPECT_EQ(id, vie_.GetSendRtpExtensionId(new_send_channel_num, ext));
-
- // Remove the extension id.
- std::vector<cricket::RtpHeaderExtension> empty_extensions;
- EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(empty_extensions));
- EXPECT_EQ(-1, vie_.GetSendRtpExtensionId(channel_num, ext));
- EXPECT_EQ(-1, vie_.GetSendRtpExtensionId(new_send_channel_num, ext));
- }
- void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
-
- // Verify extensions are off by default.
- EXPECT_EQ(-1, vie_.GetReceiveRtpExtensionId(channel_num, ext));
-
- // Enable extension.
- const int id = 2;
- std::vector<cricket::RtpHeaderExtension> extensions;
- extensions.push_back(cricket::RtpHeaderExtension(ext, id));
-
- // Verify receive extension id.
- EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
- EXPECT_EQ(id, vie_.GetReceiveRtpExtensionId(channel_num, ext));
- // Verify call with same set of extensions returns true.
- EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
- EXPECT_EQ(id, vie_.GetReceiveRtpExtensionId(channel_num, ext));
-
- // Add a new receive stream and verify the extension is set.
- // The first send stream to occupy the default channel.
- EXPECT_TRUE(
- channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(345)));
- EXPECT_TRUE(
- channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(456)));
- int new_recv_channel_num = vie_.GetLastChannel();
- EXPECT_NE(channel_num, new_recv_channel_num);
- EXPECT_EQ(id, vie_.GetReceiveRtpExtensionId(new_recv_channel_num, ext));
-
- // Remove the extension id.
- std::vector<cricket::RtpHeaderExtension> empty_extensions;
- EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(empty_extensions));
- EXPECT_EQ(-1, vie_.GetReceiveRtpExtensionId(channel_num, ext));
- EXPECT_EQ(-1, vie_.GetReceiveRtpExtensionId(new_recv_channel_num, ext));
- }
- void VerifyCodecFeedbackParams(const cricket::VideoCodec& codec) {
- EXPECT_TRUE(codec.HasFeedbackParam(
- cricket::FeedbackParam(cricket::kRtcpFbParamNack,
- cricket::kParamValueEmpty)));
- EXPECT_TRUE(codec.HasFeedbackParam(
- cricket::FeedbackParam(cricket::kRtcpFbParamNack,
- cricket::kRtcpFbNackParamPli)));
- EXPECT_TRUE(codec.HasFeedbackParam(
- cricket::FeedbackParam(cricket::kRtcpFbParamRemb,
- cricket::kParamValueEmpty)));
- EXPECT_TRUE(codec.HasFeedbackParam(
- cricket::FeedbackParam(cricket::kRtcpFbParamCcm,
- cricket::kRtcpFbCcmParamFir)));
- }
- void VerifyVP8SendCodec(int channel_num,
- unsigned int width,
- unsigned int height,
- unsigned int layers = 0,
- unsigned int max_bitrate = kMaxBandwidthKbps,
- unsigned int min_bitrate = kMinBandwidthKbps,
- unsigned int start_bitrate = kStartBandwidthKbps,
- unsigned int fps = 30,
- unsigned int max_quantization = 0
- ) {
- webrtc::VideoCodec gcodec;
- EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec));
-
- // Video codec properties.
- EXPECT_EQ(webrtc::kVideoCodecVP8, gcodec.codecType);
- EXPECT_STREQ("VP8", gcodec.plName);
- EXPECT_EQ(100, gcodec.plType);
- EXPECT_EQ(width, gcodec.width);
- EXPECT_EQ(height, gcodec.height);
- EXPECT_EQ(std::min(start_bitrate, max_bitrate), gcodec.startBitrate);
- EXPECT_EQ(max_bitrate, gcodec.maxBitrate);
- EXPECT_EQ(min_bitrate, gcodec.minBitrate);
- EXPECT_EQ(fps, gcodec.maxFramerate);
- // VP8 specific.
- EXPECT_FALSE(gcodec.codecSpecific.VP8.pictureLossIndicationOn);
- EXPECT_FALSE(gcodec.codecSpecific.VP8.feedbackModeOn);
- EXPECT_EQ(webrtc::kComplexityNormal, gcodec.codecSpecific.VP8.complexity);
- EXPECT_EQ(webrtc::kResilienceOff, gcodec.codecSpecific.VP8.resilience);
- EXPECT_EQ(max_quantization, gcodec.qpMax);
- }
- virtual void TearDown() {
- delete channel_;
- engine_.Terminate();
- }
-
- protected:
- cricket::FakeWebRtcVideoEngine vie_;
- cricket::FakeWebRtcVideoDecoderFactory decoder_factory_;
- cricket::FakeWebRtcVideoEncoderFactory encoder_factory_;
- rtc::FakeCpuMonitor* cpu_monitor_;
- cricket::WebRtcVideoEngine engine_;
- cricket::WebRtcVideoMediaChannel* channel_;
- cricket::WebRtcVoiceMediaChannel* voice_channel_;
- cricket::VideoMediaChannel::Error last_error_;
-};
-
-// Test fixtures to test WebRtcVideoEngine with a real webrtc::VideoEngine.
-class WebRtcVideoEngineTest
- : public VideoEngineTest<cricket::WebRtcVideoEngine> {
- protected:
- typedef VideoEngineTest<cricket::WebRtcVideoEngine> Base;
-};
-class WebRtcVideoMediaChannelTest
- : public VideoMediaChannelTest<
- cricket::WebRtcVideoEngine, cricket::WebRtcVideoMediaChannel> {
- protected:
- typedef VideoMediaChannelTest<cricket::WebRtcVideoEngine,
- cricket::WebRtcVideoMediaChannel> Base;
- virtual cricket::VideoCodec DefaultCodec() { return kVP8Codec; }
- virtual void SetUp() {
- Base::SetUp();
- }
- virtual void TearDown() {
- Base::TearDown();
- }
-};
-
-/////////////////////////
-// Tests with fake ViE //
-/////////////////////////
-
-// Tests that our stub library "works".
-TEST_F(WebRtcVideoEngineTestFake, StartupShutdown) {
- EXPECT_FALSE(vie_.IsInited());
- EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
- EXPECT_TRUE(vie_.IsInited());
- engine_.Terminate();
-}
-
-// Tests that webrtc logs are logged when they should be.
-TEST_F(WebRtcVideoEngineTest, WebRtcShouldLog) {
- const char webrtc_log[] = "WebRtcVideoEngineTest.WebRtcShouldLog";
- EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
- engine_.SetLogging(rtc::LS_INFO, "");
- std::string str;
- rtc::StringStream stream(str);
- rtc::LogMessage::AddLogToStream(&stream, rtc::LS_INFO);
- EXPECT_EQ(rtc::LS_INFO, rtc::LogMessage::GetLogToStream(&stream));
- webrtc::Trace::Add(webrtc::kTraceStateInfo, webrtc::kTraceUndefined, 0,
- webrtc_log);
- rtc::Thread::Current()->ProcessMessages(100);
- rtc::LogMessage::RemoveLogToStream(&stream);
- // Access |str| after LogMessage is done with it to avoid data racing.
- EXPECT_NE(std::string::npos, str.find(webrtc_log));
-}
-
-// Tests that webrtc logs are not logged when they should't be.
-TEST_F(WebRtcVideoEngineTest, WebRtcShouldNotLog) {
- const char webrtc_log[] = "WebRtcVideoEngineTest.WebRtcShouldNotLog";
- EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
- // WebRTC should never be logged lower than LS_INFO.
- engine_.SetLogging(rtc::LS_WARNING, "");
- std::string str;
- rtc::StringStream stream(str);
- // Make sure that WebRTC is not logged, even at lowest severity
- rtc::LogMessage::AddLogToStream(&stream, rtc::LS_SENSITIVE);
- EXPECT_EQ(rtc::LS_SENSITIVE,
- rtc::LogMessage::GetLogToStream(&stream));
- webrtc::Trace::Add(webrtc::kTraceStateInfo, webrtc::kTraceUndefined, 0,
- webrtc_log);
- rtc::Thread::Current()->ProcessMessages(10);
- EXPECT_EQ(std::string::npos, str.find(webrtc_log));
- rtc::LogMessage::RemoveLogToStream(&stream);
-}
-
-// Tests that we can create and destroy a channel.
-TEST_F(WebRtcVideoEngineTestFake, CreateChannel) {
- EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
- channel_ = engine_.CreateChannel(cricket::VideoOptions(), voice_channel_);
- EXPECT_TRUE(channel_ != NULL);
- EXPECT_EQ(1, engine_.GetNumOfChannels());
- delete channel_;
- channel_ = NULL;
- EXPECT_EQ(0, engine_.GetNumOfChannels());
-}
-
-// Tests that we properly handle failures in CreateChannel.
-TEST_F(WebRtcVideoEngineTestFake, CreateChannelFail) {
- vie_.set_fail_create_channel(true);
- EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
- channel_ = engine_.CreateChannel(cricket::VideoOptions(), voice_channel_);
- EXPECT_TRUE(channel_ == NULL);
-}
-
-// Tests that we properly handle failures in AllocateExternalCaptureDevice.
-TEST_F(WebRtcVideoEngineTestFake, AllocateExternalCaptureDeviceFail) {
- vie_.set_fail_alloc_capturer(true);
- EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
- channel_ = engine_.CreateChannel(cricket::VideoOptions(), voice_channel_);
- EXPECT_TRUE(channel_ == NULL);
-}
-
-// Test that we apply our default codecs properly.
-TEST_F(WebRtcVideoEngineTestFake, SetSendCodecs) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
- std::vector<cricket::VideoCodec> codecs(engine_.codecs());
- SendI420Frame(kVP8Codec.width, kVP8Codec.height);
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
- VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height);
- EXPECT_TRUE(vie_.GetHybridNackFecStatus(channel_num));
- EXPECT_FALSE(vie_.GetNackStatus(channel_num));
- EXPECT_EQ(1, vie_.GetNumSetSendCodecs());
- // TODO(juberti): Check RTCP, PLI, TMMBR.
-}
-
-TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsBeforeFrameRegistersTinyFormat) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
- std::vector<cricket::VideoCodec> codecs(engine_.codecs());
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
- VerifyVP8SendCodec(channel_num, 176, 144);
-}
-
-// Test that ViE Channel doesn't call SetSendCodec again if same codec is tried
-// to apply.
-TEST_F(WebRtcVideoEngineTestFake, DontResetSetSendCodec) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
- std::vector<cricket::VideoCodec> codecs(engine_.codecs());
- SendI420Frame(kVP8Codec.width, kVP8Codec.height);
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
- VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height);
- EXPECT_TRUE(vie_.GetHybridNackFecStatus(channel_num));
- EXPECT_FALSE(vie_.GetNackStatus(channel_num));
- EXPECT_EQ(1, vie_.GetNumSetSendCodecs());
- // Try setting same code again.
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
- // Since it's exact same codec which is already set, media channel shouldn't
- // send the codec to ViE.
- EXPECT_EQ(1, vie_.GetNumSetSendCodecs());
-}
-
-TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsWithMinMaxBitrate) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
- std::vector<cricket::VideoCodec> codecs(engine_.codecs());
- codecs[0].params[cricket::kCodecParamMinBitrate] = "10";
- codecs[0].params[cricket::kCodecParamMaxBitrate] = "20";
- SendI420Frame(kVP8Codec.width, kVP8Codec.height);
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-
- VerifyVP8SendCodec(
- channel_num, kVP8Codec.width, kVP8Codec.height, 0, 20, 10, 20);
-
- cricket::VideoCodec codec;
- EXPECT_TRUE(channel_->GetSendCodec(&codec));
- EXPECT_EQ("10", codec.params[cricket::kCodecParamMinBitrate]);
- EXPECT_EQ("20", codec.params[cricket::kCodecParamMaxBitrate]);
-}
-
-TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsWithStartBitrate) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
- std::vector<cricket::VideoCodec> codecs(engine_.codecs());
- codecs[0].params[cricket::kCodecParamStartBitrate] = "450";
- SendI420Frame(kVP8Codec.width, kVP8Codec.height);
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-
- VerifyVP8SendCodec(channel_num,
- kVP8Codec.width,
- kVP8Codec.height,
- 0,
- kMaxBandwidthKbps,
- kMinBandwidthKbps,
- 450);
-
- cricket::VideoCodec codec;
- EXPECT_TRUE(channel_->GetSendCodec(&codec));
- EXPECT_EQ("450", codec.params[cricket::kCodecParamStartBitrate]);
-}
-
-TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsWithMinMaxStartBitrate) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
- std::vector<cricket::VideoCodec> codecs(engine_.codecs());
- codecs[0].params[cricket::kCodecParamMinBitrate] = "10";
- codecs[0].params[cricket::kCodecParamMaxBitrate] = "20";
- codecs[0].params[cricket::kCodecParamStartBitrate] = "14";
- SendI420Frame(kVP8Codec.width, kVP8Codec.height);
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-
- VerifyVP8SendCodec(
- channel_num, kVP8Codec.width, kVP8Codec.height, 0, 20, 10, 14);
-
- cricket::VideoCodec codec;
- EXPECT_TRUE(channel_->GetSendCodec(&codec));
- EXPECT_EQ("10", codec.params[cricket::kCodecParamMinBitrate]);
- EXPECT_EQ("20", codec.params[cricket::kCodecParamMaxBitrate]);
- EXPECT_EQ("14", codec.params[cricket::kCodecParamStartBitrate]);
-}
-
-TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsWithMinMaxBitrateInvalid) {
- EXPECT_TRUE(SetupEngine());
- std::vector<cricket::VideoCodec> codecs(engine_.codecs());
- codecs[0].params[cricket::kCodecParamMinBitrate] = "30";
- codecs[0].params[cricket::kCodecParamMaxBitrate] = "20";
- SendI420Frame(kVP8Codec.width, kVP8Codec.height);
- EXPECT_FALSE(channel_->SetSendCodecs(codecs));
-}
-
-TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsWithLargeMinMaxBitrate) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
- std::vector<cricket::VideoCodec> codecs(engine_.codecs());
- codecs[0].params[cricket::kCodecParamMinBitrate] = "1000";
- codecs[0].params[cricket::kCodecParamMaxBitrate] = "3000";
- SendI420Frame(kVP8Codec.width, kVP8Codec.height);
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-
- VerifyVP8SendCodec(
- channel_num, kVP8Codec.width, kVP8Codec.height, 0, 3000, 1000,
- 1000);
-}
-
-TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsWithMaxQuantization) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
- std::vector<cricket::VideoCodec> codecs(engine_.codecs());
- codecs[0].params[cricket::kCodecParamMaxQuantization] = "21";
- SendI420Frame(kVP8Codec.width, kVP8Codec.height);
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-
- VerifyVP8SendCodec(channel_num,
- kVP8Codec.width,
- kVP8Codec.height,
- 0,
- kMaxBandwidthKbps,
- kMinBandwidthKbps,
- 300,
- 30,
- 21);
-
- cricket::VideoCodec codec;
- EXPECT_TRUE(channel_->GetSendCodec(&codec));
- EXPECT_EQ("21", codec.params[cricket::kCodecParamMaxQuantization]);
-}
-
-TEST_F(WebRtcVideoEngineTestFake, SetOptionsWithMaxBitrate) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
- std::vector<cricket::VideoCodec> codecs(engine_.codecs());
- codecs[0].params[cricket::kCodecParamMinBitrate] = "10";
- codecs[0].params[cricket::kCodecParamMaxBitrate] = "20";
- SendI420Frame(kVP8Codec.width, kVP8Codec.height);
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-
- VerifyVP8SendCodec(
- channel_num, kVP8Codec.width, kVP8Codec.height, 0, 20, 10, 20);
-
- // Verify that max bitrate doesn't change after SetOptions().
- cricket::VideoOptions options;
- options.video_noise_reduction.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
- VerifyVP8SendCodec(
- channel_num, kVP8Codec.width, kVP8Codec.height, 0, 20, 10, 20);
-
- options.video_noise_reduction.Set(false);
- options.conference_mode.Set(false);
- EXPECT_TRUE(channel_->SetOptions(options));
- VerifyVP8SendCodec(
- channel_num, kVP8Codec.width, kVP8Codec.height, 0, 20, 10, 20);
-}
-
-TEST_F(WebRtcVideoEngineTestFake, MaxBitrateResetWithConferenceMode) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
- std::vector<cricket::VideoCodec> codecs(engine_.codecs());
- codecs[0].params[cricket::kCodecParamMinBitrate] = "10";
- codecs[0].params[cricket::kCodecParamMaxBitrate] = "20";
- SendI420Frame(kVP8Codec.width, kVP8Codec.height);
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-
- VerifyVP8SendCodec(
- channel_num, kVP8Codec.width, kVP8Codec.height, 0, 20, 10, 20);
-
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
- options.conference_mode.Set(false);
- EXPECT_TRUE(channel_->SetOptions(options));
- VerifyVP8SendCodec(
- channel_num, kVP8Codec.width, kVP8Codec.height, 0,
- kMaxBandwidthKbps, 10, kStartBandwidthKbps);
-}
-
-// Verify the current send bitrate is used as start bitrate when reconfiguring
-// the send codec.
-TEST_F(WebRtcVideoEngineTestFake, StartSendBitrate) {
- EXPECT_TRUE(SetupEngine());
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::StreamParams::CreateLegacy(1)));
- int send_channel = vie_.GetLastChannel();
- cricket::VideoCodec codec(kVP8Codec);
- std::vector<cricket::VideoCodec> codec_list;
- codec_list.push_back(codec);
- SendI420Frame(kVP8Codec.width, kVP8Codec.height);
- EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
- VerifyVP8SendCodec(send_channel, kVP8Codec.width, kVP8Codec.height, 0,
- kMaxBandwidthKbps, kMinBandwidthKbps,
- kStartBandwidthKbps);
- EXPECT_EQ(0, vie_.StartSend(send_channel));
-
- // Increase the send bitrate and verify it is used as start bitrate.
- const unsigned int kIncreasedSendBitrateBps = 768000;
- vie_.SetSendBitrates(send_channel, kIncreasedSendBitrateBps, 0, 0);
- EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
- VerifyVP8SendCodec(send_channel, kVP8Codec.width, kVP8Codec.height, 0,
- kMaxBandwidthKbps, kMinBandwidthKbps,
- kIncreasedSendBitrateBps / 1000);
-
- // Never set a start bitrate higher than the max bitrate.
- vie_.SetSendBitrates(send_channel, kMaxBandwidthKbps + 500, 0, 0);
- EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
- VerifyVP8SendCodec(send_channel, kVP8Codec.width, kVP8Codec.height, 0,
- kMaxBandwidthKbps, kMinBandwidthKbps,
- kStartBandwidthKbps);
-
- // Use the default start bitrate if the send bitrate is lower.
- vie_.SetSendBitrates(send_channel, kStartBandwidthKbps - 50, 0,
- 0);
- EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
- VerifyVP8SendCodec(send_channel, kVP8Codec.width, kVP8Codec.height, 0,
- kMaxBandwidthKbps, kMinBandwidthKbps,
- kStartBandwidthKbps);
-}
-
-
-// Test that we constrain send codecs properly.
-TEST_F(WebRtcVideoEngineTestFake, ConstrainSendCodecs) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
-
- // Set max settings of 640x400x30.
- EXPECT_TRUE(engine_.SetDefaultEncoderConfig(
- cricket::VideoEncoderConfig(kVP8Codec)));
-
- // Send codec format bigger than max setting.
- cricket::VideoCodec codec(kVP8Codec);
- codec.width = 1280;
- codec.height = 800;
- codec.framerate = 60;
- std::vector<cricket::VideoCodec> codec_list;
- codec_list.push_back(codec);
-
- // Set send codec and verify codec has been constrained.
- SendI420Frame(kVP8Codec.width, kVP8Codec.height);
- EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
- VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height);
-}
-
-// Test that SetSendCodecs rejects bad format.
-TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsRejectBadFormat) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
-
- // Set w = 0.
- cricket::VideoCodec codec(kVP8Codec);
- codec.width = 0;
- std::vector<cricket::VideoCodec> codec_list;
- codec_list.push_back(codec);
-
- // Verify SetSendCodecs failed and send codec is not changed on engine.
- SendI420Frame(kVP8Codec.width, kVP8Codec.height);
- EXPECT_FALSE(channel_->SetSendCodecs(codec_list));
- webrtc::VideoCodec gcodec;
- // Set plType to something other than the value to test against ensuring
- // that failure will happen if it is not changed.
- gcodec.plType = 1;
- EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec));
- EXPECT_EQ(0, gcodec.plType);
-
- // Set h = 0.
- codec_list[0].width = 640;
- codec_list[0].height = 0;
-
- // Verify SetSendCodecs failed and send codec is not changed on engine.
- EXPECT_FALSE(channel_->SetSendCodecs(codec_list));
- // Set plType to something other than the value to test against ensuring
- // that failure will happen if it is not changed.
- gcodec.plType = 1;
- EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec));
- EXPECT_EQ(0, gcodec.plType);
-}
-
-// Test that SetSendCodecs rejects bad codec.
-TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsRejectBadCodec) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
-
- // Set bad codec name.
- cricket::VideoCodec codec(kVP8Codec);
- codec.name = "bad";
- std::vector<cricket::VideoCodec> codec_list;
- codec_list.push_back(codec);
-
- // Verify SetSendCodecs failed and send codec is not changed on engine.
- SendI420Frame(kVP8Codec.width, kVP8Codec.height);
- EXPECT_FALSE(channel_->SetSendCodecs(codec_list));
- webrtc::VideoCodec gcodec;
- // Set plType to something other than the value to test against ensuring
- // that failure will happen if it is not changed.
- gcodec.plType = 1;
- EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec));
- EXPECT_EQ(0, gcodec.plType);
-}
-
-// Test that vie send codec is reset on new video frame size.
-TEST_F(WebRtcVideoEngineTestFake, ResetVieSendCodecOnNewFrameSize) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
-
- // Set send codec.
- std::vector<cricket::VideoCodec> codec_list;
- codec_list.push_back(kVP8Codec);
- SendI420Frame(kVP8Codec.width, kVP8Codec.height);
- EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::StreamParams::CreateLegacy(123)));
- EXPECT_TRUE(channel_->SetSend(true));
-
- // Capture a smaller frame and verify vie send codec has been reset to
- // the new size.
- SendI420Frame(kVP8Codec.width / 2, kVP8Codec.height / 2);
- VerifyVP8SendCodec(channel_num, kVP8Codec.width / 2, kVP8Codec.height / 2);
-
- // Capture a frame bigger than send_codec_ and verify vie send codec has been
- // reset (and clipped) to send_codec_.
- SendI420Frame(kVP8Codec.width * 2, kVP8Codec.height * 2);
- VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height);
-}
-
-// Test that we set our inbound codecs properly.
-TEST_F(WebRtcVideoEngineTestFake, SetRecvCodecs) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
-
- std::vector<cricket::VideoCodec> codecs;
- codecs.push_back(kVP8Codec);
- EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
-
- webrtc::VideoCodec wcodec;
- EXPECT_TRUE(engine_.ConvertFromCricketVideoCodec(kVP8Codec, &wcodec));
- EXPECT_TRUE(vie_.ReceiveCodecRegistered(channel_num, wcodec));
-}
-
-// Test that we set our inbound RTX codecs properly.
-TEST_F(WebRtcVideoEngineTestFake, SetRecvCodecsWithRtx) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
-
- std::vector<cricket::VideoCodec> codecs;
- cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0);
- codecs.push_back(rtx_codec);
- // Should fail since there's no associated payload type set.
- EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
-
- codecs[0].SetParam("apt", 97);
- // Should still fail since the we don't support RTX on this APT.
- EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
-
- codecs[0].SetParam("apt", kVP8Codec.id);
- // Should still fail since the associated payload type is unknown.
- EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
-
- codecs.push_back(kVP8Codec);
- EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
-
- webrtc::VideoCodec wcodec;
- // Should not have been registered as a WebRTC codec.
- EXPECT_TRUE(engine_.ConvertFromCricketVideoCodec(rtx_codec, &wcodec));
- EXPECT_STREQ("rtx", wcodec.plName);
- EXPECT_FALSE(vie_.ReceiveCodecRegistered(channel_num, wcodec));
-
- EXPECT_EQ(vie_.GetRtxRecvPayloadTypes(channel_num),
- MAKE_VECTOR(kPayloadTypes1));
-}
-
-// Test that RTX packets are routed to the default video channel if
-// there's only one recv stream.
-TEST_F(WebRtcVideoEngineTestFake, TestReceiveRtxOneStream) {
- EXPECT_TRUE(SetupEngine());
-
- // Setup one channel with an associated RTX stream.
- cricket::StreamParams params =
- cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
- params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
- EXPECT_TRUE(channel_->AddRecvStream(params));
- int channel_num = vie_.GetLastChannel();
- EXPECT_EQ(static_cast<int>(kRtxSsrcs1[0]),
- vie_.GetRemoteRtxSsrc(channel_num));
-
- // Register codecs.
- std::vector<cricket::VideoCodec> codec_list;
- codec_list.push_back(kVP8Codec720p);
- cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0);
- rtx_codec.SetParam("apt", kVP8Codec.id);
- codec_list.push_back(rtx_codec);
- EXPECT_TRUE(channel_->SetRecvCodecs(codec_list));
-
- // Construct a fake RTX packet and verify that it is passed to the
- // right WebRTC channel.
- const size_t kDataLength = 12;
- uint8_t data[kDataLength];
- memset(data, 0, sizeof(data));
- data[0] = 0x80;
- data[1] = rtx_codec.id;
- rtc::SetBE32(&data[8], kRtxSsrcs1[0]);
- rtc::Buffer packet(data, kDataLength);
- rtc::PacketTime packet_time;
- channel_->OnPacketReceived(&packet, packet_time);
- EXPECT_EQ(rtx_codec.id, vie_.GetLastRecvdPayloadType(channel_num));
-}
-
-// Verify we don't crash when inserting packets after removing the default
-// receive channel.
-TEST_F(WebRtcVideoEngineTestFake, TestReceiveRtxWithRemovedDefaultChannel) {
- EXPECT_TRUE(SetupEngine());
-
- // Setup one channel with an associated RTX stream.
- cricket::StreamParams params =
- cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
- params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
- EXPECT_TRUE(channel_->AddRecvStream(params));
- int channel_num = vie_.GetLastChannel();
- EXPECT_EQ(static_cast<int>(kRtxSsrcs1[0]),
- vie_.GetRemoteRtxSsrc(channel_num));
-
- // Register codecs.
- std::vector<cricket::VideoCodec> codec_list;
- codec_list.push_back(kVP8Codec720p);
- cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0);
- rtx_codec.SetParam("apt", kVP8Codec.id);
- codec_list.push_back(rtx_codec);
- EXPECT_TRUE(channel_->SetRecvCodecs(codec_list));
-
- // Construct a fake RTX packet and verify that it is passed to the
- // right WebRTC channel.
- const size_t kDataLength = 12;
- uint8_t data[kDataLength];
- memset(data, 0, sizeof(data));
- data[0] = 0x80;
- data[1] = rtx_codec.id;
- rtc::SetBE32(&data[8], kRtxSsrcs1[0]);
- rtc::Buffer packet(data, kDataLength);
- rtc::PacketTime packet_time;
- channel_->OnPacketReceived(&packet, packet_time);
- EXPECT_EQ(rtx_codec.id, vie_.GetLastRecvdPayloadType(channel_num));
-
- // Remove the default channel and insert one more packet.
- EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcs1[0]));
- channel_->OnPacketReceived(&packet, packet_time);
-}
-
-// Test that RTX packets are routed to the correct video channel.
-TEST_F(WebRtcVideoEngineTestFake, TestReceiveRtxThreeStreams) {
- EXPECT_TRUE(SetupEngine());
-
- // Setup three channels with associated RTX streams.
- int channel_num[ARRAY_SIZE(kSsrcs3)];
- for (size_t i = 0; i < ARRAY_SIZE(kSsrcs3); ++i) {
- cricket::StreamParams params =
- cricket::StreamParams::CreateLegacy(kSsrcs3[i]);
- params.AddFidSsrc(kSsrcs3[i], kRtxSsrcs3[i]);
- EXPECT_TRUE(channel_->AddRecvStream(params));
- channel_num[i] = vie_.GetLastChannel();
- }
-
- // Register codecs.
- std::vector<cricket::VideoCodec> codec_list;
- codec_list.push_back(kVP8Codec720p);
- cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0);
- rtx_codec.SetParam("apt", kVP8Codec.id);
- codec_list.push_back(rtx_codec);
- EXPECT_TRUE(channel_->SetRecvCodecs(codec_list));
-
- // Construct a fake RTX packet and verify that it is passed to the
- // right WebRTC channel.
- const size_t kDataLength = 12;
- uint8_t data[kDataLength];
- memset(data, 0, sizeof(data));
- data[0] = 0x80;
- data[1] = rtx_codec.id;
- rtc::SetBE32(&data[8], kRtxSsrcs3[1]);
- rtc::Buffer packet(data, kDataLength);
- rtc::PacketTime packet_time;
- channel_->OnPacketReceived(&packet, packet_time);
- EXPECT_NE(rtx_codec.id, vie_.GetLastRecvdPayloadType(channel_num[0]));
- EXPECT_EQ(rtx_codec.id, vie_.GetLastRecvdPayloadType(channel_num[1]));
- EXPECT_NE(rtx_codec.id, vie_.GetLastRecvdPayloadType(channel_num[2]));
-}
-
-// Test that channel connects and disconnects external capturer correctly.
-TEST_F(WebRtcVideoEngineTestFake, HasExternalCapturer) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
-
- EXPECT_EQ(1, vie_.GetNumCapturers());
- int capture_id = vie_.GetCaptureId(channel_num);
- EXPECT_EQ(channel_num, vie_.GetCaptureChannelId(capture_id));
-
- // Delete the channel should disconnect the capturer.
- delete channel_;
- channel_ = NULL;
- EXPECT_EQ(0, vie_.GetNumCapturers());
-}
-
-// Test that channel adds and removes renderer correctly.
-TEST_F(WebRtcVideoEngineTestFake, HasRenderer) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
-
- EXPECT_TRUE(vie_.GetHasRenderer(channel_num));
- EXPECT_FALSE(vie_.GetRenderStarted(channel_num));
-}
-
-// Test that rtcp is enabled on the channel.
-TEST_F(WebRtcVideoEngineTestFake, RtcpEnabled) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
- EXPECT_EQ(webrtc::kRtcpCompound_RFC4585, vie_.GetRtcpStatus(channel_num));
-}
-
-// Test that key frame request method is set on the channel.
-TEST_F(WebRtcVideoEngineTestFake, KeyFrameRequestEnabled) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
- EXPECT_EQ(webrtc::kViEKeyFrameRequestPliRtcp,
- vie_.GetKeyFrameRequestMethod(channel_num));
-}
-
-// Test that remb receive and send is enabled for the default channel in a 1:1
-// call.
-TEST_F(WebRtcVideoEngineTestFake, RembEnabled) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::StreamParams::CreateLegacy(1)));
- EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
- EXPECT_TRUE(vie_.GetRembStatusBwPartition(channel_num));
- EXPECT_TRUE(channel_->SetSend(true));
- EXPECT_TRUE(vie_.GetRembStatusBwPartition(channel_num));
- EXPECT_TRUE(vie_.GetRembStatusContribute(channel_num));
-}
-
-// When in conference mode, test that remb is enabled on a receive channel but
-// not for the default channel and that it uses the default channel for sending
-// remb packets.
-TEST_F(WebRtcVideoEngineTestFake, RembEnabledOnReceiveChannels) {
- EXPECT_TRUE(SetupEngine());
- int default_channel = vie_.GetLastChannel();
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::StreamParams::CreateLegacy(1)));
- EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
- EXPECT_TRUE(vie_.GetRembStatusBwPartition(default_channel));
- EXPECT_TRUE(vie_.GetRembStatusContribute(default_channel));
- EXPECT_TRUE(channel_->SetSend(true));
- EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
- int new_channel_num = vie_.GetLastChannel();
- EXPECT_NE(default_channel, new_channel_num);
-
- EXPECT_TRUE(vie_.GetRembStatusBwPartition(default_channel));
- EXPECT_TRUE(vie_.GetRembStatusContribute(default_channel));
- EXPECT_FALSE(vie_.GetRembStatusBwPartition(new_channel_num));
- EXPECT_TRUE(vie_.GetRembStatusContribute(new_channel_num));
-}
-
-TEST_F(WebRtcVideoEngineTestFake, RecvStreamWithRtx) {
- EXPECT_TRUE(SetupEngine());
- int default_channel = vie_.GetLastChannel();
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::CreateSimWithRtxStreamParams("cname",
- MAKE_VECTOR(kSsrcs3),
- MAKE_VECTOR(kRtxSsrcs3))));
- EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
- EXPECT_TRUE(channel_->SetSend(true));
- EXPECT_TRUE(channel_->AddRecvStream(
- cricket::CreateSimWithRtxStreamParams("cname",
- MAKE_VECTOR(kSsrcs1),
- MAKE_VECTOR(kRtxSsrcs1))));
- int new_channel_num = vie_.GetLastChannel();
- EXPECT_NE(default_channel, new_channel_num);
- EXPECT_EQ(4, vie_.GetRemoteRtxSsrc(new_channel_num));
-}
-
-TEST_F(WebRtcVideoEngineTestFake, RecvStreamNoRtx) {
- EXPECT_TRUE(SetupEngine());
- int default_channel = vie_.GetLastChannel();
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::CreateSimWithRtxStreamParams("cname",
- MAKE_VECTOR(kSsrcs3),
- MAKE_VECTOR(kRtxSsrcs3))));
- EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
- EXPECT_TRUE(channel_->SetSend(true));
- EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
- int new_channel_num = vie_.GetLastChannel();
- EXPECT_NE(default_channel, new_channel_num);
- EXPECT_EQ(-1, vie_.GetRemoteRtxSsrc(new_channel_num));
-}
-
-// Test support for RTP timestamp offset header extension.
-TEST_F(WebRtcVideoEngineTestFake, SendRtpTimestampOffsetHeaderExtensions) {
- TestSetSendRtpHeaderExtensions(kRtpTimestampOffsetHeaderExtension);
-}
-TEST_F(WebRtcVideoEngineTestFake, RecvRtpTimestampOffsetHeaderExtensions) {
- TestSetRecvRtpHeaderExtensions(kRtpTimestampOffsetHeaderExtension);
-}
-
-// Test support for absolute send time header extension.
-TEST_F(WebRtcVideoEngineTestFake, SendAbsoluteSendTimeHeaderExtensions) {
- TestSetSendRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension);
-}
-TEST_F(WebRtcVideoEngineTestFake, RecvAbsoluteSendTimeHeaderExtensions) {
- TestSetRecvRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension);
-}
-
-// Test support for Coordination of Video Orientation (CVO) header extension.
-TEST_F(WebRtcVideoEngineTestFake, SendVideoRotationHeaderExtensions) {
- TestSetSendRtpHeaderExtensions(kRtpVideoRotationHeaderExtension);
-}
-TEST_F(WebRtcVideoEngineTestFake, RecvVideoRotationHeaderExtensions) {
- TestSetRecvRtpHeaderExtensions(kRtpVideoRotationHeaderExtension);
-}
-
-TEST_F(WebRtcVideoEngineTestFake, LeakyBucketTest) {
- EXPECT_TRUE(SetupEngine());
-
- // Verify this is on by default.
- EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(1)));
- int first_send_channel = vie_.GetLastChannel();
- EXPECT_TRUE(vie_.GetTransmissionSmoothingStatus(first_send_channel));
-
- // Add a new send stream and verify leaky bucket is enabled.
- EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(3)));
- int second_send_channel = vie_.GetLastChannel();
- EXPECT_NE(first_send_channel, second_send_channel);
- EXPECT_TRUE(vie_.GetTransmissionSmoothingStatus(second_send_channel));
-}
-
-// Verify that SuspendBelowMinBitrate is enabled if it is set in the options.
-TEST_F(WebRtcVideoEngineTestFake, SuspendBelowMinBitrateTest) {
- EXPECT_TRUE(SetupEngine());
-
- // Verify this is off by default.
- EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(1)));
- int first_send_channel = vie_.GetLastChannel();
- EXPECT_FALSE(vie_.GetSuspendBelowMinBitrateStatus(first_send_channel));
-
- // Enable the experiment and verify.
- cricket::VideoOptions options;
- options.suspend_below_min_bitrate.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
- EXPECT_TRUE(vie_.GetSuspendBelowMinBitrateStatus(first_send_channel));
-
- // Add a new send stream and verify suspend_below_min_bitrate is enabled.
- EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
- int second_send_channel = vie_.GetLastChannel();
- EXPECT_NE(first_send_channel, second_send_channel);
- EXPECT_TRUE(vie_.GetSuspendBelowMinBitrateStatus(second_send_channel));
-}
-
-TEST_F(WebRtcVideoEngineTestFake, BufferedModeLatency) {
- EXPECT_TRUE(SetupEngine());
-
- // Verify this is off by default.
- EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(1)));
- int first_send_channel = vie_.GetLastChannel();
- EXPECT_EQ(0, vie_.GetSenderTargetDelay(first_send_channel));
- EXPECT_EQ(0, vie_.GetReceiverTargetDelay(first_send_channel));
-
- // Enable the experiment and verify. The default channel will have both
- // sender and receiver buffered mode enabled.
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- options.buffered_mode_latency.Set(100);
- EXPECT_TRUE(channel_->SetOptions(options));
- EXPECT_EQ(100, vie_.GetSenderTargetDelay(first_send_channel));
- EXPECT_EQ(100, vie_.GetReceiverTargetDelay(first_send_channel));
-
- // Add a receive channel and verify sender buffered mode isn't enabled.
- EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
- int recv_channel_num = vie_.GetLastChannel();
- EXPECT_NE(first_send_channel, recv_channel_num);
- EXPECT_EQ(0, vie_.GetSenderTargetDelay(recv_channel_num));
- EXPECT_EQ(100, vie_.GetReceiverTargetDelay(recv_channel_num));
-
- // Add a new send stream and verify sender buffered mode is enabled.
- EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(3)));
- int second_send_channel = vie_.GetLastChannel();
- EXPECT_NE(first_send_channel, second_send_channel);
- EXPECT_EQ(100, vie_.GetSenderTargetDelay(second_send_channel));
- EXPECT_EQ(0, vie_.GetReceiverTargetDelay(second_send_channel));
-
- // Disable sender buffered mode and verify.
- options.buffered_mode_latency.Set(cricket::kBufferedModeDisabled);
- EXPECT_TRUE(channel_->SetOptions(options));
- EXPECT_EQ(0, vie_.GetSenderTargetDelay(first_send_channel));
- EXPECT_EQ(0, vie_.GetReceiverTargetDelay(first_send_channel));
- EXPECT_EQ(0, vie_.GetSenderTargetDelay(second_send_channel));
- EXPECT_EQ(0, vie_.GetReceiverTargetDelay(second_send_channel));
- EXPECT_EQ(0, vie_.GetSenderTargetDelay(recv_channel_num));
- EXPECT_EQ(0, vie_.GetReceiverTargetDelay(recv_channel_num));
-}
-
-TEST_F(WebRtcVideoEngineTestFake, AdditiveVideoOptions) {
- EXPECT_TRUE(SetupEngine());
- EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(1)));
- SendI420Frame(kVP8Codec.width, kVP8Codec.height);
- channel_->SetSendCodecs(engine_.codecs());
-
- int first_send_channel = vie_.GetLastChannel();
- EXPECT_EQ(0, vie_.GetSenderTargetDelay(first_send_channel));
- EXPECT_EQ(0, vie_.GetReceiverTargetDelay(first_send_channel));
-
- cricket::VideoOptions options1;
- options1.buffered_mode_latency.Set(100);
- EXPECT_TRUE(channel_->SetOptions(options1));
- EXPECT_EQ(100, vie_.GetSenderTargetDelay(first_send_channel));
- EXPECT_EQ(100, vie_.GetReceiverTargetDelay(first_send_channel));
- EXPECT_TRUE(vie_.GetTransmissionSmoothingStatus(first_send_channel));
-
- int kBoostedStartBandwidthKbps = 1000;
- cricket::VideoOptions options2;
- options2.video_start_bitrate.Set(kBoostedStartBandwidthKbps);
- EXPECT_TRUE(channel_->SetOptions(options2));
- // Check that start bitrate has changed to the new value.
- VerifyVP8SendCodec(first_send_channel, kVP8Codec.width, kVP8Codec.height, 0,
- kMaxBandwidthKbps, kMinBandwidthKbps, kBoostedStartBandwidthKbps);
- // The buffered_mode_latency should still take effect.
- EXPECT_EQ(100, vie_.GetSenderTargetDelay(first_send_channel));
- EXPECT_EQ(100, vie_.GetReceiverTargetDelay(first_send_channel));
-}
-
-TEST_F(WebRtcVideoEngineTestFake, SetCpuOveruseOptionsWithCaptureJitterMethod) {
- EXPECT_TRUE(SetupEngine());
-
- // Verify this is off by default.
- EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(1)));
- int first_send_channel = vie_.GetLastChannel();
- webrtc::CpuOveruseOptions cpu_option =
- vie_.GetCpuOveruseOptions(first_send_channel);
- EXPECT_EQ(0, cpu_option.low_capture_jitter_threshold_ms);
- EXPECT_EQ(0, cpu_option.high_capture_jitter_threshold_ms);
- EXPECT_FALSE(cpu_option.enable_capture_jitter_method);
- EXPECT_FALSE(cpu_option.enable_encode_usage_method);
-
- // Set low and high threshold and verify that cpu options are set.
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- options.cpu_underuse_threshold.Set(10);
- options.cpu_overuse_threshold.Set(20);
- EXPECT_TRUE(channel_->SetOptions(options));
- cpu_option = vie_.GetCpuOveruseOptions(first_send_channel);
- EXPECT_EQ(10, cpu_option.low_capture_jitter_threshold_ms);
- EXPECT_EQ(20, cpu_option.high_capture_jitter_threshold_ms);
- EXPECT_TRUE(cpu_option.enable_capture_jitter_method);
- EXPECT_FALSE(cpu_option.enable_encode_usage_method);
-
- // Add a receive channel and verify that cpu options are not set.
- EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
- int recv_channel_num = vie_.GetLastChannel();
- EXPECT_NE(first_send_channel, recv_channel_num);
- cpu_option = vie_.GetCpuOveruseOptions(recv_channel_num);
- EXPECT_EQ(0, cpu_option.low_capture_jitter_threshold_ms);
- EXPECT_EQ(0, cpu_option.high_capture_jitter_threshold_ms);
- EXPECT_FALSE(cpu_option.enable_capture_jitter_method);
- EXPECT_FALSE(cpu_option.enable_encode_usage_method);
-
- // Add a new send stream and verify that cpu options are set from start.
- EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(3)));
- int second_send_channel = vie_.GetLastChannel();
- EXPECT_NE(first_send_channel, second_send_channel);
- cpu_option = vie_.GetCpuOveruseOptions(second_send_channel);
- EXPECT_EQ(10, cpu_option.low_capture_jitter_threshold_ms);
- EXPECT_EQ(20, cpu_option.high_capture_jitter_threshold_ms);
- EXPECT_TRUE(cpu_option.enable_capture_jitter_method);
- EXPECT_FALSE(cpu_option.enable_encode_usage_method);
-}
-
-TEST_F(WebRtcVideoEngineTestFake, SetInvalidCpuOveruseThresholds) {
- EXPECT_TRUE(SetupEngine());
- EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(1)));
- int channel_num = vie_.GetLastChannel();
-
- // Only low threshold set. Verify that cpu options are not set.
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- options.cpu_underuse_threshold.Set(10);
- EXPECT_TRUE(channel_->SetOptions(options));
- webrtc::CpuOveruseOptions cpu_option = vie_.GetCpuOveruseOptions(channel_num);
- EXPECT_EQ(0, cpu_option.low_capture_jitter_threshold_ms);
- EXPECT_EQ(0, cpu_option.high_capture_jitter_threshold_ms);
- EXPECT_FALSE(cpu_option.enable_capture_jitter_method);
- EXPECT_FALSE(cpu_option.enable_encode_usage_method);
-
- // Set high threshold to a negative value. Verify that options are not set.
- options.cpu_overuse_threshold.Set(-1);
- EXPECT_TRUE(channel_->SetOptions(options));
- cpu_option = vie_.GetCpuOveruseOptions(channel_num);
- EXPECT_EQ(0, cpu_option.low_capture_jitter_threshold_ms);
- EXPECT_EQ(0, cpu_option.high_capture_jitter_threshold_ms);
- EXPECT_FALSE(cpu_option.enable_capture_jitter_method);
- EXPECT_FALSE(cpu_option.enable_encode_usage_method);
-
- // Low and high threshold valid. Verify that cpu options are set.
- options.cpu_overuse_threshold.Set(20);
- EXPECT_TRUE(channel_->SetOptions(options));
- cpu_option = vie_.GetCpuOveruseOptions(channel_num);
- EXPECT_EQ(10, cpu_option.low_capture_jitter_threshold_ms);
- EXPECT_EQ(20, cpu_option.high_capture_jitter_threshold_ms);
- EXPECT_TRUE(cpu_option.enable_capture_jitter_method);
- EXPECT_FALSE(cpu_option.enable_encode_usage_method);
-}
-
-TEST_F(WebRtcVideoEngineTestFake, SetCpuOveruseOptionsWithEncodeUsageMethod) {
- EXPECT_TRUE(SetupEngine());
- EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(1)));
- int first_send_channel = vie_.GetLastChannel();
-
- // Set low and high threshold and enable encode usage method.
- // Verify that cpu options are set.
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- options.cpu_underuse_threshold.Set(10);
- options.cpu_overuse_threshold.Set(20);
- options.cpu_overuse_encode_usage.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
- webrtc::CpuOveruseOptions cpu_option =
- vie_.GetCpuOveruseOptions(first_send_channel);
- EXPECT_EQ(10, cpu_option.low_encode_usage_threshold_percent);
- EXPECT_EQ(20, cpu_option.high_encode_usage_threshold_percent);
- EXPECT_FALSE(cpu_option.enable_capture_jitter_method);
- EXPECT_TRUE(cpu_option.enable_encode_usage_method);
- // Verify that optional encode rsd thresholds are not set.
- EXPECT_EQ(-1, cpu_option.low_encode_time_rsd_threshold);
- EXPECT_EQ(-1, cpu_option.high_encode_time_rsd_threshold);
-
- // Add a new send stream and verify that cpu options are set from start.
- EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(3)));
- int second_send_channel = vie_.GetLastChannel();
- EXPECT_NE(first_send_channel, second_send_channel);
- cpu_option = vie_.GetCpuOveruseOptions(second_send_channel);
- EXPECT_EQ(10, cpu_option.low_encode_usage_threshold_percent);
- EXPECT_EQ(20, cpu_option.high_encode_usage_threshold_percent);
- EXPECT_FALSE(cpu_option.enable_capture_jitter_method);
- EXPECT_TRUE(cpu_option.enable_encode_usage_method);
- // Verify that optional encode rsd thresholds are not set.
- EXPECT_EQ(-1, cpu_option.low_encode_time_rsd_threshold);
- EXPECT_EQ(-1, cpu_option.high_encode_time_rsd_threshold);
-}
-
-TEST_F(WebRtcVideoEngineTestFake, SetCpuOveruseOptionsWithEncodeRsdThresholds) {
- EXPECT_TRUE(SetupEngine());
- EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(1)));
- int first_send_channel = vie_.GetLastChannel();
-
- // Set optional encode rsd thresholds and verify cpu options.
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- options.cpu_underuse_threshold.Set(10);
- options.cpu_overuse_threshold.Set(20);
- options.cpu_underuse_encode_rsd_threshold.Set(30);
- options.cpu_overuse_encode_rsd_threshold.Set(40);
- options.cpu_overuse_encode_usage.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
- webrtc::CpuOveruseOptions cpu_option =
- vie_.GetCpuOveruseOptions(first_send_channel);
- EXPECT_EQ(10, cpu_option.low_encode_usage_threshold_percent);
- EXPECT_EQ(20, cpu_option.high_encode_usage_threshold_percent);
- EXPECT_FALSE(cpu_option.enable_capture_jitter_method);
- EXPECT_TRUE(cpu_option.enable_encode_usage_method);
- EXPECT_EQ(30, cpu_option.low_encode_time_rsd_threshold);
- EXPECT_EQ(40, cpu_option.high_encode_time_rsd_threshold);
-
- // Add a new send stream and verify that cpu options are set from start.
- EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(3)));
- int second_send_channel = vie_.GetLastChannel();
- EXPECT_NE(first_send_channel, second_send_channel);
- cpu_option = vie_.GetCpuOveruseOptions(second_send_channel);
- EXPECT_EQ(10, cpu_option.low_encode_usage_threshold_percent);
- EXPECT_EQ(20, cpu_option.high_encode_usage_threshold_percent);
- EXPECT_FALSE(cpu_option.enable_capture_jitter_method);
- EXPECT_TRUE(cpu_option.enable_encode_usage_method);
- EXPECT_EQ(30, cpu_option.low_encode_time_rsd_threshold);
- EXPECT_EQ(40, cpu_option.high_encode_time_rsd_threshold);
-}
-
-// Test that AddRecvStream doesn't create new channel for 1:1 call.
-TEST_F(WebRtcVideoEngineTestFake, AddRecvStream1On1) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
- EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
- EXPECT_EQ(channel_num, vie_.GetLastChannel());
-}
-
-// Test that NACK, PLI and REMB are enabled for internal codec.
-TEST_F(WebRtcVideoEngineTestFake, InternalCodecFeedbackParams) {
- EXPECT_TRUE(SetupEngine());
-
- std::vector<cricket::VideoCodec> codecs(engine_.codecs());
- // Vp8 will appear at the beginning.
- size_t pos = 0;
- EXPECT_EQ("VP8", codecs[pos].name);
- VerifyCodecFeedbackParams(codecs[pos]);
-}
-
-// Test that AddRecvStream doesn't change remb for 1:1 call.
-TEST_F(WebRtcVideoEngineTestFake, NoRembChangeAfterAddRecvStream) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::StreamParams::CreateLegacy(1)));
- EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
- EXPECT_TRUE(vie_.GetRembStatusBwPartition(channel_num));
- EXPECT_TRUE(vie_.GetRembStatusContribute(channel_num));
- EXPECT_TRUE(channel_->SetSend(true));
- EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
- EXPECT_TRUE(vie_.GetRembStatusBwPartition(channel_num));
- EXPECT_TRUE(vie_.GetRembStatusContribute(channel_num));
-}
-
-// Verify default REMB setting and that it can be turned on and off.
-TEST_F(WebRtcVideoEngineTestFake, RembOnOff) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
- // Verify REMB sending is always off by default.
- EXPECT_FALSE(vie_.GetRembStatusBwPartition(channel_num));
-
- // Verify that REMB is turned on when setting default codecs since the
- // default codecs have REMB enabled.
- EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
- EXPECT_TRUE(vie_.GetRembStatusBwPartition(channel_num));
-
- // Verify that REMB is turned off when codecs without REMB are set.
- std::vector<cricket::VideoCodec> codecs = engine_.codecs();
- // Clearing the codecs' FeedbackParams and setting send codecs should disable
- // REMB.
- for (std::vector<cricket::VideoCodec>::iterator iter = codecs.begin();
- iter != codecs.end(); ++iter) {
- // Intersecting with empty will clear the FeedbackParams.
- cricket::FeedbackParams empty_params;
- iter->feedback_params.Intersect(empty_params);
- EXPECT_TRUE(iter->feedback_params.params().empty());
- }
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
- EXPECT_FALSE(vie_.GetRembStatusBwPartition(channel_num));
-}
-
-// Test that nack is enabled on the channel if we don't offer red/fec.
-TEST_F(WebRtcVideoEngineTestFake, NackEnabled) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
- std::vector<cricket::VideoCodec> codecs(engine_.codecs());
- codecs.resize(1); // toss out red and ulpfec
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
- EXPECT_TRUE(vie_.GetNackStatus(channel_num));
-}
-
-// Test that we enable hybrid NACK FEC mode.
-TEST_F(WebRtcVideoEngineTestFake, HybridNackFec) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
- EXPECT_TRUE(channel_->SetRecvCodecs(engine_.codecs()));
- EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
- EXPECT_TRUE(vie_.GetHybridNackFecStatus(channel_num));
- EXPECT_FALSE(vie_.GetNackStatus(channel_num));
-}
-
-// Test that we enable hybrid NACK FEC mode when calling SetSendCodecs and
-// SetReceiveCodecs in reversed order.
-TEST_F(WebRtcVideoEngineTestFake, HybridNackFecReversedOrder) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
- EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
- EXPECT_TRUE(channel_->SetRecvCodecs(engine_.codecs()));
- EXPECT_TRUE(vie_.GetHybridNackFecStatus(channel_num));
- EXPECT_FALSE(vie_.GetNackStatus(channel_num));
-}
-
-// Test NACK vs Hybrid NACK/FEC interop call setup, i.e. only use NACK even if
-// red/fec is offered as receive codec.
-TEST_F(WebRtcVideoEngineTestFake, VideoProtectionInterop) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
- std::vector<cricket::VideoCodec> recv_codecs(engine_.codecs());
- std::vector<cricket::VideoCodec> send_codecs(engine_.codecs());
- // Only add VP8 as send codec.
- send_codecs.resize(1);
- EXPECT_TRUE(channel_->SetRecvCodecs(recv_codecs));
- EXPECT_TRUE(channel_->SetSendCodecs(send_codecs));
- EXPECT_FALSE(vie_.GetHybridNackFecStatus(channel_num));
- EXPECT_TRUE(vie_.GetNackStatus(channel_num));
-}
-
-// Test NACK vs Hybrid NACK/FEC interop call setup, i.e. only use NACK even if
-// red/fec is offered as receive codec. Call order reversed compared to
-// VideoProtectionInterop.
-TEST_F(WebRtcVideoEngineTestFake, VideoProtectionInteropReversed) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
- std::vector<cricket::VideoCodec> recv_codecs(engine_.codecs());
- std::vector<cricket::VideoCodec> send_codecs(engine_.codecs());
- // Only add VP8 as send codec.
- send_codecs.resize(1);
- EXPECT_TRUE(channel_->SetSendCodecs(send_codecs));
- EXPECT_TRUE(channel_->SetRecvCodecs(recv_codecs));
- EXPECT_FALSE(vie_.GetHybridNackFecStatus(channel_num));
- EXPECT_TRUE(vie_.GetNackStatus(channel_num));
-}
-
-// Test that NACK, not hybrid mode, is enabled in conference mode.
-TEST_F(WebRtcVideoEngineTestFake, HybridNackFecConference) {
- EXPECT_TRUE(SetupEngine());
- // Setup the send channel.
- int send_channel_num = vie_.GetLastChannel();
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
- EXPECT_TRUE(channel_->SetRecvCodecs(engine_.codecs()));
- EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
- EXPECT_FALSE(vie_.GetHybridNackFecStatus(send_channel_num));
- EXPECT_TRUE(vie_.GetNackStatus(send_channel_num));
- // Add a receive stream.
- EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
- int receive_channel_num = vie_.GetLastChannel();
- EXPECT_FALSE(vie_.GetHybridNackFecStatus(receive_channel_num));
- EXPECT_TRUE(vie_.GetNackStatus(receive_channel_num));
-}
-
-// Test that when AddRecvStream in conference mode, a new channel is created
-// for receiving. And the new channel's "original channel" is the send channel.
-TEST_F(WebRtcVideoEngineTestFake, AddRemoveRecvStreamConference) {
- EXPECT_TRUE(SetupEngine());
- // Setup the send channel.
- int send_channel_num = vie_.GetLastChannel();
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
- // Add a receive stream.
- EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
- int receive_channel_num = vie_.GetLastChannel();
- EXPECT_EQ(send_channel_num, vie_.GetOriginalChannelId(receive_channel_num));
- EXPECT_TRUE(channel_->RemoveRecvStream(1));
- EXPECT_FALSE(vie_.IsChannel(receive_channel_num));
-}
-
-// Test that adding/removing stream with 0 ssrc should fail (and not crash).
-// For crbug/351699 and 350988.
-TEST_F(WebRtcVideoEngineTestFake, AddRemoveRecvStreamWith0Ssrc) {
- EXPECT_TRUE(SetupEngine());
- EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
- EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(0)));
- EXPECT_FALSE(channel_->RemoveRecvStream(0));
- EXPECT_TRUE(channel_->RemoveRecvStream(1));
-}
-
-TEST_F(WebRtcVideoEngineTestFake, AddRemoveSendStreamWith0Ssrc) {
- EXPECT_TRUE(SetupEngine());
- EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(1)));
- EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(0)));
- EXPECT_FALSE(channel_->RemoveSendStream(0));
- EXPECT_TRUE(channel_->RemoveSendStream(1));
-}
-
-// Test that we can create a channel and start/stop rendering out on it.
-TEST_F(WebRtcVideoEngineTestFake, SetRender) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
-
- // Verify we can start/stop/start/stop rendering.
- EXPECT_TRUE(channel_->SetRender(true));
- EXPECT_TRUE(vie_.GetRenderStarted(channel_num));
- EXPECT_TRUE(channel_->SetRender(false));
- EXPECT_FALSE(vie_.GetRenderStarted(channel_num));
- EXPECT_TRUE(channel_->SetRender(true));
- EXPECT_TRUE(vie_.GetRenderStarted(channel_num));
- EXPECT_TRUE(channel_->SetRender(false));
- EXPECT_FALSE(vie_.GetRenderStarted(channel_num));
-}
-
-// Test that we can create a channel and start/stop sending out on it.
-TEST_F(WebRtcVideoEngineTestFake, SetSend) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
- // Verify receiving is also started.
- EXPECT_TRUE(vie_.GetReceive(channel_num));
-
- // Set send codecs on the channel.
- std::vector<cricket::VideoCodec> codecs;
- codecs.push_back(kVP8Codec);
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::StreamParams::CreateLegacy(123)));
-
- // Verify we can start/stop/start/stop sending.
- EXPECT_TRUE(channel_->SetSend(true));
- EXPECT_TRUE(vie_.GetSend(channel_num));
- EXPECT_TRUE(channel_->SetSend(false));
- EXPECT_FALSE(vie_.GetSend(channel_num));
- EXPECT_TRUE(channel_->SetSend(true));
- EXPECT_TRUE(vie_.GetSend(channel_num));
- EXPECT_TRUE(channel_->SetSend(false));
- EXPECT_FALSE(vie_.GetSend(channel_num));
-}
-
-// Test that we set bandwidth properly when using full auto bandwidth mode.
-TEST_F(WebRtcVideoEngineTestFake, SetBandwidthAuto) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
- SendI420Frame(kVP8Codec.width, kVP8Codec.height);
- EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
- EXPECT_TRUE(channel_->SetMaxSendBandwidth(cricket::kAutoBandwidth));
- VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height);
-}
-
-// Test that we set bandwidth properly when using auto with upper bound.
-TEST_F(WebRtcVideoEngineTestFake, SetBandwidthCapped) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
- SendI420Frame(kVP8Codec.width, kVP8Codec.height);
- EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
- EXPECT_TRUE(channel_->SetMaxSendBandwidth(768000));
- VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height, 0, 768U);
-}
-
-// Test that we reduce the start bandwidth when the requested max is less than
-// the default start bandwidth.
-TEST_F(WebRtcVideoEngineTestFake, SetMaxBandwidthBelowDefaultStart) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
- SendI420Frame(kVP8Codec.width, kVP8Codec.height);
- EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
- int max_bandwidth_kbps = (kMinBandwidthKbps + kStartBandwidthKbps) / 2;
- EXPECT_TRUE(channel_->SetMaxSendBandwidth(max_bandwidth_kbps * 1000));
- VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height, 0,
- max_bandwidth_kbps, kMinBandwidthKbps, max_bandwidth_kbps);
-}
-
-// Test that we reduce the min bandwidth when the requested max is less than
-// the min bandwidth.
-TEST_F(WebRtcVideoEngineTestFake, SetMaxBandwidthBelowMin) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
- SendI420Frame(kVP8Codec.width, kVP8Codec.height);
- EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
- int max_bandwidth_kbps = kMinBandwidthKbps / 2;
- EXPECT_TRUE(channel_->SetMaxSendBandwidth(max_bandwidth_kbps * 1000));
- VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height, 0,
- max_bandwidth_kbps, max_bandwidth_kbps, max_bandwidth_kbps);
-}
-
-// Test that the start bandwidth can be controlled by VideoOptions.
-TEST_F(WebRtcVideoEngineTestFake, SetStartBandwidthOption) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
- EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
- SendI420Frame(kVP8Codec.width, kVP8Codec.height);
- VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height, 0,
- kMaxBandwidthKbps, kMinBandwidthKbps, kStartBandwidthKbps);
-
- // Set the start bitrate option.
- unsigned int kBoostedStartBandwidthKbps = 1000;
- ASSERT_NE(kStartBandwidthKbps, kBoostedStartBandwidthKbps);
- cricket::VideoOptions options;
- options.video_start_bitrate.Set(kBoostedStartBandwidthKbps);
- EXPECT_TRUE(channel_->SetOptions(options));
-
- // Check that start bitrate has changed to the new value.
- VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height, 0,
- kMaxBandwidthKbps, kMinBandwidthKbps, kBoostedStartBandwidthKbps);
-}
-
-// Test that SetMaxSendBandwidth works as expected in conference mode.
-TEST_F(WebRtcVideoEngineTestFake, SetBandwidthInConference) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
- SendI420Frame(kVP8Codec.width, kVP8Codec.height);
- EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
- VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height);
-
- // Set send bandwidth.
- EXPECT_TRUE(channel_->SetMaxSendBandwidth(768000));
-
- // Verify that the max bitrate has changed.
- VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height, 0,
- 768, kMinBandwidthKbps, kStartBandwidthKbps);
-}
-
-// Test that sending screencast frames doesn't change bitrate.
-TEST_F(WebRtcVideoEngineTestFake, SetBandwidthScreencast) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
-
- // Set send codec.
- cricket::VideoCodec codec(kVP8Codec);
- std::vector<cricket::VideoCodec> codec_list;
- codec_list.push_back(codec);
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::StreamParams::CreateLegacy(123)));
- EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
- EXPECT_TRUE(channel_->SetMaxSendBandwidth(111000));
- EXPECT_TRUE(channel_->SetSend(true));
-
- SendI420ScreencastFrame(kVP8Codec.width, kVP8Codec.height);
- VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height, 0, 111);
-}
-
-// Test SetSendSsrc.
-TEST_F(WebRtcVideoEngineTestFake, SetSendSsrcAndCname) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
-
- cricket::StreamParams stream;
- stream.ssrcs.push_back(1234);
- stream.cname = "cname";
- channel_->AddSendStream(stream);
-
- unsigned int ssrc = 0;
- EXPECT_EQ(0, vie_.GetLocalSSRC(channel_num, ssrc));
- EXPECT_EQ(1234U, ssrc);
- EXPECT_EQ(1, vie_.GetNumSsrcs(channel_num));
-
- char rtcp_cname[256];
- EXPECT_EQ(0, vie_.GetRTCPCName(channel_num, rtcp_cname));
- EXPECT_STREQ("cname", rtcp_cname);
-}
-
-// Test that the local SSRC is the same on sending and receiving channels if the
-// receive channel is created before the send channel.
-TEST_F(WebRtcVideoEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
- EXPECT_TRUE(SetupEngine());
-
- EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
- int receive_channel_num = vie_.GetLastChannel();
- cricket::StreamParams stream = cricket::StreamParams::CreateLegacy(1234);
- EXPECT_TRUE(channel_->AddSendStream(stream));
- int send_channel_num = vie_.GetLastChannel();
- unsigned int ssrc = 0;
- EXPECT_EQ(0, vie_.GetLocalSSRC(send_channel_num, ssrc));
- EXPECT_EQ(1234U, ssrc);
- EXPECT_EQ(1, vie_.GetNumSsrcs(send_channel_num));
- ssrc = 0;
- EXPECT_EQ(0, vie_.GetLocalSSRC(receive_channel_num, ssrc));
- EXPECT_EQ(1234U, ssrc);
- EXPECT_EQ(1, vie_.GetNumSsrcs(receive_channel_num));
-}
-
-// Test SetOptions with denoising flag.
-TEST_F(WebRtcVideoEngineTestFake, SetOptionsWithDenoising) {
- EXPECT_TRUE(SetupEngine());
- EXPECT_EQ(1, vie_.GetNumCapturers());
- int channel_num = vie_.GetLastChannel();
- int capture_id = vie_.GetCaptureId(channel_num);
- // Set send codecs on the channel.
- std::vector<cricket::VideoCodec> codecs;
- codecs.push_back(kVP8Codec);
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-
- // Set options with OPT_VIDEO_NOISE_REDUCTION flag.
- cricket::VideoOptions options;
- options.video_noise_reduction.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
-
- // Verify capture has denoising turned on.
- webrtc::VideoCodec send_codec;
- memset(&send_codec, 0, sizeof(send_codec)); // avoid uninitialized warning
- EXPECT_EQ(0, vie_.GetSendCodec(channel_num, send_codec));
- EXPECT_TRUE(send_codec.codecSpecific.VP8.denoisingOn);
- EXPECT_FALSE(vie_.GetCaptureDenoising(capture_id));
-
- // Set options back to zero.
- options.video_noise_reduction.Set(false);
- EXPECT_TRUE(channel_->SetOptions(options));
-
- // Verify capture has denoising turned off.
- EXPECT_EQ(0, vie_.GetSendCodec(channel_num, send_codec));
- EXPECT_FALSE(send_codec.codecSpecific.VP8.denoisingOn);
- EXPECT_FALSE(vie_.GetCaptureDenoising(capture_id));
-}
-
-TEST_F(WebRtcVideoEngineTestFake, MultipleSendStreamsWithOneCapturer) {
- EXPECT_TRUE(SetupEngine());
-
- // Start the capturer
- cricket::FakeVideoCapturer capturer;
- cricket::VideoFormat capture_format_vga = cricket::VideoFormat(640, 480,
- cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420);
- EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format_vga));
-
- // Add send streams and connect the capturer
- for (unsigned int i = 0; i < sizeof(kSsrcs2)/sizeof(kSsrcs2[0]); ++i) {
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::StreamParams::CreateLegacy(kSsrcs2[i])));
- // Register the capturer to the ssrc.
- EXPECT_TRUE(channel_->SetCapturer(kSsrcs2[i], &capturer));
- }
-
- const int channel0 = vie_.GetChannelFromLocalSsrc(kSsrcs2[0]);
- ASSERT_NE(-1, channel0);
- const int channel1 = vie_.GetChannelFromLocalSsrc(kSsrcs2[1]);
- ASSERT_NE(-1, channel1);
- ASSERT_NE(channel0, channel1);
-
- // Both channels should have started receiving after created.
- EXPECT_TRUE(vie_.GetReceive(channel0));
- EXPECT_TRUE(vie_.GetReceive(channel1));
-
- // Set send codec.
- std::vector<cricket::VideoCodec> codecs;
- cricket::VideoCodec send_codec(100, "VP8", 640, 480, 30, 0);
- codecs.push_back(send_codec);
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-
- EXPECT_TRUE(channel_->SetSend(true));
- EXPECT_TRUE(vie_.GetSend(channel0));
- EXPECT_TRUE(vie_.GetSend(channel1));
-
- EXPECT_TRUE(capturer.CaptureFrame());
- EXPECT_EQ(1, vie_.GetIncomingFrameNum(channel0));
- EXPECT_EQ(1, vie_.GetIncomingFrameNum(channel1));
-
- EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs2[0]));
- EXPECT_TRUE(capturer.CaptureFrame());
- // channel0 is the default channel, so it won't be deleted.
- // But it should be disconnected from the capturer.
- EXPECT_EQ(1, vie_.GetIncomingFrameNum(channel0));
- EXPECT_EQ(2, vie_.GetIncomingFrameNum(channel1));
-
- EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs2[1]));
- EXPECT_TRUE(capturer.CaptureFrame());
- EXPECT_EQ(1, vie_.GetIncomingFrameNum(channel0));
- // channel1 has already been deleted.
- EXPECT_EQ(-1, vie_.GetIncomingFrameNum(channel1));
-}
-
-TEST_F(WebRtcVideoEngineTestFake, SendReceiveBitratesStats) {
- EXPECT_TRUE(SetupEngine());
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::StreamParams::CreateLegacy(1)));
- int first_send_channel = vie_.GetLastChannel();
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::StreamParams::CreateLegacy(2)));
- int second_send_channel = vie_.GetLastChannel();
- cricket::VideoCodec codec(kVP8Codec720p);
- std::vector<cricket::VideoCodec> codec_list;
- codec_list.push_back(codec);
- EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
-
- EXPECT_TRUE(channel_->AddRecvStream(
- cricket::StreamParams::CreateLegacy(3)));
- int first_receive_channel = vie_.GetLastChannel();
- EXPECT_NE(first_send_channel, first_receive_channel);
- EXPECT_TRUE(channel_->AddRecvStream(
- cricket::StreamParams::CreateLegacy(4)));
- int second_receive_channel = vie_.GetLastChannel();
- EXPECT_NE(first_receive_channel, second_receive_channel);
-
- cricket::VideoMediaInfo info;
- EXPECT_TRUE(channel_->GetStats(&info));
- ASSERT_EQ(1U, info.bw_estimations.size());
- ASSERT_EQ(0, info.bw_estimations[0].actual_enc_bitrate);
- ASSERT_EQ(0, info.bw_estimations[0].transmit_bitrate);
- ASSERT_EQ(0, info.bw_estimations[0].retransmit_bitrate);
- ASSERT_EQ(0, info.bw_estimations[0].available_send_bandwidth);
- ASSERT_EQ(0, info.bw_estimations[0].available_recv_bandwidth);
- ASSERT_EQ(0, info.bw_estimations[0].target_enc_bitrate);
-
- // Start sending and receiving on one of the channels and verify bitrates.
- EXPECT_EQ(0, vie_.StartSend(first_send_channel));
- int send_video_bitrate = 800;
- int send_fec_bitrate = 100;
- int send_nack_bitrate = 20;
- int send_total_bitrate = send_video_bitrate + send_fec_bitrate +
- send_nack_bitrate;
- int send_bandwidth = 1900;
- vie_.SetSendBitrates(first_send_channel, send_video_bitrate, send_fec_bitrate,
- send_nack_bitrate);
- vie_.SetSendBandwidthEstimate(first_send_channel, send_bandwidth);
-
- EXPECT_EQ(0, vie_.StartReceive(first_receive_channel));
- int receive_bandwidth = 600;
- vie_.SetReceiveBandwidthEstimate(first_receive_channel, receive_bandwidth);
-
- info.Clear();
- EXPECT_TRUE(channel_->GetStats(&info));
- ASSERT_EQ(1U, info.bw_estimations.size());
- ASSERT_EQ(send_video_bitrate, info.bw_estimations[0].actual_enc_bitrate);
- ASSERT_EQ(send_total_bitrate, info.bw_estimations[0].transmit_bitrate);
- ASSERT_EQ(send_nack_bitrate, info.bw_estimations[0].retransmit_bitrate);
- ASSERT_EQ(send_bandwidth, info.bw_estimations[0].available_send_bandwidth);
- ASSERT_EQ(receive_bandwidth, info.bw_estimations[0].available_recv_bandwidth);
- ASSERT_EQ(send_video_bitrate, info.bw_estimations[0].target_enc_bitrate);
-
- // Start receiving on the second channel and verify received rate.
- EXPECT_EQ(0, vie_.StartSend(second_send_channel));
- vie_.SetSendBitrates(second_send_channel,
- send_video_bitrate,
- send_fec_bitrate,
- send_nack_bitrate);
- EXPECT_EQ(0, vie_.StartReceive(second_receive_channel));
-
- info.Clear();
- EXPECT_TRUE(channel_->GetStats(&info));
- ASSERT_EQ(1U, info.bw_estimations.size());
- ASSERT_EQ(2 * send_video_bitrate, info.bw_estimations[0].actual_enc_bitrate);
- ASSERT_EQ(2 * send_total_bitrate, info.bw_estimations[0].transmit_bitrate);
- ASSERT_EQ(2 * send_nack_bitrate, info.bw_estimations[0].retransmit_bitrate);
- ASSERT_EQ(send_bandwidth, info.bw_estimations[0].available_send_bandwidth);
- ASSERT_EQ(receive_bandwidth, info.bw_estimations[0].available_recv_bandwidth);
- ASSERT_EQ(2 * send_video_bitrate, info.bw_estimations[0].target_enc_bitrate);
-}
-
-TEST_F(WebRtcVideoEngineTestFake, TestSetAdaptInputToCpuUsage) {
- EXPECT_TRUE(SetupEngine());
- cricket::VideoOptions options_in, options_out;
- bool cpu_adapt = false;
- channel_->SetOptions(options_in);
- EXPECT_TRUE(channel_->GetOptions(&options_out));
- EXPECT_FALSE(options_out.adapt_input_to_cpu_usage.Get(&cpu_adapt));
- // Set adapt input CPU usage option.
- options_in.adapt_input_to_cpu_usage.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options_in));
- EXPECT_TRUE(channel_->GetOptions(&options_out));
- EXPECT_TRUE(options_out.adapt_input_to_cpu_usage.Get(&cpu_adapt));
- EXPECT_TRUE(cpu_adapt);
-}
-
-TEST_F(WebRtcVideoEngineTestFake, TestSetCpuThreshold) {
- EXPECT_TRUE(SetupEngine());
- float low, high;
- cricket::VideoOptions options_in, options_out;
- // Verify that initial values are set.
- EXPECT_TRUE(channel_->GetOptions(&options_out));
- EXPECT_TRUE(options_out.system_low_adaptation_threshhold.Get(&low));
- EXPECT_EQ(low, 0.65f);
- EXPECT_TRUE(options_out.system_high_adaptation_threshhold.Get(&high));
- EXPECT_EQ(high, 0.85f);
- // Set new CPU threshold values.
- options_in.system_low_adaptation_threshhold.Set(0.45f);
- options_in.system_high_adaptation_threshhold.Set(0.95f);
- EXPECT_TRUE(channel_->SetOptions(options_in));
- EXPECT_TRUE(channel_->GetOptions(&options_out));
- EXPECT_TRUE(options_out.system_low_adaptation_threshhold.Get(&low));
- EXPECT_EQ(low, 0.45f);
- EXPECT_TRUE(options_out.system_high_adaptation_threshhold.Get(&high));
- EXPECT_EQ(high, 0.95f);
-}
-
-TEST_F(WebRtcVideoEngineTestFake, TestSetInvalidCpuThreshold) {
- EXPECT_TRUE(SetupEngine());
- float low, high;
- cricket::VideoOptions options_in, options_out;
- // Valid range is [0, 1].
- options_in.system_low_adaptation_threshhold.Set(-1.5f);
- options_in.system_high_adaptation_threshhold.Set(1.5f);
- EXPECT_TRUE(channel_->SetOptions(options_in));
- EXPECT_TRUE(channel_->GetOptions(&options_out));
- EXPECT_TRUE(options_out.system_low_adaptation_threshhold.Get(&low));
- EXPECT_EQ(low, 0.0f);
- EXPECT_TRUE(options_out.system_high_adaptation_threshhold.Get(&high));
- EXPECT_EQ(high, 1.0f);
-}
-
-TEST_F(WebRtcVideoEngineTestFake, ResetCodecOnScreencast) {
- EXPECT_TRUE(SetupEngine());
- cricket::VideoOptions options;
- options.video_noise_reduction.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
-
- // Set send codec.
- cricket::VideoCodec codec(kVP8Codec);
- std::vector<cricket::VideoCodec> codec_list;
- codec_list.push_back(codec);
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::StreamParams::CreateLegacy(123)));
- EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
- EXPECT_TRUE(channel_->SetSend(true));
- EXPECT_EQ(1, vie_.GetNumSetSendCodecs());
-
- webrtc::VideoCodec gcodec;
- memset(&gcodec, 0, sizeof(gcodec));
- int channel_num = vie_.GetLastChannel();
- EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec));
- EXPECT_TRUE(gcodec.codecSpecific.VP8.denoisingOn);
-
- // Send a screencast frame with the same size.
- // Verify that denoising is turned off.
- SendI420ScreencastFrame(kVP8Codec.width, kVP8Codec.height);
- EXPECT_EQ(2, vie_.GetNumSetSendCodecs());
- EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec));
- EXPECT_FALSE(gcodec.codecSpecific.VP8.denoisingOn);
-}
-
-TEST_F(WebRtcVideoEngineTestFake, DontRegisterDecoderIfFactoryIsNotGiven) {
- engine_.SetExternalDecoderFactory(NULL);
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
-
- std::vector<cricket::VideoCodec> codecs;
- codecs.push_back(kVP8Codec);
- EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
-
- EXPECT_EQ(0, vie_.GetNumExternalDecoderRegistered(channel_num));
-}
-
-TEST_F(WebRtcVideoEngineTestFake, RegisterDecoderIfFactoryIsGiven) {
- decoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8);
- engine_.SetExternalDecoderFactory(&decoder_factory_);
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
-
- std::vector<cricket::VideoCodec> codecs;
- codecs.push_back(kVP8Codec);
- EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
-
- EXPECT_TRUE(vie_.ExternalDecoderRegistered(channel_num, 100));
- EXPECT_EQ(1, vie_.GetNumExternalDecoderRegistered(channel_num));
-}
-
-TEST_F(WebRtcVideoEngineTestFake, DontRegisterDecoderMultipleTimes) {
- decoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8);
- engine_.SetExternalDecoderFactory(&decoder_factory_);
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
-
- std::vector<cricket::VideoCodec> codecs;
- codecs.push_back(kVP8Codec);
- EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
-
- EXPECT_TRUE(vie_.ExternalDecoderRegistered(channel_num, 100));
- EXPECT_EQ(1, vie_.GetNumExternalDecoderRegistered(channel_num));
- EXPECT_EQ(1, decoder_factory_.GetNumCreatedDecoders());
-
- EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
- EXPECT_EQ(1, vie_.GetNumExternalDecoderRegistered(channel_num));
- EXPECT_EQ(1, decoder_factory_.GetNumCreatedDecoders());
-}
-
-TEST_F(WebRtcVideoEngineTestFake, DontRegisterDecoderForNonVP8) {
- decoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8);
- engine_.SetExternalDecoderFactory(&decoder_factory_);
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
-
- std::vector<cricket::VideoCodec> codecs;
- codecs.push_back(kRedCodec);
- EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
-
- EXPECT_EQ(0, vie_.GetNumExternalDecoderRegistered(channel_num));
-}
-
-TEST_F(WebRtcVideoEngineTestFake, DontRegisterEncoderIfFactoryIsNotGiven) {
- engine_.SetExternalEncoderFactory(NULL);
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
-
- std::vector<cricket::VideoCodec> codecs;
- codecs.push_back(kVP8Codec);
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-
- EXPECT_EQ(0, vie_.GetNumExternalEncoderRegistered(channel_num));
-}
-
-TEST_F(WebRtcVideoEngineTestFake, RegisterEncoderIfFactoryIsGiven) {
- encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
- encoder_factory_.set_encoders_have_internal_sources(false);
- engine_.SetExternalEncoderFactory(&encoder_factory_);
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
-
- std::vector<cricket::VideoCodec> codecs;
- codecs.push_back(kVP8Codec);
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::StreamParams::CreateLegacy(kSsrc)));
-
- EXPECT_TRUE(vie_.ExternalEncoderRegistered(channel_num, 100));
- EXPECT_FALSE(vie_.ExternalEncoderHasInternalSource(channel_num, 100));
- EXPECT_EQ(1, vie_.GetNumExternalEncoderRegistered(channel_num));
-
- // Remove stream previously added to free the external encoder instance.
- EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
-}
-
-TEST_F(WebRtcVideoEngineTestFake, RegisterEncoderWithInternalSource) {
- encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
- encoder_factory_.set_encoders_have_internal_sources(true);
- engine_.SetExternalEncoderFactory(&encoder_factory_);
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
-
- std::vector<cricket::VideoCodec> codecs;
- codecs.push_back(kVP8Codec);
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-
- EXPECT_TRUE(
- channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
-
- ASSERT_TRUE(vie_.ExternalEncoderRegistered(channel_num, 100));
- EXPECT_TRUE(vie_.ExternalEncoderHasInternalSource(channel_num, 100));
- EXPECT_EQ(1, vie_.GetNumExternalEncoderRegistered(channel_num));
-
- // Remove stream previously added to free the external encoder instance.
- EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
-}
-
-TEST_F(WebRtcVideoEngineTestFake, DontRegisterEncoderMultipleTimes) {
- encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
- engine_.SetExternalEncoderFactory(&encoder_factory_);
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
-
- std::vector<cricket::VideoCodec> codecs;
- codecs.push_back(kVP8Codec);
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::StreamParams::CreateLegacy(kSsrc)));
-
- EXPECT_TRUE(vie_.ExternalEncoderRegistered(channel_num, 100));
- EXPECT_EQ(1, vie_.GetNumExternalEncoderRegistered(channel_num));
-
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
- EXPECT_EQ(1, vie_.GetNumExternalEncoderRegistered(channel_num));
-
- // Remove stream previously added to free the external encoder instance.
- EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
-}
-
-TEST_F(WebRtcVideoEngineTestFake, RegisterEncoderWithMultipleSendStreams) {
- encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
- engine_.SetExternalEncoderFactory(&encoder_factory_);
- EXPECT_TRUE(SetupEngine());
-
- std::vector<cricket::VideoCodec> codecs;
- codecs.push_back(kVP8Codec);
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
- EXPECT_EQ(1, vie_.GetTotalNumExternalEncoderRegistered());
-
- // When we add the first stream (1234), it reuses the default send channel,
- // so it doesn't increase the registration count of external encoders.
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::StreamParams::CreateLegacy(1234)));
- EXPECT_EQ(1, vie_.GetTotalNumExternalEncoderRegistered());
-
- // When we add the second stream (2345), it creates a new channel and
- // increments the registration count.
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::StreamParams::CreateLegacy(2345)));
- EXPECT_EQ(2, vie_.GetTotalNumExternalEncoderRegistered());
-
- // At this moment the total registration count is two, but only one encoder
- // is registered per channel.
- int channel_num = vie_.GetLastChannel();
- EXPECT_EQ(1, vie_.GetNumExternalEncoderRegistered(channel_num));
-
- // Removing send streams decrements the registration count.
- EXPECT_TRUE(channel_->RemoveSendStream(1234));
- EXPECT_EQ(1, vie_.GetTotalNumExternalEncoderRegistered());
-
- // When we remove the last send stream, it also destroys the last send
- // channel and causes the registration count to drop to zero. It is a little
- // weird, but not a bug.
- EXPECT_TRUE(channel_->RemoveSendStream(2345));
- EXPECT_EQ(0, vie_.GetTotalNumExternalEncoderRegistered());
-}
-
-TEST_F(WebRtcVideoEngineTestFake, DontRegisterEncoderForNonVP8) {
- encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecGeneric,
- "GENERIC");
- engine_.SetExternalEncoderFactory(&encoder_factory_);
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
-
- // Note: unlike the SetRecvCodecs, we must set a valid video codec for
- // channel_->SetSendCodecs() to succeed.
- std::vector<cricket::VideoCodec> codecs;
- codecs.push_back(kVP8Codec);
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-
- EXPECT_EQ(0, vie_.GetNumExternalEncoderRegistered(channel_num));
-}
-
-// Test that NACK, PLI and REMB are enabled for external codec.
-TEST_F(WebRtcVideoEngineTestFake, ExternalCodecFeedbackParams) {
- encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecGeneric,
- "GENERIC");
- engine_.SetExternalEncoderFactory(&encoder_factory_);
- EXPECT_TRUE(SetupEngine());
-
- std::vector<cricket::VideoCodec> codecs(engine_.codecs());
- // The external codec will appear at last.
- size_t pos = codecs.size() - 1;
- EXPECT_EQ("GENERIC", codecs[pos].name);
- VerifyCodecFeedbackParams(codecs[pos]);
-}
-
-// Test external codec will be added to the end of the supported codec list.
-TEST_F(WebRtcVideoEngineTestFake, ExternalCodecAddedToTheEnd) {
- encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecGeneric,
- "GENERIC");
- engine_.SetExternalEncoderFactory(&encoder_factory_);
- EXPECT_TRUE(SetupEngine());
-
- std::vector<cricket::VideoCodec> codecs(engine_.codecs());
- EXPECT_EQ("VP8", codecs[0].name);
-
- codecs = engine_.codecs();
- cricket::VideoCodec internal_codec = codecs[0];
- cricket::VideoCodec external_codec = codecs[codecs.size() - 1];
- // The external codec will appear at last.
- EXPECT_EQ("GENERIC", external_codec.name);
- // The internal codec is preferred.
- EXPECT_GE(internal_codec.preference, external_codec.preference);
-}
-
-// Test that external codecs that we support internally are not added as
-// duplicate entries to the codecs list.
-TEST_F(WebRtcVideoEngineTestFake, ExternalCodecIgnored) {
- encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
- engine_.SetExternalEncoderFactory(&encoder_factory_);
- EXPECT_TRUE(SetupEngine());
-
- std::vector<cricket::VideoCodec> internal_codecs(engine_.codecs());
- EXPECT_EQ("VP8", internal_codecs[0].name);
-
- std::vector<cricket::VideoCodec> codecs = engine_.codecs();
- EXPECT_EQ("VP8", codecs[0].name);
- EXPECT_EQ(internal_codecs[0].height, codecs[0].height);
- EXPECT_EQ(internal_codecs[0].width, codecs[0].width);
- // Verify the last codec is not the external codec.
- EXPECT_NE("VP8", codecs[codecs.size() - 1].name);
-}
-
-TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsWithExternalH264) {
- encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
- engine_.SetExternalEncoderFactory(&encoder_factory_);
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
-
- std::vector<cricket::VideoCodec> codecs;
- codecs.push_back(kH264Codec);
- cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0);
- rtx_codec.SetParam("apt", kH264Codec.id);
- codecs.push_back(rtx_codec);
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-
- EXPECT_EQ(vie_.GetRtxSendPayloadTypes(channel_num),
- MAKE_VECTOR(kPayloadTypes1));
-
- cricket::StreamParams params =
- cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
- params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
- EXPECT_TRUE(channel_->AddSendStream(params));
-
- EXPECT_EQ(1, vie_.GetNumSsrcs(channel_num));
- EXPECT_EQ(1, vie_.GetNumRtxSsrcs(channel_num));
- EXPECT_EQ(static_cast<int>(kRtxSsrcs1[0]), vie_.GetRtxSsrc(channel_num, 0));
-
- EXPECT_TRUE(vie_.ExternalEncoderRegistered(channel_num, 127));
- EXPECT_EQ(1, vie_.GetNumExternalEncoderRegistered(channel_num));
- EXPECT_EQ(1, encoder_factory_.GetNumCreatedEncoders());
-
- EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs1[0]));
-}
-
-TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsWithVP8AndExternalH264) {
- encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
- engine_.SetExternalEncoderFactory(&encoder_factory_);
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
-
- std::vector<cricket::VideoCodec> codecs;
- codecs.push_back(kH264Codec);
- cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0);
- rtx_codec.SetParam("apt", kH264Codec.id);
- codecs.push_back(rtx_codec);
- codecs.push_back(kVP8Codec);
- cricket::VideoCodec rtx_codec2(97, "rtx", 0, 0, 0, 0);
- rtx_codec2.SetParam("apt", kVP8Codec.id);
- codecs.push_back(rtx_codec2);
-
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-
- // The first matched codec should be set, i.e., H.264.
- EXPECT_EQ(vie_.GetRtxSendPayloadTypes(channel_num),
- MAKE_VECTOR(kPayloadTypes1));
-
- cricket::StreamParams params =
- cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
- params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
- EXPECT_TRUE(channel_->AddSendStream(params));
-
- EXPECT_EQ(1, vie_.GetNumSsrcs(channel_num));
- EXPECT_EQ(1, vie_.GetNumRtxSsrcs(channel_num));
- EXPECT_EQ(static_cast<int>(kRtxSsrcs1[0]), vie_.GetRtxSsrc(channel_num, 0));
-
- EXPECT_TRUE(vie_.ExternalEncoderRegistered(channel_num, 127));
- EXPECT_EQ(1, vie_.GetNumExternalEncoderRegistered(channel_num));
- EXPECT_EQ(1, encoder_factory_.GetNumCreatedEncoders());
-
- EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs1[0]));
-}
-
-TEST_F(WebRtcVideoEngineTestFake, SetRecvCodecsWithExternalH264) {
- // WebRtcVideoEngine assumes that if we have encode support for a codec, we
- // also have decode support. It doesn't support decode only support. Therefore
- // we here have to register both an encoder and a decoder factory with H264
- // support, to be able to test the decoder factory.
- encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
- decoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecH264);
- EXPECT_TRUE(SetupEngine());
- engine_.SetExternalEncoderFactory(&encoder_factory_);
- engine_.SetExternalDecoderFactory(&decoder_factory_);
- int channel_num = vie_.GetLastChannel();
-
- std::vector<cricket::VideoCodec> codecs;
- codecs.push_back(kH264Codec);
- cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0);
- rtx_codec.SetParam("apt", kH264Codec.id);
- codecs.push_back(rtx_codec);
- EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
-
- EXPECT_EQ(vie_.GetRtxRecvPayloadTypes(channel_num),
- MAKE_VECTOR(kPayloadTypes1));
-
- cricket::StreamParams params =
- cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
- params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
- EXPECT_TRUE(channel_->AddRecvStream(params));
-
- EXPECT_EQ(1, vie_.GetNumSsrcs(channel_num));
- EXPECT_EQ(static_cast<int>(kRtxSsrcs1[0]),
- vie_.GetRemoteRtxSsrc(channel_num));
-
- EXPECT_TRUE(vie_.ExternalDecoderRegistered(channel_num, 127));
- EXPECT_EQ(1, vie_.GetNumExternalDecoderRegistered(channel_num));
- EXPECT_EQ(1, decoder_factory_.GetNumCreatedDecoders());
-
- EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcs1[0]));
-}
-
-TEST_F(WebRtcVideoEngineTestFake, SetRecvCodecsWithVP8AndExternalH264) {
- encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
- decoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecH264);
- EXPECT_TRUE(SetupEngine());
- engine_.SetExternalEncoderFactory(&encoder_factory_);
- engine_.SetExternalDecoderFactory(&decoder_factory_);
- int channel_num = vie_.GetLastChannel();
-
- std::vector<cricket::VideoCodec> codecs;
- cricket::VideoCodec rtx_codec(97, "rtx", 0, 0, 0, 0);
- rtx_codec.SetParam("apt", kH264Codec.id);
- codecs.push_back(kH264Codec);
- codecs.push_back(rtx_codec);
-
- cricket::VideoCodec rtx_codec2(96, "rtx", 0, 0, 0, 0);
- rtx_codec2.SetParam("apt", kVP8Codec.id);
- codecs.push_back(kVP8Codec);
- codecs.push_back(rtx_codec2);
- EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
- EXPECT_EQ(vie_.GetRtxRecvPayloadTypes(channel_num),
- MAKE_VECTOR(kPayloadTypes2));
-
- codecs.pop_back();
- // One RTX codec should be fine.
- EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
-
- // TODO(changbin): The Rtx key can still be found from the Rtx-Apt map
- // if the new codec list doesn't assign it with a new value.
- // Should pass a map to SetRtxRecvPayloadType in future.
- EXPECT_EQ(vie_.GetRtxRecvPayloadTypes(channel_num),
- MAKE_VECTOR(kPayloadTypes2));
-}
-
-// Tests that OnReadyToSend will be propagated into ViE.
-TEST_F(WebRtcVideoEngineTestFake, OnReadyToSend) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
- EXPECT_TRUE(vie_.GetIsTransmitting(channel_num));
-
- channel_->OnReadyToSend(false);
- EXPECT_FALSE(vie_.GetIsTransmitting(channel_num));
-
- channel_->OnReadyToSend(true);
- EXPECT_TRUE(vie_.GetIsTransmitting(channel_num));
-}
-
-#if 0
-TEST_F(WebRtcVideoEngineTestFake, CaptureFrameTimestampToNtpTimestamp) {
- EXPECT_TRUE(SetupEngine());
- int capture_id = vie_.GetCaptureId(vie_.GetLastChannel());
-
- // Set send codec.
- cricket::VideoCodec codec(kVP8Codec);
- std::vector<cricket::VideoCodec> codec_list;
- codec_list.push_back(codec);
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::StreamParams::CreateLegacy(123)));
- EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
- EXPECT_TRUE(channel_->SetSend(true));
-
- int64 timestamp = time(NULL) * rtc::kNumNanosecsPerSec;
- SendI420ScreencastFrameWithTimestamp(
- kVP8Codec.width, kVP8Codec.height, timestamp);
- EXPECT_EQ(rtc::UnixTimestampNanosecsToNtpMillisecs(timestamp),
- vie_.GetCaptureLastTimestamp(capture_id));
-
- SendI420ScreencastFrameWithTimestamp(kVP8Codec.width, kVP8Codec.height, 0);
- EXPECT_EQ(0, vie_.GetCaptureLastTimestamp(capture_id));
-}
-#endif
-
-/////////////////////////
-// Tests with real ViE //
-/////////////////////////
-
-// Tests that we can find codecs by name or id.
-TEST_F(WebRtcVideoEngineTest, FindCodec) {
- // We should not need to init engine in order to get codecs.
- const std::vector<cricket::VideoCodec>& c = engine_.codecs();
- EXPECT_EQ(cricket::DefaultVideoCodecList().size(), c.size());
-
- cricket::VideoCodec vp8(104, "VP8", 320, 200, 30, 0);
- EXPECT_TRUE(engine_.FindCodec(vp8));
-
- cricket::VideoCodec vp8_ci(104, "vp8", 320, 200, 30, 0);
- EXPECT_TRUE(engine_.FindCodec(vp8));
-
- cricket::VideoCodec vp8_diff_fr_diff_pref(104, "VP8", 320, 200, 50, 50);
- EXPECT_TRUE(engine_.FindCodec(vp8_diff_fr_diff_pref));
-
- cricket::VideoCodec vp8_diff_id(95, "VP8", 320, 200, 30, 0);
- EXPECT_FALSE(engine_.FindCodec(vp8_diff_id));
- vp8_diff_id.id = 97;
- EXPECT_TRUE(engine_.FindCodec(vp8_diff_id));
-
- cricket::VideoCodec vp8_diff_res(104, "VP8", 320, 111, 30, 0);
- // FindCodec ignores the codec size.
- // Test that FindCodec can accept uncommon codec size.
- EXPECT_TRUE(engine_.FindCodec(vp8_diff_res));
-
- // PeerConnection doesn't negotiate the resolution at this point.
- // Test that FindCodec can handle the case when width/height is 0.
- cricket::VideoCodec vp8_zero_res(104, "VP8", 0, 0, 30, 0);
- EXPECT_TRUE(engine_.FindCodec(vp8_zero_res));
-
- cricket::VideoCodec red(101, "RED", 0, 0, 30, 0);
- EXPECT_TRUE(engine_.FindCodec(red));
-
- cricket::VideoCodec red_ci(101, "red", 0, 0, 30, 0);
- EXPECT_TRUE(engine_.FindCodec(red));
-
- cricket::VideoCodec fec(102, "ULPFEC", 0, 0, 30, 0);
- EXPECT_TRUE(engine_.FindCodec(fec));
-
- cricket::VideoCodec fec_ci(102, "ulpfec", 0, 0, 30, 0);
- EXPECT_TRUE(engine_.FindCodec(fec));
-
- cricket::VideoCodec rtx(96, "rtx", 0, 0, 30, 0);
- rtx.SetParam("apt", kVP8Codec.id);
- EXPECT_TRUE(engine_.FindCodec(rtx));
-}
-
-TEST_F(WebRtcVideoEngineTest, RtxCodecHasAptSet) {
- std::vector<cricket::VideoCodec>::const_iterator it;
- bool apt_checked = false;
- for (it = engine_.codecs().begin(); it != engine_.codecs().end(); ++it) {
- if (_stricmp(cricket::kRtxCodecName, it->name.c_str()) || it->id != 96) {
- continue;
- }
- int apt;
- EXPECT_TRUE(it->GetParam("apt", &apt));
- EXPECT_EQ(100, apt);
- apt_checked = true;
- }
- EXPECT_TRUE(apt_checked);
-}
-
-TEST_F(WebRtcVideoEngineTest, StartupShutdown) {
- EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
- engine_.Terminate();
-}
-
-TEST_PRE_VIDEOENGINE_INIT(WebRtcVideoEngineTest, ConstrainNewCodec2)
-TEST_POST_VIDEOENGINE_INIT(WebRtcVideoEngineTest, ConstrainNewCodec2)
-
-// TODO(juberti): Figure out why ViE is munging the COM refcount.
-#ifdef WIN32
-TEST_F(WebRtcVideoEngineTest, DISABLED_CheckCoInitialize) {
- Base::CheckCoInitialize();
-}
-#endif
-
-TEST_F(WebRtcVideoEngineTest, CreateChannel) {
- EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
- cricket::VideoMediaChannel* channel =
- engine_.CreateChannel(cricket::VideoOptions(), NULL);
- EXPECT_TRUE(channel != NULL);
- delete channel;
-}
-
-TEST_F(WebRtcVideoMediaChannelTest, SetRecvCodecs) {
- std::vector<cricket::VideoCodec> codecs;
- codecs.push_back(kVP8Codec);
- EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
-}
-TEST_F(WebRtcVideoMediaChannelTest, SetRecvCodecsWrongPayloadType) {
- std::vector<cricket::VideoCodec> codecs;
- codecs.push_back(kVP8Codec);
- codecs[0].id = 99;
- EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
-}
-TEST_F(WebRtcVideoMediaChannelTest, SetRecvCodecsUnsupportedCodec) {
- std::vector<cricket::VideoCodec> codecs;
- codecs.push_back(kVP8Codec);
- codecs.push_back(cricket::VideoCodec(101, "VP1", 640, 400, 30, 0));
- EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
-}
-
-TEST_F(WebRtcVideoMediaChannelTest, GetRtpSendTimeExtension) {
- // Enable RTP timestamp extension.
- const int id = 12;
- std::vector<cricket::RtpHeaderExtension> extensions;
- extensions.push_back(cricket::RtpHeaderExtension(
- "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time", id));
-
- // Verify the send extension id.
- EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
- EXPECT_EQ(id, channel_->GetRtpSendTimeExtnId());
-}
-
-TEST_F(WebRtcVideoMediaChannelTest, SetSend) {
- Base::SetSend();
-}
-TEST_F(WebRtcVideoMediaChannelTest, SetSendWithoutCodecs) {
- Base::SetSendWithoutCodecs();
-}
-TEST_F(WebRtcVideoMediaChannelTest, SetSendSetsTransportBufferSizes) {
- Base::SetSendSetsTransportBufferSizes();
-}
-
-TEST_F(WebRtcVideoMediaChannelTest, SendAndReceiveVp8Vga) {
- SendAndReceive(cricket::VideoCodec(100, "VP8", 640, 400, 30, 0));
-}
-TEST_F(WebRtcVideoMediaChannelTest, SendAndReceiveVp8Qvga) {
- SendAndReceive(cricket::VideoCodec(100, "VP8", 320, 200, 30, 0));
-}
-TEST_F(WebRtcVideoMediaChannelTest, SendAndReceiveVp8Qqvga) {
- SendAndReceive(cricket::VideoCodec(100, "VP8", 160, 100, 30, 0));
-}
-TEST_F(WebRtcVideoMediaChannelTest, SendManyResizeOnce) {
- SendManyResizeOnce();
-}
-
-TEST_F(WebRtcVideoMediaChannelTest, DISABLED_SendVp8HdAndReceiveAdaptedVp8Vga) {
- EXPECT_TRUE(channel_->SetCapturer(kSsrc, NULL));
- channel_->UpdateAspectRatio(1280, 720);
- video_capturer_.reset(new cricket::FakeVideoCapturer);
- const std::vector<cricket::VideoFormat>* formats =
- video_capturer_->GetSupportedFormats();
- cricket::VideoFormat capture_format_hd = (*formats)[0];
- EXPECT_EQ(cricket::CS_RUNNING, video_capturer_->Start(capture_format_hd));
- EXPECT_TRUE(channel_->SetCapturer(kSsrc, video_capturer_.get()));
-
- // Capture format HD -> adapt (OnOutputFormatRequest VGA) -> VGA.
- cricket::VideoCodec codec(100, "VP8", 1280, 720, 30, 0);
- EXPECT_TRUE(SetOneCodec(codec));
- codec.width /= 2;
- codec.height /= 2;
- EXPECT_TRUE(SetSend(true));
- EXPECT_TRUE(channel_->SetRender(true));
- EXPECT_EQ(0, renderer_.num_rendered_frames());
- EXPECT_TRUE(SendFrame());
- EXPECT_FRAME_WAIT(1, codec.width, codec.height, kTimeout);
-}
-
-TEST_F(WebRtcVideoMediaChannelTest, GetStats) {
- Base::GetStats();
-}
-
-TEST_F(WebRtcVideoMediaChannelTest, GetStatsMultipleRecvStreams) {
- Base::GetStatsMultipleRecvStreams();
-}
-
-TEST_F(WebRtcVideoMediaChannelTest, GetStatsMultipleSendStreams) {
- Base::GetStatsMultipleSendStreams();
-}
-
-TEST_F(WebRtcVideoMediaChannelTest, SetSendBandwidth) {
- Base::SetSendBandwidth();
-}
-TEST_F(WebRtcVideoMediaChannelTest, SetSendSsrc) {
- Base::SetSendSsrc();
-}
-TEST_F(WebRtcVideoMediaChannelTest, SetSendSsrcAfterSetCodecs) {
- Base::SetSendSsrcAfterSetCodecs();
-}
-
-TEST_F(WebRtcVideoMediaChannelTest, SetRenderer) {
- Base::SetRenderer();
-}
-
-TEST_F(WebRtcVideoMediaChannelTest, AddRemoveRecvStreams) {
- Base::AddRemoveRecvStreams();
-}
-
-// Flaky on Linux and Windows. See webrtc:4452.
-#if defined(WEBRTC_WIN) || defined(WEBRTC_LINUX)
-#define MAYBE_AddRemoveRecvStreamAndRender DISABLED_AddRemoveRecvStreamAndRender
-#else
-#define MAYBE_AddRemoveRecvStreamAndRender AddRemoveRecvStreamAndRender
-#endif
-TEST_F(WebRtcVideoMediaChannelTest, MAYBE_AddRemoveRecvStreamAndRender) {
- Base::AddRemoveRecvStreamAndRender();
-}
-
-TEST_F(WebRtcVideoMediaChannelTest, AddRemoveRecvStreamsNoConference) {
- Base::AddRemoveRecvStreamsNoConference();
-}
-
-TEST_F(WebRtcVideoMediaChannelTest, AddRemoveSendStreams) {
- Base::AddRemoveSendStreams();
-}
-
-TEST_F(WebRtcVideoMediaChannelTest, SimulateConference) {
- Base::SimulateConference();
-}
-
-TEST_F(WebRtcVideoMediaChannelTest, AddRemoveCapturer) {
- Base::AddRemoveCapturer();
-}
-
-TEST_F(WebRtcVideoMediaChannelTest, RemoveCapturerWithoutAdd) {
- Base::RemoveCapturerWithoutAdd();
-}
-
-TEST_F(WebRtcVideoMediaChannelTest, AddRemoveCapturerMultipleSources) {
- Base::AddRemoveCapturerMultipleSources();
-}
-
-// This test verifies DSCP settings are properly applied on video media channel.
-TEST_F(WebRtcVideoMediaChannelTest, TestSetDscpOptions) {
- rtc::scoped_ptr<cricket::FakeNetworkInterface> network_interface(
- new cricket::FakeNetworkInterface);
- channel_->SetInterface(network_interface.get());
- cricket::VideoOptions options;
- options.dscp.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
- EXPECT_EQ(rtc::DSCP_AF41, network_interface->dscp());
- // Verify previous value is not modified if dscp option is not set.
- cricket::VideoOptions options1;
- EXPECT_TRUE(channel_->SetOptions(options1));
- EXPECT_EQ(rtc::DSCP_AF41, network_interface->dscp());
- options.dscp.Set(false);
- EXPECT_TRUE(channel_->SetOptions(options));
- EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
- channel_->SetInterface(NULL);
-}
-
-TEST_F(WebRtcVideoMediaChannelTest, HighAspectHighHeightCapturer) {
- Base::HighAspectHighHeightCapturer();
-}
-
-TEST_F(WebRtcVideoMediaChannelTest, SetOptionsSucceedsWhenSending) {
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
-
- // Verify SetOptions returns true on a different options.
- cricket::VideoOptions options2;
- options2.adapt_input_to_cpu_usage.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options2));
-
- // Set send codecs on the channel and start sending.
- std::vector<cricket::VideoCodec> codecs;
- codecs.push_back(kVP8Codec);
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
- EXPECT_TRUE(channel_->SetSend(true));
-
- // Verify SetOptions returns true if channel is already sending.
- cricket::VideoOptions options3;
- options3.conference_mode.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options3));
-}
-
-// Tests empty StreamParams is rejected.
-TEST_F(WebRtcVideoMediaChannelTest, RejectEmptyStreamParams) {
- Base::RejectEmptyStreamParams();
-}
-
-TEST_F(WebRtcVideoMediaChannelTest, AdaptResolution16x10) {
- Base::AdaptResolution16x10();
-}
-
-TEST_F(WebRtcVideoMediaChannelTest, AdaptResolution4x3) {
- Base::AdaptResolution4x3();
-}
-
-TEST_F(WebRtcVideoMediaChannelTest, MuteStream) {
- Base::MuteStream();
-}
-
-TEST_F(WebRtcVideoMediaChannelTest, MultipleSendStreams) {
- Base::MultipleSendStreams();
-}
-
-// TODO(juberti): Restore this test once we support sending 0 fps.
-TEST_F(WebRtcVideoMediaChannelTest, DISABLED_AdaptDropAllFrames) {
- Base::AdaptDropAllFrames();
-}
-// TODO(juberti): Understand why we get decode errors on this test.
-TEST_F(WebRtcVideoMediaChannelTest, DISABLED_AdaptFramerate) {
- Base::AdaptFramerate();
-}
-
-TEST_F(WebRtcVideoMediaChannelTest, SetSendStreamFormat0x0) {
- Base::SetSendStreamFormat0x0();
-}
-
-// TODO(zhurunz): Fix the flakey test.
-TEST_F(WebRtcVideoMediaChannelTest, DISABLED_SetSendStreamFormat) {
- Base::SetSendStreamFormat();
-}
-
-TEST_F(WebRtcVideoMediaChannelTest, TwoStreamsSendAndReceive) {
- Base::TwoStreamsSendAndReceive(cricket::VideoCodec(100, "VP8", 640, 400, 30,
- 0));
-}
-
-TEST_F(WebRtcVideoMediaChannelTest, TwoStreamsReUseFirstStream) {
- Base::TwoStreamsReUseFirstStream(cricket::VideoCodec(100, "VP8", 640, 400, 30,
- 0));
-}
-
-TEST_F(WebRtcVideoMediaChannelTest, DISABLED_TwoStreamsSendAndUnsignalledRecv) {
- Base::TwoStreamsSendAndUnsignalledRecv(cricket::VideoCodec(100, "VP8", 640,
- 400, 30, 0));
-}
-
-TEST_F(WebRtcVideoMediaChannelTest,
- TwoStreamsSendAndFailUnsignalledRecv) {
- Base::TwoStreamsSendAndFailUnsignalledRecv(
- cricket::VideoCodec(100, "VP8", 640, 400, 30, 0));
-}
-
-TEST_F(WebRtcVideoMediaChannelTest,
- TwoStreamsSendAndFailUnsignalledRecvInOneToOne) {
- Base::TwoStreamsSendAndFailUnsignalledRecvInOneToOne(
- cricket::VideoCodec(100, "VP8", 640, 400, 30, 0));
-}
-
-TEST_F(WebRtcVideoMediaChannelTest,
- TwoStreamsAddAndRemoveUnsignalledRecv) {
- Base::TwoStreamsAddAndRemoveUnsignalledRecv(cricket::VideoCodec(100, "VP8",
- 640, 400, 30,
- 0));
-}
-
-// Test that sequence number are not reset if stopping and then
-// resuming a stream.
-TEST_F(WebRtcVideoMediaChannelTest, DontResetSequenceNumbers) {
- cricket::VideoCodec codec = DefaultCodec();
- EXPECT_TRUE(SetOneCodec(codec));
-
- uint16_t seq_before =
- engine_.vie()
- ->rtp()
- ->GetRtpStateForSsrc(channel_->GetDefaultChannelId(), kSsrc)
- .sequence_number;
-
- // Deactive.
- EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
- EXPECT_TRUE(SetOneCodec(codec));
-
- // Reactivate.
- EXPECT_TRUE(channel_->AddSendStream(DefaultSendStreamParams()));
- EXPECT_TRUE(SetOneCodec(codec));
-
- // Sequence number should now have changed.
- uint16_t seq_after =
- engine_.vie()
- ->rtp()
- ->GetRtpStateForSsrc(channel_->GetDefaultChannelId(), kSsrc)
- .sequence_number;
-
- EXPECT_EQ(seq_before, seq_after);
-}
-
-static const unsigned int kNumberOfTemporalLayers = 1;
-static const unsigned int kSimulcastNumberOfTemporalLayers = 3;
-static const unsigned int kSimStream0Bitrate = 100;
-static const unsigned int kSimStream0MaxBitrateBoosted = 200;
-static const unsigned int kSimStream0MaxBitrateXd = 200;
-static const unsigned int kSimStream0TargetBitrateBoosted = 150;
-static const unsigned int kSimStream0TargetBitrateXd = 150;
-static const unsigned int kSimStream1Bitrate = 350;
-static const unsigned int kSimStream1MaxBitrateBoosted = 450;
-static const unsigned int kSimStream1MaxBitrateXd = 450;
-static const unsigned int kSimStream1TargetBitrateBoosted = 350;
-static const unsigned int kSimStream1TargetBitrateXd = 350;
-static const unsigned int kSimStream2Bitrate = 500;
-static const unsigned int kSimStream2MaxBitrateBoosted = 700;
-static const unsigned int kSimStream2MaxBitrateXd = 700;
-static const unsigned int kSimStream2TargetBitrateBoosted = 500;
-static const unsigned int kSimStream2TargetBitrateXd = 500;
-static const unsigned int kSimStream3Bitrate = 900;
-static const unsigned int kSimStream3MaxBitrateBoosted = 900;
-static const unsigned int kSimStream3MaxBitrateXd = 900;
-static const unsigned int kSimStream3TargetBitrateBoosted = 900;
-static const unsigned int kSimStream3TargetBitrateXd = 900;
-static const unsigned int kSimStream4Bitrate = 1200;
-static const unsigned int kSimStream4MaxBitrateBoosted = 1200;
-static const unsigned int kSimStream4MaxBitrateXd = 2500;
-static const unsigned int kSimStream4TargetBitrateBoosted = 1200;
-static const unsigned int kSimStream4TargetBitrateXd = 2500;
-
-struct SimulcastFormat {
- unsigned int width;
- unsigned int height;
- unsigned int max_layers;
- unsigned int max_bitrate[cricket::SBM_COUNT];
- unsigned int target_bitrate[cricket::SBM_COUNT];
-};
-
-static const SimulcastFormat kSimulcastFormats[] = {
- {1280, 720, 3,
- {kSimStream4Bitrate, kSimStream4MaxBitrateBoosted,
- kSimStream4MaxBitrateXd},
- {kSimStream4Bitrate, kSimStream4TargetBitrateBoosted,
- kSimStream4TargetBitrateXd}},
- {960, 540, 3,
- {kSimStream3Bitrate, kSimStream3MaxBitrateBoosted,
- kSimStream3MaxBitrateXd},
- {kSimStream3Bitrate, kSimStream3TargetBitrateBoosted,
- kSimStream3TargetBitrateXd}},
- {640, 360, 2,
- {kSimStream2Bitrate, kSimStream2MaxBitrateBoosted,
- kSimStream2MaxBitrateXd},
- {kSimStream2Bitrate, kSimStream2TargetBitrateBoosted,
- kSimStream2TargetBitrateXd}},
- {480, 270, 2,
- {kSimStream1Bitrate, kSimStream1MaxBitrateBoosted,
- kSimStream1MaxBitrateXd},
- {kSimStream1Bitrate, kSimStream1TargetBitrateBoosted,
- kSimStream1TargetBitrateXd}},
- {320, 180, 1,
- {kSimStream0Bitrate, kSimStream0MaxBitrateBoosted,
- kSimStream0MaxBitrateXd},
- {kSimStream0Bitrate, kSimStream0TargetBitrateBoosted,
- kSimStream0TargetBitrateXd}},
- {0, 0, 1,
- {kSimStream0Bitrate, kSimStream0MaxBitrateBoosted,
- kSimStream0MaxBitrateXd},
- {kSimStream0Bitrate, kSimStream0TargetBitrateBoosted,
- kSimStream0TargetBitrateXd}}
-};
-
-// Test fixture to test WebRtcVideoEngine with a fake webrtc::VideoEngine.
-// Useful for testing failure paths.
-class WebRtcVideoEngineSimulcastTestFake : public testing::Test,
- public sigslot::has_slots<> {
- public:
- WebRtcVideoEngineSimulcastTestFake()
- : vie_(kVideoCodecs, ARRAY_SIZE(kVideoCodecs)),
- cpu_monitor_(new rtc::FakeCpuMonitor(
- rtc::Thread::Current())),
- engine_(NULL, // cricket::WebRtcVoiceEngineExtended
- new FakeViEWrapper(&vie_), cpu_monitor_),
- channel_(NULL),
- voice_channel_(NULL),
- last_error_(cricket::VideoMediaChannel::ERROR_NONE) {
- }
- bool SetupEngine() {
- bool result = engine_.Init(rtc::Thread::Current());
- if (result) {
- channel_ = engine_.CreateChannel(cricket::VideoOptions(), voice_channel_);
- channel_->SignalMediaError.connect(this,
- &WebRtcVideoEngineSimulcastTestFake::OnMediaError);
- result = (channel_ != NULL);
- }
- return result;
- }
- void OnMediaError(uint32 ssrc, cricket::VideoMediaChannel::Error error) {
- last_error_ = error;
- }
- bool SendI420Frame(int width, int height) {
- cricket::FakeVideoCapturer capturer;
- return SendI420Frame(&capturer, width, height);
- }
-
- bool SendI420Frame(
- cricket::FakeVideoCapturer* capturer, int width, int height) {
- if (NULL == channel_) {
- return false;
- }
- cricket::WebRtcVideoFrame frame;
- if (!frame.InitToBlack(width, height, 1, 1, 0, 0)) {
- return false;
- }
- channel_->SendFrame(capturer, &frame);
- return true;
- }
- bool SendI420ScreencastFrame(int width, int height) {
- return SendI420ScreencastFrameWithTimestamp(width, height, 0);
- }
- bool SendI420ScreencastFrameWithTimestamp(
- int width, int height, int64 timestamp) {
- if (NULL == channel_) {
- return false;
- }
- cricket::WebRtcVideoFrame frame;
- if (!frame.InitToBlack(width, height, 1, 1, 0, 0)) {
- return false;
- }
- cricket::FakeVideoCapturer capturer;
- capturer.SetScreencast(true);
- channel_->SendFrame(&capturer, &frame);
- return true;
- }
- void VerifyVP8SendCodec(
- int channel_num,
- unsigned int width,
- unsigned int height,
- unsigned int layers = 0,
- unsigned int max_bitrate = kMaxBandwidthKbps,
- unsigned int min_bitrate = kMinBandwidthKbps,
- unsigned int start_bitrate = kStartBandwidthKbps,
- unsigned int fps = 30,
- unsigned int max_quantization = 0,
- cricket::SimulcastBitrateMode bitrate_mode = cricket::SBM_NORMAL) {
- webrtc::VideoCodec gcodec;
- EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec));
-
- // Video codec properties.
- EXPECT_EQ(webrtc::kVideoCodecVP8, gcodec.codecType);
- EXPECT_STREQ("VP8", gcodec.plName);
- EXPECT_EQ(100, gcodec.plType);
- EXPECT_EQ(width, gcodec.width);
- EXPECT_EQ(height, gcodec.height);
- EXPECT_EQ(std::min(start_bitrate, max_bitrate), gcodec.startBitrate);
- EXPECT_EQ(max_bitrate, gcodec.maxBitrate);
- EXPECT_EQ(min_bitrate, gcodec.minBitrate);
- EXPECT_EQ(fps, gcodec.maxFramerate);
- // VP8 specific.
- EXPECT_FALSE(gcodec.codecSpecific.VP8.pictureLossIndicationOn);
- EXPECT_FALSE(gcodec.codecSpecific.VP8.feedbackModeOn);
- EXPECT_EQ(webrtc::kComplexityNormal, gcodec.codecSpecific.VP8.complexity);
- EXPECT_EQ(webrtc::kResilienceOff, gcodec.codecSpecific.VP8.resilience);
- EXPECT_EQ(max_quantization, gcodec.qpMax);
- // Simulcast.
- EXPECT_EQ(layers, gcodec.numberOfSimulcastStreams);
- if (layers > 0) {
- EXPECT_EQ(kSimulcastNumberOfTemporalLayers,
- gcodec.codecSpecific.VP8.numberOfTemporalLayers);
- } else {
- EXPECT_EQ(kNumberOfTemporalLayers,
- gcodec.codecSpecific.VP8.numberOfTemporalLayers);
- }
- for (int i = 0; i < static_cast<int>(layers) - 1; ++i) {
- EXPECT_EQ(gcodec.width / (0x01 << (layers - 1 - i)),
- gcodec.simulcastStream[i].width);
- EXPECT_EQ(gcodec.height / (0x01 << (layers - 1 - i)),
- gcodec.simulcastStream[i].height);
- EXPECT_EQ(kSimulcastNumberOfTemporalLayers,
- gcodec.simulcastStream[i].numberOfTemporalLayers);
- EXPECT_EQ(FindSimulcastMaxBitrate(gcodec.simulcastStream[i].width,
- gcodec.simulcastStream[i].height,
- bitrate_mode),
- gcodec.simulcastStream[i].maxBitrate);
- EXPECT_EQ(gcodec.qpMax,
- gcodec.simulcastStream[i].qpMax);
- }
- if (layers > 0)
- EXPECT_EQ(kMinBandwidthKbps, gcodec.simulcastStream[0].minBitrate);
- }
- unsigned int FindSimulcastMaxBitrate(
- unsigned int width,
- unsigned int height,
- cricket::SimulcastBitrateMode bitrate_mode) {
- for (size_t i = 0; i < ARRAY_SIZE(kSimulcastFormats); ++i) {
- if (width >= kSimulcastFormats[i].width &&
- height >= kSimulcastFormats[i].height) {
- return kSimulcastFormats[i].max_bitrate[bitrate_mode];
- }
- }
- return 0;
- }
- void SetUp2SimulcastStreams(
- cricket::VideoOptions::HighestBitrate high_bitrate_mode,
- const cricket::VideoCodec& codec) {
- EXPECT_TRUE(SetupEngine());
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- options.video_highest_bitrate.Set(high_bitrate_mode);
- EXPECT_TRUE(channel_->SetOptions(options));
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs2))));
- std::vector<cricket::VideoCodec> codec_list;
- codec_list.push_back(codec);
- SendI420Frame(kVP8Codec.width, kVP8Codec.height);
- EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
- }
- void SetUp3SimulcastStreams(
- cricket::VideoOptions::HighestBitrate high_bitrate_mode,
- const cricket::VideoCodec& codec) {
- EXPECT_TRUE(SetupEngine());
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- options.video_highest_bitrate.Set(high_bitrate_mode);
- EXPECT_TRUE(channel_->SetOptions(options));
-
- // Set max settings of 1280x720x30 to make sure we can have maximumly 3
- // simulcast streams.
- EXPECT_TRUE(engine_.SetDefaultEncoderConfig(
- cricket::VideoEncoderConfig(kVP8Codec720p)));
-
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs3))));
- std::vector<cricket::VideoCodec> codec_list;
- codec_list.push_back(codec);
- SendI420Frame(kVP8Codec720p.width, kVP8Codec720p.height);
- EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
- }
- void TestSimulcastAdapter(const cricket::VideoCodec& send_codec,
- bool expect_use_adapter) {
- // Setup
- engine_.SetExternalEncoderFactory(&encoder_factory_);
- EXPECT_TRUE(SetupEngine());
- std::vector<cricket::VideoCodec> codecs;
- codecs.push_back(send_codec);
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::StreamParams::CreateLegacy(kSsrc)));
-
- // Verify
- int channel_num = vie_.GetLastChannel();
- EXPECT_EQ(1, vie_.GetNumExternalEncoderRegistered(channel_num));
- // If simulcast adapter is used, no external encoder instance will be
- // created at this point. Otherwise 1 instance should have been created.
- int num_enc_instance = expect_use_adapter ? 0 : 1;
- EXPECT_EQ(num_enc_instance, encoder_factory_.GetNumCreatedEncoders());
-
- // Clean up
- EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
- }
- virtual void TearDown() {
- delete channel_;
- engine_.Terminate();
- }
-
- protected:
- cricket::FakeWebRtcVideoEngine vie_;
- cricket::FakeWebRtcVideoDecoderFactory decoder_factory_;
- cricket::FakeWebRtcVideoEncoderFactory encoder_factory_;
- rtc::FakeCpuMonitor* cpu_monitor_;
- cricket::WebRtcVideoEngine engine_;
- cricket::WebRtcVideoMediaChannel* channel_;
- cricket::WebRtcVoiceMediaChannel* voice_channel_;
- cricket::VideoMediaChannel::Error last_error_;
-};
-
-// Test fixtures to test WebRtcVideoEngine with a real
-// webrtc::VideoEngine.
-class WebRtcVideoEngineSimulcastTest
- : public VideoEngineTest<cricket::WebRtcVideoEngine> {
- protected:
- typedef VideoEngineTest<cricket::WebRtcVideoEngine> Base;
-};
-class WebRtcVideoMediaChannelSimulcastTest
- : public VideoMediaChannelTest<
- cricket::WebRtcVideoEngine, cricket::WebRtcVideoMediaChannel> {
- protected:
- typedef VideoMediaChannelTest<cricket::WebRtcVideoEngine,
- cricket::WebRtcVideoMediaChannel> Base;
- virtual cricket::VideoCodec DefaultCodec() { return kVP8Codec; }
- virtual void SetUp() {
- Base::SetUp();
- }
- virtual void TearDown() {
- Base::TearDown();
- }
- // Tests that simulcast sends rtp packets containing expected number of
- // layers and payload type.
- void SimulcastSend(const cricket::VideoCodec& codec,
- const std::vector<uint32>& ssrcs) {
- // Remove stream added in Setup.
- EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
-
- // Setup channel for sending and receiving simulcast packets.
- cricket::VideoOptions vmo;
- vmo.conference_mode.Set(true);
- EXPECT_TRUE(channel_->SetOptions(vmo));
- EXPECT_TRUE(SetOneCodec(codec));
- if (ssrcs.size() > 1) {
- cricket::StreamParams sp;
- cricket::SsrcGroup sg(cricket::kSimSsrcGroupSemantics, ssrcs);
- sp.ssrcs = ssrcs;
- sp.ssrc_groups.push_back(sg);
- sp.cname = "cname";
- EXPECT_TRUE(channel_->AddSendStream(sp));
- } else {
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::StreamParams::CreateLegacy(ssrcs[0])));
- }
-
- // Re-configure capturer.
- channel_->SetCapturer(kSsrc, NULL);
- cricket::VideoFormat capture_format(codec.width, codec.height,
- cricket::VideoFormat::FpsToInterval(codec.framerate),
- cricket::FOURCC_I420);
- EXPECT_TRUE(channel_->SetCapturer(ssrcs[0], video_capturer_.get()));
- EXPECT_EQ(cricket::CS_RUNNING, video_capturer_->Start(capture_format));
-
- EXPECT_TRUE(SetSend(true));
-
- // Send one frame.
- EXPECT_EQ(0, NumRtpPackets());
- EXPECT_EQ(0, NumRtpBytes());
- EXPECT_EQ(0, NumSentSsrcs());
- EXPECT_TRUE(SendFrame());
-
- // Verify received expected simulcast layers.
- EXPECT_TRUE_WAIT(NumSentSsrcs() == static_cast<int>(ssrcs.size()),
- 10 * kTimeout);
-
- // Stop sending before counting the packets, as padding will keep being sent
- // which can cause a difference between total number of packets and the
- // sum of packets on each ssrc if padding is sent in the summation loop.
- EXPECT_TRUE(SetSend(false));
-
- int total_num_packets = 0;
- int total_num_bytes = 0;
- for (size_t i = 0; i < ssrcs.size(); ++i) {
- EXPECT_GE(NumRtpPackets(ssrcs[i]), 1);
- EXPECT_GT(NumRtpBytes(ssrcs[i]), NumRtpPackets(ssrcs[i]));
- total_num_packets += NumRtpPackets(ssrcs[i]);
- total_num_bytes += NumRtpBytes(ssrcs[i]);
- }
- EXPECT_EQ(total_num_packets, NumRtpPackets());
- EXPECT_EQ(total_num_bytes, NumRtpBytes());
-
- // All packets have the given payload type.
- for (int i = 0; i < total_num_packets; ++i) {
- rtc::scoped_ptr<const rtc::Buffer> p(GetRtpPacket(i));
- EXPECT_EQ(codec.id, GetPayloadType(p.get()));
- }
- }
- void TestScreencastSettings() {
- // Remove stream added in SetUp.
- EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
-
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- // Enable noise reduction to ensure that it's being disabled for
- // screencasting.
- options.video_noise_reduction.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
-
- // Setup a simulcast stream and verify that we have the correct
- // settings.
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs2))));
- cricket::VideoCodec codec(DefaultCodec());
- EXPECT_TRUE(SetOneCodec(codec));
-
- channel_->SetCapturer(kSsrc, NULL);
- cricket::VideoFormat capture_format(codec.width, codec.height,
- cricket::VideoFormat::FpsToInterval(codec.framerate),
- cricket::FOURCC_I420);
- EXPECT_TRUE(channel_->SetCapturer(kSsrcs2[0], video_capturer_.get()));
- EXPECT_EQ(cricket::CS_RUNNING, video_capturer_->Start(capture_format));
-
- EXPECT_TRUE(SetSend(true));
- EXPECT_TRUE(SendFrame());
- webrtc::VideoCodec video_codec;
- int default_channel_id = channel_->GetDefaultChannelId();
- EXPECT_EQ(0, channel_->engine()->vie()->codec()->GetSendCodec(
- default_channel_id, video_codec));
- EXPECT_FALSE(video_codec.codecSpecific.VP8.automaticResizeOn);
- EXPECT_TRUE(video_codec.codecSpecific.VP8.denoisingOn);
- EXPECT_EQ(webrtc::kRealtimeVideo, video_codec.mode);
- EXPECT_EQ(3, video_codec.codecSpecific.VP8.numberOfTemporalLayers);
- EXPECT_EQ(2, video_codec.numberOfSimulcastStreams);
- EXPECT_NE(0u, video_codec.simulcastStream[0].minBitrate);
- EXPECT_NE(0u, video_codec.simulcastStream[0].targetBitrate);
- EXPECT_NE(0u, video_codec.simulcastStream[0].maxBitrate);
- EXPECT_NE(0u, video_codec.simulcastStream[1].minBitrate);
- EXPECT_NE(0u, video_codec.simulcastStream[1].targetBitrate);
- EXPECT_NE(0u, video_codec.simulcastStream[1].maxBitrate);
-
- // Register a fake screencast capturer and verify that the video settings
- // change as expected.
- rtc::scoped_ptr<cricket::FakeVideoCapturer> capturer(
- new cricket::FakeVideoCapturer);
- capturer->SetScreencast(true);
- const std::vector<cricket::VideoFormat>* formats =
- capturer->GetSupportedFormats();
- capture_format = (*formats)[0];
- EXPECT_EQ(cricket::CS_RUNNING, capturer->Start(capture_format));
- EXPECT_TRUE(channel_->SetCapturer(kSsrcs2[0], capturer.get()));
- EXPECT_TRUE(rtc::Thread::Current()->ProcessMessages(30));
- EXPECT_TRUE(capturer->CaptureFrame());
- default_channel_id = channel_->GetDefaultChannelId();
- EXPECT_EQ(0, channel_->engine()->vie()->codec()->GetSendCodec(
- default_channel_id, video_codec));
- EXPECT_FALSE(video_codec.codecSpecific.VP8.automaticResizeOn);
- EXPECT_FALSE(video_codec.codecSpecific.VP8.denoisingOn);
- EXPECT_EQ(webrtc::kScreensharing, video_codec.mode);
- const int expected_num_layers = 2;
- EXPECT_EQ(expected_num_layers,
- video_codec.codecSpecific.VP8.numberOfTemporalLayers);
- EXPECT_EQ(2, video_codec.numberOfSimulcastStreams);
- EXPECT_EQ(0u, video_codec.simulcastStream[0].minBitrate);
- EXPECT_EQ(0u, video_codec.simulcastStream[0].targetBitrate);
- EXPECT_EQ(0u, video_codec.simulcastStream[0].maxBitrate);
-
- // Make sure that removing screencast restores the simulcast settings.
- EXPECT_TRUE(channel_->SetCapturer(kSsrcs2[0], video_capturer_.get()));
- EXPECT_TRUE(WaitAndSendFrame(30));
- EXPECT_EQ(0, channel_->engine()->vie()->codec()->GetSendCodec(
- default_channel_id, video_codec));
- EXPECT_FALSE(video_codec.codecSpecific.VP8.automaticResizeOn);
- EXPECT_TRUE(video_codec.codecSpecific.VP8.denoisingOn);
- EXPECT_EQ(webrtc::kRealtimeVideo, video_codec.mode);
- EXPECT_EQ(3, video_codec.codecSpecific.VP8.numberOfTemporalLayers);
- EXPECT_EQ(2, video_codec.numberOfSimulcastStreams);
- EXPECT_NE(0u, video_codec.simulcastStream[0].minBitrate);
- EXPECT_NE(0u, video_codec.simulcastStream[0].targetBitrate);
- EXPECT_NE(0u, video_codec.simulcastStream[0].maxBitrate);
- EXPECT_NE(0u, video_codec.simulcastStream[1].minBitrate);
- EXPECT_NE(0u, video_codec.simulcastStream[1].targetBitrate);
- EXPECT_NE(0u, video_codec.simulcastStream[1].maxBitrate);
- }
-};
-
-// Test that we apply send codec with simulcast properly.
-TEST_F(WebRtcVideoEngineSimulcastTestFake, SetSendCodecsWith1SimulcastStreams) {
- EXPECT_TRUE(SetupEngine());
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
-
- // One ssrc simulcast StreamParams should be rejected.
- EXPECT_FALSE(channel_->AddSendStream(
- cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs1))));
-}
-
-TEST_F(WebRtcVideoEngineSimulcastTestFake, SetSendCodecsWith2SimulcastStreams) {
- cricket::VideoCodec codec(kVP8Codec);
- SetUp2SimulcastStreams(cricket::VideoOptions::NORMAL, codec);
- int channel_num = vie_.GetLastChannel();
- VerifyVP8SendCodec(channel_num, codec.width, codec.height, 2,
- kSimStream0Bitrate + kSimStream2MaxBitrateBoosted);
-}
-
-TEST_F(WebRtcVideoEngineSimulcastTestFake, SetSendCodecsWith3SimulcastStreams) {
- cricket::VideoCodec codec(kVP8Codec720p);
- SetUp3SimulcastStreams(cricket::VideoOptions::NORMAL, codec);
- int channel_num = vie_.GetLastChannel();
- VerifyVP8SendCodec(channel_num, codec.width, codec.height, 3,
- kSimStream0Bitrate + kSimStream2Bitrate +
- kSimStream4Bitrate);
-}
-
-TEST_F(WebRtcVideoEngineSimulcastTestFake,
- SetSendCodecsWith2SimulcastStreamsHighBitrateMode) {
- cricket::VideoCodec codec(kVP8Codec);
- SetUp2SimulcastStreams(cricket::VideoOptions::HIGH, codec);
- int channel_num = vie_.GetLastChannel();
- VerifyVP8SendCodec(channel_num, codec.width, codec.height, 2,
- kSimStream0TargetBitrateBoosted +
- kSimStream2MaxBitrateBoosted, kMinBandwidthKbps,
- kStartBandwidthKbps, 30, 0, cricket::SBM_HIGH);
-}
-
-TEST_F(WebRtcVideoEngineSimulcastTestFake,
- SetSendCodecsWith3SimulcastStreamsHighBitrateMode) {
- cricket::VideoCodec codec(kVP8Codec720p);
- SetUp3SimulcastStreams(cricket::VideoOptions::HIGH, codec);
- int channel_num = vie_.GetLastChannel();
- VerifyVP8SendCodec(channel_num, codec.width, codec.height, 3,
- kSimStream0TargetBitrateBoosted +
- kSimStream2TargetBitrateBoosted +
- kSimStream4MaxBitrateBoosted, kMinBandwidthKbps,
- kStartBandwidthKbps, 30, 0, cricket::SBM_HIGH);
-}
-
-TEST_F(WebRtcVideoEngineSimulcastTestFake,
- SetSendCodecsWith2SimulcastStreamsVeryHighBitrateMode) {
- cricket::VideoCodec codec(kVP8Codec);
- SetUp2SimulcastStreams(cricket::VideoOptions::VERY_HIGH,
- codec);
- int channel_num = vie_.GetLastChannel();
- VerifyVP8SendCodec(channel_num, codec.width, codec.height, 2,
- kSimStream0TargetBitrateXd +
- kSimStream2MaxBitrateXd, kMinBandwidthKbps,
- kStartBandwidthKbps, 30, 0, cricket::SBM_VERY_HIGH);
-}
-
-TEST_F(WebRtcVideoEngineSimulcastTestFake,
- SetSendCodecsWith3SimulcastStreamsVeryHighBitrateMode) {
- cricket::VideoCodec codec(kVP8Codec720p);
- SetUp3SimulcastStreams(cricket::VideoOptions::VERY_HIGH,
- codec);
- int channel_num = vie_.GetLastChannel();
- VerifyVP8SendCodec(channel_num, codec.width, codec.height, 3,
- kSimStream0TargetBitrateXd +
- kSimStream2TargetBitrateXd +
- kSimStream4MaxBitrateXd, kMinBandwidthKbps,
- kStartBandwidthKbps, 30, 0, cricket::SBM_VERY_HIGH);
-}
-
-// Test that we normalize send codec format size in simulcast.
-TEST_F(WebRtcVideoEngineSimulcastTestFake,
- SetSendCodecsWithOddSizeInSimulcast) {
- EXPECT_TRUE(SetupEngine());
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
- int channel_num = vie_.GetLastChannel();
-
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs2))));
-
- // Set send codec and verify we get two simulcast sub-streams with
- // normalized size.
- cricket::VideoCodec codec(kVP8Codec270p);
- codec.width += 0x01;
- codec.height += 0x01;
- std::vector<cricket::VideoCodec> codec_list;
- codec_list.push_back(codec);
- SendI420Frame(kVP8Codec.width, kVP8Codec.height);
- EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
-
- codec.width &= ~0x01;
- codec.height &= ~0x01;
- VerifyVP8SendCodec(channel_num, codec.width, codec.height, 2,
- kSimStream0Bitrate + kSimStream1MaxBitrateBoosted);
-}
-
-// Test that if we add a stream with RTX SSRC's, SSRC's get set correctly.
-TEST_F(WebRtcVideoEngineSimulcastTestFake, TestStreamWithRtx) {
- EXPECT_TRUE(SetupEngine());
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
- int channel_num = vie_.GetLastChannel();
-
- // Set max settings of 1280x720x30 to make sure we can have maximumly 3
- // simulcast streams.
- EXPECT_TRUE(engine_.SetDefaultEncoderConfig(
- cricket::VideoEncoderConfig(kVP8Codec720p)));
-
- // Verify only the first SSRC is set here.
- // The rest are set during SetSendCodecs.
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::CreateSimWithRtxStreamParams("cname",
- MAKE_VECTOR(kSsrcs3),
- MAKE_VECTOR(kRtxSsrcs3))));
- EXPECT_EQ(1, vie_.GetNumSsrcs(channel_num));
- EXPECT_EQ(1, vie_.GetNumRtxSsrcs(channel_num));
-
- std::vector<cricket::VideoCodec> codec_list;
- codec_list.push_back(kVP8Codec720p);
- cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0);
- rtx_codec.SetParam("apt", kVP8Codec.id);
- codec_list.push_back(rtx_codec);
- SendI420Frame(kVP8Codec720p.width, kVP8Codec720p.height);
- EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
-
- // RTX payload type should now be set.
- EXPECT_EQ(vie_.GetRtxSendPayloadTypes(channel_num),
- MAKE_VECTOR(kPayloadTypes1));
-
- // Verify all SSRCs are set after SetSendCodecs.
- EXPECT_EQ(3, vie_.GetNumSsrcs(channel_num));
- EXPECT_EQ(3, vie_.GetNumRtxSsrcs(channel_num));
- EXPECT_EQ(1, vie_.GetSsrc(channel_num, 0));
- EXPECT_EQ(2, vie_.GetSsrc(channel_num, 1));
- EXPECT_EQ(3, vie_.GetSsrc(channel_num, 2));
- EXPECT_EQ(4, vie_.GetRtxSsrc(channel_num, 0));
- EXPECT_EQ(5, vie_.GetRtxSsrc(channel_num, 1));
- EXPECT_EQ(6, vie_.GetRtxSsrc(channel_num, 2));
- uint32 ssrc;
- EXPECT_EQ(0, vie_.GetLocalSSRC(channel_num, ssrc));
- EXPECT_EQ(1U, ssrc);
-}
-
-// Test that if we get too few ssrcs are given in AddSendStream(),
-// only supported sub-streams will be added.
-TEST_F(WebRtcVideoEngineSimulcastTestFake, TooFewSimulcastSsrcs) {
- EXPECT_TRUE(SetupEngine());
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
- int channel_num = vie_.GetLastChannel();
-
- // Set max settings of 1280x720x30 to make sure we can have maximumly 3
- // simulcast streams.
- EXPECT_TRUE(engine_.SetDefaultEncoderConfig(
- cricket::VideoEncoderConfig(kVP8Codec720p)));
-
- // Verify only the first SSRC is set here.
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs2))));
- EXPECT_EQ(1, vie_.GetNumSsrcs(channel_num));
-
- cricket::VideoCodec codec(kVP8Codec720p);
- std::vector<cricket::VideoCodec> codec_list;
- codec_list.push_back(codec);
- SendI420Frame(kVP8Codec720p.width, kVP8Codec720p.height);
- EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
-
- // Verify all SSRCs are set after SetSendCodecs.
- EXPECT_EQ(2, vie_.GetNumSsrcs(channel_num));
- EXPECT_EQ(1, vie_.GetSsrc(channel_num, 0));
- EXPECT_EQ(2, vie_.GetSsrc(channel_num, 1));
- uint32 ssrc;
- EXPECT_EQ(0, vie_.GetLocalSSRC(channel_num, ssrc));
- EXPECT_EQ(1U, ssrc);
- VerifyVP8SendCodec(channel_num, 640, 360, 2,
- kSimStream0Bitrate + kSimStream2MaxBitrateBoosted);
-}
-
-// Test that even more than enough ssrcs are given in AddSendStream(),
-// only supported sub-streams will be added.
-TEST_F(WebRtcVideoEngineSimulcastTestFake, MoreThanEnoughSimulcastSscrs) {
- EXPECT_TRUE(SetupEngine());
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
- int channel_num = vie_.GetLastChannel();
-
- // Set max settings of 1280x720x30 to make sure we can have maximumly 3
- // simulcast streams.
- EXPECT_TRUE(engine_.SetDefaultEncoderConfig(
- cricket::VideoEncoderConfig(kVP8Codec720p)));
-
- // Verify only the first SSRC is set here.
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs4))));
- EXPECT_EQ(1, vie_.GetNumSsrcs(channel_num));
-
- cricket::VideoCodec codec(kVP8Codec720p);
- std::vector<cricket::VideoCodec> codec_list;
- codec_list.push_back(codec);
- SendI420Frame(kVP8Codec720p.width, kVP8Codec720p.height);
- EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
-
- // Verify all SSRCs are set after SetSendCodecs.
- EXPECT_EQ(3, vie_.GetNumSsrcs(channel_num));
- EXPECT_EQ(1, vie_.GetSsrc(channel_num, 0));
- EXPECT_EQ(2, vie_.GetSsrc(channel_num, 1));
- EXPECT_EQ(3, vie_.GetSsrc(channel_num, 2));
- uint32 ssrc;
- EXPECT_EQ(0, vie_.GetLocalSSRC(channel_num, ssrc));
- EXPECT_EQ(1U, ssrc);
- VerifyVP8SendCodec(channel_num, codec.width, codec.height, 3,
- kSimStream0Bitrate + kSimStream2Bitrate + kSimStream4Bitrate);
-}
-
-// Test that SetSendStreamFormat works well with simulcast.
-TEST_F(WebRtcVideoEngineSimulcastTestFake, SetSendStreamFormatWithSimulcast) {
- EXPECT_TRUE(SetupEngine());
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
- int channel_num = vie_.GetLastChannel();
-
- // Verify SetSendStreamFormat fail before there is a send stream.
- cricket::VideoFormat format = engine_.default_codec_format();
- EXPECT_FALSE(channel_->SetSendStreamFormat(1, format));
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs2))));
-
- // Capture format HD
- cricket::FakeVideoCapturer video_capturer;
- const std::vector<cricket::VideoFormat>* formats =
- video_capturer.GetSupportedFormats();
- cricket::VideoFormat capture_format_hd = (*formats)[0];
- EXPECT_EQ(cricket::CS_RUNNING, video_capturer.Start(capture_format_hd));
- EXPECT_TRUE(channel_->SetCapturer(kSsrcs2[0], &video_capturer));
-
- cricket::VideoCodec codec(kVP8Codec360p);
- std::vector<cricket::VideoCodec> codec_list;
- codec_list.push_back(codec);
- SendI420Frame(&video_capturer, kVP8Codec.width, kVP8Codec.height);
- EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
-
- EXPECT_EQ(2, vie_.GetNumSsrcs(channel_num));
- EXPECT_EQ(1, vie_.GetSsrc(channel_num, 0));
- EXPECT_EQ(2, vie_.GetSsrc(channel_num, 1));
- VerifyVP8SendCodec(channel_num, codec.width, codec.height, 2,
- kSimStream0Bitrate + kSimStream2MaxBitrateBoosted);
-
- // Verify SetSendStreamFormat with the same resolution doesn't
- // change the number of simulcast sub-streams.
- format.width = codec.width;
- format.height = codec.height;
- EXPECT_TRUE(channel_->SetSendStreamFormat(1, format));
- EXPECT_EQ(2, vie_.GetNumSsrcs(channel_num));
- EXPECT_EQ(1, vie_.GetSsrc(channel_num, 0));
- EXPECT_EQ(2, vie_.GetSsrc(channel_num, 1));
-
- // Capture format HD -> adapt (OnOutputFormatRequest VGA) -> VGA.
- EXPECT_TRUE(video_capturer.CaptureFrame());
- VerifyVP8SendCodec(channel_num, codec.width, codec.height, 2,
- kSimStream0Bitrate + kSimStream2MaxBitrateBoosted);
-
- // Now, ask for a small resolution and verify that we only get one stream.
- format.width = codec.width / 2;
- format.height = codec.height / 2;
- EXPECT_TRUE(channel_->SetSendStreamFormat(1, format));
- // Capture format HD -> adapt (OnOutputFormatRequest QVGA) -> QVGA.
- EXPECT_TRUE(video_capturer.CaptureFrame());
- VerifyVP8SendCodec(channel_num, format.width, format.height, 1,
- kSimStream0MaxBitrateBoosted);
-
- // Bump resolution back and verify there are 2 sub-streams again.
- format.width = codec.width;
- format.height = codec.height;
- EXPECT_TRUE(channel_->SetSendStreamFormat(1, format));
- EXPECT_EQ(2, vie_.GetNumSsrcs(channel_num));
- EXPECT_EQ(1, vie_.GetSsrc(channel_num, 0));
- EXPECT_EQ(2, vie_.GetSsrc(channel_num, 1));
- // Capture format HD -> adapt (OnOutputFormatRequest VGA) -> VGA.
- EXPECT_TRUE(video_capturer.CaptureFrame());
- VerifyVP8SendCodec(channel_num, format.width, format.height, 2,
- kSimStream0Bitrate + kSimStream2MaxBitrateBoosted);
-
- // Verify SetSendStreamFormat can use either ssrc in the simulcast
- // ssrc group.
- format.width = codec.width / 2;
- format.height = codec.height / 2;
- EXPECT_TRUE(channel_->SetSendStreamFormat(2, format));
- EXPECT_EQ(2, vie_.GetNumSsrcs(channel_num));
- EXPECT_EQ(1, vie_.GetSsrc(channel_num, 0));
- EXPECT_EQ(2, vie_.GetSsrc(channel_num, 1));
- // Capture format HD -> adapt (OnOutputFormatRequest QVGA) -> QVGA.
- EXPECT_TRUE(video_capturer.CaptureFrame());
- VerifyVP8SendCodec(channel_num, format.width, format.height, 1,
- kSimStream0MaxBitrateBoosted);
-
- // Verify SetSendStreamFormat with bad ssrc fail.
- format.width = codec.width;
- format.height = codec.height;
- EXPECT_FALSE(channel_->SetSendStreamFormat(3, format));
- EXPECT_EQ(2, vie_.GetNumSsrcs(channel_num));
- EXPECT_EQ(1, vie_.GetSsrc(channel_num, 0));
- EXPECT_EQ(2, vie_.GetSsrc(channel_num, 1));
- VerifyVP8SendCodec(channel_num, format.width / 2, format.height / 2, 1,
- kSimStream0MaxBitrateBoosted);
- EXPECT_TRUE(channel_->SetCapturer(kSsrcs2[0], NULL));
-}
-
-// Test that simulcast send codec is reset on new video frame size.
-TEST_F(WebRtcVideoEngineSimulcastTestFake,
- ResetSimulcastSendCodecOnNewFrameSize) {
- EXPECT_TRUE(SetupEngine());
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
- int channel_num = vie_.GetLastChannel();
-
- // Set send codec.
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs2))));
- cricket::VideoCodec codec(kVP8Codec);
- std::vector<cricket::VideoCodec> codec_list;
- codec_list.push_back(codec);
- EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
- EXPECT_TRUE(channel_->SetSend(true));
- EXPECT_EQ(1, vie_.GetNumSetSendCodecs());
-
- // Feed in frames with different sizes and verify simulcast send codec
- // changes accordingly.
-
- // Send an odd frame. Verify format size get normalized.
- SendI420Frame(kVP8Codec.width | 0x01, kVP8Codec.height | 0x01);
- VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height, 2,
- kSimStream0Bitrate + kSimStream2MaxBitrateBoosted);
- EXPECT_EQ(2, vie_.GetNumSetSendCodecs());
-
- // Send a big frame. Verify format size never exceed original send codec
- // format size.
- SendI420Frame(kVP8Codec.width * 2, kVP8Codec.height * 2);
- VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height, 2,
- kSimStream0Bitrate + kSimStream2MaxBitrateBoosted);
- EXPECT_EQ(2, vie_.GetNumSetSendCodecs());
-
- // Send a small frame. Verify format size is bumped in order to meet
- // the minimum simulcast reqirement while keeping the aspect ratio.
- SendI420Frame(kVP8Codec.width / 2, kVP8Codec.height / 2);
- // Need at least 480x270 to have simulcast.
- VerifyVP8SendCodec(channel_num, kVP8Codec.width / 2, kVP8Codec.height / 2, 1,
- kSimStream0MaxBitrateBoosted);
- EXPECT_EQ(3, vie_.GetNumSetSendCodecs());
-
- // Send a normal frame. Verify format size is back to normal.
- SendI420Frame(kVP8Codec.width, kVP8Codec.height);
- VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height, 2,
- kSimStream0Bitrate + kSimStream2MaxBitrateBoosted);
- EXPECT_EQ(4, vie_.GetNumSetSendCodecs());
-
- // Send an odd frame again.
- SendI420Frame(kVP8Codec.width | 0x01, kVP8Codec.height | 0x01);
- VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height, 2,
- kSimStream0Bitrate + kSimStream2MaxBitrateBoosted);
- EXPECT_EQ(4, vie_.GetNumSetSendCodecs());
-}
-
-// Test that simulcast send codec is reset on new portait mode video frame.
-TEST_F(WebRtcVideoEngineSimulcastTestFake,
- ResetSimulcastSendCodecOnNewPortaitFrame) {
- EXPECT_TRUE(SetupEngine());
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
- int channel_num = vie_.GetLastChannel();
-
- // Set send codec.
- EXPECT_TRUE(engine_.SetDefaultEncoderConfig(
- cricket::VideoEncoderConfig(kVP8Codec720p)));
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs2))));
- cricket::VideoCodec codec(kVP8Codec720p);
- std::vector<cricket::VideoCodec> codec_list;
- codec_list.push_back(codec);
- EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
- EXPECT_TRUE(channel_->SetSend(true));
- EXPECT_EQ(1, vie_.GetNumSetSendCodecs());
-
- // Feed in frames with different sizes and verify simulcast send codec
- // changes accordingly.
-
- // Send a portait mode frame.
- SendI420Frame(kVP8Codec.height, kVP8Codec.width);
- VerifyVP8SendCodec(channel_num, kVP8Codec.height, kVP8Codec.width, 2,
- kSimStream0Bitrate + kSimStream2MaxBitrateBoosted);
- EXPECT_EQ(2, vie_.GetNumSetSendCodecs());
-}
-
-TEST_F(WebRtcVideoEngineSimulcastTestFake,
- SetBandwidthInConferenceWithSimulcast) {
- cricket::VideoCodec ccodec(kVP8Codec720p);
- SetUp3SimulcastStreams(cricket::VideoOptions::NORMAL, ccodec);
-
- // A higher value than the sum of max of all layers should add the extra
- // bandwidth to the higher layer.
- uint32 max_bandwidth = 5000;
- EXPECT_TRUE(channel_->SetMaxSendBandwidth(max_bandwidth * 1000));
-
- int channel_num = vie_.GetLastChannel();
- webrtc::VideoCodec codec;
- codec.width = 0; codec.height = 0;
- EXPECT_EQ(0, vie_.GetSendCodec(channel_num, codec));
- EXPECT_EQ(max_bandwidth, codec.maxBitrate);
-
- int nr_layers = 3;
- uint32 sum_bandwidth = 0;
- for (int i = 0; i < nr_layers; ++i) {
- if (i == nr_layers - 1) {
- EXPECT_EQ(max_bandwidth - sum_bandwidth,
- codec.simulcastStream[i].maxBitrate);
- } else {
- EXPECT_EQ(FindSimulcastMaxBitrate(codec.simulcastStream[i].width,
- codec.simulcastStream[i].height,
- cricket::SBM_NORMAL),
- codec.simulcastStream[i].maxBitrate);
- sum_bandwidth += codec.simulcastStream[i].maxBitrate;
- }
- }
-
- // Test setting max bandwidth below the sum of layer specific max bandwidth.
- // Basically, the simulcast max overrides the SetMaxSendBandwidth value.
- EXPECT_TRUE(channel_->SetMaxSendBandwidth(1));
- VerifyVP8SendCodec(channel_num, codec.width, codec.height, 3,
- kSimStream0Bitrate + kSimStream2Bitrate +
- kSimStream4Bitrate);
-}
-
-// Test that sending screencast frames in conference mode changes
-// bitrate.
-TEST_F(WebRtcVideoEngineSimulcastTestFake, SetBandwidthScreencastInConference) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
-
- // Set send codec.
- cricket::VideoCodec codec(kVP8Codec);
- std::vector<cricket::VideoCodec> codec_list;
- codec_list.push_back(codec);
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::StreamParams::CreateLegacy(123)));
- EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
- EXPECT_TRUE(channel_->SetMaxSendBandwidth(1200000));
- EXPECT_EQ(2, vie_.GetNumSetSendCodecs());
-
- // Set conference mode and verify that this caps maxBitrate.
- webrtc::VideoCodec gcodec;
- EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec));
- EXPECT_GT(gcodec.maxBitrate, 1000u);
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
- EXPECT_TRUE(channel_->SetSend(true));
- SendI420ScreencastFrame(kVP8Codec.width, kVP8Codec.height);
- EXPECT_EQ(3, vie_.GetNumSetSendCodecs());
- EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec));
- EXPECT_EQ(1000u, gcodec.maxBitrate);
-}
-
-// Test AddSendStream with simulcast rejects bad StreamParams.
-TEST_F(WebRtcVideoEngineSimulcastTestFake, AddSendStreamWithBadStreamParams) {
- EXPECT_TRUE(SetupEngine());
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
-
- // Verify non-sim StreamParams is rejected.
- cricket::StreamParams sp_bad;
- std::vector<uint32> ssrcs;
- ssrcs.push_back(1234);
- ssrcs.push_back(5678);
- cricket::SsrcGroup sg("bad", ssrcs);
- sp_bad.ssrcs = ssrcs;
- sp_bad.ssrc_groups.push_back(sg);
- sp_bad.cname = "cname";
- EXPECT_FALSE(channel_->AddSendStream(sp_bad));
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs2))));
-}
-
-// Test AddSendStream with simulcast sets ssrc and cname correctly.
-TEST_F(WebRtcVideoEngineSimulcastTestFake, AddSendStreamWithSimulcast) {
- EXPECT_TRUE(SetupEngine());
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
- int channel_num = vie_.GetLastChannel();
-
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs2))));
-
- unsigned int ssrc = 0;
- EXPECT_EQ(1, vie_.GetNumSsrcs(channel_num));
- EXPECT_EQ(0, vie_.GetLocalSSRC(channel_num, ssrc));
- EXPECT_EQ(1U, ssrc);
-
- char rtcp_cname[256];
- EXPECT_EQ(0, vie_.GetRTCPCName(channel_num, rtcp_cname));
- EXPECT_STREQ("cname", rtcp_cname);
-
- EXPECT_TRUE(channel_->RemoveSendStream(1));
-}
-
-// Test RemoveSendStream with simulcast.
-TEST_F(WebRtcVideoEngineSimulcastTestFake, RemoveSendStreamWithSimulcast) {
- EXPECT_TRUE(SetupEngine());
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
-
- // RemoveSendStream should fail when there is no send stream.
- EXPECT_FALSE(channel_->RemoveSendStream(1));
-
- cricket::StreamParams stream =
- cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs2));
- EXPECT_TRUE(channel_->AddSendStream(stream));
-
- // RemoveSendStream should fail with bad ssrc.
- EXPECT_FALSE(channel_->RemoveSendStream(3));
- EXPECT_TRUE(channel_->RemoveSendStream(1));
-
- // RemoveSendStream should work with either ssrc.
- EXPECT_TRUE(channel_->AddSendStream(stream));
- EXPECT_TRUE(channel_->RemoveSendStream(1));
- EXPECT_TRUE(channel_->AddSendStream(stream));
- EXPECT_TRUE(channel_->RemoveSendStream(2));
-
- // RemoveSendStream should fail when there is no send stream.
- EXPECT_FALSE(channel_->RemoveSendStream(1));
-}
-
-// Test AddSendStream after send codec has already been set will reset
-// send codec with simulcast settings.
-TEST_F(WebRtcVideoEngineSimulcastTestFake,
- AddSimulcastStreamAfterSetSendCodec) {
- EXPECT_TRUE(SetupEngine());
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
- int channel_num = vie_.GetLastChannel();
-
- // Set send codec.
- cricket::VideoCodec codec(kVP8Codec);
- std::vector<cricket::VideoCodec> codec_list;
- codec_list.push_back(codec);
- SendI420Frame(kVP8Codec.width, kVP8Codec.height);
- EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
- VerifyVP8SendCodec(channel_num, codec.width, codec.height);
-
- // Add simulcast send stream and verify send codec has been reset.
- // Provide 3 ssrcs here and only 2 layers should be added.
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs3))));
- VerifyVP8SendCodec(channel_num, codec.width, codec.height, 2,
- kSimStream0Bitrate + kSimStream2MaxBitrateBoosted);
-
- // Verify local SSRCs are now populated correctly.
- EXPECT_EQ(2, vie_.GetNumSsrcs(channel_num));
- EXPECT_EQ(1, vie_.GetSsrc(channel_num, 0));
- EXPECT_EQ(2, vie_.GetSsrc(channel_num, 1));
- uint32 ssrc;
- EXPECT_EQ(0, vie_.GetLocalSSRC(channel_num, ssrc));
- EXPECT_EQ(1U, ssrc);
-
- // Remove the stream and reset send codec with a smaller size.
- EXPECT_TRUE(channel_->RemoveSendStream(1));
- VerifyVP8SendCodec(channel_num, codec.width, codec.height, 2,
- kSimStream0Bitrate + kSimStream2MaxBitrateBoosted);
- codec_list.clear();
- codec.width /= 2;
- codec.height /= 2;
- codec_list.push_back(codec);
- EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
- VerifyVP8SendCodec(channel_num, codec.width, codec.height);
-
- // Add simulcast send stream again and verify simulcast have one stream.
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs2))));
- VerifyVP8SendCodec(channel_num, codec.width, codec.height, 1,
- kSimStream0MaxBitrateBoosted);
-
- // Verify we still have 2 SSRCs.
- EXPECT_EQ(2, vie_.GetNumSsrcs(channel_num));
- EXPECT_EQ(1, vie_.GetSsrc(channel_num, 0));
- EXPECT_EQ(2, vie_.GetSsrc(channel_num, 1));
- EXPECT_EQ(0, vie_.GetLocalSSRC(channel_num, ssrc));
- EXPECT_EQ(1U, ssrc);
-}
-
-TEST_F(WebRtcVideoEngineSimulcastTestFake, GetStatsWithMultipleSsrcs) {
- EXPECT_TRUE(SetupEngine());
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
-
- // Add simulcast stream.
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs2))));
-
- // Set send codec and verify we get two simulcast sub-streams.
- cricket::VideoCodec codec(kVP8Codec);
- std::vector<cricket::VideoCodec> codec_list;
- codec_list.push_back(codec);
- EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
- EXPECT_TRUE(channel_->SetSend(true));
-
- cricket::FakeVideoCapturer video_capturer;
- const std::vector<cricket::VideoFormat>* formats =
- video_capturer.GetSupportedFormats();
- cricket::VideoFormat capture_format_vga = (*formats)[1];
- EXPECT_EQ(cricket::CS_RUNNING, video_capturer.Start(capture_format_vga));
- EXPECT_TRUE(channel_->SetCapturer(kSsrcs2[0], &video_capturer));
-
- // Only require one cpu sample for testing whether the adapter is hooked up.
- cricket::CoordinatedVideoAdapter* video_adapter = NULL;
- ASSERT_TRUE(channel_->GetVideoAdapter(0u, &video_adapter));
- video_adapter->set_cpu_load_min_samples(1);
- cpu_monitor_->SignalUpdate(1, 1, 0.1f, 0.85f);
-
- // Capture format VGA -> adapt (OnCpuLoadUpdate downgrade) -> VGA/2.
- EXPECT_TRUE(video_capturer.CaptureFrame());
-
- // Get stats and verify there are 2 ssrcs.
- cricket::VideoMediaInfo info;
- EXPECT_TRUE(channel_->GetStats(&info));
- ASSERT_EQ(1U, info.senders.size());
- ASSERT_EQ(2U, info.senders[0].ssrcs().size());
- EXPECT_EQ(1U, info.senders[0].ssrcs()[0]);
- EXPECT_EQ(2U, info.senders[0].ssrcs()[1]);
- // Verify the input/send width/height.
- EXPECT_EQ(capture_format_vga.width, info.senders[0].input_frame_width);
- EXPECT_EQ(capture_format_vga.height, info.senders[0].input_frame_height);
- EXPECT_EQ(capture_format_vga.width * 3 / 4,
- info.senders[0].send_frame_width);
- EXPECT_EQ(capture_format_vga.height * 3 / 4,
- info.senders[0].send_frame_height);
-
- EXPECT_TRUE(channel_->SetCapturer(kSsrcs2[0], NULL));
-}
-
-// Test receiving channel(s) local ssrc is set to the same as the first
-// simulcast sending ssrc.
-TEST_F(WebRtcVideoEngineSimulcastTestFake,
- AddSimulcastStreamAfterCreatingRecvChannels) {
- EXPECT_TRUE(SetupEngine());
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
- int channel_num = vie_.GetLastChannel();
-
- EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(10)));
- int receive_channel_1 = vie_.GetLastChannel();
- EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(11)));
- int receive_channel_2 = vie_.GetLastChannel();
-
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs2))));
-
- unsigned int ssrc = 0;
- EXPECT_EQ(1, vie_.GetNumSsrcs(channel_num));
- EXPECT_EQ(0, vie_.GetLocalSSRC(channel_num, ssrc));
- EXPECT_EQ(1U, ssrc);
-
- EXPECT_EQ(0, vie_.GetLocalSSRC(receive_channel_1, ssrc));
- EXPECT_EQ(1U, ssrc);
- EXPECT_EQ(1, vie_.GetNumSsrcs(receive_channel_1));
-
- EXPECT_EQ(0, vie_.GetLocalSSRC(receive_channel_2, ssrc));
- EXPECT_EQ(1U, ssrc);
- EXPECT_EQ(1, vie_.GetNumSsrcs(receive_channel_2));
-}
-
-// Test 1:1 call never turn on simulcast.
-TEST_F(WebRtcVideoEngineSimulcastTestFake, NoSimulcastWith1on1) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
-
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs2))));
-
- // Set send codec and verify there is no simulcast sub-streams.
- cricket::VideoCodec codec(kVP8Codec);
- std::vector<cricket::VideoCodec> codec_list;
- codec_list.push_back(codec);
- SendI420Frame(kVP8Codec.width, kVP8Codec.height);
- EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
- VerifyVP8SendCodec(channel_num, codec.width, codec.height);
- EXPECT_EQ(1, vie_.GetNumSsrcs(channel_num));
-
- // Set options with OPT_CONFERENCE flag and set send codec again.
- // Verify simulcast is used now.
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
- EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
- VerifyVP8SendCodec(channel_num, codec.width, codec.height, 2,
- kSimStream0Bitrate + kSimStream2MaxBitrateBoosted);
- EXPECT_EQ(2, vie_.GetNumSsrcs(channel_num));
- EXPECT_EQ(1, vie_.GetSsrc(channel_num, 0));
- EXPECT_EQ(2, vie_.GetSsrc(channel_num, 1));
-
- // Remove OPT_CONFERENCE flag and set send codec again.
- // Verify simulcast is off again.
- options.conference_mode.Set(false);
- EXPECT_TRUE(channel_->SetOptions(options));
- EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
- VerifyVP8SendCodec(channel_num, codec.width, codec.height);
-
- // Verify we still have 2 SSRCs.
- EXPECT_EQ(2, vie_.GetNumSsrcs(channel_num));
- EXPECT_EQ(1, vie_.GetSsrc(channel_num, 0));
- EXPECT_EQ(2, vie_.GetSsrc(channel_num, 1));
-}
-
-// Test SetOptions with OPT_CONFERENCE flag.
-TEST_F(WebRtcVideoEngineSimulcastTestFake, SetOptionsWithConferenceMode) {
- EXPECT_TRUE(SetupEngine());
- int channel_num = vie_.GetLastChannel();
-
- // Set send codec.
- cricket::VideoCodec codec(kVP8Codec);
- std::vector<cricket::VideoCodec> codec_list;
- codec_list.push_back(codec);
- SendI420Frame(kVP8Codec.width, kVP8Codec.height);
- EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
-
- // Verify default send codec and bitrate.
- VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height);
-
- // Set options with OPT_CONFERENCE flag.
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
-
- // Change the max bitrate and verify it has changed.
- channel_->SetMaxSendBandwidth(kSimStream2MaxBitrateBoosted * 1000);
- VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height, 0,
- kSimStream2MaxBitrateBoosted);
-
- // Turn off conference mode and verify the max bandwidth changed
- // back.
- options.conference_mode.Set(false);
- EXPECT_TRUE(channel_->SetOptions(options));
- VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height);
-
- // Set send codec again with a smaller size.
- codec_list.clear();
- codec.width /= 2;
- codec.height /= 2;
- codec_list.push_back(codec);
- EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
-
- // Set options with OPT_CONFERENCE flag and set the max bitrate again.
- options.conference_mode.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
- channel_->SetMaxSendBandwidth(kSimStream0MaxBitrateBoosted * 1000);
-
- // Verify channel now has a new max bitrate.
- VerifyVP8SendCodec(channel_num, kVP8Codec.width / 2, kVP8Codec.height / 2, 0,
- kSimStream0MaxBitrateBoosted);
-}
-
-// Test that two different streams can have different formats.
-TEST_F(WebRtcVideoEngineSimulcastTestFake,
- MultipleSendStreamsDifferentFormats) {
- EXPECT_TRUE(SetupEngine());
- for (unsigned int i = 0; i < sizeof(kSsrcs2)/sizeof(kSsrcs2[0]); ++i) {
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::StreamParams::CreateLegacy(kSsrcs2[i])));
- }
- const int channel0 = vie_.GetChannelFromLocalSsrc(kSsrcs2[0]);
- ASSERT_NE(-1, channel0);
- const int channel1 = vie_.GetChannelFromLocalSsrc(kSsrcs2[1]);
- ASSERT_NE(-1, channel1);
- ASSERT_NE(channel0, channel1);
- std::vector<cricket::VideoCodec> codecs;
- codecs.push_back(kVP8Codec);
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
- cricket::VideoFormat format(kVP8Codec.width / 2, kVP8Codec.height / 2,
- cricket::VideoFormat::FpsToInterval(kVP8Codec.framerate / 2),
- cricket::FOURCC_I420);
- EXPECT_TRUE(channel_->SetSendStreamFormat(kSsrcs2[1], format));
-
- SendI420Frame(kVP8Codec.width, kVP8Codec.height);
- VerifyVP8SendCodec(channel0, kVP8Codec.width, kVP8Codec.height, 0,
- kMaxBandwidthKbps, kMinBandwidthKbps, kStartBandwidthKbps,
- kVP8Codec.framerate);
- VerifyVP8SendCodec(channel1, kVP8Codec.width / 2, kVP8Codec.height / 2, 0,
- kMaxBandwidthKbps, kMinBandwidthKbps, kStartBandwidthKbps,
- kVP8Codec.framerate / 2);
-}
-
-TEST_F(WebRtcVideoEngineSimulcastTestFake, TestAdaptToOutputFormat) {
- EXPECT_TRUE(SetupEngine());
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs3))));
-
- // Capture format HD
- cricket::FakeVideoCapturer video_capturer;
- const std::vector<cricket::VideoFormat>* formats =
- video_capturer.GetSupportedFormats();
- cricket::VideoFormat capture_format_hd = (*formats)[0];
- EXPECT_EQ(cricket::CS_RUNNING, video_capturer.Start(capture_format_hd));
- EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], &video_capturer));
-
- cricket::VideoCodec send_codec(100, "VP8", 800, 600, 30, 0);
- cricket::VideoFormat vga_format(640, 360,
- cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420);
- std::vector<cricket::VideoCodec> codecs;
- codecs.push_back(send_codec);
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
- EXPECT_TRUE(channel_->SetSendStreamFormat(kSsrcs3[0], vga_format));
- EXPECT_TRUE(channel_->SetSend(true));
-
- // Capture format HD -> adapt (OnOutputFormatRequest VGA) -> VGA.
- EXPECT_TRUE(video_capturer.CaptureFrame());
- const int channel0 = vie_.GetChannelFromLocalSsrc(kSsrcs3[0]);
- ASSERT_NE(-1, channel0);
- VerifyVP8SendCodec(channel0, vga_format.width, vga_format.height, 0,
- kMaxBandwidthKbps, kMinBandwidthKbps, kStartBandwidthKbps,
- 30);
- EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], NULL));
-}
-
-TEST_F(WebRtcVideoEngineSimulcastTestFake, TestAdaptToCpuLoad) {
- EXPECT_TRUE(SetupEngine());
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs3))));
-
- // Capture format VGA
- cricket::FakeVideoCapturer video_capturer;
- const std::vector<cricket::VideoFormat>* formats =
- video_capturer.GetSupportedFormats();
- cricket::VideoFormat capture_format_vga = (*formats)[1];
-
- // Make OnCpuLoadUpdate trigger downgrade.
- cricket::VideoOptions options;
- options.adapt_input_to_cpu_usage.Set(true);
- options.process_adaptation_threshhold.Set(0.1f);
- options.system_low_adaptation_threshhold.Set(0.65f);
- options.system_high_adaptation_threshhold.Set(0.85f);
- options.cpu_overuse_detection.Set(false);
- EXPECT_TRUE(channel_->SetOptions(options));
-
- // Verify toggling cpu overuse detection works.
- options.cpu_overuse_detection.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
- options.cpu_overuse_detection.Set(false);
- EXPECT_TRUE(channel_->SetOptions(options));
-
- EXPECT_EQ(cricket::CS_RUNNING, video_capturer.Start(capture_format_vga));
- EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], &video_capturer));
-
- // Only require one cpu sample for testing whether the adapter is hooked up.
- cricket::CoordinatedVideoAdapter* video_adapter = NULL;
- ASSERT_TRUE(channel_->GetVideoAdapter(0u, &video_adapter));
- video_adapter->set_cpu_load_min_samples(1);
-
- cpu_monitor_->SignalUpdate(1, 1, 0.1f, 0.85f);
-
- cricket::VideoCodec send_codec(100, "VP8", 640, 480, 30, 0);
- std::vector<cricket::VideoCodec> codecs;
- codecs.push_back(send_codec);
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
- EXPECT_TRUE(channel_->SetSend(true));
-
- // Capture format VGA -> adapt (OnCpuLoadUpdate downgrade) -> VGA/2.
- EXPECT_TRUE(video_capturer.CaptureFrame());
- const int channel0 = vie_.GetChannelFromLocalSsrc(kSsrcs3[0]);
- ASSERT_NE(-1, channel0);
- VerifyVP8SendCodec(
- channel0, 3 * send_codec.width / 4, 3 * send_codec.height / 4, 0,
- kMaxBandwidthKbps, kMinBandwidthKbps, kStartBandwidthKbps,
- send_codec.framerate);
-
- // Trigger more downgrades and check for multiple unable to adapt signal.
- EXPECT_EQ(cricket::VideoMediaChannel::ERROR_NONE, last_error_);
- cpu_monitor_->SignalUpdate(1, 1, 0.1f, 0.85f);
- cpu_monitor_->SignalUpdate(1, 1, 0.1f, 0.85f);
- EXPECT_EQ(cricket::VideoMediaChannel::ERROR_REC_CPU_MAX_CANT_DOWNGRADE,
- last_error_);
-
- last_error_ = cricket::VideoMediaChannel::ERROR_NONE;
- cpu_monitor_->SignalUpdate(1, 1, 0.1f, 0.85f);
- EXPECT_EQ(cricket::VideoMediaChannel::ERROR_REC_CPU_MAX_CANT_DOWNGRADE,
- last_error_);
-
- EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], NULL));
-}
-
-TEST_F(WebRtcVideoEngineSimulcastTestFake, TestAdaptToCpuLoadDisabled) {
- EXPECT_TRUE(SetupEngine());
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs3))));
-
- // Capture format VGA
- cricket::FakeVideoCapturer video_capturer;
- const std::vector<cricket::VideoFormat>* formats =
- video_capturer.GetSupportedFormats();
- cricket::VideoFormat capture_format_vga = (*formats)[1];
- EXPECT_EQ(cricket::CS_RUNNING, video_capturer.Start(capture_format_vga));
- EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], &video_capturer));
-
- // Make OnCpuLoadUpdate trigger downgrade.
- cricket::VideoOptions options;
- options.adapt_input_to_cpu_usage.Set(false);
- options.process_adaptation_threshhold.Set(0.1f);
- options.system_low_adaptation_threshhold.Set(0.65f);
- options.system_high_adaptation_threshhold.Set(0.85f);
- EXPECT_TRUE(channel_->SetOptions(options));
-
- // Only require one cpu sample for testing whether the adapter is hooked up.
- cricket::CoordinatedVideoAdapter* video_adapter = NULL;
- ASSERT_TRUE(channel_->GetVideoAdapter(0u, &video_adapter));
- video_adapter->set_cpu_load_min_samples(1);
- cpu_monitor_->SignalUpdate(1, 1, 0.1f, 0.85f);
-
- cricket::VideoCodec send_codec(100, "VP8", 640, 480, 30, 0);
- std::vector<cricket::VideoCodec> codecs;
- codecs.push_back(send_codec);
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
- EXPECT_TRUE(channel_->SetSend(true));
-
- // Capture format VGA -> no adapt -> VGA.
- EXPECT_TRUE(video_capturer.CaptureFrame());
- const int channel0 = vie_.GetChannelFromLocalSsrc(kSsrcs3[0]);
- ASSERT_NE(-1, channel0);
- VerifyVP8SendCodec(channel0, capture_format_vga.width,
- capture_format_vga.height, 0,
- kMaxBandwidthKbps, kMinBandwidthKbps, kStartBandwidthKbps,
- send_codec.framerate);
- EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], NULL));
-}
-
-TEST_F(WebRtcVideoEngineSimulcastTestFake, TestAdaptWithCpuOveruseObserver) {
- EXPECT_TRUE(SetupEngine());
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs3))));
-
- // Verify that the CpuOveruseObserver is not set by default.
- const int channel0 = vie_.GetChannelFromLocalSsrc(kSsrcs3[0]);
- ASSERT_NE(-1, channel0);
- webrtc::CpuOveruseObserver* observer = vie_.GetCpuOveruseObserver(channel0);
- EXPECT_TRUE(observer == NULL);
-
- // Capture format VGA.
- cricket::FakeVideoCapturer video_capturer;
- const std::vector<cricket::VideoFormat>* formats =
- video_capturer.GetSupportedFormats();
- cricket::VideoFormat capture_format_vga = (*formats)[1];
- EXPECT_EQ(cricket::CS_RUNNING, video_capturer.Start(capture_format_vga));
- EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], &video_capturer));
-
- // Verify that the CpuOveruseObserver is registered and trigger downgrade.
- cricket::VideoOptions options;
- options.cpu_overuse_detection.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
- observer = vie_.GetCpuOveruseObserver(channel0);
- ASSERT_TRUE(observer != NULL);
- observer->OveruseDetected();
-
- cricket::VideoCodec send_codec(100, "VP8", 640, 480, 30, 0);
- std::vector<cricket::VideoCodec> codecs;
- codecs.push_back(send_codec);
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
- EXPECT_TRUE(channel_->SetSend(true));
-
- // Capture format VGA -> adapt (OnCpuResolutionRequest downgrade) -> VGA/2.
- EXPECT_TRUE(video_capturer.CaptureFrame());
- VerifyVP8SendCodec(
- channel0, 3 * send_codec.width / 4, 3 * send_codec.height / 4, 0,
- kMaxBandwidthKbps, kMinBandwidthKbps, kStartBandwidthKbps,
- send_codec.framerate);
-
- // Trigger upgrade and verify that we adapt back up to VGA.
- observer->NormalUsage();
- EXPECT_TRUE(video_capturer.CaptureFrame());
- VerifyVP8SendCodec(
- channel0, send_codec.width, send_codec.height, 0,
- kMaxBandwidthKbps, kMinBandwidthKbps, kStartBandwidthKbps,
- send_codec.framerate);
-
- // Verify that the CpuOveruseObserver is deregistered.
- EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], NULL));
- EXPECT_TRUE(vie_.GetCpuOveruseObserver(channel0) == NULL);
-}
-
-TEST_F(WebRtcVideoEngineSimulcastTestFake,
- TestAdaptWithCpuOveruseObserverDisabled) {
- EXPECT_TRUE(SetupEngine());
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs3))));
-
- // Verify that the CpuOveruseObserver is not set by default.
- const int channel0 = vie_.GetChannelFromLocalSsrc(kSsrcs3[0]);
- ASSERT_NE(-1, channel0);
- webrtc::CpuOveruseObserver* observer = vie_.GetCpuOveruseObserver(channel0);
- EXPECT_TRUE(observer == NULL);
-
- // Capture format VGA.
- cricket::FakeVideoCapturer video_capturer;
- const std::vector<cricket::VideoFormat>* formats =
- video_capturer.GetSupportedFormats();
- cricket::VideoFormat capture_format_vga = (*formats)[1];
- EXPECT_EQ(cricket::CS_RUNNING, video_capturer.Start(capture_format_vga));
- EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], &video_capturer));
-
- // Disable cpu overuse detection.
- cricket::VideoOptions options;
- options.cpu_overuse_detection.Set(false);
- EXPECT_TRUE(channel_->SetOptions(options));
- cricket::CoordinatedVideoAdapter* video_adapter = NULL;
- ASSERT_TRUE(channel_->GetVideoAdapter(0u, &video_adapter));
- EXPECT_FALSE(video_adapter->cpu_adaptation());
-
- // Verify that the CpuOveruseObserver is registered and trigger downgrade.
- observer = vie_.GetCpuOveruseObserver(channel0);
- ASSERT_TRUE(observer != NULL);
- observer->OveruseDetected();
-
- cricket::VideoCodec send_codec(100, "VP8", 640, 480, 30, 0);
- std::vector<cricket::VideoCodec> codecs;
- codecs.push_back(send_codec);
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
- EXPECT_TRUE(channel_->SetSend(true));
-
- // Capture format VGA -> no adapt -> VGA.
- EXPECT_TRUE(video_capturer.CaptureFrame());
- VerifyVP8SendCodec(
- channel0, capture_format_vga.width, capture_format_vga.height, 0,
- kMaxBandwidthKbps, kMinBandwidthKbps, kStartBandwidthKbps,
- send_codec.framerate);
-
- // Verify that the CpuOveruseObserver is deregistered.
- EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], NULL));
- EXPECT_TRUE(vie_.GetCpuOveruseObserver(channel0) == NULL);
-}
-
-TEST_F(WebRtcVideoEngineSimulcastTestFake, GetAdaptStats) {
- EXPECT_TRUE(SetupEngine());
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs3))));
-
- // Capture format VGA.
- cricket::FakeVideoCapturer video_capturer_vga;
- const std::vector<cricket::VideoFormat>* formats =
- video_capturer_vga.GetSupportedFormats();
- cricket::VideoFormat capture_format_vga = (*formats)[1];
- EXPECT_EQ(cricket::CS_RUNNING, video_capturer_vga.Start(capture_format_vga));
- EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], &video_capturer_vga));
- EXPECT_TRUE(video_capturer_vga.CaptureFrame());
-
- cricket::VideoCodec send_codec(100, "VP8", 640, 480, 30, 0);
- std::vector<cricket::VideoCodec> codecs;
- codecs.push_back(send_codec);
- EXPECT_TRUE(channel_->SetSendCodecs(codecs));
- EXPECT_TRUE(channel_->SetSend(true));
-
- // Verify that the CpuOveruseObserver is registered and trigger downgrade.
- cricket::VideoOptions options;
- options.cpu_overuse_detection.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
- const int channel0 = vie_.GetChannelFromLocalSsrc(kSsrcs3[0]);
- ASSERT_NE(-1, channel0);
- webrtc::CpuOveruseObserver* observer = vie_.GetCpuOveruseObserver(channel0);
- ASSERT_TRUE(observer != NULL);
- observer->OveruseDetected();
-
- // Capture format VGA -> adapt (OnCpuResolutionRequest downgrade) -> VGA/2.
- EXPECT_TRUE(video_capturer_vga.CaptureFrame());
- cricket::VideoMediaInfo info;
- EXPECT_TRUE(channel_->GetStats(&info));
- ASSERT_EQ(1U, info.senders.size());
- EXPECT_EQ(1, info.senders[0].adapt_changes);
- EXPECT_EQ(cricket::CoordinatedVideoAdapter::ADAPTREASON_CPU,
- info.senders[0].adapt_reason);
-
- // Trigger upgrade and verify that we adapt back up to VGA.
- observer->NormalUsage();
- EXPECT_TRUE(video_capturer_vga.CaptureFrame());
- info.Clear();
- EXPECT_TRUE(channel_->GetStats(&info));
- ASSERT_EQ(1U, info.senders.size());
- EXPECT_EQ(2, info.senders[0].adapt_changes);
- EXPECT_EQ(cricket::CoordinatedVideoAdapter::ADAPTREASON_NONE,
- info.senders[0].adapt_reason);
-
- // No capturer (no adapter). Adapt changes from old adapter should be kept.
- EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], NULL));
- EXPECT_TRUE(vie_.GetCpuOveruseObserver(channel0) == NULL);
- info.Clear();
- EXPECT_TRUE(channel_->GetStats(&info));
- ASSERT_EQ(1U, info.senders.size());
- EXPECT_EQ(2, info.senders[0].adapt_changes);
- EXPECT_EQ(cricket::CoordinatedVideoAdapter::ADAPTREASON_NONE,
- info.senders[0].adapt_reason);
-
- // Set new capturer, capture format HD.
- cricket::FakeVideoCapturer video_capturer_hd;
- cricket::VideoFormat capture_format_hd = (*formats)[0];
- EXPECT_EQ(cricket::CS_RUNNING, video_capturer_hd.Start(capture_format_hd));
- EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], &video_capturer_hd));
- EXPECT_TRUE(video_capturer_hd.CaptureFrame());
- observer = vie_.GetCpuOveruseObserver(channel0);
- ASSERT_TRUE(observer != NULL);
-
- // Trigger overuse, HD -> adapt (OnCpuResolutionRequest downgrade) -> HD/2.
- observer->OveruseDetected();
- EXPECT_TRUE(video_capturer_hd.CaptureFrame());
- info.Clear();
- EXPECT_TRUE(channel_->GetStats(&info));
- ASSERT_EQ(1U, info.senders.size());
- EXPECT_EQ(3, info.senders[0].adapt_changes);
- EXPECT_EQ(cricket::CoordinatedVideoAdapter::ADAPTREASON_CPU,
- info.senders[0].adapt_reason);
-
- EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], NULL));
-}
-
-// Test that the codec is not reset for every frame sent in
-// non-conference and non-screencast mode.
-TEST_F(WebRtcVideoEngineSimulcastTestFake, DontResetCodecOnSendFrame) {
- EXPECT_TRUE(SetupEngine());
-
- // Set send codec.
- cricket::VideoCodec codec(kVP8Codec);
- std::vector<cricket::VideoCodec> codec_list;
- codec_list.push_back(codec);
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::StreamParams::CreateLegacy(123)));
- SendI420Frame(kVP8Codec.width, kVP8Codec.height);
- EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
- EXPECT_TRUE(channel_->SetSend(true));
- EXPECT_EQ(1, vie_.GetNumSetSendCodecs());
-
- SendI420Frame(kVP8Codec.width, kVP8Codec.height);
- EXPECT_EQ(1, vie_.GetNumSetSendCodecs());
- SendI420Frame(kVP8Codec.width, kVP8Codec.height);
- EXPECT_EQ(1, vie_.GetNumSetSendCodecs());
-}
-
-TEST_F(WebRtcVideoEngineSimulcastTestFake,
- UseSimulcastAdapterOnVp8OnlyFactory) {
- encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
- TestSimulcastAdapter(kVP8Codec, true);
-}
-
-TEST_F(WebRtcVideoEngineSimulcastTestFake,
- UsesSimulcastAdapterForVp8WithCombinedVP8AndH264Factory) {
- encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
- encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecGeneric,
- "H264");
- TestSimulcastAdapter(kVP8Codec, true);
-}
-
-TEST_F(WebRtcVideoEngineSimulcastTestFake,
- DontUseSimulcastAdapterForH264WithCombinedVP8AndH264Factory) {
- encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
- encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecGeneric,
- "H264");
- static const cricket::VideoCodec kH264Codec(100, "H264", 640, 400, 30, 0);
- TestSimulcastAdapter(kH264Codec, false);
-}
-
-TEST_F(WebRtcVideoEngineSimulcastTestFake,
- DontUseSimulcastAdapterOnNonVp8Factory) {
- encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecGeneric,
- "H264");
- static const cricket::VideoCodec kH264Codec(100, "H264", 640, 400, 30, 0);
- TestSimulcastAdapter(kH264Codec, false);
-}
-
-// Flaky on Windows and tsan. https://code.google.com/p/webrtc/issues/detail?id=4135
-#if defined(WIN32) || defined(THREAD_SANITIZER)
-#define MAYBE_SimulcastSend_1280x800 DISABLED_SimulcastSend_1280x800
-#else
-#define MAYBE_SimulcastSend_1280x800 SimulcastSend_1280x800
-#endif
-TEST_F(WebRtcVideoMediaChannelSimulcastTest, MAYBE_SimulcastSend_1280x800) {
- cricket::VideoCodec codec = kVP8Codec;
- codec.width = 1280;
- codec.height = 800;
- // TODO(zhurunz): Support 3 layers of simulcast.
- SimulcastSend(codec, MAKE_VECTOR(kSsrcs2));
-}
-
-// Flaky on Windows and tsan. https://code.google.com/p/webrtc/issues/detail?id=4135
-#if defined(WIN32) || defined(THREAD_SANITIZER)
-#define MAYBE_SimulcastSend_1280x720 DISABLED_SimulcastSend_1280x720
-#else
-#define MAYBE_SimulcastSend_1280x720 SimulcastSend_1280x720
-#endif
-TEST_F(WebRtcVideoMediaChannelSimulcastTest, MAYBE_SimulcastSend_1280x720) {
- cricket::VideoCodec codec = kVP8Codec;
- codec.width = 1280;
- codec.height = 720;
- // TODO(zhurunz): Support 3 layers of simulcast.
- SimulcastSend(codec, MAKE_VECTOR(kSsrcs2));
-}
-
-// Flaky on Windows and tsan. https://code.google.com/p/webrtc/issues/detail?id=4135
-#if defined(WIN32) || defined(THREAD_SANITIZER)
-#define MAYBE_SimulcastSend_960x540 DISABLED_SimulcastSend_960x540
-#else
-#define MAYBE_SimulcastSend_960x540 SimulcastSend_960x540
-#endif
-TEST_F(WebRtcVideoMediaChannelSimulcastTest, MAYBE_SimulcastSend_960x540) {
- cricket::VideoCodec codec = kVP8Codec;
- codec.width = 960;
- codec.height = 540;
- // TODO(zhurunz): Support 3 layers of simulcast.
- SimulcastSend(codec, MAKE_VECTOR(kSsrcs2));
-}
-
-// Flaky on Windows and tsan. https://code.google.com/p/webrtc/issues/detail?id=4135
-#if defined(WIN32) || defined(THREAD_SANITIZER)
-#define MAYBE_SimulcastSend_960x600 DISABLED_SimulcastSend_960x600
-#else
-#define MAYBE_SimulcastSend_960x600 SimulcastSend_960x600
-#endif
-TEST_F(WebRtcVideoMediaChannelSimulcastTest, MAYBE_SimulcastSend_960x600) {
- cricket::VideoCodec codec = kVP8Codec;
- codec.width = 960;
- codec.height = 600;
- // TODO(zhurunz): Support 3 layers of simulcast.
- SimulcastSend(codec, MAKE_VECTOR(kSsrcs2));
-}
-
-// Flaky on Windows and tsan. https://code.google.com/p/webrtc/issues/detail?id=4135
-#if defined(WIN32) || defined(THREAD_SANITIZER)
-#define MAYBE_SimulcastSend_640x400 DISABLED_SimulcastSend_640x400
-#else
-#define MAYBE_SimulcastSend_640x400 SimulcastSend_640x400
-#endif
-TEST_F(WebRtcVideoMediaChannelSimulcastTest, MAYBE_SimulcastSend_640x400) {
- cricket::VideoCodec codec = kVP8Codec;
- codec.width = 640;
- codec.height = 400;
- SimulcastSend(codec, MAKE_VECTOR(kSsrcs2));
-}
-
-// Flaky on Windows and tsan. https://code.google.com/p/webrtc/issues/detail?id=4135
-#if defined(WIN32) || defined(THREAD_SANITIZER)
-#define MAYBE_SimulcastSend_640x360 DISABLED_SimulcastSend_640x360
-#else
-#define MAYBE_SimulcastSend_640x360 SimulcastSend_640x360
-#endif
-TEST_F(WebRtcVideoMediaChannelSimulcastTest, MAYBE_SimulcastSend_640x360) {
- cricket::VideoCodec codec = kVP8Codec;
- codec.width = 640;
- codec.height = 360;
- SimulcastSend(codec, MAKE_VECTOR(kSsrcs2));
-}
-
-// Flaky on Windows and tsan. https://code.google.com/p/webrtc/issues/detail?id=4135
-#if defined(WIN32) || defined(THREAD_SANITIZER)
-#define MAYBE_SimulcastSend_480x300 DISABLED_SimulcastSend_480x300
-#else
-#define MAYBE_SimulcastSend_480x300 SimulcastSend_480x300
-#endif
-TEST_F(WebRtcVideoMediaChannelSimulcastTest, MAYBE_SimulcastSend_480x300) {
- cricket::VideoCodec codec = kVP8Codec;
- codec.width = 480;
- codec.height = 300;
- SimulcastSend(codec, MAKE_VECTOR(kSsrcs2));
-}
-
-TEST_F(WebRtcVideoMediaChannelSimulcastTest, DISABLED_SimulcastSend_480x270) {
- cricket::VideoCodec codec = kVP8Codec;
- codec.width = 480;
- codec.height = 270;
- SimulcastSend(codec, MAKE_VECTOR(kSsrcs2));
-}
-
-// Flaky on Windows and tsan. https://code.google.com/p/webrtc/issues/detail?id=4135
-#if defined(WIN32) || defined(THREAD_SANITIZER)
-#define MAYBE_SimulcastSend_320x200 DISABLED_SimulcastSend_320x200
-#else
-#define MAYBE_SimulcastSend_320x200 SimulcastSend_320x200
-#endif
-TEST_F(WebRtcVideoMediaChannelSimulcastTest, MAYBE_SimulcastSend_320x200) {
- cricket::VideoCodec codec = kVP8Codec;
- codec.width = 320;
- codec.height = 200;
- SimulcastSend(codec, MAKE_VECTOR(kSsrcs1));
-}
-
-// Flaky on Windows and tsan. https://code.google.com/p/webrtc/issues/detail?id=4135
-#if defined(WIN32) || defined(THREAD_SANITIZER)
-#define MAYBE_SimulcastSend_320x180 DISABLED_SimulcastSend_320x180
-#else
-#define MAYBE_SimulcastSend_320x180 SimulcastSend_320x180
-#endif
-TEST_F(WebRtcVideoMediaChannelSimulcastTest, MAYBE_SimulcastSend_320x180) {
- cricket::VideoCodec codec = kVP8Codec;
- codec.width = 320;
- codec.height = 180;
- SimulcastSend(codec, MAKE_VECTOR(kSsrcs1));
-}
-
-// Test reset send codec with simulcast.
-// Disabled per b/6773425
-TEST_F(WebRtcVideoMediaChannelSimulcastTest, DISABLED_SimulcastResetSendCodec) {
- // Remove stream added in Setup.
- EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
-
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs2))));
- cricket::VideoCodec codec(DefaultCodec());
- EXPECT_TRUE(SetOneCodec(codec));
- EXPECT_TRUE(SetSend(true));
- int packets = 0;
-
- // Send the first frame with default format size.
- EXPECT_TRUE(SendFrame());
- EXPECT_TRUE_WAIT(NumRtpPackets() > packets, kTimeout);
- DrainOutgoingPackets();
- packets = NumRtpPackets();
-
- // Simulate capture frame size changes.
- // Verify there is new rtp packet coming out of the encoder.
-
- // Send an odd frame.
- EXPECT_TRUE(SendCustomVideoFrame(DefaultCodec().width | 0x01,
- DefaultCodec().height | 0x01));
- EXPECT_TRUE_WAIT(NumRtpPackets() > packets, kTimeout);
- packets = DrainOutgoingPackets();
-
- // Send a small frame in width.
- EXPECT_TRUE(SendCustomVideoFrame(DefaultCodec().width / 2,
- DefaultCodec().height));
- EXPECT_TRUE_WAIT(NumRtpPackets() > packets, kTimeout);
- packets = DrainOutgoingPackets();
-
- // Send a small frame in height.
- EXPECT_TRUE(SendCustomVideoFrame(DefaultCodec().width,
- DefaultCodec().height / 2));
- EXPECT_TRUE_WAIT(NumRtpPackets() > packets, kTimeout);
- packets = DrainOutgoingPackets();
-
- // Send a big frame in width.
- EXPECT_TRUE(SendCustomVideoFrame(DefaultCodec().width * 2,
- DefaultCodec().height));
- EXPECT_TRUE_WAIT(NumRtpPackets() > packets, kTimeout);
- packets = DrainOutgoingPackets();
-
- // Send a big frame in height.
- EXPECT_TRUE(SendCustomVideoFrame(DefaultCodec().width,
- DefaultCodec().height * 2));
- EXPECT_TRUE_WAIT(NumRtpPackets() > packets, kTimeout);
- packets = DrainOutgoingPackets();
-
- // Send a normal frame.
- EXPECT_TRUE(SendCustomVideoFrame(DefaultCodec().width,
- DefaultCodec().height));
- EXPECT_TRUE_WAIT(NumRtpPackets() > packets, kTimeout);
- packets = DrainOutgoingPackets();
-}
-
-// Test simulcast streams are decodeable with expected sizes.
-TEST_F(WebRtcVideoMediaChannelSimulcastTest, SimulcastStreams) {
- // Remove stream added in Setup.
- EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
-
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs2))));
- cricket::VideoCodec codec(DefaultCodec());
- EXPECT_TRUE(SetOneCodec(codec));
-
- // Re-configure capturer.
- channel_->SetCapturer(kSsrc, NULL);
- EXPECT_TRUE(channel_->SetCapturer(kSsrcs2[0], video_capturer_.get()));
- cricket::VideoFormat capture_format(codec.width, codec.height,
- cricket::VideoFormat::FpsToInterval(codec.framerate),
- cricket::FOURCC_I420);
- EXPECT_EQ(cricket::CS_RUNNING, video_capturer_->Start(capture_format));
-
- EXPECT_TRUE(SetSend(true));
-
- cricket::FakeVideoRenderer renderer1, renderer2;
- EXPECT_TRUE(channel_->AddRecvStream(
- cricket::StreamParams::CreateLegacy(kSsrcs2[0])));
- EXPECT_TRUE(channel_->AddRecvStream(
- cricket::StreamParams::CreateLegacy(kSsrcs2[1])));
- EXPECT_TRUE(channel_->SetRenderer(kSsrcs2[0], &renderer1));
- EXPECT_TRUE(channel_->SetRenderer(kSsrcs2[1], &renderer2));
- EXPECT_TRUE(channel_->SetRender(true));
- EXPECT_EQ(0, renderer1.num_rendered_frames());
- EXPECT_EQ(0, renderer2.num_rendered_frames());
-
- EXPECT_TRUE(SendFrame());
- EXPECT_FRAME_ON_RENDERER_WAIT(renderer1, 1,
- DefaultCodec().width / 2, DefaultCodec().height / 2, kTimeout);
- EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1,
- DefaultCodec().width, DefaultCodec().height, kTimeout);
- EXPECT_EQ(1, renderer1.num_set_sizes());
- EXPECT_EQ(1, renderer2.num_set_sizes());
-}
-
-// Simulcast and resolution resizing should be turned off when screencasting
-// but not otherwise.
-// TODO(dmunene): Fix flaky test with bug 15773660.
-TEST_F(WebRtcVideoMediaChannelSimulcastTest, DISABLED_ScreencastRendering) {
- // Remove stream added in SetUp.
- EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
-
- cricket::VideoOptions options;
- options.conference_mode.Set(true);
- EXPECT_TRUE(channel_->SetOptions(options));
-
- // Setup a simulcast stream and verify that frames are rendered on
- // both renderers.
- EXPECT_TRUE(channel_->AddSendStream(
- cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs2))));
- cricket::VideoCodec codec(DefaultCodec());
- EXPECT_TRUE(SetOneCodec(codec));
- EXPECT_TRUE(SetSend(true));
-
- cricket::FakeVideoRenderer renderer1, renderer2;
- EXPECT_TRUE(channel_->AddRecvStream(
- cricket::StreamParams::CreateLegacy(kSsrcs2[0])));
- EXPECT_TRUE(channel_->AddRecvStream(
- cricket::StreamParams::CreateLegacy(kSsrcs2[1])));
- EXPECT_TRUE(channel_->SetRenderer(kSsrcs2[0], &renderer1));
- EXPECT_TRUE(channel_->SetRenderer(kSsrcs2[1], &renderer2));
- EXPECT_TRUE(channel_->SetRender(true));
- EXPECT_EQ(0, renderer1.num_rendered_frames());
- EXPECT_EQ(0, renderer2.num_rendered_frames());
-
- // Re-configure capturer.
- channel_->SetCapturer(kSsrc, NULL);
- EXPECT_TRUE(channel_->SetCapturer(kSsrcs2[0], video_capturer_.get()));
- EXPECT_TRUE(channel_->SetCapturer(kSsrcs2[1], video_capturer_.get()));
- cricket::VideoFormat capture_format(codec.width, codec.height,
- cricket::VideoFormat::FpsToInterval(codec.framerate),
- cricket::FOURCC_I420);
- EXPECT_EQ(cricket::CS_RUNNING, video_capturer_->Start(capture_format));
-
- EXPECT_TRUE(SendFrame());
- EXPECT_FRAME_ON_RENDERER_WAIT(renderer1, 1, codec.width / 2, codec.height / 2,
- kTimeout);
- EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, codec.width, codec.height,
- kTimeout);
-
- // Register a fake screencast capturer and verify that frames are only
- // rendered to a single renderer.
- rtc::scoped_ptr<cricket::FakeVideoCapturer> capturer(
- new cricket::FakeVideoCapturer);
- capturer->SetScreencast(true);
- const std::vector<cricket::VideoFormat>* formats =
- capturer->GetSupportedFormats();
- capture_format = (*formats)[0];
- EXPECT_EQ(cricket::CS_RUNNING, capturer->Start(capture_format));
- // Capture a frame to increment the frame timestamp since the default video
- // capturer starts at the same timestamp.
- EXPECT_TRUE(capturer->CaptureFrame());
- EXPECT_TRUE(channel_->SetCapturer(kSsrcs2[0], capturer.get()));
- EXPECT_TRUE(rtc::Thread::Current()->ProcessMessages(30));
- EXPECT_TRUE(capturer->CaptureFrame());
- EXPECT_FRAME_ON_RENDERER_WAIT(renderer1, 2, capture_format.width,
- capture_format.height, kTimeout);
- // When screencasting we only encode a single stream (no simulcast), which is
- // why we only expect frames to be rendered in one of the renderers.
- EXPECT_EQ(1, renderer2.num_rendered_frames());
-
- // Disable screencast and make sure frames are now rendered in both renderers.
- EXPECT_TRUE(channel_->SetCapturer(kSsrcs2[0], NULL));
- EXPECT_FRAME_ON_RENDERER_WAIT(renderer1, 3, codec.width / 2, codec.height / 2,
- kTimeout);
- EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 2, codec.width, codec.height,
- kTimeout);
-}
-
-// Disable for TSan v2, see
-// https://code.google.com/p/webrtc/issues/detail?id=3525 for details.
-#if !defined(THREAD_SANITIZER)
-// Ensures that the correct settings are applied to the codec when two temporal
-// layer screencasting is enabled, and that the correct simulcast settings are
-// reapplied when disabling screencasting.
-TEST_F(WebRtcVideoMediaChannelSimulcastTest, ConferenceModeScreencastSettings) {
- TestScreencastSettings();
-}
-#endif // if !defined(THREAD_SANITIZER)
diff --git a/talk/session/media/channelmanager.cc b/talk/session/media/channelmanager.cc
index e4de6d4..9c30a97 100644
--- a/talk/session/media/channelmanager.cc
+++ b/talk/session/media/channelmanager.cc
@@ -76,16 +76,6 @@
#endif
}
-#if !defined(DISABLE_MEDIA_ENGINE_FACTORY)
-ChannelManager::ChannelManager(rtc::Thread* worker_thread) {
- Construct(MediaEngineFactory::Create(),
- ConstructDataEngine(),
- cricket::DeviceManagerFactory::Create(),
- new CaptureManager(),
- worker_thread);
-}
-#endif
-
ChannelManager::ChannelManager(MediaEngineInterface* me,
DataEngineInterface* dme,
DeviceManagerInterface* dm,
diff --git a/talk/session/media/channelmanager.h b/talk/session/media/channelmanager.h
index ca95f65..a8eb88d 100644
--- a/talk/session/media/channelmanager.h
+++ b/talk/session/media/channelmanager.h
@@ -60,11 +60,6 @@
class ChannelManager : public rtc::MessageHandler,
public sigslot::has_slots<> {
public:
-#if !defined(DISABLE_MEDIA_ENGINE_FACTORY)
- // Creates the channel manager, and specifies the worker thread to use.
- explicit ChannelManager(rtc::Thread* worker);
-#endif
-
// For testing purposes. Allows the media engine and data media
// engine and dev manager to be mocks. The ChannelManager takes
// ownership of these objects.