diff --git a/talk/app/webrtc/peerconnectionfactory.cc b/talk/app/webrtc/peerconnectionfactory.cc index ee89e09fcd..a328bd0e92 100644 --- a/talk/app/webrtc/peerconnectionfactory.cc +++ b/talk/app/webrtc/peerconnectionfactory.cc @@ -111,9 +111,9 @@ enum { namespace webrtc { -talk_base::scoped_refptr +scoped_refptr CreatePeerConnectionFactory() { - talk_base::scoped_refptr pc_factory( + scoped_refptr pc_factory( new talk_base::RefCountedObject()); if (!pc_factory->Initialize()) { @@ -122,19 +122,17 @@ CreatePeerConnectionFactory() { return pc_factory; } -talk_base::scoped_refptr +scoped_refptr CreatePeerConnectionFactory( talk_base::Thread* worker_thread, talk_base::Thread* signaling_thread, AudioDeviceModule* default_adm, cricket::WebRtcVideoEncoderFactory* encoder_factory, cricket::WebRtcVideoDecoderFactory* decoder_factory) { - talk_base::scoped_refptr pc_factory( - new talk_base::RefCountedObject(worker_thread, - signaling_thread, - default_adm, - encoder_factory, - decoder_factory)); + scoped_refptr pc_factory( + new talk_base::RefCountedObject( + worker_thread, signaling_thread, default_adm, + encoder_factory, decoder_factory)); if (!pc_factory->Initialize()) { return NULL; } @@ -280,7 +278,7 @@ bool PeerConnectionFactory::StartAecDump_s(talk_base::PlatformFile file) { return channel_manager_->StartAecDump(file); } -talk_base::scoped_refptr +scoped_refptr PeerConnectionFactory::CreatePeerConnection( const PeerConnectionInterface::RTCConfiguration& configuration, const MediaConstraintsInterface* constraints, @@ -316,7 +314,7 @@ PeerConnectionFactory::CreatePeerConnection_s( return PeerConnectionProxy::Create(signaling_thread(), pc); } -talk_base::scoped_refptr +scoped_refptr PeerConnectionFactory::CreateLocalMediaStream(const std::string& label) { return MediaStreamProxy::Create(signaling_thread_, MediaStream::Create(label)); @@ -350,9 +348,9 @@ PeerConnectionFactory::CreateVideoTrack( return VideoTrackProxy::Create(signaling_thread_, track); } -talk_base::scoped_refptr -PeerConnectionFactory::CreateAudioTrack(const std::string& id, - AudioSourceInterface* source) { +scoped_refptr PeerConnectionFactory::CreateAudioTrack( + const std::string& id, + AudioSourceInterface* source) { talk_base::scoped_refptr track( AudioTrack::Create(id, source)); return AudioTrackProxy::Create(signaling_thread_, track); diff --git a/talk/libjingle.gyp b/talk/libjingle.gyp index 770bcd42dd..143e96b6e5 100755 --- a/talk/libjingle.gyp +++ b/talk/libjingle.gyp @@ -806,7 +806,7 @@ '<(DEPTH)/third_party/usrsctp/usrsctp.gyp:usrsctplib', '<(webrtc_root)/modules/modules.gyp:video_capture_module', '<(webrtc_root)/modules/modules.gyp:video_render_module', - '<(webrtc_root)/webrtc.gyp:webrtc', + '<(webrtc_root)/video_engine/video_engine.gyp:video_engine_core', '<(webrtc_root)/voice_engine/voice_engine.gyp:voice_engine', '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers', 'libjingle', @@ -889,8 +889,6 @@ 'media/webrtc/webrtcvideoencoderfactory.h', 'media/webrtc/webrtcvideoengine.cc', 'media/webrtc/webrtcvideoengine.h', - 'media/webrtc/webrtcvideoengine2.cc', - 'media/webrtc/webrtcvideoengine2.h', 'media/webrtc/webrtcvideoframe.cc', 'media/webrtc/webrtcvideoframe.h', 'media/webrtc/webrtcvie.h', diff --git a/talk/libjingle_tests.gyp b/talk/libjingle_tests.gyp index d21c77549d..f700261bc6 100755 --- a/talk/libjingle_tests.gyp +++ b/talk/libjingle_tests.gyp @@ -300,7 +300,6 @@ # 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', ], 'conditions': [ diff --git a/talk/media/base/codec.cc b/talk/media/base/codec.cc index 6d3a3f7f6a..2d54c9907a 100644 --- a/talk/media/base/codec.cc +++ b/talk/media/base/codec.cc @@ -31,7 +31,6 @@ #include #include "talk/base/common.h" -#include "talk/base/logging.h" #include "talk/base/stringencode.h" #include "talk/base/stringutils.h" @@ -161,55 +160,6 @@ std::string VideoCodec::ToString() const { return os.str(); } -VideoCodec VideoCodec::CreateRtxCodec(int rtx_payload_type, - int associated_payload_type) { - VideoCodec rtx_codec(rtx_payload_type, kRtxCodecName, 0, 0, 0, 0); - rtx_codec.SetParam(kCodecParamAssociatedPayloadType, associated_payload_type); - return rtx_codec; -} - -VideoCodec::CodecType VideoCodec::GetCodecType() const { - const char* payload_name = name.c_str(); - if (_stricmp(payload_name, kRedCodecName) == 0) { - return CODEC_RED; - } - if (_stricmp(payload_name, kUlpfecCodecName) == 0) { - return CODEC_ULPFEC; - } - if (_stricmp(payload_name, kRtxCodecName) == 0) { - return CODEC_RTX; - } - - return CODEC_VIDEO; -} - -bool VideoCodec::ValidateCodecFormat() const { - if (id < 0 || id > 127) { - LOG(LS_ERROR) << "Codec with invalid payload type: " << ToString(); - return false; - } - if (GetCodecType() != CODEC_VIDEO) { - return true; - } - - // Video validation from here on. - - if (width <= 0 || height <= 0) { - LOG(LS_ERROR) << "Codec with invalid dimensions: " << ToString(); - return false; - } - int min_bitrate; - int max_bitrate; - if (GetParam(kCodecParamMinBitrate, &min_bitrate) && - GetParam(kCodecParamMaxBitrate, &max_bitrate)) { - if (max_bitrate < min_bitrate) { - LOG(LS_ERROR) << "Codec with max < min bitrate: " << ToString(); - return false; - } - } - return true; -} - std::string DataCodec::ToString() const { std::ostringstream os; os << "DataCodec[" << id << ":" << name << "]"; diff --git a/talk/media/base/codec.h b/talk/media/base/codec.h index 0e9bf3ca07..120c17b0f7 100644 --- a/talk/media/base/codec.h +++ b/talk/media/base/codec.h @@ -246,22 +246,6 @@ struct VideoCodec : public Codec { bool operator!=(const VideoCodec& c) const { return !(*this == c); } - - static VideoCodec CreateRtxCodec(int rtx_payload_type, - int associated_payload_type); - - enum CodecType { - CODEC_VIDEO, - CODEC_RED, - CODEC_ULPFEC, - CODEC_RTX, - }; - - CodecType GetCodecType() const; - // Validates a VideoCodec's payload type, dimensions and bitrates etc. If they - // don't make sense (such as max < min bitrate), and error is logged and - // ValidateCodecFormat returns false. - bool ValidateCodecFormat() const; }; struct DataCodec : public Codec { diff --git a/talk/media/base/codec_unittest.cc b/talk/media/base/codec_unittest.cc index 35d1ab7613..f2bf4c70dc 100644 --- a/talk/media/base/codec_unittest.cc +++ b/talk/media/base/codec_unittest.cc @@ -34,9 +34,6 @@ using cricket::DataCodec; using cricket::FeedbackParam; using cricket::VideoCodec; using cricket::VideoEncoderConfig; -using cricket::kCodecParamAssociatedPayloadType; -using cricket::kCodecParamMaxBitrate; -using cricket::kCodecParamMinBitrate; class CodecTest : public testing::Test { public: @@ -315,81 +312,3 @@ TEST_F(CodecTest, TestIntersectFeedbackParams) { EXPECT_FALSE(c1.HasFeedbackParam(b2)); EXPECT_FALSE(c1.HasFeedbackParam(c3)); } - -TEST_F(CodecTest, TestGetCodecType) { - // Codec type comparison should be case insenstive on names. - const VideoCodec codec(96, "V", 320, 200, 30, 3); - const VideoCodec rtx_codec(96, "rTx", 320, 200, 30, 3); - const VideoCodec ulpfec_codec(96, "ulpFeC", 320, 200, 30, 3); - const VideoCodec red_codec(96, "ReD", 320, 200, 30, 3); - EXPECT_EQ(VideoCodec::CODEC_VIDEO, codec.GetCodecType()); - EXPECT_EQ(VideoCodec::CODEC_RTX, rtx_codec.GetCodecType()); - EXPECT_EQ(VideoCodec::CODEC_ULPFEC, ulpfec_codec.GetCodecType()); - EXPECT_EQ(VideoCodec::CODEC_RED, red_codec.GetCodecType()); -} - -TEST_F(CodecTest, TestCreateRtxCodec) { - VideoCodec rtx_codec = VideoCodec::CreateRtxCodec(96, 120); - EXPECT_EQ(96, rtx_codec.id); - EXPECT_EQ(VideoCodec::CODEC_RTX, rtx_codec.GetCodecType()); - int associated_payload_type; - ASSERT_TRUE(rtx_codec.GetParam(kCodecParamAssociatedPayloadType, - &associated_payload_type)); - EXPECT_EQ(120, associated_payload_type); -} - -TEST_F(CodecTest, TestValidateCodecFormat) { - const VideoCodec codec(96, "V", 320, 200, 30, 3); - ASSERT_TRUE(codec.ValidateCodecFormat()); - - // Accept 0-127 as payload types. - VideoCodec low_payload_type = codec; - low_payload_type.id = 0; - VideoCodec high_payload_type = codec; - high_payload_type.id = 127; - ASSERT_TRUE(low_payload_type.ValidateCodecFormat()); - EXPECT_TRUE(high_payload_type.ValidateCodecFormat()); - - // Reject negative payloads. - VideoCodec negative_payload_type = codec; - negative_payload_type.id = -1; - EXPECT_FALSE(negative_payload_type.ValidateCodecFormat()); - - // Reject too-high payloads. - VideoCodec too_high_payload_type = codec; - too_high_payload_type.id = 128; - EXPECT_FALSE(too_high_payload_type.ValidateCodecFormat()); - - // Reject zero-width codecs. - VideoCodec zero_width = codec; - zero_width.width = 0; - EXPECT_FALSE(zero_width.ValidateCodecFormat()); - - // Reject zero-height codecs. - VideoCodec zero_height = codec; - zero_height.height = 0; - EXPECT_FALSE(zero_height.ValidateCodecFormat()); - - // Accept non-video codecs with zero dimensions. - VideoCodec zero_width_rtx_codec = VideoCodec::CreateRtxCodec(96, 120); - zero_width_rtx_codec.width = 0; - EXPECT_TRUE(zero_width_rtx_codec.ValidateCodecFormat()); - - // Reject codecs with min bitrate > max bitrate. - VideoCodec incorrect_bitrates = codec; - incorrect_bitrates.params[kCodecParamMinBitrate] = "100"; - incorrect_bitrates.params[kCodecParamMaxBitrate] = "80"; - EXPECT_FALSE(incorrect_bitrates.ValidateCodecFormat()); - - // Accept min bitrate == max bitrate. - VideoCodec equal_bitrates = codec; - equal_bitrates.params[kCodecParamMinBitrate] = "100"; - equal_bitrates.params[kCodecParamMaxBitrate] = "100"; - EXPECT_TRUE(equal_bitrates.ValidateCodecFormat()); - - // Accept min bitrate < max bitrate. - VideoCodec different_bitrates = codec; - different_bitrates.params[kCodecParamMinBitrate] = "99"; - different_bitrates.params[kCodecParamMaxBitrate] = "100"; - EXPECT_TRUE(different_bitrates.ValidateCodecFormat()); -} diff --git a/talk/media/base/constants.cc b/talk/media/base/constants.cc index cd10ef75f3..e81a537f06 100644 --- a/talk/media/base/constants.cc +++ b/talk/media/base/constants.cc @@ -40,8 +40,6 @@ const float kLowSystemCpuThreshold = 0.65f; const float kProcessCpuThreshold = 0.10f; const char kRtxCodecName[] = "rtx"; -const char kRedCodecName[] = "red"; -const char kUlpfecCodecName[] = "ulpfec"; // RTP payload type is in the 0-127 range. Use 128 to indicate "all" payload // types. diff --git a/talk/media/base/constants.h b/talk/media/base/constants.h index dc5405d172..6a2302e3df 100644 --- a/talk/media/base/constants.h +++ b/talk/media/base/constants.h @@ -44,9 +44,6 @@ extern const float kLowSystemCpuThreshold; extern const float kProcessCpuThreshold; extern const char kRtxCodecName[]; -extern const char kRedCodecName[]; -extern const char kUlpfecCodecName[]; - // Codec parameters extern const int kWildcardPayloadType; diff --git a/talk/media/webrtc/webrtcvideochannelfactory.h b/talk/media/webrtc/webrtcvideochannelfactory.h deleted file mode 100644 index 646348cd55..0000000000 --- a/talk/media/webrtc/webrtcvideochannelfactory.h +++ /dev/null @@ -1,44 +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_WEBRTC_WEBRTCVIDEOCHANNEL_H_ -#define TALK_MEDIA_WEBRTC_WEBRTCVIDEOCHANNEL_H_ - -namespace cricket { -class VoiceMediaChannel; -class WebRtcVideoEngine2; -class WebRtcVideoChannel2; - -class WebRtcVideoChannelFactory { - public: - virtual ~WebRtcVideoChannelFactory() {} - virtual WebRtcVideoChannel2* Create(WebRtcVideoEngine2* engine, - VoiceMediaChannel* voice_channel) = 0; -}; -} // namespace cricket - -#endif // TALK_MEDIA_WEBRTC_WEBRTCVIDEOCHANNEL_H_ diff --git a/talk/media/webrtc/webrtcvideoengine2.cc b/talk/media/webrtc/webrtcvideoengine2.cc deleted file mode 100644 index 68492ce190..0000000000 --- a/talk/media/webrtc/webrtcvideoengine2.cc +++ /dev/null @@ -1,1658 +0,0 @@ -/* - * libjingle - * Copyright 2014 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/webrtcvideoengine2.h" - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include - -#include "libyuv/convert_from.h" -#include "talk/base/buffer.h" -#include "talk/base/logging.h" -#include "talk/base/stringutils.h" -#include "talk/media/base/videocapturer.h" -#include "talk/media/base/videorenderer.h" -#include "talk/media/webrtc/webrtcvideocapturer.h" -#include "talk/media/webrtc/webrtcvideoframe.h" -#include "talk/media/webrtc/webrtcvoiceengine.h" -#include "webrtc/call.h" -// TODO(pbos): Move codecs out of modules (webrtc:3070). -#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h" - -#define UNIMPLEMENTED \ - LOG(LS_ERROR) << "Call to unimplemented function " << __FUNCTION__; \ - ASSERT(false) - -namespace cricket { - -static const int kCpuMonitorPeriodMs = 2000; // 2 seconds. - -// This constant is really an on/off, lower-level configurable NACK history -// duration hasn't been implemented. -static const int kNackHistoryMs = 1000; - -static const int kDefaultFramerate = 30; -static const int kMinVideoBitrate = 50; -static const int kMaxVideoBitrate = 2000; - -static const int kVideoMtu = 1200; -static const int kVideoRtpBufferSize = 65536; - -static const char kVp8PayloadName[] = "VP8"; - -static const int kDefaultRtcpReceiverReportSsrc = 1; - -struct VideoCodecPref { - int payload_type; - const char* name; - int rtx_payload_type; -} kDefaultVideoCodecPref = {100, kVp8PayloadName, 96}; - -VideoCodecPref kRedPref = {116, kRedCodecName, -1}; -VideoCodecPref kUlpfecPref = {117, kUlpfecCodecName, -1}; - -// The formats are sorted by the descending order of width. We use the order to -// find the next format for CPU and bandwidth adaptation. -const VideoFormatPod kDefaultVideoFormat = { - 640, 400, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}; -const VideoFormatPod kVideoFormats[] = { - {1280, 800, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, - {1280, 720, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, - {960, 600, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, - {960, 540, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, - kDefaultVideoFormat, - {640, 360, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, - {640, 480, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, - {480, 300, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, - {480, 270, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, - {480, 360, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, - {320, 200, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, - {320, 180, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, - {320, 240, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, - {240, 150, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, - {240, 135, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, - {240, 180, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, - {160, 100, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, - {160, 90, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, - {160, 120, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, }; - -static bool FindFirstMatchingCodec(const std::vector& codecs, - const VideoCodec& requested_codec, - VideoCodec* matching_codec) { - for (size_t i = 0; i < codecs.size(); ++i) { - if (requested_codec.Matches(codecs[i])) { - *matching_codec = codecs[i]; - return true; - } - } - return false; -} -static bool FindBestVideoFormat(int max_width, - int max_height, - int aspect_width, - int aspect_height, - VideoFormat* video_format) { - assert(max_width > 0); - assert(max_height > 0); - assert(aspect_width > 0); - assert(aspect_height > 0); - VideoFormat best_format; - for (int i = 0; i < ARRAY_SIZE(kVideoFormats); ++i) { - const VideoFormat format(kVideoFormats[i]); - - // Skip any format that is larger than the local or remote maximums, or - // smaller than the current best match - if (format.width > max_width || format.height > max_height || - (format.width < best_format.width && - format.height < best_format.height)) { - continue; - } - - // If we don't have any matches yet, this is the best so far. - if (best_format.width == 0) { - best_format = format; - continue; - } - - // Prefer closer aspect ratios i.e: - // |format| aspect - requested aspect < - // |best_format| aspect - requested aspect - if (abs(format.width * aspect_height * best_format.height - - aspect_width * format.height * best_format.height) < - abs(best_format.width * aspect_height * format.height - - aspect_width * format.height * best_format.height)) { - best_format = format; - } - } - if (best_format.width != 0) { - *video_format = best_format; - return true; - } - return false; -} - -static VideoCodec DefaultVideoCodec() { - VideoCodec default_codec(kDefaultVideoCodecPref.payload_type, - kDefaultVideoCodecPref.name, - kDefaultVideoFormat.width, - kDefaultVideoFormat.height, - kDefaultFramerate, - 0); - return default_codec; -} - -static VideoCodec DefaultRedCodec() { - return VideoCodec(kRedPref.payload_type, kRedPref.name, 0, 0, 0, 0); -} - -static VideoCodec DefaultUlpfecCodec() { - return VideoCodec(kUlpfecPref.payload_type, kUlpfecPref.name, 0, 0, 0, 0); -} - -static std::vector DefaultVideoCodecs() { - std::vector codecs; - codecs.push_back(DefaultVideoCodec()); - codecs.push_back(DefaultRedCodec()); - codecs.push_back(DefaultUlpfecCodec()); - if (kDefaultVideoCodecPref.rtx_payload_type != -1) { - codecs.push_back( - VideoCodec::CreateRtxCodec(kDefaultVideoCodecPref.rtx_payload_type, - kDefaultVideoCodecPref.payload_type)); - } - return codecs; -} - -class DefaultVideoEncoderFactory : public WebRtcVideoEncoderFactory2 { - public: - virtual bool CreateEncoderSettings( - webrtc::VideoSendStream::Config::EncoderSettings* encoder_settings, - const VideoOptions& options, - const VideoCodec& codec, - size_t num_streams) OVERRIDE { - if (num_streams != 1) { - LOG(LS_ERROR) << "Unsupported number of streams: " << num_streams; - return false; - } - if (!SupportsCodec(codec)) { - LOG(LS_ERROR) << "Can't create encoder settings for unsupported codec: '" - << codec.name << "'"; - return false; - } - - *encoder_settings = webrtc::VideoSendStream::Config::EncoderSettings(); - - webrtc::VideoStream stream; - stream.width = codec.width; - stream.height = codec.height; - stream.max_framerate = - codec.framerate != 0 ? codec.framerate : kDefaultFramerate; - - int min_bitrate = kMinVideoBitrate; - codec.GetParam(kCodecParamMinBitrate, &min_bitrate); - int max_bitrate = kMaxVideoBitrate; - codec.GetParam(kCodecParamMaxBitrate, &max_bitrate); - stream.min_bitrate_bps = min_bitrate * 1000; - stream.target_bitrate_bps = stream.max_bitrate_bps = max_bitrate * 1000; - - int max_qp = 56; - codec.GetParam(kCodecParamMaxQuantization, &max_qp); - stream.max_qp = max_qp; - encoder_settings->streams.push_back(stream); - - encoder_settings->encoder = webrtc::VP8Encoder::Create(); - encoder_settings->payload_type = kDefaultVideoCodecPref.payload_type; - encoder_settings->payload_name = kDefaultVideoCodecPref.name; - - return true; - } - - virtual bool SupportsCodec(const VideoCodec& codec) OVERRIDE { - return _stricmp(codec.name.c_str(), kVp8PayloadName) == 0; - } -} default_encoder_factory; - -WebRtcVideoEngine2::WebRtcVideoEngine2() { - // Construct without a factory or voice engine. - Construct(NULL, NULL, new talk_base::CpuMonitor(NULL)); -} - -WebRtcVideoEngine2::WebRtcVideoEngine2( - WebRtcVideoChannelFactory* channel_factory) { - // Construct without a voice engine. - Construct(channel_factory, NULL, new talk_base::CpuMonitor(NULL)); -} - -void WebRtcVideoEngine2::Construct(WebRtcVideoChannelFactory* channel_factory, - WebRtcVoiceEngine* voice_engine, - talk_base::CpuMonitor* cpu_monitor) { - LOG(LS_INFO) << "WebRtcVideoEngine2::WebRtcVideoEngine2"; - worker_thread_ = NULL; - voice_engine_ = voice_engine; - initialized_ = false; - capture_started_ = false; - cpu_monitor_.reset(cpu_monitor); - channel_factory_ = channel_factory; - - video_codecs_ = DefaultVideoCodecs(); - default_codec_format_ = VideoFormat(kDefaultVideoFormat); -} - -WebRtcVideoEngine2::~WebRtcVideoEngine2() { - LOG(LS_INFO) << "WebRtcVideoEngine2::~WebRtcVideoEngine2"; - - if (initialized_) { - Terminate(); - } -} - -bool WebRtcVideoEngine2::Init(talk_base::Thread* worker_thread) { - LOG(LS_INFO) << "WebRtcVideoEngine2::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(); - } - - initialized_ = true; - return true; -} - -void WebRtcVideoEngine2::Terminate() { - LOG(LS_INFO) << "WebRtcVideoEngine2::Terminate"; - - cpu_monitor_->Stop(); - - initialized_ = false; -} - -int WebRtcVideoEngine2::GetCapabilities() { return VIDEO_RECV | VIDEO_SEND; } - -bool WebRtcVideoEngine2::SetOptions(const VideoOptions& options) { - // TODO(pbos): Do we need this? This is a no-op in the existing - // WebRtcVideoEngine implementation. - LOG(LS_VERBOSE) << "SetOptions: " << options.ToString(); - // options_ = options; - return true; -} - -bool WebRtcVideoEngine2::SetDefaultEncoderConfig( - const VideoEncoderConfig& config) { - // TODO(pbos): Implement. Should be covered by corresponding unit tests. - LOG(LS_VERBOSE) << "SetDefaultEncoderConfig()"; - return true; -} - -VideoEncoderConfig WebRtcVideoEngine2::GetDefaultEncoderConfig() const { - return VideoEncoderConfig(DefaultVideoCodec()); -} - -WebRtcVideoChannel2* WebRtcVideoEngine2::CreateChannel( - VoiceMediaChannel* voice_channel) { - LOG(LS_INFO) << "CreateChannel: " - << (voice_channel != NULL ? "With" : "Without") - << " voice channel."; - WebRtcVideoChannel2* channel = - channel_factory_ != NULL - ? channel_factory_->Create(this, voice_channel) - : new WebRtcVideoChannel2( - this, voice_channel, GetDefaultVideoEncoderFactory()); - if (!channel->Init()) { - delete channel; - return NULL; - } - return channel; -} - -const std::vector& WebRtcVideoEngine2::codecs() const { - return video_codecs_; -} - -const std::vector& -WebRtcVideoEngine2::rtp_header_extensions() const { - return rtp_header_extensions_; -} - -void WebRtcVideoEngine2::SetLogging(int min_sev, const char* filter) { - // TODO(pbos): Set up logging. - LOG(LS_VERBOSE) << "SetLogging: " << min_sev << '"' << filter << '"'; - // if min_sev == -1, we keep the current log level. - if (min_sev < 0) { - assert(min_sev == -1); - return; - } -} - -bool WebRtcVideoEngine2::EnableTimedRender() { - // TODO(pbos): Figure out whether this can be removed. - return true; -} - -bool WebRtcVideoEngine2::SetLocalRenderer(VideoRenderer* renderer) { - // TODO(pbos): Implement or remove. Unclear which stream should be rendered - // locally even. - return true; -} - -// Checks to see whether we comprehend and could receive a particular codec -bool WebRtcVideoEngine2::FindCodec(const VideoCodec& in) { - // TODO(pbos): Probe encoder factory to figure out that the codec is supported - // if supported by the encoder factory. Add a corresponding test that fails - // with this code (that doesn't ask the factory). - for (int i = 0; i < ARRAY_SIZE(kVideoFormats); ++i) { - const VideoFormat fmt(kVideoFormats[i]); - if ((in.width != 0 || in.height != 0) && - (fmt.width != in.width || fmt.height != in.height)) { - continue; - } - for (size_t j = 0; j < video_codecs_.size(); ++j) { - VideoCodec codec(video_codecs_[j].id, video_codecs_[j].name, 0, 0, 0, 0); - if (codec.Matches(in)) { - return true; - } - } - } - return false; -} - -// Tells whether the |requested| codec can be transmitted or not. If it can be -// transmitted |out| is set with the best settings supported. Aspect ratio will -// be set as close to |current|'s as possible. If not set |requested|'s -// dimensions will be used for aspect ratio matching. -bool WebRtcVideoEngine2::CanSendCodec(const VideoCodec& requested, - const VideoCodec& current, - VideoCodec* out) { - assert(out != NULL); - // TODO(pbos): Implement. - - if (requested.width != requested.height && - (requested.height == 0 || requested.width == 0)) { - // 0xn and nx0 are invalid resolutions. - return false; - } - - VideoCodec matching_codec; - if (!FindFirstMatchingCodec(video_codecs_, requested, &matching_codec)) { - // Codec not supported. - return false; - } - - // Pick the best quality that is within their and our bounds and has the - // correct aspect ratio. - VideoFormat format; - if (requested.width == 0 && requested.height == 0) { - // Special case with resolution 0. The channel should not send frames. - } else { - int max_width = talk_base::_min(requested.width, matching_codec.width); - int max_height = talk_base::_min(requested.height, matching_codec.height); - int aspect_width = max_width; - int aspect_height = max_height; - if (current.width > 0 && current.height > 0) { - aspect_width = current.width; - aspect_height = current.height; - } - if (!FindBestVideoFormat( - max_width, max_height, aspect_width, aspect_height, &format)) { - return false; - } - } - - out->id = requested.id; - out->name = requested.name; - out->preference = requested.preference; - out->params = requested.params; - out->framerate = - talk_base::_min(requested.framerate, matching_codec.framerate); - out->width = format.width; - out->height = format.height; - out->params = requested.params; - out->feedback_params = requested.feedback_params; - return true; -} - -bool WebRtcVideoEngine2::SetVoiceEngine(WebRtcVoiceEngine* voice_engine) { - if (initialized_) { - LOG(LS_WARNING) << "SetVoiceEngine can not be called after Init"; - return false; - } - voice_engine_ = voice_engine; - return true; -} - -// Ignore spammy trace messages, mostly from the stats API when we haven't -// gotten RTCP info yet from the remote side. -bool WebRtcVideoEngine2::ShouldIgnoreTrace(const std::string& trace) { - static const char* const kTracesToIgnore[] = {NULL}; - for (const char* const* p = kTracesToIgnore; *p; ++p) { - if (trace.find(*p) == 0) { - return true; - } - } - return false; -} - -WebRtcVideoEncoderFactory2* WebRtcVideoEngine2::GetDefaultVideoEncoderFactory() - const { - return &default_encoder_factory; -} - -// Thin map between cricket::VideoFrame and an existing webrtc::I420VideoFrame -// to avoid having to copy the rendered VideoFrame prematurely. -// This implementation is only safe to use in a const context and should never -// be written to. -class WebRtcVideoRenderFrame : public cricket::VideoFrame { - public: - explicit WebRtcVideoRenderFrame(const webrtc::I420VideoFrame* frame) - : frame_(frame) {} - - virtual bool InitToBlack(int w, - int h, - size_t pixel_width, - size_t pixel_height, - int64 elapsed_time, - int64 time_stamp) OVERRIDE { - UNIMPLEMENTED; - return false; - } - - virtual bool Reset(uint32 fourcc, - int w, - int h, - int dw, - int dh, - uint8* sample, - size_t sample_size, - size_t pixel_width, - size_t pixel_height, - int64 elapsed_time, - int64 time_stamp, - int rotation) OVERRIDE { - UNIMPLEMENTED; - return false; - } - - virtual size_t GetWidth() const OVERRIDE { - return static_cast(frame_->width()); - } - virtual size_t GetHeight() const OVERRIDE { - return static_cast(frame_->height()); - } - - virtual const uint8* GetYPlane() const OVERRIDE { - return frame_->buffer(webrtc::kYPlane); - } - virtual const uint8* GetUPlane() const OVERRIDE { - return frame_->buffer(webrtc::kUPlane); - } - virtual const uint8* GetVPlane() const OVERRIDE { - return frame_->buffer(webrtc::kVPlane); - } - - virtual uint8* GetYPlane() OVERRIDE { - UNIMPLEMENTED; - return NULL; - } - virtual uint8* GetUPlane() OVERRIDE { - UNIMPLEMENTED; - return NULL; - } - virtual uint8* GetVPlane() OVERRIDE { - UNIMPLEMENTED; - return NULL; - } - - virtual int32 GetYPitch() const OVERRIDE { - return frame_->stride(webrtc::kYPlane); - } - virtual int32 GetUPitch() const OVERRIDE { - return frame_->stride(webrtc::kUPlane); - } - virtual int32 GetVPitch() const OVERRIDE { - return frame_->stride(webrtc::kVPlane); - } - - virtual void* GetNativeHandle() const OVERRIDE { return NULL; } - - virtual size_t GetPixelWidth() const OVERRIDE { return 1; } - virtual size_t GetPixelHeight() const OVERRIDE { return 1; } - - virtual int64 GetElapsedTime() const OVERRIDE { - // Convert millisecond render time to ns timestamp. - return frame_->render_time_ms() * talk_base::kNumNanosecsPerMillisec; - } - virtual int64 GetTimeStamp() const OVERRIDE { - // Convert 90K rtp timestamp to ns timestamp. - return (frame_->timestamp() / 90) * talk_base::kNumNanosecsPerMillisec; - } - virtual void SetElapsedTime(int64 elapsed_time) OVERRIDE { UNIMPLEMENTED; } - virtual void SetTimeStamp(int64 time_stamp) OVERRIDE { UNIMPLEMENTED; } - - virtual int GetRotation() const OVERRIDE { - UNIMPLEMENTED; - return ROTATION_0; - } - - virtual VideoFrame* Copy() const OVERRIDE { - UNIMPLEMENTED; - return NULL; - } - - virtual bool MakeExclusive() OVERRIDE { - UNIMPLEMENTED; - return false; - } - - virtual size_t CopyToBuffer(uint8* buffer, size_t size) const { - UNIMPLEMENTED; - return 0; - } - - // TODO(fbarchard): Refactor into base class and share with LMI - virtual size_t ConvertToRgbBuffer(uint32 to_fourcc, - uint8* buffer, - size_t size, - int stride_rgb) const OVERRIDE { - size_t width = GetWidth(); - size_t height = GetHeight(); - size_t needed = (stride_rgb >= 0 ? stride_rgb : -stride_rgb) * height; - if (size < needed) { - LOG(LS_WARNING) << "RGB buffer is not large enough"; - return needed; - } - - if (libyuv::ConvertFromI420(GetYPlane(), - GetYPitch(), - GetUPlane(), - GetUPitch(), - GetVPlane(), - GetVPitch(), - buffer, - stride_rgb, - static_cast(width), - static_cast(height), - to_fourcc)) { - LOG(LS_ERROR) << "RGB type not supported: " << to_fourcc; - return 0; // 0 indicates error - } - return needed; - } - - protected: - virtual VideoFrame* CreateEmptyFrame(int w, - int h, - size_t pixel_width, - size_t pixel_height, - int64 elapsed_time, - int64 time_stamp) const OVERRIDE { - // TODO(pbos): Remove WebRtcVideoFrame dependency, and have a non-const - // version of I420VideoFrame wrapped. - WebRtcVideoFrame* frame = new WebRtcVideoFrame(); - frame->InitToBlack( - w, h, pixel_width, pixel_height, elapsed_time, time_stamp); - return frame; - } - - private: - const webrtc::I420VideoFrame* const frame_; -}; - -WebRtcVideoRenderer::WebRtcVideoRenderer() - : last_width_(-1), last_height_(-1), renderer_(NULL) {} - -void WebRtcVideoRenderer::RenderFrame(const webrtc::I420VideoFrame& frame, - int time_to_render_ms) { - talk_base::CritScope crit(&lock_); - if (renderer_ == NULL) { - LOG(LS_WARNING) << "VideoReceiveStream not connected to a VideoRenderer."; - return; - } - - if (frame.width() != last_width_ || frame.height() != last_height_) { - SetSize(frame.width(), frame.height()); - } - - LOG(LS_VERBOSE) << "RenderFrame: (" << frame.width() << "x" << frame.height() - << ")"; - - const WebRtcVideoRenderFrame render_frame(&frame); - renderer_->RenderFrame(&render_frame); -} - -void WebRtcVideoRenderer::SetRenderer(cricket::VideoRenderer* renderer) { - talk_base::CritScope crit(&lock_); - renderer_ = renderer; - if (renderer_ != NULL && last_width_ != -1) { - SetSize(last_width_, last_height_); - } -} - -VideoRenderer* WebRtcVideoRenderer::GetRenderer() { - talk_base::CritScope crit(&lock_); - return renderer_; -} - -void WebRtcVideoRenderer::SetSize(int width, int height) { - talk_base::CritScope crit(&lock_); - if (!renderer_->SetSize(width, height, 0)) { - LOG(LS_ERROR) << "Could not set renderer size."; - } - last_width_ = width; - last_height_ = height; -} - -// WebRtcVideoChannel2 - -WebRtcVideoChannel2::WebRtcVideoChannel2( - WebRtcVideoEngine2* engine, - VoiceMediaChannel* voice_channel, - WebRtcVideoEncoderFactory2* encoder_factory) - : encoder_factory_(encoder_factory) { - // TODO(pbos): Connect the video and audio with |voice_channel|. - webrtc::Call::Config config(this); - Construct(webrtc::Call::Create(config), engine); -} - -WebRtcVideoChannel2::WebRtcVideoChannel2( - webrtc::Call* call, - WebRtcVideoEngine2* engine, - WebRtcVideoEncoderFactory2* encoder_factory) - : encoder_factory_(encoder_factory) { - Construct(call, engine); -} - -void WebRtcVideoChannel2::Construct(webrtc::Call* call, - WebRtcVideoEngine2* engine) { - rtcp_receiver_report_ssrc_ = kDefaultRtcpReceiverReportSsrc; - sending_ = false; - call_.reset(call); - default_renderer_ = NULL; - default_send_ssrc_ = 0; - default_recv_ssrc_ = 0; -} - -WebRtcVideoChannel2::~WebRtcVideoChannel2() { - for (std::map::iterator it = - send_streams_.begin(); - it != send_streams_.end(); - ++it) { - delete it->second; - } - - for (std::map::iterator it = - receive_streams_.begin(); - it != receive_streams_.end(); - ++it) { - assert(it->second != NULL); - call_->DestroyVideoReceiveStream(it->second); - } - - for (std::map::iterator it = renderers_.begin(); - it != renderers_.end(); - ++it) { - assert(it->second != NULL); - delete it->second; - } -} - -bool WebRtcVideoChannel2::Init() { return true; } - -namespace { - -static bool ValidateCodecFormats(const std::vector& codecs) { - for (size_t i = 0; i < codecs.size(); ++i) { - if (!codecs[i].ValidateCodecFormat()) { - return false; - } - } - return true; -} - -static std::string CodecVectorToString(const std::vector& codecs) { - std::stringstream out; - out << '{'; - for (size_t i = 0; i < codecs.size(); ++i) { - out << codecs[i].ToString(); - if (i != codecs.size() - 1) { - out << ", "; - } - } - out << '}'; - return out.str(); -} - -} // namespace - -bool WebRtcVideoChannel2::SetRecvCodecs(const std::vector& codecs) { - // TODO(pbos): Must these receive codecs propagate to existing receive - // streams? - LOG(LS_INFO) << "SetRecvCodecs: " << CodecVectorToString(codecs); - if (!ValidateCodecFormats(codecs)) { - return false; - } - - const std::vector mapped_codecs = MapCodecs(codecs); - if (mapped_codecs.empty()) { - LOG(LS_ERROR) << "SetRecvCodecs called without video codec payloads."; - return false; - } - - // TODO(pbos): Add a decoder factory which controls supported codecs. - // Blocked on webrtc:2854. - for (size_t i = 0; i < mapped_codecs.size(); ++i) { - if (_stricmp(mapped_codecs[i].codec.name.c_str(), kVp8PayloadName) != 0) { - LOG(LS_ERROR) << "SetRecvCodecs called with unsupported codec: '" - << mapped_codecs[i].codec.name << "'"; - return false; - } - } - - recv_codecs_ = mapped_codecs; - return true; -} - -bool WebRtcVideoChannel2::SetSendCodecs(const std::vector& codecs) { - LOG(LS_INFO) << "SetSendCodecs: " << CodecVectorToString(codecs); - if (!ValidateCodecFormats(codecs)) { - return false; - } - - const std::vector supported_codecs = - FilterSupportedCodecs(MapCodecs(codecs)); - - if (supported_codecs.empty()) { - LOG(LS_ERROR) << "No video codecs supported by encoder factory."; - return false; - } - - send_codec_.Set(supported_codecs.front()); - LOG(LS_INFO) << "Using codec: " << supported_codecs.front().codec.ToString(); - - SetCodecForAllSendStreams(supported_codecs.front()); - - return true; -} - -bool WebRtcVideoChannel2::GetSendCodec(VideoCodec* codec) { - VideoCodecSettings codec_settings; - if (!send_codec_.Get(&codec_settings)) { - LOG(LS_VERBOSE) << "GetSendCodec: No send codec set."; - return false; - } - *codec = codec_settings.codec; - return true; -} - -bool WebRtcVideoChannel2::SetSendStreamFormat(uint32 ssrc, - const VideoFormat& format) { - LOG(LS_VERBOSE) << "SetSendStreamFormat:" << ssrc << " -> " - << format.ToString(); - if (send_streams_.find(ssrc) == send_streams_.end()) { - return false; - } - return send_streams_[ssrc]->SetVideoFormat(format); -} - -bool WebRtcVideoChannel2::SetRender(bool render) { - // TODO(pbos): Implement. Or refactor away as it shouldn't be needed. - LOG(LS_VERBOSE) << "SetRender: " << (render ? "true" : "false"); - return true; -} - -bool WebRtcVideoChannel2::SetSend(bool send) { - LOG(LS_VERBOSE) << "SetSend: " << (send ? "true" : "false"); - if (send && !send_codec_.IsSet()) { - LOG(LS_ERROR) << "SetSend(true) called before setting codec."; - return false; - } - if (send) { - StartAllSendStreams(); - } else { - StopAllSendStreams(); - } - sending_ = send; - return true; -} - -static bool ConfigureSendSsrcs(webrtc::VideoSendStream::Config* config, - const StreamParams& sp) { - if (!sp.has_ssrc_groups()) { - config->rtp.ssrcs = sp.ssrcs; - return true; - } - - if (sp.get_ssrc_group(kFecSsrcGroupSemantics) != NULL) { - LOG(LS_ERROR) << "Standalone FEC SSRCs not supported."; - return false; - } - - const SsrcGroup* sim_group = sp.get_ssrc_group(kSimSsrcGroupSemantics); - if (sim_group == NULL) { - LOG(LS_ERROR) << "Grouped StreamParams without regular SSRC group: " - << sp.ToString(); - return false; - } - - // Map RTX SSRCs. - std::vector rtx_ssrcs; - for (size_t i = 0; i < sim_group->ssrcs.size(); ++i) { - uint32_t rtx_ssrc; - if (!sp.GetFidSsrc(sim_group->ssrcs[i], &rtx_ssrc)) { - continue; - } - rtx_ssrcs.push_back(rtx_ssrc); - } - if (!rtx_ssrcs.empty() && sim_group->ssrcs.size() != rtx_ssrcs.size()) { - LOG(LS_ERROR) - << "RTX SSRCs exist, but don't cover all SSRCs (unsupported): " - << sp.ToString(); - return false; - } - config->rtp.rtx.ssrcs = rtx_ssrcs; - config->rtp.ssrcs = sim_group->ssrcs; - return true; -} - -bool WebRtcVideoChannel2::AddSendStream(const StreamParams& sp) { - LOG(LS_INFO) << "AddSendStream: " << sp.ToString(); - if (sp.ssrcs.empty()) { - LOG(LS_ERROR) << "No SSRCs in stream parameters."; - return false; - } - - uint32 ssrc = sp.first_ssrc(); - assert(ssrc != 0); - // TODO(pbos): Make sure none of sp.ssrcs are used, not just the identifying - // ssrc. - if (send_streams_.find(ssrc) != send_streams_.end()) { - LOG(LS_ERROR) << "Send stream with ssrc '" << ssrc << "' already exists."; - return false; - } - - webrtc::VideoSendStream::Config config = call_->GetDefaultSendConfig(); - - if (!ConfigureSendSsrcs(&config, sp)) { - return false; - } - - VideoCodecSettings codec_settings; - if (!send_codec_.Get(&codec_settings)) { - // TODO(pbos): Set up a temporary fake encoder for VideoSendStream instead - // of setting default codecs not to break CreateEncoderSettings. - SetSendCodecs(DefaultVideoCodecs()); - assert(send_codec_.IsSet()); - send_codec_.Get(&codec_settings); - // This is only to bring up defaults to make VideoSendStream setup easier - // and avoid complexity. We still don't want to allow sending with the - // default codec. - send_codec_.Clear(); - } - - // CreateEncoderSettings will allocate a suitable VideoEncoder instance - // matching current settings. - if (!encoder_factory_->CreateEncoderSettings(&config.encoder_settings, - options_, - codec_settings.codec, - config.rtp.ssrcs.size())) { - LOG(LS_ERROR) << "Failed to create suitable encoder settings."; - return false; - } - - config.rtp.c_name = sp.cname; - config.rtp.fec = codec_settings.fec; - if (!config.rtp.rtx.ssrcs.empty()) { - config.rtp.rtx.payload_type = codec_settings.rtx_payload_type; - } - - config.rtp.nack.rtp_history_ms = kNackHistoryMs; - config.rtp.max_packet_size = kVideoMtu; - - WebRtcVideoSendStream* stream = - new WebRtcVideoSendStream(call_.get(), config, encoder_factory_); - send_streams_[ssrc] = stream; - - if (rtcp_receiver_report_ssrc_ == kDefaultRtcpReceiverReportSsrc) { - rtcp_receiver_report_ssrc_ = ssrc; - } - if (default_send_ssrc_ == 0) { - default_send_ssrc_ = ssrc; - } - if (sending_) { - stream->Start(); - } - - return true; -} - -bool WebRtcVideoChannel2::RemoveSendStream(uint32 ssrc) { - LOG(LS_INFO) << "RemoveSendStream: " << ssrc; - - if (ssrc == 0) { - if (default_send_ssrc_ == 0) { - LOG(LS_ERROR) << "No default send stream active."; - return false; - } - - LOG(LS_VERBOSE) << "Removing default stream: " << default_send_ssrc_; - ssrc = default_send_ssrc_; - } - - std::map::iterator it = - send_streams_.find(ssrc); - if (it == send_streams_.end()) { - return false; - } - - delete it->second; - send_streams_.erase(it); - - if (ssrc == default_send_ssrc_) { - default_send_ssrc_ = 0; - } - - return true; -} - -bool WebRtcVideoChannel2::AddRecvStream(const StreamParams& sp) { - LOG(LS_INFO) << "AddRecvStream: " << sp.ToString(); - assert(sp.ssrcs.size() > 0); - - uint32 ssrc = sp.first_ssrc(); - assert(ssrc != 0); // TODO(pbos): Is this ever valid? - if (default_recv_ssrc_ == 0) { - default_recv_ssrc_ = ssrc; - } - - // TODO(pbos): Check if any of the SSRCs overlap. - if (receive_streams_.find(ssrc) != receive_streams_.end()) { - LOG(LS_ERROR) << "Receive stream for SSRC " << ssrc << "already exists."; - return false; - } - - webrtc::VideoReceiveStream::Config config = call_->GetDefaultReceiveConfig(); - config.rtp.remote_ssrc = ssrc; - config.rtp.local_ssrc = rtcp_receiver_report_ssrc_; - uint32 rtx_ssrc = 0; - if (sp.GetFidSsrc(ssrc, &rtx_ssrc)) { - // TODO(pbos): Right now, VideoReceiveStream accepts any rtx payload, this - // should use the actual codec payloads that may be received. - // (for each receive payload, set rtx[payload].ssrc = rtx_ssrc. - config.rtp.rtx[0].ssrc = rtx_ssrc; - } - - config.rtp.remb = true; - // TODO(pbos): This protection is against setting the same local ssrc as - // remote which is not permitted by the lower-level API. RTCP requires a - // corresponding sender SSRC. Figure out what to do when we don't have - // (receive-only) or know a good local SSRC. - if (config.rtp.remote_ssrc == config.rtp.local_ssrc) { - if (config.rtp.local_ssrc != kDefaultRtcpReceiverReportSsrc) { - config.rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc; - } else { - config.rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc + 1; - } - } - bool default_renderer_used = false; - for (std::map::iterator it = renderers_.begin(); - it != renderers_.end(); - ++it) { - if (it->second->GetRenderer() == default_renderer_) { - default_renderer_used = true; - break; - } - } - - assert(renderers_[ssrc] == NULL); - renderers_[ssrc] = new WebRtcVideoRenderer(); - if (!default_renderer_used) { - renderers_[ssrc]->SetRenderer(default_renderer_); - } - config.renderer = renderers_[ssrc]; - - { - // TODO(pbos): Base receive codecs off recv_codecs_ and set up using a - // DecoderFactory similar to send side. Pending webrtc:2854. - // Also set up default codecs if there's nothing in recv_codecs_. - webrtc::VideoCodec codec; - memset(&codec, 0, sizeof(codec)); - - codec.plType = kDefaultVideoCodecPref.payload_type; - strcpy(codec.plName, kDefaultVideoCodecPref.name); - codec.codecType = webrtc::kVideoCodecVP8; - codec.codecSpecific.VP8.resilience = webrtc::kResilientStream; - codec.codecSpecific.VP8.numberOfTemporalLayers = 1; - codec.codecSpecific.VP8.denoisingOn = true; - codec.codecSpecific.VP8.errorConcealmentOn = false; - codec.codecSpecific.VP8.automaticResizeOn = false; - codec.codecSpecific.VP8.frameDroppingOn = true; - codec.codecSpecific.VP8.keyFrameInterval = 3000; - // Bitrates don't matter and are ignored for the receiver. This is put in to - // have the current underlying implementation accept the VideoCodec. - codec.minBitrate = codec.startBitrate = codec.maxBitrate = 300; - config.codecs.push_back(codec); - for (size_t i = 0; i < recv_codecs_.size(); ++i) { - if (recv_codecs_[i].codec.id == codec.plType) { - config.rtp.fec = recv_codecs_[i].fec; - if (recv_codecs_[i].rtx_payload_type != -1 && rtx_ssrc != 0) { - config.rtp.rtx[codec.plType].ssrc = rtx_ssrc; - config.rtp.rtx[codec.plType].payload_type = - recv_codecs_[i].rtx_payload_type; - } - break; - } - } - } - - webrtc::VideoReceiveStream* receive_stream = - call_->CreateVideoReceiveStream(config); - assert(receive_stream != NULL); - - receive_streams_[ssrc] = receive_stream; - receive_stream->Start(); - - return true; -} - -bool WebRtcVideoChannel2::RemoveRecvStream(uint32 ssrc) { - LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; - if (ssrc == 0) { - ssrc = default_recv_ssrc_; - } - - std::map::iterator stream = - receive_streams_.find(ssrc); - if (stream == receive_streams_.end()) { - LOG(LS_ERROR) << "Stream not found for ssrc: " << ssrc; - return false; - } - call_->DestroyVideoReceiveStream(stream->second); - receive_streams_.erase(stream); - - std::map::iterator renderer = - renderers_.find(ssrc); - assert(renderer != renderers_.end()); - delete renderer->second; - renderers_.erase(renderer); - - if (ssrc == default_recv_ssrc_) { - default_recv_ssrc_ = 0; - } - - return true; -} - -bool WebRtcVideoChannel2::SetRenderer(uint32 ssrc, VideoRenderer* renderer) { - LOG(LS_INFO) << "SetRenderer: ssrc:" << ssrc << " " - << (renderer ? "(ptr)" : "NULL"); - bool is_default_ssrc = false; - if (ssrc == 0) { - is_default_ssrc = true; - ssrc = default_recv_ssrc_; - default_renderer_ = renderer; - } - - std::map::iterator it = renderers_.find(ssrc); - if (it == renderers_.end()) { - return is_default_ssrc; - } - - it->second->SetRenderer(renderer); - return true; -} - -bool WebRtcVideoChannel2::GetRenderer(uint32 ssrc, VideoRenderer** renderer) { - if (ssrc == 0) { - if (default_renderer_ == NULL) { - return false; - } - *renderer = default_renderer_; - return true; - } - - std::map::iterator it = renderers_.find(ssrc); - if (it == renderers_.end()) { - return false; - } - *renderer = it->second->GetRenderer(); - return true; -} - -bool WebRtcVideoChannel2::GetStats(const StatsOptions& options, - VideoMediaInfo* info) { - // TODO(pbos): Implement. - return true; -} - -bool WebRtcVideoChannel2::SetCapturer(uint32 ssrc, VideoCapturer* capturer) { - LOG(LS_INFO) << "SetCapturer: " << ssrc << " -> " - << (capturer != NULL ? "(capturer)" : "NULL"); - assert(ssrc != 0); - if (send_streams_.find(ssrc) == send_streams_.end()) { - LOG(LS_ERROR) << "No sending stream on ssrc " << ssrc; - return false; - } - return send_streams_[ssrc]->SetCapturer(capturer); -} - -bool WebRtcVideoChannel2::SendIntraFrame() { - // TODO(pbos): Implement. - LOG(LS_VERBOSE) << "SendIntraFrame()."; - return true; -} - -bool WebRtcVideoChannel2::RequestIntraFrame() { - // TODO(pbos): Implement. - LOG(LS_VERBOSE) << "SendIntraFrame()."; - return true; -} - -void WebRtcVideoChannel2::OnPacketReceived( - talk_base::Buffer* packet, - const talk_base::PacketTime& packet_time) { - if (call_->Receiver()->DeliverPacket( - reinterpret_cast(packet->data()), packet->length())) { - return; - } - // Packet ignored most likely because there's no receiver for it, try to - // create one unless it already exists. - - uint32 ssrc = 0; - if (default_recv_ssrc_ != 0) { // Already one default stream. - LOG(LS_WARNING) << "Default receive stream already set."; - return; - } - - if (!GetRtpSsrc(packet->data(), packet->length(), &ssrc)) { - return; - } - - StreamParams sp; - sp.ssrcs.push_back(ssrc); - AddRecvStream(sp); - - if (!call_->Receiver()->DeliverPacket( - reinterpret_cast(packet->data()), packet->length())) { - LOG(LS_WARNING) << "Failed to deliver RTP packet."; - return; - } -} - -void WebRtcVideoChannel2::OnRtcpReceived( - talk_base::Buffer* packet, - const talk_base::PacketTime& packet_time) { - if (!call_->Receiver()->DeliverPacket( - reinterpret_cast(packet->data()), packet->length())) { - LOG(LS_WARNING) << "Failed to deliver RTCP packet."; - } -} - -void WebRtcVideoChannel2::OnReadyToSend(bool ready) { - LOG(LS_VERBOSE) << "OnReadySend: " << (ready ? "Ready." : "Not ready."); -} - -bool WebRtcVideoChannel2::MuteStream(uint32 ssrc, bool mute) { - LOG(LS_VERBOSE) << "MuteStream: " << ssrc << " -> " - << (mute ? "mute" : "unmute"); - assert(ssrc != 0); - if (send_streams_.find(ssrc) == send_streams_.end()) { - LOG(LS_ERROR) << "No sending stream on ssrc " << ssrc; - return false; - } - return send_streams_[ssrc]->MuteStream(mute); -} - -bool WebRtcVideoChannel2::SetRecvRtpHeaderExtensions( - const std::vector& extensions) { - // TODO(pbos): Implement. - LOG(LS_VERBOSE) << "SetRecvRtpHeaderExtensions()"; - return true; -} - -bool WebRtcVideoChannel2::SetSendRtpHeaderExtensions( - const std::vector& extensions) { - // TODO(pbos): Implement. - LOG(LS_VERBOSE) << "SetSendRtpHeaderExtensions()"; - return true; -} - -bool WebRtcVideoChannel2::SetStartSendBandwidth(int bps) { - // TODO(pbos): Implement. - LOG(LS_VERBOSE) << "SetStartSendBandwidth: " << bps; - return true; -} - -bool WebRtcVideoChannel2::SetMaxSendBandwidth(int bps) { - // TODO(pbos): Implement. - LOG(LS_VERBOSE) << "SetMaxSendBandwidth: " << bps; - return true; -} - -bool WebRtcVideoChannel2::SetOptions(const VideoOptions& options) { - LOG(LS_VERBOSE) << "SetOptions: " << options.ToString(); - options_.SetAll(options); - return true; -} - -void WebRtcVideoChannel2::SetInterface(NetworkInterface* iface) { - MediaChannel::SetInterface(iface); - // Set the RTP recv/send buffer to a bigger size - MediaChannel::SetOption(NetworkInterface::ST_RTP, - talk_base::Socket::OPT_RCVBUF, - kVideoRtpBufferSize); - - // TODO(sriniv): Remove or re-enable this. - // As part of b/8030474, send-buffer is size now controlled through - // portallocator flags. - // network_interface_->SetOption(NetworkInterface::ST_RTP, - // talk_base::Socket::OPT_SNDBUF, - // kVideoRtpBufferSize); -} - -void WebRtcVideoChannel2::UpdateAspectRatio(int ratio_w, int ratio_h) { - // TODO(pbos): Implement. -} - -void WebRtcVideoChannel2::OnMessage(talk_base::Message* msg) { - // Ignored. -} - -bool WebRtcVideoChannel2::SendRtp(const uint8_t* data, size_t len) { - talk_base::Buffer packet(data, len, kMaxRtpPacketLen); - return MediaChannel::SendPacket(&packet); -} - -bool WebRtcVideoChannel2::SendRtcp(const uint8_t* data, size_t len) { - talk_base::Buffer packet(data, len, kMaxRtpPacketLen); - return MediaChannel::SendRtcp(&packet); -} - -void WebRtcVideoChannel2::StartAllSendStreams() { - for (std::map::iterator it = - send_streams_.begin(); - it != send_streams_.end(); - ++it) { - it->second->Start(); - } -} - -void WebRtcVideoChannel2::StopAllSendStreams() { - for (std::map::iterator it = - send_streams_.begin(); - it != send_streams_.end(); - ++it) { - it->second->Stop(); - } -} - -void WebRtcVideoChannel2::SetCodecForAllSendStreams( - const WebRtcVideoChannel2::VideoCodecSettings& codec) { - for (std::map::iterator it = - send_streams_.begin(); - it != send_streams_.end(); - ++it) { - assert(it->second != NULL); - it->second->SetCodec(options_, codec); - } -} - -WebRtcVideoChannel2::WebRtcVideoSendStream::WebRtcVideoSendStream( - webrtc::Call* call, - const webrtc::VideoSendStream::Config& config, - WebRtcVideoEncoderFactory2* encoder_factory) - : call_(call), - config_(config), - encoder_factory_(encoder_factory), - capturer_(NULL), - stream_(NULL), - sending_(false), - muted_(false), - format_(static_cast(config.encoder_settings.streams.back().height), - static_cast(config.encoder_settings.streams.back().width), - VideoFormat::FpsToInterval( - config.encoder_settings.streams.back().max_framerate), - FOURCC_I420) { - RecreateWebRtcStream(); -} - -WebRtcVideoChannel2::WebRtcVideoSendStream::~WebRtcVideoSendStream() { - DisconnectCapturer(); - call_->DestroyVideoSendStream(stream_); - delete config_.encoder_settings.encoder; -} - -static void SetWebRtcFrameToBlack(webrtc::I420VideoFrame* video_frame) { - assert(video_frame != NULL); - memset(video_frame->buffer(webrtc::kYPlane), - 16, - video_frame->allocated_size(webrtc::kYPlane)); - memset(video_frame->buffer(webrtc::kUPlane), - 128, - video_frame->allocated_size(webrtc::kUPlane)); - memset(video_frame->buffer(webrtc::kVPlane), - 128, - video_frame->allocated_size(webrtc::kVPlane)); -} - -static void CreateBlackFrame(webrtc::I420VideoFrame* video_frame, - int width, - int height) { - video_frame->CreateEmptyFrame( - width, height, width, (width + 1) / 2, (width + 1) / 2); - SetWebRtcFrameToBlack(video_frame); -} - -static void ConvertToI420VideoFrame(const VideoFrame& frame, - webrtc::I420VideoFrame* i420_frame) { - i420_frame->CreateFrame( - static_cast(frame.GetYPitch() * frame.GetHeight()), - frame.GetYPlane(), - static_cast(frame.GetUPitch() * ((frame.GetHeight() + 1) / 2)), - frame.GetUPlane(), - static_cast(frame.GetVPitch() * ((frame.GetHeight() + 1) / 2)), - frame.GetVPlane(), - static_cast(frame.GetWidth()), - static_cast(frame.GetHeight()), - static_cast(frame.GetYPitch()), - static_cast(frame.GetUPitch()), - static_cast(frame.GetVPitch())); -} - -void WebRtcVideoChannel2::WebRtcVideoSendStream::InputFrame( - VideoCapturer* capturer, - const VideoFrame* frame) { - LOG(LS_VERBOSE) << "InputFrame: " << frame->GetWidth() << "x" - << frame->GetHeight(); - bool is_screencast = capturer->IsScreencast(); - // Lock before copying, can be called concurrently when swapping input source. - talk_base::CritScope frame_cs(&frame_lock_); - if (!muted_) { - ConvertToI420VideoFrame(*frame, &video_frame_); - } else { - // Create a tiny black frame to transmit instead. - CreateBlackFrame(&video_frame_, 1, 1); - is_screencast = false; - } - talk_base::CritScope cs(&lock_); - if (format_.width == 0) { // Dropping frames. - assert(format_.height == 0); - LOG(LS_VERBOSE) << "VideoFormat 0x0 set, Dropping frame."; - return; - } - // Reconfigure codec if necessary. - if (is_screencast) { - SetDimensions(video_frame_.width(), video_frame_.height()); - } - LOG(LS_VERBOSE) << "SwapFrame: " << video_frame_.width() << "x" - << video_frame_.height() << " -> (codec) " - << config_.encoder_settings.streams.back().width << "x" - << config_.encoder_settings.streams.back().height; - stream_->Input()->SwapFrame(&video_frame_); -} - -bool WebRtcVideoChannel2::WebRtcVideoSendStream::SetCapturer( - VideoCapturer* capturer) { - if (!DisconnectCapturer() && capturer == NULL) { - return false; - } - - { - talk_base::CritScope cs(&lock_); - - if (capturer == NULL) { - LOG(LS_VERBOSE) << "Disabling capturer, sending black frame."; - webrtc::I420VideoFrame black_frame; - - int width = format_.width; - int height = format_.height; - int half_width = (width + 1) / 2; - black_frame.CreateEmptyFrame( - width, height, width, half_width, half_width); - SetWebRtcFrameToBlack(&black_frame); - SetDimensions(width, height); - stream_->Input()->SwapFrame(&black_frame); - - capturer_ = NULL; - return true; - } - - capturer_ = capturer; - } - // Lock cannot be held while connecting the capturer to prevent lock-order - // violations. - capturer->SignalVideoFrame.connect(this, &WebRtcVideoSendStream::InputFrame); - return true; -} - -bool WebRtcVideoChannel2::WebRtcVideoSendStream::SetVideoFormat( - const VideoFormat& format) { - if ((format.width == 0 || format.height == 0) && - format.width != format.height) { - LOG(LS_ERROR) << "Can't set VideoFormat, width or height is zero (but not " - "both, 0x0 drops frames)."; - return false; - } - - talk_base::CritScope cs(&lock_); - if (format.width == 0 && format.height == 0) { - LOG(LS_INFO) - << "0x0 resolution selected. Captured frames will be dropped for ssrc: " - << config_.rtp.ssrcs[0] << "."; - } else { - // TODO(pbos): Fix me, this only affects the last stream! - config_.encoder_settings.streams.back().max_framerate = - VideoFormat::IntervalToFps(format.interval); - SetDimensions(format.width, format.height); - } - - format_ = format; - return true; -} - -bool WebRtcVideoChannel2::WebRtcVideoSendStream::MuteStream(bool mute) { - talk_base::CritScope cs(&lock_); - bool was_muted = muted_; - muted_ = mute; - return was_muted != mute; -} - -bool WebRtcVideoChannel2::WebRtcVideoSendStream::DisconnectCapturer() { - talk_base::CritScope cs(&lock_); - if (capturer_ == NULL) { - return false; - } - capturer_->SignalVideoFrame.disconnect(this); - capturer_ = NULL; - return true; -} - -void WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodec( - const VideoOptions& options, - const VideoCodecSettings& codec) { - talk_base::CritScope cs(&lock_); - webrtc::VideoEncoder* old_encoder = config_.encoder_settings.encoder; - if (!encoder_factory_->CreateEncoderSettings( - &config_.encoder_settings, - options, - codec.codec, - config_.encoder_settings.streams.size())) { - LOG(LS_ERROR) << "Could not create encoder settings for: '" - << codec.codec.name - << "'. This is most definitely a bug as SetCodec should only " - "receive codecs which the encoder factory claims to " - "support."; - return; - } - format_ = VideoFormat(codec.codec.width, - codec.codec.height, - VideoFormat::FpsToInterval(30), - FOURCC_I420); - config_.rtp.fec = codec.fec; - // TODO(pbos): Should changing RTX payload type be allowed? - RecreateWebRtcStream(); - delete old_encoder; -} - -void WebRtcVideoChannel2::WebRtcVideoSendStream::SetDimensions(int width, - int height) { - assert(!config_.encoder_settings.streams.empty()); - LOG(LS_VERBOSE) << "SetDimensions: " << width << "x" << height; - if (config_.encoder_settings.streams.back().width == width && - config_.encoder_settings.streams.back().height == height) { - return; - } - - // TODO(pbos): Fix me, this only affects the last stream! - config_.encoder_settings.streams.back().width = width; - config_.encoder_settings.streams.back().height = height; - // TODO(pbos): Last parameter shouldn't always be NULL? - if (!stream_->ReconfigureVideoEncoder(config_.encoder_settings.streams, - NULL)) { - LOG(LS_WARNING) << "Failed to reconfigure video encoder for dimensions: " - << width << "x" << height; - return; - } -} - -void WebRtcVideoChannel2::WebRtcVideoSendStream::Start() { - talk_base::CritScope cs(&lock_); - stream_->Start(); - sending_ = true; -} - -void WebRtcVideoChannel2::WebRtcVideoSendStream::Stop() { - talk_base::CritScope cs(&lock_); - stream_->Stop(); - sending_ = false; -} - -void WebRtcVideoChannel2::WebRtcVideoSendStream::RecreateWebRtcStream() { - if (stream_ != NULL) { - call_->DestroyVideoSendStream(stream_); - } - stream_ = call_->CreateVideoSendStream(config_); - if (sending_) { - stream_->Start(); - } -} - -WebRtcVideoChannel2::VideoCodecSettings::VideoCodecSettings() - : rtx_payload_type(-1) {} - -std::vector -WebRtcVideoChannel2::MapCodecs(const std::vector& codecs) { - assert(!codecs.empty()); - - std::vector video_codecs; - std::map payload_used; - std::map rtx_mapping; // video payload type -> rtx payload type. - - webrtc::FecConfig fec_settings; - - for (size_t i = 0; i < codecs.size(); ++i) { - const VideoCodec& in_codec = codecs[i]; - int payload_type = in_codec.id; - - if (payload_used[payload_type]) { - LOG(LS_ERROR) << "Payload type already registered: " - << in_codec.ToString(); - return std::vector(); - } - payload_used[payload_type] = true; - - switch (in_codec.GetCodecType()) { - case VideoCodec::CODEC_RED: { - // RED payload type, should not have duplicates. - assert(fec_settings.red_payload_type == -1); - fec_settings.red_payload_type = in_codec.id; - continue; - } - - case VideoCodec::CODEC_ULPFEC: { - // ULPFEC payload type, should not have duplicates. - assert(fec_settings.ulpfec_payload_type == -1); - fec_settings.ulpfec_payload_type = in_codec.id; - continue; - } - - case VideoCodec::CODEC_RTX: { - int associated_payload_type; - if (!in_codec.GetParam(kCodecParamAssociatedPayloadType, - &associated_payload_type)) { - LOG(LS_ERROR) << "RTX codec without associated payload type: " - << in_codec.ToString(); - return std::vector(); - } - rtx_mapping[associated_payload_type] = in_codec.id; - continue; - } - - case VideoCodec::CODEC_VIDEO: - break; - } - - video_codecs.push_back(VideoCodecSettings()); - video_codecs.back().codec = in_codec; - } - - // One of these codecs should have been a video codec. Only having FEC - // parameters into this code is a logic error. - assert(!video_codecs.empty()); - - // TODO(pbos): Write tests that figure out that I have not verified that RTX - // codecs aren't mapped to bogus payloads. - for (size_t i = 0; i < video_codecs.size(); ++i) { - video_codecs[i].fec = fec_settings; - if (rtx_mapping[video_codecs[i].codec.id] != 0) { - video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; - } - } - - return video_codecs; -} - -std::vector -WebRtcVideoChannel2::FilterSupportedCodecs( - const std::vector& mapped_codecs) { - std::vector supported_codecs; - for (size_t i = 0; i < mapped_codecs.size(); ++i) { - if (encoder_factory_->SupportsCodec(mapped_codecs[i].codec)) { - supported_codecs.push_back(mapped_codecs[i]); - } - } - return supported_codecs; -} - -} // namespace cricket - -#endif // HAVE_WEBRTC_VIDEO diff --git a/talk/media/webrtc/webrtcvideoengine2.h b/talk/media/webrtc/webrtcvideoengine2.h deleted file mode 100644 index e6b9598b19..0000000000 --- a/talk/media/webrtc/webrtcvideoengine2.h +++ /dev/null @@ -1,332 +0,0 @@ -/* - * libjingle - * Copyright 2014 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_WEBRTC_WEBRTCVIDEOENGINE2_H_ -#define TALK_MEDIA_WEBRTC_WEBRTCVIDEOENGINE2_H_ - -#include -#include -#include - -#include "talk/base/cpumonitor.h" -#include "talk/base/scoped_ptr.h" -#include "talk/media/base/mediaengine.h" -#include "talk/media/webrtc/webrtcvideochannelfactory.h" -#include "webrtc/common_video/interface/i420_video_frame.h" -#include "webrtc/system_wrappers/interface/thread_annotations.h" -#include "webrtc/transport.h" -#include "webrtc/video_renderer.h" -#include "webrtc/video_send_stream.h" - -namespace webrtc { -class Call; -class VideoCaptureModule; -class VideoDecoder; -class VideoEncoder; -class VideoRender; -class VideoSendStreamInput; -class VideoReceiveStream; -} - -namespace talk_base { -class CpuMonitor; -class Thread; -} // namespace talk_base - -namespace cricket { - -class VideoCapturer; -class VideoFrame; -class VideoProcessor; -class VideoRenderer; -class VoiceMediaChannel; -class WebRtcVideoChannel2; -class WebRtcDecoderObserver; -class WebRtcEncoderObserver; -class WebRtcLocalStreamInfo; -class WebRtcRenderAdapter; -class WebRtcVideoChannelRecvInfo; -class WebRtcVideoChannelSendInfo; -class WebRtcVideoDecoderFactory; -class WebRtcVoiceEngine; - -struct CapturedFrame; -struct Device; - -class WebRtcVideoEngine2; -class WebRtcVideoChannel2; - -class WebRtcVideoEncoderFactory2 { - public: - virtual bool CreateEncoderSettings( - webrtc::VideoSendStream::Config::EncoderSettings* encoder_settings, - const VideoOptions& options, - const cricket::VideoCodec& codec, - size_t num_streams) = 0; - virtual bool SupportsCodec(const cricket::VideoCodec& codec) = 0; -}; - -// WebRtcVideoEngine2 is used for the new native WebRTC Video API (webrtc:1667). -class WebRtcVideoEngine2 : public sigslot::has_slots<> { - public: - // Creates the WebRtcVideoEngine2 with internal VideoCaptureModule. - WebRtcVideoEngine2(); - // Custom WebRtcVideoChannelFactory for testing purposes. - explicit WebRtcVideoEngine2(WebRtcVideoChannelFactory* channel_factory); - ~WebRtcVideoEngine2(); - - // Basic video engine implementation. - bool Init(talk_base::Thread* worker_thread); - void Terminate(); - - int GetCapabilities(); - bool SetOptions(const VideoOptions& options); - bool SetDefaultEncoderConfig(const VideoEncoderConfig& config); - VideoEncoderConfig GetDefaultEncoderConfig() const; - - WebRtcVideoChannel2* CreateChannel(VoiceMediaChannel* voice_channel); - - const std::vector& codecs() const; - const std::vector& rtp_header_extensions() const; - void SetLogging(int min_sev, const char* filter); - - bool EnableTimedRender(); - // No-op, never used. - bool SetLocalRenderer(VideoRenderer* renderer); - // This is currently ignored. - sigslot::repeater2 SignalCaptureStateChange; - - // Set the VoiceEngine for A/V sync. This can only be called before Init. - bool SetVoiceEngine(WebRtcVoiceEngine* voice_engine); - - // Functions called by WebRtcVideoChannel2. - const VideoFormat& default_codec_format() const { - return default_codec_format_; - } - - bool FindCodec(const VideoCodec& in); - bool CanSendCodec(const VideoCodec& in, - const VideoCodec& current, - VideoCodec* out); - // Check whether the supplied trace should be ignored. - bool ShouldIgnoreTrace(const std::string& trace); - - VideoFormat GetStartCaptureFormat() const { return default_codec_format_; } - - talk_base::CpuMonitor* cpu_monitor() { return cpu_monitor_.get(); } - - virtual WebRtcVideoEncoderFactory2* GetDefaultVideoEncoderFactory() const; - - private: - void Construct(WebRtcVideoChannelFactory* channel_factory, - WebRtcVoiceEngine* voice_engine, - talk_base::CpuMonitor* cpu_monitor); - - talk_base::Thread* worker_thread_; - WebRtcVoiceEngine* voice_engine_; - std::vector video_codecs_; - std::vector rtp_header_extensions_; - VideoFormat default_codec_format_; - - bool initialized_; - - bool capture_started_; - - // Critical section to protect the media processor register/unregister - // while processing a frame - talk_base::CriticalSection signal_media_critical_; - - talk_base::scoped_ptr cpu_monitor_; - WebRtcVideoChannelFactory* channel_factory_; -}; - -// Adapter between webrtc::VideoRenderer and cricket::VideoRenderer. -// The webrtc::VideoRenderer is set once, whereas the cricket::VideoRenderer can -// be set after initialization. This adapter will also convert the incoming -// webrtc::I420VideoFrame to a frame type that cricket::VideoRenderer can -// render. -class WebRtcVideoRenderer : public webrtc::VideoRenderer { - public: - WebRtcVideoRenderer(); - - virtual void RenderFrame(const webrtc::I420VideoFrame& frame, - int time_to_render_ms) OVERRIDE; - - void SetRenderer(cricket::VideoRenderer* renderer); - cricket::VideoRenderer* GetRenderer(); - - private: - void SetSize(int width, int height); - int last_width_; - int last_height_; - talk_base::CriticalSection lock_; - cricket::VideoRenderer* renderer_ GUARDED_BY(lock_); -}; - -class WebRtcVideoChannel2 : public talk_base::MessageHandler, - public VideoMediaChannel, - public webrtc::newapi::Transport { - public: - WebRtcVideoChannel2(WebRtcVideoEngine2* engine, - VoiceMediaChannel* voice_channel, - WebRtcVideoEncoderFactory2* encoder_factory); - // For testing purposes insert a pre-constructed call to verify that - // WebRtcVideoChannel2 calls the correct corresponding methods. - WebRtcVideoChannel2(webrtc::Call* call, - WebRtcVideoEngine2* engine, - WebRtcVideoEncoderFactory2* encoder_factory); - ~WebRtcVideoChannel2(); - bool Init(); - - // VideoMediaChannel implementation - virtual bool SetRecvCodecs(const std::vector& codecs) OVERRIDE; - virtual bool SetSendCodecs(const std::vector& codecs) OVERRIDE; - virtual bool GetSendCodec(VideoCodec* send_codec) OVERRIDE; - virtual bool SetSendStreamFormat(uint32 ssrc, - const VideoFormat& format) OVERRIDE; - virtual bool SetRender(bool render) OVERRIDE; - virtual bool SetSend(bool send) OVERRIDE; - - virtual bool AddSendStream(const StreamParams& sp) OVERRIDE; - virtual bool RemoveSendStream(uint32 ssrc) OVERRIDE; - virtual bool AddRecvStream(const StreamParams& sp) OVERRIDE; - virtual bool RemoveRecvStream(uint32 ssrc) OVERRIDE; - virtual bool SetRenderer(uint32 ssrc, VideoRenderer* renderer) OVERRIDE; - virtual bool GetStats(const StatsOptions& options, - VideoMediaInfo* info) OVERRIDE; - virtual bool SetCapturer(uint32 ssrc, VideoCapturer* capturer) OVERRIDE; - virtual bool SendIntraFrame() OVERRIDE; - virtual bool RequestIntraFrame() OVERRIDE; - - virtual void OnPacketReceived(talk_base::Buffer* packet, - const talk_base::PacketTime& packet_time) - OVERRIDE; - virtual void OnRtcpReceived(talk_base::Buffer* packet, - const talk_base::PacketTime& packet_time) - OVERRIDE; - virtual void OnReadyToSend(bool ready) OVERRIDE; - virtual bool MuteStream(uint32 ssrc, bool mute) OVERRIDE; - virtual bool SetRecvRtpHeaderExtensions( - const std::vector& extensions) OVERRIDE; - virtual bool SetSendRtpHeaderExtensions( - const std::vector& extensions) OVERRIDE; - virtual bool SetStartSendBandwidth(int bps) OVERRIDE; - virtual bool SetMaxSendBandwidth(int bps) OVERRIDE; - virtual bool SetOptions(const VideoOptions& options) OVERRIDE; - virtual bool GetOptions(VideoOptions* options) const OVERRIDE { - *options = options_; - return true; - } - virtual void SetInterface(NetworkInterface* iface) OVERRIDE; - virtual void UpdateAspectRatio(int ratio_w, int ratio_h) OVERRIDE; - - virtual void OnMessage(talk_base::Message* msg) OVERRIDE; - - // Implemented for VideoMediaChannelTest. - bool sending() const { return sending_; } - uint32 GetDefaultChannelSsrc() { return default_send_ssrc_; } - bool GetRenderer(uint32 ssrc, VideoRenderer** renderer); - - private: - struct VideoCodecSettings { - VideoCodecSettings(); - - cricket::VideoCodec codec; - webrtc::FecConfig fec; - int rtx_payload_type; - }; - - class WebRtcVideoSendStream : public sigslot::has_slots<> { - public: - WebRtcVideoSendStream(webrtc::Call* call, - const webrtc::VideoSendStream::Config& config, - WebRtcVideoEncoderFactory2* encoder_factory); - ~WebRtcVideoSendStream(); - void SetCodec(const VideoOptions& options, const VideoCodecSettings& codec); - - void InputFrame(VideoCapturer* capturer, const VideoFrame* frame); - bool SetCapturer(VideoCapturer* capturer); - bool SetVideoFormat(const VideoFormat& format); - bool MuteStream(bool mute); - bool DisconnectCapturer(); - - void Start(); - void Stop(); - - private: - void RecreateWebRtcStream(); - void SetDimensions(int width, int height); - - webrtc::Call* const call_; - WebRtcVideoEncoderFactory2* const encoder_factory_; - - talk_base::CriticalSection lock_; - webrtc::VideoSendStream* stream_ GUARDED_BY(lock_); - webrtc::VideoSendStream::Config config_ GUARDED_BY(lock_); - VideoCapturer* capturer_ GUARDED_BY(lock_); - bool sending_ GUARDED_BY(lock_); - bool muted_ GUARDED_BY(lock_); - VideoFormat format_ GUARDED_BY(lock_); - - talk_base::CriticalSection frame_lock_; - webrtc::I420VideoFrame video_frame_ GUARDED_BY(frame_lock_); - }; - - void Construct(webrtc::Call* call, WebRtcVideoEngine2* engine); - - virtual bool SendRtp(const uint8_t* data, size_t len) OVERRIDE; - virtual bool SendRtcp(const uint8_t* data, size_t len) OVERRIDE; - - void StartAllSendStreams(); - void StopAllSendStreams(); - void SetCodecForAllSendStreams(const VideoCodecSettings& codec); - static std::vector MapCodecs( - const std::vector& codecs); - std::vector FilterSupportedCodecs( - const std::vector& mapped_codecs); - - uint32_t rtcp_receiver_report_ssrc_; - bool sending_; - talk_base::scoped_ptr call_; - std::map renderers_; - VideoRenderer* default_renderer_; - uint32_t default_send_ssrc_; - uint32_t default_recv_ssrc_; - - // Using primary-ssrc (first ssrc) as key. - std::map send_streams_; - std::map receive_streams_; - - Settable send_codec_; - WebRtcVideoEncoderFactory2* const encoder_factory_; - std::vector recv_codecs_; - VideoOptions options_; -}; - -} // namespace cricket - -#endif // TALK_MEDIA_WEBRTC_WEBRTCVIDEOENGINE2_H_ diff --git a/talk/media/webrtc/webrtcvideoengine2_unittest.cc b/talk/media/webrtc/webrtcvideoengine2_unittest.cc deleted file mode 100644 index 4ef15a16cb..0000000000 --- a/talk/media/webrtc/webrtcvideoengine2_unittest.cc +++ /dev/null @@ -1,1187 +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 - -#include "talk/base/gunit.h" -#include "talk/media/base/testutils.h" -#include "talk/media/base/videoengine_unittest.h" -#include "talk/media/webrtc/webrtcvideoengine2.h" -#include "talk/media/webrtc/webrtcvideochannelfactory.h" -#include "webrtc/call.h" - -namespace { -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 kVp8Codec180p(100, "VP8", 320, 180, 30, 0); - -static const cricket::VideoCodec kVp8Codec(100, "VP8", 640, 400, 30, 0); -static const cricket::VideoCodec kVp9Codec(101, "VP9", 640, 400, 30, 0); -static const cricket::VideoCodec kRedCodec(116, "red", 0, 0, 0, 0); -static const cricket::VideoCodec kUlpfecCodec(117, "ulpfec", 0, 0, 0, 0); - -static const uint32 kSsrcs1[] = {1}; -static const uint32 kRtxSsrcs1[] = {4}; -} // namespace - -namespace cricket { -class FakeVideoSendStream : public webrtc::VideoSendStream { - public: - explicit FakeVideoSendStream(const webrtc::VideoSendStream::Config& config) - : sending_(false) { - config_ = config; - } - - webrtc::VideoSendStream::Config GetConfig() { return config_; } - - bool IsSending() { return sending_; } - - private: - virtual webrtc::VideoSendStream::Stats GetStats() const OVERRIDE { - return webrtc::VideoSendStream::Stats(); - } - - virtual bool ReconfigureVideoEncoder( - const std::vector& streams, - void* encoder_specific) OVERRIDE { - // TODO(pbos): Store encoder_specific ptr? - config_.encoder_settings.streams = streams; - return true; - } - - virtual webrtc::VideoSendStreamInput* Input() OVERRIDE { - // TODO(pbos): Fix. - return NULL; - } - - virtual void Start() OVERRIDE { sending_ = true; } - - virtual void Stop() OVERRIDE { sending_ = false; } - - bool sending_; - webrtc::VideoSendStream::Config config_; -}; - -class FakeVideoReceiveStream : public webrtc::VideoReceiveStream { - public: - explicit FakeVideoReceiveStream( - const webrtc::VideoReceiveStream::Config& config) - : config_(config), receiving_(false) {} - - webrtc::VideoReceiveStream::Config GetConfig() { return config_; } - - private: - virtual webrtc::VideoReceiveStream::Stats GetStats() const OVERRIDE { - return webrtc::VideoReceiveStream::Stats(); - } - - virtual void Start() OVERRIDE { receiving_ = true; } - virtual void Stop() OVERRIDE { receiving_ = false; } - virtual void GetCurrentReceiveCodec(webrtc::VideoCodec* codec) OVERRIDE {} - - webrtc::VideoReceiveStream::Config config_; - bool receiving_; -}; - -class FakeCall : public webrtc::Call { - public: - FakeCall() { SetVideoCodecs(GetDefaultVideoCodecs()); } - - ~FakeCall() { - EXPECT_EQ(0u, video_send_streams_.size()); - EXPECT_EQ(0u, video_receive_streams_.size()); - } - - void SetVideoCodecs(const std::vector codecs) { - codecs_ = codecs; - } - - std::vector GetVideoSendStreams() { - return video_send_streams_; - } - - std::vector GetVideoReceiveStreams() { - return video_receive_streams_; - } - - webrtc::VideoCodec GetEmptyVideoCodec() { - webrtc::VideoCodec codec; - codec.minBitrate = 300; - codec.startBitrate = 800; - codec.maxBitrate = 1500; - codec.maxFramerate = 10; - codec.width = 640; - codec.height = 480; - codec.qpMax = 56; - - return codec; - } - - webrtc::VideoCodec GetVideoCodecVp8() { - webrtc::VideoCodec vp8_codec = GetEmptyVideoCodec(); - vp8_codec.codecType = webrtc::kVideoCodecVP8; - strcpy(vp8_codec.plName, kVp8Codec.name.c_str()); - vp8_codec.plType = kVp8Codec.id; - - return vp8_codec; - } - - webrtc::VideoCodec GetVideoCodecVp9() { - webrtc::VideoCodec vp9_codec = GetEmptyVideoCodec(); - // TODO(pbos): Add a correct codecType when webrtc has one. - vp9_codec.codecType = webrtc::kVideoCodecVP8; - strcpy(vp9_codec.plName, kVp9Codec.name.c_str()); - vp9_codec.plType = kVp9Codec.id; - - return vp9_codec; - } - - std::vector GetDefaultVideoCodecs() { - std::vector codecs; - codecs.push_back(GetVideoCodecVp8()); - // codecs.push_back(GetVideoCodecVp9()); - - return codecs; - } - - private: - virtual webrtc::VideoSendStream::Config GetDefaultSendConfig() OVERRIDE { - webrtc::VideoSendStream::Config config; - // TODO(pbos): Encoder settings. - // config.codec = GetVideoCodecVp8(); - return config; - } - - virtual webrtc::VideoSendStream* CreateVideoSendStream( - const webrtc::VideoSendStream::Config& config) OVERRIDE { - FakeVideoSendStream* fake_stream = new FakeVideoSendStream(config); - video_send_streams_.push_back(fake_stream); - return fake_stream; - } - - virtual void DestroyVideoSendStream(webrtc::VideoSendStream* send_stream) - OVERRIDE { - FakeVideoSendStream* fake_stream = - static_cast(send_stream); - for (size_t i = 0; i < video_send_streams_.size(); ++i) { - if (video_send_streams_[i] == fake_stream) { - delete video_send_streams_[i]; - video_send_streams_.erase(video_send_streams_.begin() + i); - return; - } - } - ADD_FAILURE() << "DestroyVideoSendStream called with unknown paramter."; - } - - virtual webrtc::VideoReceiveStream::Config GetDefaultReceiveConfig() - OVERRIDE { - return webrtc::VideoReceiveStream::Config(); - } - - virtual webrtc::VideoReceiveStream* CreateVideoReceiveStream( - const webrtc::VideoReceiveStream::Config& config) OVERRIDE { - video_receive_streams_.push_back(new FakeVideoReceiveStream(config)); - return video_receive_streams_[video_receive_streams_.size() - 1]; - } - - virtual void DestroyVideoReceiveStream( - webrtc::VideoReceiveStream* receive_stream) OVERRIDE { - FakeVideoReceiveStream* fake_stream = - static_cast(receive_stream); - for (size_t i = 0; i < video_receive_streams_.size(); ++i) { - if (video_receive_streams_[i] == fake_stream) { - delete video_receive_streams_[i]; - video_receive_streams_.erase(video_receive_streams_.begin() + i); - return; - } - } - ADD_FAILURE() << "DestroyVideoReceiveStream called with unknown paramter."; - } - - virtual webrtc::PacketReceiver* Receiver() OVERRIDE { - // TODO(pbos): Fix this. - return NULL; - } - - virtual uint32_t SendBitrateEstimate() OVERRIDE { return 0; } - - virtual uint32_t ReceiveBitrateEstimate() OVERRIDE { return 0; } - - private: - std::vector codecs_; - std::vector video_send_streams_; - std::vector video_receive_streams_; -}; - -class FakeWebRtcVideoChannel2 : public WebRtcVideoChannel2 { - public: - FakeWebRtcVideoChannel2(FakeCall* call, - WebRtcVideoEngine2* engine, - VoiceMediaChannel* voice_channel) - : WebRtcVideoChannel2(call, - engine, - engine->GetDefaultVideoEncoderFactory()), - fake_call_(call), - voice_channel_(voice_channel) {} - - virtual ~FakeWebRtcVideoChannel2() {} - - VoiceMediaChannel* GetVoiceChannel() { return voice_channel_; } - FakeCall* GetFakeCall() { return fake_call_; } - - private: - FakeCall* fake_call_; - VoiceMediaChannel* voice_channel_; -}; - -class FakeWebRtcVideoMediaChannelFactory : public WebRtcVideoChannelFactory { - public: - FakeWebRtcVideoChannel2* GetFakeChannel(VideoMediaChannel* channel) { - return channel_map_[channel]; - } - - private: - virtual WebRtcVideoChannel2* Create(WebRtcVideoEngine2* engine, - VoiceMediaChannel* voice_channel) - OVERRIDE { - FakeWebRtcVideoChannel2* channel = - new FakeWebRtcVideoChannel2(new FakeCall(), engine, voice_channel); - channel_map_[channel] = channel; - return channel; - } - - std::map channel_map_; -}; - -class WebRtcVideoEngine2Test : public testing::Test { - public: - WebRtcVideoEngine2Test() - : engine_(&factory_), engine_codecs_(engine_.codecs()) { - assert(!engine_codecs_.empty()); - bool codec_set = false; - for (size_t i = 0; i < engine_codecs_.size(); ++i) { - if (engine_codecs_[i].name == "red") { - default_red_codec_ = engine_codecs_[i]; - } else if (engine_codecs_[i].name == "ulpfec") { - default_ulpfec_codec_ = engine_codecs_[i]; - } else if (engine_codecs_[i].name == "rtx") { - default_rtx_codec_ = engine_codecs_[i]; - } else if (!codec_set) { - default_codec_ = engine_codecs_[i]; - codec_set = true; - } - } - - assert(codec_set); - } - - protected: - FakeWebRtcVideoMediaChannelFactory factory_; - WebRtcVideoEngine2 engine_; - VideoCodec default_codec_; - VideoCodec default_red_codec_; - VideoCodec default_ulpfec_codec_; - VideoCodec default_rtx_codec_; - // TODO(pbos): Remove engine_codecs_ unless used a lot. - std::vector engine_codecs_; -}; - -TEST_F(WebRtcVideoEngine2Test, CreateChannel) { - talk_base::scoped_ptr channel(engine_.CreateChannel(NULL)); - ASSERT_TRUE(channel.get() != NULL) << "Could not create channel."; - EXPECT_TRUE(factory_.GetFakeChannel(channel.get()) != NULL) - << "Channel not created through factory."; -} - -TEST_F(WebRtcVideoEngine2Test, CreateChannelWithVoiceEngine) { - VoiceMediaChannel* voice_channel = reinterpret_cast(0x42); - talk_base::scoped_ptr channel( - engine_.CreateChannel(voice_channel)); - ASSERT_TRUE(channel.get() != NULL) << "Could not create channel."; - - FakeWebRtcVideoChannel2* fake_channel = - factory_.GetFakeChannel(channel.get()); - ASSERT_TRUE(fake_channel != NULL) << "Channel not created through factory."; - - EXPECT_TRUE(fake_channel->GetVoiceChannel() != NULL) - << "VoiceChannel not set."; - EXPECT_EQ(voice_channel, fake_channel->GetVoiceChannel()) - << "Different VoiceChannel set than the provided one."; -} - -class WebRtcVideoChannel2BaseTest - : public VideoMediaChannelTest { - protected: - virtual cricket::VideoCodec DefaultCodec() OVERRIDE { return kVp8Codec; } - typedef VideoMediaChannelTest Base; -}; - -// TODO(pbos): Fix WebRtcVideoEngine2BaseTest, where we want CheckCoInitialize. -#if 0 -// TODO(juberti): Figure out why ViE is munging the COM refcount. -#ifdef WIN32 -TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_CheckCoInitialize) { - Base::CheckCoInitialize(); -} -#endif -#endif - -TEST_F(WebRtcVideoChannel2BaseTest, SetSend) { Base::SetSend(); } - -TEST_F(WebRtcVideoChannel2BaseTest, SetSendWithoutCodecs) { - Base::SetSendWithoutCodecs(); -} - -TEST_F(WebRtcVideoChannel2BaseTest, SetSendSetsTransportBufferSizes) { - Base::SetSendSetsTransportBufferSizes(); -} - -// TODO(juberti): Fix this test to tolerate missing stats. -TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_GetStats) { Base::GetStats(); } - -// TODO(juberti): Fix this test to tolerate missing stats. -TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_GetStatsMultipleRecvStreams) { - Base::GetStatsMultipleRecvStreams(); -} - -TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_GetStatsMultipleSendStreams) { - Base::GetStatsMultipleSendStreams(); -} - -TEST_F(WebRtcVideoChannel2BaseTest, SetSendBandwidth) { - Base::SetSendBandwidth(); -} -TEST_F(WebRtcVideoChannel2BaseTest, SetSendSsrc) { Base::SetSendSsrc(); } -TEST_F(WebRtcVideoChannel2BaseTest, SetSendSsrcAfterSetCodecs) { - Base::SetSendSsrcAfterSetCodecs(); -} - -TEST_F(WebRtcVideoChannel2BaseTest, SetRenderer) { Base::SetRenderer(); } - -TEST_F(WebRtcVideoChannel2BaseTest, AddRemoveRecvStreams) { - Base::AddRemoveRecvStreams(); -} - -TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_AddRemoveRecvStreamAndRender) { - Base::AddRemoveRecvStreamAndRender(); -} - -TEST_F(WebRtcVideoChannel2BaseTest, AddRemoveRecvStreamsNoConference) { - Base::AddRemoveRecvStreamsNoConference(); -} - -TEST_F(WebRtcVideoChannel2BaseTest, AddRemoveSendStreams) { - Base::AddRemoveSendStreams(); -} - -TEST_F(WebRtcVideoChannel2BaseTest, SimulateConference) { - Base::SimulateConference(); -} - -TEST_F(WebRtcVideoChannel2BaseTest, AddRemoveCapturer) { - Base::AddRemoveCapturer(); -} - -TEST_F(WebRtcVideoChannel2BaseTest, RemoveCapturerWithoutAdd) { - Base::RemoveCapturerWithoutAdd(); -} - -TEST_F(WebRtcVideoChannel2BaseTest, AddRemoveCapturerMultipleSources) { - Base::AddRemoveCapturerMultipleSources(); -} - -// TODO(pbos): Figure out why this fails so often. -TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_HighAspectHighHeightCapturer) { - Base::HighAspectHighHeightCapturer(); -} - -TEST_F(WebRtcVideoChannel2BaseTest, RejectEmptyStreamParams) { - Base::RejectEmptyStreamParams(); -} - -TEST_F(WebRtcVideoChannel2BaseTest, AdaptResolution16x10) { - Base::AdaptResolution16x10(); -} - -TEST_F(WebRtcVideoChannel2BaseTest, AdaptResolution4x3) { - Base::AdaptResolution4x3(); -} - -TEST_F(WebRtcVideoChannel2BaseTest, MuteStream) { Base::MuteStream(); } - -TEST_F(WebRtcVideoChannel2BaseTest, MultipleSendStreams) { - Base::MultipleSendStreams(); -} - -// TODO(juberti): Restore this test once we support sending 0 fps. -TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_AdaptDropAllFrames) { - Base::AdaptDropAllFrames(); -} -// TODO(juberti): Understand why we get decode errors on this test. -TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_AdaptFramerate) { - Base::AdaptFramerate(); -} - -TEST_F(WebRtcVideoChannel2BaseTest, SetSendStreamFormat0x0) { - Base::SetSendStreamFormat0x0(); -} - -// TODO(zhurunz): Fix the flakey test. -TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_SetSendStreamFormat) { - Base::SetSendStreamFormat(); -} - -TEST_F(WebRtcVideoChannel2BaseTest, TwoStreamsSendAndReceive) { - Base::TwoStreamsSendAndReceive(kVp8Codec); -} - -TEST_F(WebRtcVideoChannel2BaseTest, TwoStreamsReUseFirstStream) { - Base::TwoStreamsReUseFirstStream(kVp8Codec); -} - -class WebRtcVideoChannel2Test : public WebRtcVideoEngine2Test { - public: - virtual void SetUp() OVERRIDE { - channel_.reset(engine_.CreateChannel(NULL)); - fake_channel_ = factory_.GetFakeChannel(channel_.get()); - last_ssrc_ = 123; - ASSERT_TRUE(fake_channel_ != NULL) - << "Channel not created through factory."; - } - - protected: - FakeVideoSendStream* AddSendStream() { - return AddSendStream(StreamParams::CreateLegacy(last_ssrc_++)); - } - - FakeVideoSendStream* AddSendStream(const StreamParams& sp) { - size_t num_streams = - fake_channel_->GetFakeCall()->GetVideoSendStreams().size(); - EXPECT_TRUE(channel_->AddSendStream(sp)); - std::vector streams = - fake_channel_->GetFakeCall()->GetVideoSendStreams(); - EXPECT_EQ(num_streams + 1, streams.size()); - return streams[streams.size() - 1]; - } - - std::vector GetFakeSendStreams() { - return fake_channel_->GetFakeCall()->GetVideoSendStreams(); - } - - FakeVideoReceiveStream* AddRecvStream() { - return AddRecvStream(StreamParams::CreateLegacy(last_ssrc_++)); - } - - FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) { - size_t num_streams = - fake_channel_->GetFakeCall()->GetVideoReceiveStreams().size(); - EXPECT_TRUE(channel_->AddRecvStream(sp)); - std::vector streams = - fake_channel_->GetFakeCall()->GetVideoReceiveStreams(); - EXPECT_EQ(num_streams + 1, streams.size()); - return streams[streams.size() - 1]; - } - - void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate, - const char* max_bitrate) { - std::vector codecs; - codecs.push_back(kVp8Codec); - codecs[0].params[kCodecParamMinBitrate] = min_bitrate; - codecs[0].params[kCodecParamMaxBitrate] = max_bitrate; - EXPECT_TRUE(channel_->SetSendCodecs(codecs)); - - FakeVideoSendStream* stream = AddSendStream(); - - webrtc::VideoSendStream::Config::EncoderSettings encoder_settings = - stream->GetConfig().encoder_settings; - ASSERT_EQ(1u, encoder_settings.streams.size()); - EXPECT_EQ(atoi(min_bitrate), - encoder_settings.streams.back().min_bitrate_bps / 1000); - EXPECT_EQ(atoi(max_bitrate), - encoder_settings.streams.back().max_bitrate_bps / 1000); - - VideoCodec codec; - EXPECT_TRUE(channel_->GetSendCodec(&codec)); - EXPECT_EQ(min_bitrate, codec.params[kCodecParamMinBitrate]); - EXPECT_EQ(max_bitrate, codec.params[kCodecParamMaxBitrate]); - } - - void ExpectEqualCodecs(const VideoCodec video_codec, - const webrtc::VideoCodec& webrtc_codec) { - EXPECT_STREQ(video_codec.name.c_str(), webrtc_codec.plName); - EXPECT_EQ(video_codec.id, webrtc_codec.plType); - EXPECT_EQ(video_codec.width, webrtc_codec.width); - EXPECT_EQ(video_codec.height, webrtc_codec.height); - EXPECT_EQ(video_codec.framerate, webrtc_codec.maxFramerate); - } - talk_base::scoped_ptr channel_; - FakeWebRtcVideoChannel2* fake_channel_; - uint32 last_ssrc_; -}; - -TEST_F(WebRtcVideoChannel2Test, DISABLED_MaxBitrateResetsWithConferenceMode) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_StartSendBitrate) { - // TODO(pbos): Is this test testing vie_ ? this is confusing. No API to set - // start send bitrate from outside? Add defaults here that should be kept? - std::vector codec_list; - codec_list.push_back(kVp8Codec); - EXPECT_TRUE(channel_->SetSendCodecs(codec_list)); - const unsigned int kVideoMinSendBitrateKbps = 50; - const unsigned int kVideoTargetSendBitrateKbps = 300; - const unsigned int kVideoMaxSendBitrateKbps = 2000; - FakeVideoSendStream* stream = AddSendStream(); - webrtc::VideoSendStream::Config::EncoderSettings encoder_settings = - stream->GetConfig().encoder_settings; - ASSERT_EQ(1u, encoder_settings.streams.size()); - EXPECT_EQ(kVideoMinSendBitrateKbps, - encoder_settings.streams.back().min_bitrate_bps / 1000); - EXPECT_EQ(kVideoTargetSendBitrateKbps, - encoder_settings.streams.back().target_bitrate_bps / 1000); - EXPECT_EQ(kVideoMaxSendBitrateKbps, - encoder_settings.streams.back().max_bitrate_bps / 1000); -#if 0 - // TODO(pbos): un-#if - VerifyVP8SendCodec(send_channel, kVP8Codec.width, kVP8Codec.height, 0, - kVideoMaxSendBitrateKbps, kVideoMinSendBitrateKbps, - kVideoDefaultStartSendBitrateKbps); - EXPECT_EQ(0, vie_.StartSend(send_channel)); - - // Increase the send bitrate and verify it is used as start bitrate. - const unsigned int kVideoSendBitrateBps = 768000; - vie_.SetSendBitrates(send_channel, kVideoSendBitrateBps, 0, 0); - EXPECT_TRUE(channel_->SetSendCodecs(codec_list)); - VerifyVP8SendCodec(send_channel, kVP8Codec.width, kVP8Codec.height, 0, - kVideoMaxSendBitrateKbps, kVideoMinSendBitrateKbps, - kVideoSendBitrateBps / 1000); - - // Never set a start bitrate higher than the max bitrate. - vie_.SetSendBitrates(send_channel, kVideoMaxSendBitrateKbps + 500, 0, 0); - EXPECT_TRUE(channel_->SetSendCodecs(codec_list)); - VerifyVP8SendCodec(send_channel, kVP8Codec.width, kVP8Codec.height, 0, - kVideoMaxSendBitrateKbps, kVideoMinSendBitrateKbps, - kVideoDefaultStartSendBitrateKbps); - - // Use the default start bitrate if the send bitrate is lower. - vie_.SetSendBitrates(send_channel, kVideoDefaultStartSendBitrateKbps - 50, 0, - 0); - EXPECT_TRUE(channel_->SetSendCodecs(codec_list)); - VerifyVP8SendCodec(send_channel, kVP8Codec.width, kVP8Codec.height, 0, - kVideoMaxSendBitrateKbps, kVideoMinSendBitrateKbps, - kVideoDefaultStartSendBitrateKbps); -#endif -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_RtcpEnabled) { - // Note(pbos): This is a receiver-side setting, dumbo. - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_KeyFrameRequestEnabled) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, RembIsEnabledByDefault) { - FakeVideoReceiveStream* stream = AddRecvStream(); - EXPECT_TRUE(stream->GetConfig().rtp.remb); -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_RembEnabledOnReceiveChannels) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, RecvStreamWithRtx) { - EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs())); - EXPECT_TRUE(channel_->SetSend(true)); - cricket::VideoOptions options; - options.conference_mode.Set(true); - EXPECT_TRUE(channel_->SetOptions(options)); - - // Send side. - const std::vector ssrcs = MAKE_VECTOR(kSsrcs1); - const std::vector rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1); - FakeVideoSendStream* send_stream = AddSendStream( - cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs)); - - ASSERT_EQ(rtx_ssrcs.size(), send_stream->GetConfig().rtp.rtx.ssrcs.size()); - for (size_t i = 0; i < rtx_ssrcs.size(); ++i) - EXPECT_EQ(rtx_ssrcs[i], send_stream->GetConfig().rtp.rtx.ssrcs[i]); - - // Receiver side. - FakeVideoReceiveStream* recv_stream = AddRecvStream( - cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs)); - ASSERT_GT(recv_stream->GetConfig().rtp.rtx.size(), 0u) - << "No SSRCs for RTX configured by AddRecvStream."; - ASSERT_EQ(1u, recv_stream->GetConfig().rtp.rtx.size()) - << "This test only works with one receive codec. Please update the test."; - EXPECT_EQ(rtx_ssrcs[0], - recv_stream->GetConfig().rtp.rtx.begin()->second.ssrc); - // TODO(pbos): Make sure we set the RTX for correct payloads etc. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_RecvStreamWithRtxOnMultiplePayloads) { - FAIL() << "Not implemented."; -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_RecvStreamNoRtx) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_RtpTimestampOffsetHeaderExtensions) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_AbsoluteSendTimeHeaderExtensions) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_LeakyBucketTest) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_BufferedModeLatency) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_AdditiveVideoOptions) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, AddRecvStreamOnlyUsesOneReceiveStream) { - EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1))); - EXPECT_EQ(1u, fake_channel_->GetFakeCall()->GetVideoReceiveStreams().size()); -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_NoRembChangeAfterAddRecvStream) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_RembOnOff) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_NackEnabled) { - // Verify NACK on both sender and receiver. - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_VideoProtectionInterop) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_VideoProtectionInteropReversed) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_HybridNackFecConference) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_AddRemoveRecvStreamConference) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_SetRender) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthAuto) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthAutoCapped) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthFixed) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthInConference) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthScreencast) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_SetSendSsrcAndCname) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, - DISABLED_SetSendSsrcAfterCreatingReceiveChannel) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_SetOptionsWithDenoising) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_MultipleSendStreamsWithOneCapturer) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_DISABLED_SendReceiveBitratesStats) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_TestSetAdaptInputToCpuUsage) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_TestSetCpuThreshold) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_TestSetInvalidCpuThreshold) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_WebRtcShouldLog) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_WebRtcShouldNotLog) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoEngine2Test, FindCodec) { - const std::vector& c = engine_.codecs(); - EXPECT_EQ(4U, 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); - EXPECT_FALSE(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); - EXPECT_TRUE(engine_.FindCodec(rtx)); -} - -TEST_F(WebRtcVideoEngine2Test, DefaultRtxCodecHasAssociatedPayloadTypeSet) { - for (size_t i = 0; i < engine_codecs_.size(); ++i) { - if (engine_codecs_[i].name != kRtxCodecName) - continue; - int associated_payload_type; - EXPECT_TRUE(engine_codecs_[i].GetParam(kCodecParamAssociatedPayloadType, - &associated_payload_type)); - EXPECT_EQ(default_codec_.id, associated_payload_type); - return; - } - FAIL() << "No RTX codec found among default codecs."; -} - -TEST_F(WebRtcVideoChannel2Test, SetDefaultSendCodecs) { - ASSERT_TRUE(channel_->SetSendCodecs(engine_codecs_)); - - VideoCodec codec; - EXPECT_TRUE(channel_->GetSendCodec(&codec)); - EXPECT_TRUE(codec.Matches(engine_codecs_[0])); - - // Using a RTX setup to verify that the default RTX payload type is good. - const std::vector ssrcs = MAKE_VECTOR(kSsrcs1); - const std::vector rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1); - FakeVideoSendStream* stream = AddSendStream( - cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs)); - webrtc::VideoSendStream::Config config = stream->GetConfig(); - // TODO(pbos): Replace ExpectEqualCodecs. - // ExpectEqualCodecs(engine_codecs_[0], config.codec); - - // Make sure NACK and FEC are enabled on the correct payload types. - EXPECT_EQ(1000, config.rtp.nack.rtp_history_ms); - EXPECT_EQ(default_ulpfec_codec_.id, config.rtp.fec.ulpfec_payload_type); - EXPECT_EQ(default_red_codec_.id, config.rtp.fec.red_payload_type); - // TODO(pbos): Verify that the rtx ssrc is set, correct, not taken by anything - // else. - // ASSERT_EQ(1u, config.rtp.rtx.ssrcs.size()); - EXPECT_EQ(static_cast(default_rtx_codec_.id), - config.rtp.rtx.payload_type); - // TODO(juberti): Check RTCP, PLI, TMMBR. -} - -TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithoutFec) { - std::vector codecs; - codecs.push_back(kVp8Codec); - ASSERT_TRUE(channel_->SetSendCodecs(codecs)); - - FakeVideoSendStream* stream = AddSendStream(); - webrtc::VideoSendStream::Config config = stream->GetConfig(); - - EXPECT_EQ(-1, config.rtp.fec.ulpfec_payload_type); - EXPECT_EQ(-1, config.rtp.fec.red_payload_type); -} - -TEST_F(WebRtcVideoChannel2Test, - DISABLED_SetSendCodecRejectsRtxWithoutAssociatedPayloadType) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -}; - -TEST_F(WebRtcVideoChannel2Test, - DISABLED_SetSendCodecRejectsRtxWithoutMatchingVideoCodec) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -}; - -TEST_F(WebRtcVideoChannel2Test, - DISABLED_SetCodecsWithoutFecDisablesCurrentFec) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -}; - -TEST_F(WebRtcVideoChannel2Test, DISABLED_SetSendCodecsChangesExistingStreams) { - FAIL(); // TODO(pbos): Implement, make sure that it's changing running - // streams. Should it? -} - -TEST_F(WebRtcVideoChannel2Test, - DISABLED_ConstrainsSetCodecsAccordingToEncoderConfig) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithMinMaxBitrate) { - SetSendCodecsShouldWorkForBitrates("10", "20"); -} - -TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectsMaxLessThanMinBitrate) { - engine_codecs_[0].params[kCodecParamMinBitrate] = "30"; - engine_codecs_[0].params[kCodecParamMaxBitrate] = "20"; - EXPECT_FALSE(channel_->SetSendCodecs(engine_codecs_)); -} - -TEST_F(WebRtcVideoChannel2Test, SetSendCodecsAcceptLargeMinMaxBitrate) { - SetSendCodecsShouldWorkForBitrates("1000", "2000"); -} - -TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithMaxQuantization) { - static const char* kMaxQuantization = "21"; - std::vector codecs; - codecs.push_back(kVp8Codec); - codecs[0].params[kCodecParamMaxQuantization] = kMaxQuantization; - EXPECT_TRUE(channel_->SetSendCodecs(codecs)); - EXPECT_EQ( - static_cast(atoi(kMaxQuantization)), - AddSendStream()->GetConfig().encoder_settings.streams.back().max_qp); - - VideoCodec codec; - EXPECT_TRUE(channel_->GetSendCodec(&codec)); - EXPECT_EQ(kMaxQuantization, codec.params[kCodecParamMaxQuantization]); -} - -TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectBadDimensions) { - std::vector codecs; - codecs.push_back(kVp8Codec); - - codecs[0].width = 0; - EXPECT_FALSE(channel_->SetSendCodecs(codecs)) - << "Codec set though codec width is zero."; - - codecs[0].width = kVp8Codec.width; - codecs[0].height = 0; - EXPECT_FALSE(channel_->SetSendCodecs(codecs)) - << "Codec set though codec height is zero."; -} - -TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectBadPayloadTypes) { - // TODO(pbos): Should we only allow the dynamic range? - static const size_t kNumIncorrectPayloads = 4; - static const int kIncorrectPayloads[kNumIncorrectPayloads] = {-2, -1, 128, - 129}; - std::vector codecs; - codecs.push_back(kVp8Codec); - for (size_t i = 0; i < kNumIncorrectPayloads; ++i) { - int payload_type = kIncorrectPayloads[i]; - codecs[0].id = payload_type; - EXPECT_FALSE(channel_->SetSendCodecs(codecs)) - << "Bad payload type '" << payload_type << "' accepted."; - } -} - -TEST_F(WebRtcVideoChannel2Test, SetSendCodecsAcceptAllValidPayloadTypes) { - std::vector codecs; - codecs.push_back(kVp8Codec); - for (int payload_type = 0; payload_type <= 127; ++payload_type) { - codecs[0].id = payload_type; - EXPECT_TRUE(channel_->SetSendCodecs(codecs)) - << "Payload type '" << payload_type << "' rejected."; - } -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_ResetVieSendCodecOnNewFrameSize) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithOnlyVp8) { - std::vector codecs; - codecs.push_back(kVp8Codec); - EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); -} - -TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsDifferentPayloadType) { - std::vector codecs; - codecs.push_back(kVp8Codec); - codecs[0].id = 99; - EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_SetRecvCodecsAcceptDefaultCodecs) { - EXPECT_TRUE(channel_->SetRecvCodecs(engine_.codecs())); - // (I've added this one.) Make sure they propagate down to VideoReceiveStream! - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsRejectUnsupportedCodec) { - std::vector codecs; - codecs.push_back(kVp8Codec); - codecs.push_back(VideoCodec(101, "WTF3", 640, 400, 30, 0)); - EXPECT_FALSE(channel_->SetRecvCodecs(codecs)); -} - -// TODO(pbos): Enable VP9 through external codec support -TEST_F(WebRtcVideoChannel2Test, - DISABLED_SetRecvCodecsAcceptsMultipleVideoCodecs) { - std::vector codecs; - codecs.push_back(kVp8Codec); - codecs.push_back(kVp9Codec); - EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); -} - -TEST_F(WebRtcVideoChannel2Test, - DISABLED_SetRecvCodecsSetsFecForAllVideoCodecs) { - std::vector codecs; - codecs.push_back(kVp8Codec); - codecs.push_back(kVp9Codec); - EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); - FAIL(); // TODO(pbos): Verify that the FEC parameters are set for all codecs. -} - -TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectDuplicateFecPayloads) { - std::vector codecs; - codecs.push_back(kVp8Codec); - codecs.push_back(kRedCodec); - codecs[1].id = codecs[0].id; - EXPECT_FALSE(channel_->SetRecvCodecs(codecs)); -} - -TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsRejectDuplicateCodecPayloads) { - std::vector codecs; - codecs.push_back(kVp8Codec); - codecs.push_back(kVp9Codec); - codecs[1].id = codecs[0].id; - EXPECT_FALSE(channel_->SetRecvCodecs(codecs)); -} - -TEST_F(WebRtcVideoChannel2Test, - SetRecvCodecsAcceptSameCodecOnMultiplePayloadTypes) { - std::vector codecs; - codecs.push_back(kVp8Codec); - codecs.push_back(kVp8Codec); - codecs[1].id += 1; - EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); -} - -TEST_F(WebRtcVideoChannel2Test, SendStreamNotSendingByDefault) { - EXPECT_FALSE(AddSendStream()->IsSending()); -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_ReceiveStreamReceivingByDefault) { - // Is this test correct though? Auto-receive? Enable receive on first packet? - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, SetSend) { - AddSendStream(); - EXPECT_FALSE(channel_->SetSend(true)) - << "Channel should not start without codecs."; - EXPECT_TRUE(channel_->SetSend(false)) - << "Channel should be stoppable even without set codecs."; - - std::vector codecs; - codecs.push_back(kVp8Codec); - channel_->SetSendCodecs(codecs); - std::vector streams = GetFakeSendStreams(); - ASSERT_EQ(1u, streams.size()); - FakeVideoSendStream* stream = streams.back(); - - EXPECT_FALSE(stream->IsSending()); - - // false->true - EXPECT_TRUE(channel_->SetSend(true)); - EXPECT_TRUE(stream->IsSending()); - // true->true - EXPECT_TRUE(channel_->SetSend(true)); - EXPECT_TRUE(stream->IsSending()); - // true->false - EXPECT_TRUE(channel_->SetSend(false)); - EXPECT_FALSE(stream->IsSending()); - // false->false - EXPECT_TRUE(channel_->SetSend(false)); - EXPECT_FALSE(stream->IsSending()); - - EXPECT_TRUE(channel_->SetSend(true)); - FakeVideoSendStream* new_stream = AddSendStream(); - EXPECT_TRUE(new_stream->IsSending()) - << "Send stream created after SetSend(true) not sending initially."; -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_SendAndReceiveVp8Vga) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_SendAndReceiveVp8Qvga) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_SendAndReceiveH264SvcQqvga) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_SendManyResizeOnce) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_SendVp8HdAndReceiveAdaptedVp8Vga) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_TestSetDscpOptions) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_SetOptionsWithMaxBitrate) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_SetOptionsWithLoweredBitrate) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_SetOptionsSucceedsWhenSending) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_ResetCodecOnScreencast) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_DontResetCodecOnSendFrame) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, - DISABLED_DontRegisterDecoderIfFactoryIsNotGiven) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_RegisterDecoderIfFactoryIsGiven) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_DontRegisterDecoderMultipleTimes) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_DontRegisterDecoderForNonVP8) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, - DISABLED_DontRegisterEncoderIfFactoryIsNotGiven) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_RegisterEncoderIfFactoryIsGiven) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_DontRegisterEncoderMultipleTimes) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, - DISABLED_RegisterEncoderWithMultipleSendStreams) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_DontRegisterEncoderForNonVP8) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_FeedbackParamsForNonVP8) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_ExternalCodecAddedToTheEnd) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_ExternalCodecIgnored) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_UpdateEncoderCodecsAfterSetFactory) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_OnReadyToSend) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} - -TEST_F(WebRtcVideoChannel2Test, DISABLED_CaptureFrameTimestampToNtpTimestamp) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. -} -} // namespace cricket