webrtcvideoengine2.cc revision e5269747595864eedd604f153df5d7bcbe1b475a
1b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org/* 2b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * libjingle 3b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * Copyright 2014 Google Inc. 4b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 5b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * Redistribution and use in source and binary forms, with or without 6b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * modification, are permitted provided that the following conditions are met: 7b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 8b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 1. Redistributions of source code must retain the above copyright notice, 9b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * this list of conditions and the following disclaimer. 10b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 2. Redistributions in binary form must reproduce the above copyright notice, 11b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * this list of conditions and the following disclaimer in the documentation 12b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * and/or other materials provided with the distribution. 13b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 3. The name of the author may not be used to endorse or promote products 14b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * derived from this software without specific prior written permission. 15b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 16b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org */ 27b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 28b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#ifdef HAVE_WEBRTC_VIDEO 29b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/webrtc/webrtcvideoengine2.h" 30b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 31c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org#include <algorithm> 323c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org#include <set> 33b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include <string> 34b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 35b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/base/videocapturer.h" 36b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/base/videorenderer.h" 37df9bbbee56f4d9ecef93b3c46964b6f29803f81bbuildbot@webrtc.org#include "talk/media/webrtc/constants.h" 38a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org#include "talk/media/webrtc/simulcast.h" 3981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström#include "talk/media/webrtc/webrtcvideoencoderfactory.h" 40b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/webrtc/webrtcvideoframe.h" 41b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/webrtc/webrtcvoiceengine.h" 42a09a99950ec40aef6421e4ba35eee7196b7a6e68buildbot@webrtc.org#include "webrtc/base/buffer.h" 43a09a99950ec40aef6421e4ba35eee7196b7a6e68buildbot@webrtc.org#include "webrtc/base/logging.h" 44a09a99950ec40aef6421e4ba35eee7196b7a6e68buildbot@webrtc.org#include "webrtc/base/stringutils.h" 45c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen#include "webrtc/base/timeutils.h" 46b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "webrtc/call.h" 4771f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin#include "webrtc/modules/video_coding/codecs/h264/include/h264.h" 4881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström#include "webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.h" 4981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström#include "webrtc/system_wrappers/interface/field_trial.h" 5050fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org#include "webrtc/system_wrappers/interface/trace_event.h" 51776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org#include "webrtc/video_decoder.h" 52ab990ae43a2b84b103cb3c50bc38502375c13e68pbos@webrtc.org#include "webrtc/video_encoder.h" 53b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 54b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#define UNIMPLEMENTED \ 55b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Call to unimplemented function " << __FUNCTION__; \ 56d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg RTC_NOTREACHED() 57b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 58b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgnamespace cricket { 597fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgnamespace { 6081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 6181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström// Wrap cricket::WebRtcVideoEncoderFactory as a webrtc::VideoEncoderFactory. 6281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmclass EncoderFactoryAdapter : public webrtc::VideoEncoderFactory { 6381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström public: 6481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // EncoderFactoryAdapter doesn't take ownership of |factory|, which is owned 6581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // by e.g. PeerConnectionFactory. 6681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström explicit EncoderFactoryAdapter(cricket::WebRtcVideoEncoderFactory* factory) 6781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström : factory_(factory) {} 6881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström virtual ~EncoderFactoryAdapter() {} 6981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 7081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // Implement webrtc::VideoEncoderFactory. 7181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström webrtc::VideoEncoder* Create() override { 7281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return factory_->CreateVideoEncoder(webrtc::kVideoCodecVP8); 7381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 7481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 7581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström void Destroy(webrtc::VideoEncoder* encoder) override { 7681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return factory_->DestroyVideoEncoder(encoder); 7781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 7881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 7981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström private: 8081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström cricket::WebRtcVideoEncoderFactory* const factory_; 8181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström}; 8281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 8381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström// An encoder factory that wraps Create requests for simulcastable codec types 8481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström// with a webrtc::SimulcastEncoderAdapter. Non simulcastable codec type 8581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström// requests are just passed through to the contained encoder factory. 8681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmclass WebRtcSimulcastEncoderFactory 8781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström : public cricket::WebRtcVideoEncoderFactory { 8881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström public: 8981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // WebRtcSimulcastEncoderFactory doesn't take ownership of |factory|, which is 9081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // owned by e.g. PeerConnectionFactory. 9181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström explicit WebRtcSimulcastEncoderFactory( 9281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström cricket::WebRtcVideoEncoderFactory* factory) 9381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström : factory_(factory) {} 9481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 9581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström static bool UseSimulcastEncoderFactory( 9681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström const std::vector<VideoCodec>& codecs) { 9781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // If any codec is VP8, use the simulcast factory. If asked to create a 9881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // non-VP8 codec, we'll just return a contained factory encoder directly. 9981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström for (const auto& codec : codecs) { 10081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if (codec.type == webrtc::kVideoCodecVP8) { 10181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return true; 10281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 10381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 10481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return false; 10581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 10681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 10781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström webrtc::VideoEncoder* CreateVideoEncoder( 10881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström webrtc::VideoCodecType type) override { 109d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(factory_ != NULL); 11081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // If it's a codec type we can simulcast, create a wrapped encoder. 11181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if (type == webrtc::kVideoCodecVP8) { 11281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return new webrtc::SimulcastEncoderAdapter( 11381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström new EncoderFactoryAdapter(factory_)); 11481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 11581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström webrtc::VideoEncoder* encoder = factory_->CreateVideoEncoder(type); 11681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if (encoder) { 11781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström non_simulcast_encoders_.push_back(encoder); 11881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 11981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return encoder; 12081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 12181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 12281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström const std::vector<VideoCodec>& codecs() const override { 12381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return factory_->codecs(); 12481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 12581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 12681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström bool EncoderTypeHasInternalSource( 12781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström webrtc::VideoCodecType type) const override { 12881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return factory_->EncoderTypeHasInternalSource(type); 12981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 13081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 13181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström void DestroyVideoEncoder(webrtc::VideoEncoder* encoder) override { 13281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // Check first to see if the encoder wasn't wrapped in a 13381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // SimulcastEncoderAdapter. In that case, ask the factory to destroy it. 13481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if (std::remove(non_simulcast_encoders_.begin(), 13581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström non_simulcast_encoders_.end(), 13681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström encoder) != non_simulcast_encoders_.end()) { 13781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström factory_->DestroyVideoEncoder(encoder); 13881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return; 13981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 14081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 14181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // Otherwise, SimulcastEncoderAdapter can be deleted directly, and will call 14281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // DestroyVideoEncoder on the factory for individual encoder instances. 14381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström delete encoder; 14481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 14581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 14681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström private: 14781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström cricket::WebRtcVideoEncoderFactory* factory_; 14881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // A list of encoders that were created without being wrapped in a 14981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // SimulcastEncoderAdapter. 15081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström std::vector<webrtc::VideoEncoder*> non_simulcast_encoders_; 15181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström}; 15281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 15381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmbool CodecIsInternallySupported(const std::string& codec_name) { 15481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if (CodecNamesEq(codec_name, kVp8CodecName)) { 15581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return true; 15681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 15781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if (CodecNamesEq(codec_name, kVp9CodecName)) { 158bd3842808996dbb85007242214352f1e6ebd3d17jbauch const std::string group_name = 15981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström webrtc::field_trial::FindFullName("WebRTC-SupportVP9"); 16081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return group_name == "Enabled" || group_name == "EnabledByFlag"; 16181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 16271f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin if (CodecNamesEq(codec_name, kH264CodecName)) { 16371f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin return webrtc::H264Encoder::IsSupported() && 16471f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin webrtc::H264Decoder::IsSupported(); 16571f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin } 16681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return false; 16781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström} 16881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 16981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmvoid AddDefaultFeedbackParams(VideoCodec* codec) { 17081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamCcm, kRtcpFbCcmParamFir)); 17181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kParamValueEmpty)); 17281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kRtcpFbNackParamPli)); 17381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamRemb, kParamValueEmpty)); 17481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström} 17581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 17681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmstatic VideoCodec MakeVideoCodecWithDefaultFeedbackParams(int payload_type, 17781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström const char* name) { 17881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström VideoCodec codec(payload_type, name, kDefaultVideoMaxWidth, 17981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström kDefaultVideoMaxHeight, kDefaultVideoMaxFramerate, 0); 18081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström AddDefaultFeedbackParams(&codec); 18181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return codec; 18281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström} 18381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 1847fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgstatic std::string CodecVectorToString(const std::vector<VideoCodec>& codecs) { 1857fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org std::stringstream out; 1867fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << '{'; 1877fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 1887fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << codecs[i].ToString(); 1897fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (i != codecs.size() - 1) { 1907fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << ", "; 1917fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 1927fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 1937fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << '}'; 1947fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return out.str(); 1957fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 1967fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 1977fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgstatic bool ValidateCodecFormats(const std::vector<VideoCodec>& codecs) { 1987fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org bool has_video = false; 1997fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 2007fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (!codecs[i].ValidateCodecFormat()) { 2017fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return false; 2027fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 2037fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (codecs[i].GetCodecType() == VideoCodec::CODEC_VIDEO) { 2047fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org has_video = true; 2057fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 2067fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 2077fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (!has_video) { 2087fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org LOG(LS_ERROR) << "Setting codecs without a video codec is invalid: " 2097fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org << CodecVectorToString(codecs); 2107fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return false; 2117fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 2127fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return true; 2137fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 2147fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 215d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boströmstatic bool ValidateStreamParams(const StreamParams& sp) { 216d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström if (sp.ssrcs.empty()) { 217d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström LOG(LS_ERROR) << "No SSRCs in stream parameters: " << sp.ToString(); 218d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström return false; 219d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström } 220d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström 221d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström std::vector<uint32> primary_ssrcs; 222d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström sp.GetPrimarySsrcs(&primary_ssrcs); 223d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström std::vector<uint32> rtx_ssrcs; 224d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström sp.GetFidSsrcs(primary_ssrcs, &rtx_ssrcs); 225d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström for (uint32_t rtx_ssrc : rtx_ssrcs) { 226d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström bool rtx_ssrc_present = false; 227d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström for (uint32_t sp_ssrc : sp.ssrcs) { 228d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström if (sp_ssrc == rtx_ssrc) { 229d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström rtx_ssrc_present = true; 230d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström break; 231d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström } 232d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström } 233d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström if (!rtx_ssrc_present) { 234d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström LOG(LS_ERROR) << "RTX SSRC '" << rtx_ssrc 235d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström << "' missing from StreamParams ssrcs: " << sp.ToString(); 236d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström return false; 237d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström } 238d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström } 239d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström if (!rtx_ssrcs.empty() && primary_ssrcs.size() != rtx_ssrcs.size()) { 240d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström LOG(LS_ERROR) 241d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström << "RTX SSRCs exist, but don't cover all SSRCs (unsupported): " 242d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström << sp.ToString(); 243d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström return false; 244d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström } 245d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström 246d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström return true; 247d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström} 248d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström 2497fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgstatic std::string RtpExtensionsToString( 2507fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 2517fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org std::stringstream out; 2527fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << '{'; 2537fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 2547fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << "{" << extensions[i].uri << ": " << extensions[i].id << "}"; 2557fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (i != extensions.size() - 1) { 2567fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << ", "; 2577fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 2587fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 2597fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << '}'; 2607fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return out.str(); 2617fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 2627fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 26364c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shiehinline const webrtc::RtpExtension* FindHeaderExtension( 26464c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh const std::vector<webrtc::RtpExtension>& extensions, 26564c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh const std::string& name) { 26664c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh for (const auto& kv : extensions) { 26764c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh if (kv.name == name) { 26864c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh return &kv; 26964c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh } 27064c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh } 27164c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh return NULL; 27264c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh} 27364c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh 27482775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org// Merges two fec configs and logs an error if a conflict arises 275e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin// such that merging in different order would trigger a different output. 27682775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.orgstatic void MergeFecConfig(const webrtc::FecConfig& other, 27782775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org webrtc::FecConfig* output) { 27882775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org if (other.ulpfec_payload_type != -1) { 27982775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org if (output->ulpfec_payload_type != -1 && 28082775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org output->ulpfec_payload_type != other.ulpfec_payload_type) { 28182775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org LOG(LS_WARNING) << "Conflict merging ulpfec_payload_type configs: " 28282775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org << output->ulpfec_payload_type << " and " 28382775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org << other.ulpfec_payload_type; 28482775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 28582775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org output->ulpfec_payload_type = other.ulpfec_payload_type; 28682775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 28782775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org if (other.red_payload_type != -1) { 28882775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org if (output->red_payload_type != -1 && 28982775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org output->red_payload_type != other.red_payload_type) { 29082775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org LOG(LS_WARNING) << "Conflict merging red_payload_type configs: " 29182775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org << output->red_payload_type << " and " 29282775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org << other.red_payload_type; 29382775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 29482775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org output->red_payload_type = other.red_payload_type; 29582775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 296e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (other.red_rtx_payload_type != -1) { 297e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (output->red_rtx_payload_type != -1 && 298e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin output->red_rtx_payload_type != other.red_rtx_payload_type) { 299e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin LOG(LS_WARNING) << "Conflict merging red_rtx_payload_type configs: " 300e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin << output->red_rtx_payload_type << " and " 301e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin << other.red_rtx_payload_type; 302e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin } 303e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin output->red_rtx_payload_type = other.red_rtx_payload_type; 304e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin } 30582775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org} 306fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric 307fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric// Returns true if the given codec is disallowed from doing simulcast. 308fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahricbool IsCodecBlacklistedForSimulcast(const std::string& codec_name) { 309fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric return CodecNamesEq(codec_name, kH264CodecName); 310fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric} 311fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric 3121c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Persson// The selected thresholds for QVGA and VGA corresponded to a QP around 10. 3131c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Persson// The change in QP declined above the selected bitrates. 3141c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Perssonstatic int GetMaxDefaultVideoBitrateKbps(int width, int height) { 3151c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Persson if (width * height <= 320 * 240) { 3161c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Persson return 600; 3171c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Persson } else if (width * height <= 640 * 480) { 3181c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Persson return 1700; 3191c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Persson } else if (width * height <= 960 * 540) { 3201c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Persson return 2000; 3211c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Persson } else { 3221c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Persson return 2500; 3231c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Persson } 3241c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Persson} 3257fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} // namespace 326b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 32781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström// Constants defined in talk/media/webrtc/constants.h 32881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström// TODO(pbos): Move these to a separate constants.cc file. 32981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmconst int kMinVideoBitrate = 30; 33081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmconst int kStartVideoBitrate = 300; 33181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 33281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmconst int kVideoMtu = 1200; 33381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmconst int kVideoRtpBufferSize = 65536; 33481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 335b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// This constant is really an on/off, lower-level configurable NACK history 336b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// duration hasn't been implemented. 337b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic const int kNackHistoryMs = 1000; 338b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 339933d88af58b00517570ef78f38852bfd7fb1bb02buildbot@webrtc.orgstatic const int kDefaultQpMax = 56; 340933d88af58b00517570ef78f38852bfd7fb1bb02buildbot@webrtc.org 341b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic const int kDefaultRtcpReceiverReportSsrc = 1; 342b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 343e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmerconst int kMinBandwidthBps = 30000; 344e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmerconst int kStartBandwidthBps = 300000; 345e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmerconst int kMaxBandwidthBps = 2000000; 346e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer 34781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmstd::vector<VideoCodec> DefaultVideoCodecList() { 34881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström std::vector<VideoCodec> codecs; 34981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if (CodecIsInternallySupported(kVp9CodecName)) { 35081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström codecs.push_back(MakeVideoCodecWithDefaultFeedbackParams(kDefaultVp9PlType, 35181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström kVp9CodecName)); 35281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // TODO(andresp): Add rtx codec for vp9 and verify it works. 35381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 35481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström codecs.push_back(MakeVideoCodecWithDefaultFeedbackParams(kDefaultVp8PlType, 35581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström kVp8CodecName)); 35671f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin if (CodecIsInternallySupported(kH264CodecName)) { 35771f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin codecs.push_back(MakeVideoCodecWithDefaultFeedbackParams(kDefaultH264PlType, 35871f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin kH264CodecName)); 35971f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin } 36081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström codecs.push_back( 36181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström VideoCodec::CreateRtxCodec(kDefaultRtxVp8PlType, kDefaultVp8PlType)); 36281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström codecs.push_back(VideoCodec(kDefaultRedPlType, kRedCodecName)); 36381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström codecs.push_back(VideoCodec(kDefaultUlpfecType, kUlpfecCodecName)); 36481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return codecs; 36581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström} 36681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 367b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic bool FindFirstMatchingCodec(const std::vector<VideoCodec>& codecs, 368b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& requested_codec, 369b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec* matching_codec) { 370b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 371b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (requested_codec.Matches(codecs[i])) { 372b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *matching_codec = codecs[i]; 373b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 374b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 375b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 376b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 377b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 378b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 3793c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.orgstatic bool ValidateRtpHeaderExtensionIds( 3803c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 3813c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org std::set<int> extensions_used; 3823c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 38323914fe756903353eae13fffc868d2c84f51f06fPeter Boström if (extensions[i].id <= 0 || extensions[i].id >= 15 || 3843c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org !extensions_used.insert(extensions[i].id).second) { 3853c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org LOG(LS_ERROR) << "RTP extensions are with incorrect or duplicate ids."; 3863c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return false; 3873c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 3883c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 3893c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return true; 3903c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org} 3913c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org 392c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.orgstatic bool CompareRtpHeaderExtensionIds( 393c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org const webrtc::RtpExtension& extension1, 394c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org const webrtc::RtpExtension& extension2) { 395c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org // Sorting on ID is sufficient, more than one extension per ID is unsupported. 396c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return extension1.id > extension2.id; 397c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org} 398c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org 3993c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.orgstatic std::vector<webrtc::RtpExtension> FilterRtpExtensions( 4003c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 4013c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org std::vector<webrtc::RtpExtension> webrtc_extensions; 4023c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 4033c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org // Unsupported extensions will be ignored. 40423fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg if (webrtc::RtpExtension::IsSupportedForVideo(extensions[i].uri)) { 4053c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org webrtc_extensions.push_back(webrtc::RtpExtension( 4063c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org extensions[i].uri, extensions[i].id)); 4073c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } else { 4083c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org LOG(LS_WARNING) << "Unsupported RTP extension: " << extensions[i].uri; 4093c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 4103c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 411c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org 412c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org // Sort filtered headers to make sure that they can later be compared 413c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org // regardless of in which order they were entered. 414c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org std::sort(webrtc_extensions.begin(), webrtc_extensions.end(), 415c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org CompareRtpHeaderExtensionIds); 4163c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return webrtc_extensions; 4173c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org} 4183c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org 419c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.orgstatic bool RtpExtensionsHaveChanged( 420c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org const std::vector<webrtc::RtpExtension>& before, 421c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org const std::vector<webrtc::RtpExtension>& after) { 422c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org if (before.size() != after.size()) 423c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return true; 424c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org for (size_t i = 0; i < before.size(); ++i) { 425c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org if (before[i].id != after[i].id) 426c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return true; 427c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org if (before[i].name != after[i].name) 428c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return true; 429c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org } 430c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return false; 431c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org} 432c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org 433a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.orgstd::vector<webrtc::VideoStream> 434f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::CreateSimulcastVideoStreams( 435d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoCodec& codec, 436d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoOptions& options, 437dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström int max_bitrate_bps, 438d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org size_t num_streams) { 439a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org int max_qp = kDefaultQpMax; 440a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org codec.GetParam(kCodecParamMaxQuantization, &max_qp); 441a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org 442a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org return GetSimulcastConfig( 443dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström num_streams, GetSimulcastBitrateMode(options), codec.width, codec.height, 444dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström max_bitrate_bps, max_qp, 445a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org codec.framerate != 0 ? codec.framerate : kDefaultVideoMaxFramerate); 446a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org} 447a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org 448f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.orgstd::vector<webrtc::VideoStream> 449f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoStreams( 450a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org const VideoCodec& codec, 451a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org const VideoOptions& options, 452dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström int max_bitrate_bps, 453a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org size_t num_streams) { 454dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström int codec_max_bitrate_kbps; 455dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström if (codec.GetParam(kCodecParamMaxBitrate, &codec_max_bitrate_kbps)) { 456dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström max_bitrate_bps = codec_max_bitrate_kbps * 1000; 457dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström } 458dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström if (num_streams != 1) { 459dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström return CreateSimulcastVideoStreams(codec, options, max_bitrate_bps, 460dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström num_streams); 461dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström } 462dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström 463dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström // For unset max bitrates set default bitrate for non-simulcast. 4641c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Persson if (max_bitrate_bps <= 0) { 4651c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Persson max_bitrate_bps = 4661c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Persson GetMaxDefaultVideoBitrateKbps(codec.width, codec.height) * 1000; 4671c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Persson } 468a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org 469d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org webrtc::VideoStream stream; 470d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.width = codec.width; 471d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.height = codec.height; 472d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.max_framerate = 47382775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org codec.framerate != 0 ? codec.framerate : kDefaultVideoMaxFramerate; 474d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org 475008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org stream.min_bitrate_bps = kMinVideoBitrate * 1000; 476dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström stream.target_bitrate_bps = stream.max_bitrate_bps = max_bitrate_bps; 477d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org 478933d88af58b00517570ef78f38852bfd7fb1bb02buildbot@webrtc.org int max_qp = kDefaultQpMax; 479d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org codec.GetParam(kCodecParamMaxQuantization, &max_qp); 480d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.max_qp = max_qp; 481d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org std::vector<webrtc::VideoStream> streams; 482d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org streams.push_back(stream); 483d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org return streams; 484d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org} 485b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 486f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.orgvoid* WebRtcVideoChannel2::WebRtcVideoSendStream::ConfigureVideoEncoderSettings( 4876f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org const VideoCodec& codec, 488143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng const VideoOptions& options, 489143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng bool is_screencast) { 490143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng // No automatic resizing when using simulcast. 491143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng bool automatic_resize = !is_screencast && ssrcs_.size() == 1; 492143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng bool frame_dropping = !is_screencast; 493143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng bool denoising; 494143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng if (is_screencast) { 495143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng denoising = false; 496143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng } else { 497143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng options.video_noise_reduction.Get(&denoising); 498143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng } 499143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng 500e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (CodecNamesEq(codec.name, kVp8CodecName)) { 501f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org encoder_settings_.vp8 = webrtc::VideoEncoder::GetDefaultVp8Settings(); 502143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng encoder_settings_.vp8.automaticResizeOn = automatic_resize; 503143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng encoder_settings_.vp8.denoisingOn = denoising; 504143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng encoder_settings_.vp8.frameDroppingOn = frame_dropping; 505f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org return &encoder_settings_.vp8; 5066f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org } 507e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (CodecNamesEq(codec.name, kVp9CodecName)) { 508f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org encoder_settings_.vp9 = webrtc::VideoEncoder::GetDefaultVp9Settings(); 509143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng encoder_settings_.vp9.denoisingOn = denoising; 510143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng encoder_settings_.vp9.frameDroppingOn = frame_dropping; 511f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org return &encoder_settings_.vp9; 512188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org } 5136f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org return NULL; 5146f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org} 5156f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 516afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgDefaultUnsignalledSsrcHandler::DefaultUnsignalledSsrcHandler() 517afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org : default_recv_ssrc_(0), default_renderer_(NULL) {} 518afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 519afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgUnsignalledSsrcHandler::Action DefaultUnsignalledSsrcHandler::OnUnsignalledSsrc( 520a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org WebRtcVideoChannel2* channel, 521afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org uint32_t ssrc) { 522afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org if (default_recv_ssrc_ != 0) { // Already one default stream. 523afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_WARNING) << "Unknown SSRC, but default receive stream already set."; 524afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return kDropPacket; 525afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 526afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 527afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org StreamParams sp; 528afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org sp.ssrcs.push_back(ssrc); 529afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_INFO) << "Creating default receive stream for SSRC=" << ssrc << "."; 530a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org if (!channel->AddRecvStream(sp, true)) { 531afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_WARNING) << "Could not create default receive stream."; 532afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 533afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 534afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org channel->SetRenderer(ssrc, default_renderer_); 535afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org default_recv_ssrc_ = ssrc; 536afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return kDeliverPacket; 537afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org} 538afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 53942684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.orgWebRtcCallFactory::~WebRtcCallFactory() { 54042684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org} 54142684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.orgwebrtc::Call* WebRtcCallFactory::CreateCall( 54242684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org const webrtc::Call::Config& config) { 54342684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org return webrtc::Call::Create(config); 54442684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org} 54542684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org 546afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgVideoRenderer* DefaultUnsignalledSsrcHandler::GetDefaultRenderer() const { 547afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return default_renderer_; 548afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org} 549afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 550afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgvoid DefaultUnsignalledSsrcHandler::SetDefaultRenderer( 551afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org VideoMediaChannel* channel, 552afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org VideoRenderer* renderer) { 553afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org default_renderer_ = renderer; 554afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org if (default_recv_ssrc_ != 0) { 555afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org channel->SetRenderer(default_recv_ssrc_, default_renderer_); 556afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 557afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org} 558afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 559f1f0d9a4cd53f4eacbf791cb7317612fa7382a45pbos@webrtc.orgWebRtcVideoEngine2::WebRtcVideoEngine2(WebRtcVoiceEngine* voice_engine) 5609a416bd14ee225d8f1a1ada627a1dd7daf275032Fredrik Solenberg : voice_engine_(voice_engine), 561b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org initialized_(false), 56242684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org call_factory_(&default_call_factory_), 5630a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_decoder_factory_(NULL), 5640a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_encoder_factory_(NULL) { 565b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::WebRtcVideoEngine2()"; 5667fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org video_codecs_ = GetSupportedCodecs(); 567587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org rtp_header_extensions_.push_back( 568587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org RtpHeaderExtension(kRtpTimestampOffsetHeaderExtension, 569587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org kRtpTimestampOffsetHeaderExtensionDefaultId)); 570587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org rtp_header_extensions_.push_back( 571587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, 572587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org kRtpAbsoluteSenderTimeHeaderExtensionDefaultId)); 57364c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh rtp_header_extensions_.push_back( 57464c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh RtpHeaderExtension(kRtpVideoRotationHeaderExtension, 57564c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh kRtpVideoRotationHeaderExtensionDefaultId)); 576b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 577b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 578b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoEngine2::~WebRtcVideoEngine2() { 579b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::~WebRtcVideoEngine2"; 580b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 581b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 58242684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.orgvoid WebRtcVideoEngine2::SetCallFactory(WebRtcCallFactory* call_factory) { 583d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(!initialized_); 58442684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org call_factory_ = call_factory; 58542684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org} 58642684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org 5879a416bd14ee225d8f1a1ada627a1dd7daf275032Fredrik Solenbergvoid WebRtcVideoEngine2::Init() { 588b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::Init"; 589b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org initialized_ = true; 590b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 591b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 592b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgint WebRtcVideoEngine2::GetCapabilities() { return VIDEO_RECV | VIDEO_SEND; } 593b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 594b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::SetDefaultEncoderConfig( 595b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoEncoderConfig& config) { 5968fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org const VideoCodec& codec = config.max_codec; 597957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org bool supports_codec = false; 598957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org for (size_t i = 0; i < video_codecs_.size(); ++i) { 599e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (CodecNamesEq(video_codecs_[i].name, codec.name)) { 6002a72c6506a49b15d5e079eaa28cb80abb445684bpbos@webrtc.org video_codecs_[i].width = codec.width; 6012a72c6506a49b15d5e079eaa28cb80abb445684bpbos@webrtc.org video_codecs_[i].height = codec.height; 6022a72c6506a49b15d5e079eaa28cb80abb445684bpbos@webrtc.org video_codecs_[i].framerate = codec.framerate; 603957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org supports_codec = true; 604957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org break; 605957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org } 606957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org } 607957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org 608957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org if (!supports_codec) { 609957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org LOG(LS_ERROR) << "SetDefaultEncoderConfig, codec not supported: " 6108fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org << codec.ToString(); 6118fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return false; 6128fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org } 6138fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org 614b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 615b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 616b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 617b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2* WebRtcVideoEngine2::CreateChannel( 6181ecbe45c7e4c9142896cb2810d699558518f4f28buildbot@webrtc.org const VideoOptions& options, 619b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VoiceMediaChannel* voice_channel) { 620d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(initialized_); 621b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "CreateChannel: " 622b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (voice_channel != NULL ? "With" : "Without") 623fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org << " voice channel. Options: " << options.ToString(); 6247fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org WebRtcVideoChannel2* channel = 6254b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg new WebRtcVideoChannel2(call_factory_, voice_engine_, 6264b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg static_cast<WebRtcVoiceMediaChannel*>(voice_channel), options, 6274b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg external_encoder_factory_, external_decoder_factory_); 628b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!channel->Init()) { 629b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete channel; 630b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 631b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 632e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org channel->SetRecvCodecs(video_codecs_); 633b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return channel; 634b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 635b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 636b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgconst std::vector<VideoCodec>& WebRtcVideoEngine2::codecs() const { 637b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return video_codecs_; 638b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 639b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 640b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgconst std::vector<RtpHeaderExtension>& 641b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoEngine2::rtp_header_extensions() const { 642b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return rtp_header_extensions_; 643b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 644b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 645b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoEngine2::SetLogging(int min_sev, const char* filter) { 646b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Set up logging. 647b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetLogging: " << min_sev << '"' << filter << '"'; 648b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // if min_sev == -1, we keep the current log level. 649b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (min_sev < 0) { 650d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(min_sev == -1); 651b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 652b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 653b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 654b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 6550a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.orgvoid WebRtcVideoEngine2::SetExternalDecoderFactory( 6560a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org WebRtcVideoDecoderFactory* decoder_factory) { 657d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(!initialized_); 6580a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_decoder_factory_ = decoder_factory; 6590a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org} 6600a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org 6610a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.orgvoid WebRtcVideoEngine2::SetExternalEncoderFactory( 6620a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org WebRtcVideoEncoderFactory* encoder_factory) { 663d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(!initialized_); 664f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org if (external_encoder_factory_ == encoder_factory) 665f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org return; 666f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org 667f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org // No matter what happens we shouldn't hold on to a stale 668f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org // WebRtcSimulcastEncoderFactory. 669f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org simulcast_encoder_factory_.reset(); 670f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org 671f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org if (encoder_factory && 672f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org WebRtcSimulcastEncoderFactory::UseSimulcastEncoderFactory( 673f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org encoder_factory->codecs())) { 674f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org simulcast_encoder_factory_.reset( 675f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org new WebRtcSimulcastEncoderFactory(encoder_factory)); 676f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org encoder_factory = simulcast_encoder_factory_.get(); 677f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org } 6780a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_encoder_factory_ = encoder_factory; 6797fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 6807fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org video_codecs_ = GetSupportedCodecs(); 6810a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org} 6820a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org 683b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::EnableTimedRender() { 684b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Figure out whether this can be removed. 685b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 686b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 687b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 688b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Checks to see whether we comprehend and could receive a particular codec 689b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::FindCodec(const VideoCodec& in) { 690b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Probe encoder factory to figure out that the codec is supported 691b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // if supported by the encoder factory. Add a corresponding test that fails 692b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // with this code (that doesn't ask the factory). 6938fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org for (size_t j = 0; j < video_codecs_.size(); ++j) { 6948fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org VideoCodec codec(video_codecs_[j].id, video_codecs_[j].name, 0, 0, 0, 0); 6958fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org if (codec.Matches(in)) { 6968fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return true; 697b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 698b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 699b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 700b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 701b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 702b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Tells whether the |requested| codec can be transmitted or not. If it can be 703b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// transmitted |out| is set with the best settings supported. Aspect ratio will 704b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// be set as close to |current|'s as possible. If not set |requested|'s 705b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// dimensions will be used for aspect ratio matching. 706b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::CanSendCodec(const VideoCodec& requested, 707b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& current, 708b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec* out) { 709d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(out != NULL); 710b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 711b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (requested.width != requested.height && 712b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org (requested.height == 0 || requested.width == 0)) { 713b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // 0xn and nx0 are invalid resolutions. 714b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 715b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 716b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 717b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec matching_codec; 718b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!FindFirstMatchingCodec(video_codecs_, requested, &matching_codec)) { 719b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Codec not supported. 720b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 721b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 722b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 723b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->id = requested.id; 724b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->name = requested.name; 725b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->preference = requested.preference; 726b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->params = requested.params; 727ff689be3c0c59c1be29aaa0697aa0f762566d6c6andresp@webrtc.org out->framerate = std::min(requested.framerate, matching_codec.framerate); 728b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->params = requested.params; 729b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->feedback_params = requested.feedback_params; 7308fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->width = requested.width; 7318fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->height = requested.height; 7328fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org if (requested.width == 0 && requested.height == 0) { 7338fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return true; 7348fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org } 7358fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org 7368fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org while (out->width > matching_codec.width) { 7378fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->width /= 2; 7388fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->height /= 2; 7398fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org } 7408fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org 7418fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return out->width > 0 && out->height > 0; 742b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 743b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 744b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Ignore spammy trace messages, mostly from the stats API when we haven't 745b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// gotten RTCP info yet from the remote side. 746b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::ShouldIgnoreTrace(const std::string& trace) { 747b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static const char* const kTracesToIgnore[] = {NULL}; 748b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (const char* const* p = kTracesToIgnore; *p; ++p) { 749b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (trace.find(*p) == 0) { 750b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 751b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 752b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 753b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 754b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 755b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 7567fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgstd::vector<VideoCodec> WebRtcVideoEngine2::GetSupportedCodecs() const { 75782775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org std::vector<VideoCodec> supported_codecs = DefaultVideoCodecList(); 7587fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 7597fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (external_encoder_factory_ == NULL) { 7607fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return supported_codecs; 7617fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 7627fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 7637fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org const std::vector<WebRtcVideoEncoderFactory::VideoCodec>& codecs = 7647fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_->codecs(); 7657fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 7667fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org // Don't add internally-supported codecs twice. 7677fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (CodecIsInternallySupported(codecs[i].name)) { 7687fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org continue; 7697fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 7707fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 771d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org // External video encoders are given payloads 120-127. This also means that 772d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org // we only support up to 8 external payload types. 773d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org const int kExternalVideoPayloadTypeBase = 120; 774d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org size_t payload_type = kExternalVideoPayloadTypeBase + i; 775d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(payload_type < 128); 776d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org VideoCodec codec(static_cast<int>(payload_type), 7777fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org codecs[i].name, 7787fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org codecs[i].max_width, 7797fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org codecs[i].max_height, 7807fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org codecs[i].max_fps, 7817fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 0); 7827fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 7837fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org AddDefaultFeedbackParams(&codec); 7847fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org supported_codecs.push_back(codec); 7857fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 7867fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return supported_codecs; 7877fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 7887fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 789b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoChannel2( 79042684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org WebRtcCallFactory* call_factory, 7913bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org WebRtcVoiceEngine* voice_engine, 7924b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg WebRtcVoiceMediaChannel* voice_channel, 793fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org const VideoOptions& options, 7947fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org WebRtcVideoEncoderFactory* external_encoder_factory, 795f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org WebRtcVideoDecoderFactory* external_decoder_factory) 796b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org : unsignalled_ssrc_handler_(&default_unsignalled_ssrc_handler_), 7974b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg voice_channel_(voice_channel), 7984b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg voice_channel_id_(voice_channel ? voice_channel->voe_channel() : -1), 7997fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_(external_encoder_factory), 800f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org external_decoder_factory_(external_decoder_factory) { 8014b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg DCHECK(thread_checker_.CalledOnValidThread()); 802fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org SetDefaultOptions(); 803fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org options_.SetAll(options); 804e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström options_.cpu_overuse_detection.Get(&signal_cpu_adaptation_); 8054fbae2b79134572135d9d5fe35a7d1ccdeea3a4dsolenberg webrtc::Call::Config config; 8063bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org if (voice_engine != NULL) { 8073bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org config.voice_engine = voice_engine->voe()->engine(); 8083bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org } 809e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer config.bitrate_config.min_bitrate_bps = kMinBandwidthBps; 810e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer config.bitrate_config.start_bitrate_bps = kStartBandwidthBps; 811e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer config.bitrate_config.max_bitrate_bps = kMaxBandwidthBps; 81242684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org call_.reset(call_factory->CreateCall(config)); 8134b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg if (voice_channel_) { 8144b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg voice_channel_->SetCall(call_.get()); 8154b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg } 816b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtcp_receiver_report_ssrc_ = kDefaultRtcpReceiverReportSsrc; 817b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = false; 818b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = 0; 8196f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org} 8206f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 8216f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.orgvoid WebRtcVideoChannel2::SetDefaultOptions() { 822e432800aeb6b695bda14acf2d60c0200803b5218Peter Boström options_.cpu_overuse_detection.Set(true); 823d819803d4570564a9800a7dd54f4593e6e21a6e7pbos@webrtc.org options_.dscp.Set(false); 8245ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org options_.suspend_below_min_bitrate.Set(false); 82542684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org options_.video_noise_reduction.Set(true); 826efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org options_.screencast_min_bitrate.Set(0); 827b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 828b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 829b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::~WebRtcVideoChannel2() { 8304b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg DetachVoiceChannel(); 831dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström for (auto& kv : send_streams_) 832dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström delete kv.second; 833dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström for (auto& kv : receive_streams_) 834dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström delete kv.second; 835b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 836b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 837b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::Init() { return true; } 838b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 8394b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenbergvoid WebRtcVideoChannel2::DetachVoiceChannel() { 8404b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg DCHECK(thread_checker_.CalledOnValidThread()); 8414b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg if (voice_channel_) { 8424b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg voice_channel_->SetCall(nullptr); 8434b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg voice_channel_ = nullptr; 8444b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg } 8454b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg} 8464b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg 84796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgbool WebRtcVideoChannel2::CodecIsExternallySupported( 84896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const std::string& name) const { 84996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (external_encoder_factory_ == NULL) { 85096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return false; 85196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 85296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 85396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const std::vector<WebRtcVideoEncoderFactory::VideoCodec> external_codecs = 85496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org external_encoder_factory_->codecs(); 85596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org for (size_t c = 0; c < external_codecs.size(); ++c) { 856e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (CodecNamesEq(name, external_codecs[c].name)) { 85796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return true; 85896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 85996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 86096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return false; 86196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org} 86296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 86396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgstd::vector<WebRtcVideoChannel2::VideoCodecSettings> 86496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgWebRtcVideoChannel2::FilterSupportedCodecs( 86596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const std::vector<WebRtcVideoChannel2::VideoCodecSettings>& mapped_codecs) 86696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const { 86796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org std::vector<VideoCodecSettings> supported_codecs; 86896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org for (size_t i = 0; i < mapped_codecs.size(); ++i) { 86996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const VideoCodecSettings& codec = mapped_codecs[i]; 87096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (CodecIsInternallySupported(codec.codec.name) || 87196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org CodecIsExternallySupported(codec.codec.name)) { 87296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org supported_codecs.push_back(codec); 87396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 87496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 87596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return supported_codecs; 87696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org} 87796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 878874ca3af5b163e1b3fd8802171e44ee252557842deadbeefbool WebRtcVideoChannel2::ReceiveCodecsHaveChanged( 879874ca3af5b163e1b3fd8802171e44ee252557842deadbeef std::vector<VideoCodecSettings> before, 880874ca3af5b163e1b3fd8802171e44ee252557842deadbeef std::vector<VideoCodecSettings> after) { 881874ca3af5b163e1b3fd8802171e44ee252557842deadbeef if (before.size() != after.size()) { 882874ca3af5b163e1b3fd8802171e44ee252557842deadbeef return true; 883874ca3af5b163e1b3fd8802171e44ee252557842deadbeef } 884874ca3af5b163e1b3fd8802171e44ee252557842deadbeef // The receive codec order doesn't matter, so we sort the codecs before 885874ca3af5b163e1b3fd8802171e44ee252557842deadbeef // comparing. This is necessary because currently the 886874ca3af5b163e1b3fd8802171e44ee252557842deadbeef // only way to change the send codec is to munge SDP, which causes 887874ca3af5b163e1b3fd8802171e44ee252557842deadbeef // the receive codec list to change order, which causes the streams 888874ca3af5b163e1b3fd8802171e44ee252557842deadbeef // to be recreates which causes a "blink" of black video. In order 889874ca3af5b163e1b3fd8802171e44ee252557842deadbeef // to support munging the SDP in this way without recreating receive 890874ca3af5b163e1b3fd8802171e44ee252557842deadbeef // streams, we ignore the order of the received codecs so that 891874ca3af5b163e1b3fd8802171e44ee252557842deadbeef // changing the order doesn't cause this "blink". 892874ca3af5b163e1b3fd8802171e44ee252557842deadbeef auto comparison = 893874ca3af5b163e1b3fd8802171e44ee252557842deadbeef [](const VideoCodecSettings& codec1, const VideoCodecSettings& codec2) { 894874ca3af5b163e1b3fd8802171e44ee252557842deadbeef return codec1.codec.id > codec2.codec.id; 895874ca3af5b163e1b3fd8802171e44ee252557842deadbeef }; 896874ca3af5b163e1b3fd8802171e44ee252557842deadbeef std::sort(before.begin(), before.end(), comparison); 897874ca3af5b163e1b3fd8802171e44ee252557842deadbeef std::sort(after.begin(), after.end(), comparison); 898874ca3af5b163e1b3fd8802171e44ee252557842deadbeef for (size_t i = 0; i < before.size(); ++i) { 899874ca3af5b163e1b3fd8802171e44ee252557842deadbeef // For the same reason that we sort the codecs, we also ignore the 900874ca3af5b163e1b3fd8802171e44ee252557842deadbeef // preference. We don't want a preference change on the receive 901874ca3af5b163e1b3fd8802171e44ee252557842deadbeef // side to cause recreation of the stream. 902874ca3af5b163e1b3fd8802171e44ee252557842deadbeef before[i].codec.preference = 0; 903874ca3af5b163e1b3fd8802171e44ee252557842deadbeef after[i].codec.preference = 0; 904874ca3af5b163e1b3fd8802171e44ee252557842deadbeef if (before[i] != after[i]) { 905874ca3af5b163e1b3fd8802171e44ee252557842deadbeef return true; 906874ca3af5b163e1b3fd8802171e44ee252557842deadbeef } 907874ca3af5b163e1b3fd8802171e44ee252557842deadbeef } 908874ca3af5b163e1b3fd8802171e44ee252557842deadbeef return false; 909874ca3af5b163e1b3fd8802171e44ee252557842deadbeef} 910874ca3af5b163e1b3fd8802171e44ee252557842deadbeef 911c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcherbool WebRtcVideoChannel2::SetSendParameters(const VideoSendParameters& params) { 912c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher // TODO(pbos): Refactor this to only recreate the send streams once 913c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher // instead of 4 times. 914c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher return (SetSendCodecs(params.codecs) && 915c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher SetSendRtpHeaderExtensions(params.extensions) && 916c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher SetMaxSendBandwidth(params.max_bandwidth_bps) && 917c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher SetOptions(params.options)); 918c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher} 919c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher 920c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcherbool WebRtcVideoChannel2::SetRecvParameters(const VideoRecvParameters& params) { 921c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher // TODO(pbos): Refactor this to only recreate the recv streams once 922c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher // instead of twice. 923c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher return (SetRecvCodecs(params.codecs) && 924c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher SetRecvRtpHeaderExtensions(params.extensions)); 925c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher} 926c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher 927874ca3af5b163e1b3fd8802171e44ee252557842deadbeefstd::string WebRtcVideoChannel2::CodecSettingsVectorToString( 928874ca3af5b163e1b3fd8802171e44ee252557842deadbeef const std::vector<VideoCodecSettings>& codecs) { 929874ca3af5b163e1b3fd8802171e44ee252557842deadbeef std::stringstream out; 930874ca3af5b163e1b3fd8802171e44ee252557842deadbeef out << '{'; 931874ca3af5b163e1b3fd8802171e44ee252557842deadbeef for (size_t i = 0; i < codecs.size(); ++i) { 932874ca3af5b163e1b3fd8802171e44ee252557842deadbeef out << codecs[i].codec.ToString(); 933874ca3af5b163e1b3fd8802171e44ee252557842deadbeef if (i != codecs.size() - 1) { 934874ca3af5b163e1b3fd8802171e44ee252557842deadbeef out << ", "; 935874ca3af5b163e1b3fd8802171e44ee252557842deadbeef } 936874ca3af5b163e1b3fd8802171e44ee252557842deadbeef } 937874ca3af5b163e1b3fd8802171e44ee252557842deadbeef out << '}'; 938874ca3af5b163e1b3fd8802171e44ee252557842deadbeef return out.str(); 939874ca3af5b163e1b3fd8802171e44ee252557842deadbeef} 940874ca3af5b163e1b3fd8802171e44ee252557842deadbeef 941b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRecvCodecs(const std::vector<VideoCodec>& codecs) { 94250fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetRecvCodecs"); 943b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetRecvCodecs: " << CodecVectorToString(codecs); 944b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!ValidateCodecFormats(codecs)) { 945b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 946b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 947b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 948b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<VideoCodecSettings> mapped_codecs = MapCodecs(codecs); 949b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (mapped_codecs.empty()) { 95096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org LOG(LS_ERROR) << "SetRecvCodecs called without any video codecs."; 951b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 952b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 953b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 954874ca3af5b163e1b3fd8802171e44ee252557842deadbeef std::vector<VideoCodecSettings> supported_codecs = 95596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org FilterSupportedCodecs(mapped_codecs); 95696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 95796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (mapped_codecs.size() != supported_codecs.size()) { 95896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org LOG(LS_ERROR) << "SetRecvCodecs called with unsupported video codecs."; 95996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return false; 960b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 961b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 962ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström // Prevent reconfiguration when setting identical receive codecs. 963874ca3af5b163e1b3fd8802171e44ee252557842deadbeef if (!ReceiveCodecsHaveChanged(recv_codecs_, supported_codecs)) { 964874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) 965874ca3af5b163e1b3fd8802171e44ee252557842deadbeef << "Ignoring call to SetRecvCodecs because codecs haven't changed."; 966874ca3af5b163e1b3fd8802171e44ee252557842deadbeef return true; 967ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström } 968ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström 969874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "Changing recv codecs from " 970874ca3af5b163e1b3fd8802171e44ee252557842deadbeef << CodecSettingsVectorToString(recv_codecs_) << " to " 971874ca3af5b163e1b3fd8802171e44ee252557842deadbeef << CodecSettingsVectorToString(supported_codecs); 97296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org recv_codecs_ = supported_codecs; 973d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 974575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 975d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 976d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.begin(); 977d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != receive_streams_.end(); 978d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 979d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetRecvCodecs(recv_codecs_); 980d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 981d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 982b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 983b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 984b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 985b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendCodecs(const std::vector<VideoCodec>& codecs) { 98650fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetSendCodecs"); 987b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetSendCodecs: " << CodecVectorToString(codecs); 988b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!ValidateCodecFormats(codecs)) { 989b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 990b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 991b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 992b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<VideoCodecSettings> supported_codecs = 993b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org FilterSupportedCodecs(MapCodecs(codecs)); 994b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 995b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (supported_codecs.empty()) { 9963c3f6460646183914629e5dab8ae5fcede4f0e80Peter Boström LOG(LS_ERROR) << "No video codecs supported."; 997b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 998b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 999b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1000b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "Using codec: " << supported_codecs.front().codec.ToString(); 1001b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1002a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org VideoCodecSettings old_codec; 1003a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (send_codec_.Get(&old_codec) && supported_codecs.front() == old_codec) { 1004874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "Ignore call to SetSendCodecs because first supported " 1005874ca3af5b163e1b3fd8802171e44ee252557842deadbeef "codec hasn't changed."; 1006a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org // Using same codec, avoid reconfiguring. 1007a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org return true; 1008a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } 1009a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 1010a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org send_codec_.Set(supported_codecs.front()); 1011a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 1012575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1013874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "Change the send codec because SetSendCodecs has a different " 1014874ca3af5b163e1b3fd8802171e44ee252557842deadbeef "first supported codec."; 1015126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström for (auto& kv : send_streams_) { 1016126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström DCHECK(kv.second != nullptr); 1017126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström kv.second->SetCodec(supported_codecs.front()); 1018126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström } 1019874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "SetNackAndRemb on all the receive streams because the send " 1020874ca3af5b163e1b3fd8802171e44ee252557842deadbeef "codec has changed."; 1021126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström for (auto& kv : receive_streams_) { 1022126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström DCHECK(kv.second != nullptr); 102367c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström kv.second->SetNackAndRemb(HasNack(supported_codecs.front().codec), 102467c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström HasRemb(supported_codecs.front().codec)); 1025d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1026b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1027e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer // TODO(holmer): Changing the codec parameters shouldn't necessarily mean that 1028e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer // we change the min/max of bandwidth estimation. Reevaluate this. 1029008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org VideoCodec codec = supported_codecs.front().codec; 1030008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org int bitrate_kbps; 1031008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org if (codec.GetParam(kCodecParamMinBitrate, &bitrate_kbps) && 1032008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_kbps > 0) { 1033008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.min_bitrate_bps = bitrate_kbps * 1000; 1034008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } else { 1035008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.min_bitrate_bps = 0; 1036008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } 1037008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org if (codec.GetParam(kCodecParamStartBitrate, &bitrate_kbps) && 1038008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_kbps > 0) { 1039008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.start_bitrate_bps = bitrate_kbps * 1000; 1040008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } else { 1041008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org // Do not reconfigure start bitrate unless it's specified and positive. 1042008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.start_bitrate_bps = -1; 1043008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } 1044008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org if (codec.GetParam(kCodecParamMaxBitrate, &bitrate_kbps) && 1045008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_kbps > 0) { 1046008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.max_bitrate_bps = bitrate_kbps * 1000; 1047008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } else { 1048008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.max_bitrate_bps = -1; 1049008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } 1050008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org call_->SetBitrateConfig(bitrate_config_); 1051008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org 1052b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1053b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1054b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1055b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::GetSendCodec(VideoCodec* codec) { 1056b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodecSettings codec_settings; 1057b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!send_codec_.Get(&codec_settings)) { 1058b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "GetSendCodec: No send codec set."; 1059b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1060b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1061b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *codec = codec_settings.codec; 1062b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1063b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1064b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1065b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendStreamFormat(uint32 ssrc, 1066b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFormat& format) { 1067b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetSendStreamFormat:" << ssrc << " -> " 1068b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << format.ToString(); 1069575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1070b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 1071b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1072b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1073b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return send_streams_[ssrc]->SetVideoFormat(format); 1074b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1075b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1076b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRender(bool render) { 1077b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. Or refactor away as it shouldn't be needed. 1078b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetRender: " << (render ? "true" : "false"); 1079b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1080b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1081b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1082b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSend(bool send) { 1083b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetSend: " << (send ? "true" : "false"); 1084b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send && !send_codec_.IsSet()) { 1085b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "SetSend(true) called before setting codec."; 1086b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1087b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1088b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send) { 1089b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org StartAllSendStreams(); 1090b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 1091b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org StopAllSendStreams(); 1092b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1093b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = send; 1094b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1095b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1096b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1097d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boströmbool WebRtcVideoChannel2::ValidateSendSsrcAvailability( 1098d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström const StreamParams& sp) const { 1099d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström for (uint32_t ssrc: sp.ssrcs) { 1100d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström if (send_ssrcs_.find(ssrc) != send_ssrcs_.end()) { 1101d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström LOG(LS_ERROR) << "Send stream with SSRC '" << ssrc << "' already exists."; 1102d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström return false; 1103d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström } 1104d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström } 1105d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström return true; 1106d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström} 1107d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 1108d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boströmbool WebRtcVideoChannel2::ValidateReceiveSsrcAvailability( 1109d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström const StreamParams& sp) const { 1110d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström for (uint32_t ssrc: sp.ssrcs) { 1111d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström if (receive_ssrcs_.find(ssrc) != receive_ssrcs_.end()) { 1112d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström LOG(LS_ERROR) << "Receive stream with SSRC '" << ssrc 1113d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström << "' already exists."; 1114d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström return false; 1115d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström } 1116d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström } 1117d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström return true; 1118d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström} 1119d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 1120b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::AddSendStream(const StreamParams& sp) { 1121b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "AddSendStream: " << sp.ToString(); 1122d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström if (!ValidateStreamParams(sp)) 1123b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1124b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1125575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1126d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 1127d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström if (!ValidateSendSsrcAvailability(sp)) 1128b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1129d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 1130d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström for (uint32 used_ssrc : sp.ssrcs) 1131d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström send_ssrcs_.insert(used_ssrc); 1132b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1133e5269747595864eedd604f153df5d7bcbe1b475asolenberg webrtc::VideoSendStream::Config config(this); 1134e5269747595864eedd604f153df5d7bcbe1b475asolenberg config.overuse_callback = this; 1135e5269747595864eedd604f153df5d7bcbe1b475asolenberg 1136b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoSendStream* stream = 11376ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org new WebRtcVideoSendStream(call_.get(), 11384fbae2b79134572135d9d5fe35a7d1ccdeea3a4dsolenberg sp, 1139e5269747595864eedd604f153df5d7bcbe1b475asolenberg config, 11407fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_, 11416ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org options_, 1142dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström bitrate_config_.max_bitrate_bps, 11435301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org send_codec_, 11445301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org send_rtp_extensions_); 11455301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 1146d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström uint32 ssrc = sp.first_ssrc(); 1147d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(ssrc != 0); 1148b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_[ssrc] = stream; 1149b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1150b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (rtcp_receiver_report_ssrc_ == kDefaultRtcpReceiverReportSsrc) { 1151b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtcp_receiver_report_ssrc_ = ssrc; 1152874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "SetLocalSsrc on all the receive streams because we added " 1153874ca3af5b163e1b3fd8802171e44ee252557842deadbeef "a send stream."; 11543548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström for (auto& kv : receive_streams_) 11553548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström kv.second->SetLocalSsrc(ssrc); 1156b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1157b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (default_send_ssrc_ == 0) { 1158b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = ssrc; 1159b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1160b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sending_) { 1161b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream->Start(); 1162b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1163b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1164b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1165b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1166b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1167b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::RemoveSendStream(uint32 ssrc) { 1168b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "RemoveSendStream: " << ssrc; 1169b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1170b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1171b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (default_send_ssrc_ == 0) { 1172b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No default send stream active."; 1173b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1174b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1175b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1176b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "Removing default stream: " << default_send_ssrc_; 1177b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ssrc = default_send_ssrc_; 1178b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1179b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1180575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org WebRtcVideoSendStream* removed_stream; 1181575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org { 1182575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1183575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1184575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org send_streams_.find(ssrc); 1185575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org if (it == send_streams_.end()) { 1186575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org return false; 1187575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org } 1188575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org 1189d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström for (uint32 old_ssrc : it->second->GetSsrcs()) 1190d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström send_ssrcs_.erase(old_ssrc); 1191d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 1192575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org removed_stream = it->second; 1193575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org send_streams_.erase(it); 1194b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1195b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1196575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org delete removed_stream; 1197b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1198b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == default_send_ssrc_) { 1199b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = 0; 1200b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1201b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1202b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1203b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1204b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1205d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boströmvoid WebRtcVideoChannel2::DeleteReceiveStream( 1206d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström WebRtcVideoChannel2::WebRtcVideoReceiveStream* stream) { 1207d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström for (uint32 old_ssrc : stream->GetSsrcs()) 1208d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström receive_ssrcs_.erase(old_ssrc); 1209d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström delete stream; 1210d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström} 1211d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 1212b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::AddRecvStream(const StreamParams& sp) { 1213a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org return AddRecvStream(sp, false); 1214a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org} 1215a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org 1216a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.orgbool WebRtcVideoChannel2::AddRecvStream(const StreamParams& sp, 1217a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org bool default_stream) { 12184b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg DCHECK(thread_checker_.CalledOnValidThread()); 12194b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg 1220d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström LOG(LS_INFO) << "AddRecvStream" << (default_stream ? " (default stream)" : "") 1221d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström << ": " << sp.ToString(); 1222d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström if (!ValidateStreamParams(sp)) 1223d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström return false; 1224b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1225b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint32 ssrc = sp.first_ssrc(); 1226d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(ssrc != 0); // TODO(pbos): Is this ever valid? 1227b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1228575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1229d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström // Remove running stream if this was a default stream. 1230d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström auto prev_stream = receive_streams_.find(ssrc); 1231d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström if (prev_stream != receive_streams_.end()) { 1232d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström if (default_stream || !prev_stream->second->IsDefaultStream()) { 1233d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström LOG(LS_ERROR) << "Receive stream for SSRC '" << ssrc 1234d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström << "' already exists."; 1235d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström return false; 1236a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org } 1237d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström DeleteReceiveStream(prev_stream->second); 1238d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström receive_streams_.erase(prev_stream); 1239b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1240b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1241d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström if (!ValidateReceiveSsrcAvailability(sp)) 1242d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström return false; 1243d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 1244d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström for (uint32 used_ssrc : sp.ssrcs) 1245d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström receive_ssrcs_.insert(used_ssrc); 1246d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 12474fbae2b79134572135d9d5fe35a7d1ccdeea3a4dsolenberg webrtc::VideoReceiveStream::Config config(this); 1248d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ConfigureReceiverRtp(&config, sp); 12493bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org 12508fc7fa798f7a36955f1b933980401afad2aff592pbos // Set up A/V sync group based on sync label. 12518fc7fa798f7a36955f1b933980401afad2aff592pbos config.sync_group = sp.sync_label; 12523bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org 1253126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström config.rtp.remb = false; 1254126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström VideoCodecSettings send_codec; 1255126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström if (send_codec_.Get(&send_codec)) { 1256126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström config.rtp.remb = HasRemb(send_codec.codec); 1257126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström } 1258126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström 1259d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström receive_streams_[ssrc] = new WebRtcVideoReceiveStream( 12604fbae2b79134572135d9d5fe35a7d1ccdeea3a4dsolenberg call_.get(), sp, config, external_decoder_factory_, default_stream, 1261d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström recv_codecs_); 1262d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1263d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return true; 1264d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1265d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1266d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::ConfigureReceiverRtp( 1267d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org webrtc::VideoReceiveStream::Config* config, 1268d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const StreamParams& sp) const { 1269d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org uint32 ssrc = sp.first_ssrc(); 1270d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1271d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.remote_ssrc = ssrc; 1272d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.local_ssrc = rtcp_receiver_report_ssrc_; 1273b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1274d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.extensions = recv_rtp_extensions_; 1275257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org 1276b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): This protection is against setting the same local ssrc as 1277b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // remote which is not permitted by the lower-level API. RTCP requires a 1278b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // corresponding sender SSRC. Figure out what to do when we don't have 1279b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // (receive-only) or know a good local SSRC. 1280d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (config->rtp.remote_ssrc == config->rtp.local_ssrc) { 1281d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (config->rtp.local_ssrc != kDefaultRtcpReceiverReportSsrc) { 1282d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc; 1283b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 1284d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc + 1; 1285b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1286b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1287b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1288d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (size_t i = 0; i < recv_codecs_.size(); ++i) { 128982775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org MergeFecConfig(recv_codecs_[i].fec, &config->rtp.fec); 1290b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1291b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 129282775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org for (size_t i = 0; i < recv_codecs_.size(); ++i) { 129382775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org uint32 rtx_ssrc; 129482775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org if (recv_codecs_[i].rtx_payload_type != -1 && 129582775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org sp.GetFidSsrc(ssrc, &rtx_ssrc)) { 129682775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org webrtc::VideoReceiveStream::Config::Rtp::Rtx& rtx = 129782775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org config->rtp.rtx[recv_codecs_[i].codec.id]; 129882775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org rtx.ssrc = rtx_ssrc; 129982775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org rtx.payload_type = recv_codecs_[i].rtx_payload_type; 130082775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 130182775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 1302b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1303b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1304b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::RemoveRecvStream(uint32 ssrc) { 1305b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; 1306b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1307afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_ERROR) << "RemoveRecvStream with 0 ssrc is not supported."; 1308afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return false; 1309b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1310b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1311575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1312d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org std::map<uint32, WebRtcVideoReceiveStream*>::iterator stream = 1313b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_streams_.find(ssrc); 1314b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (stream == receive_streams_.end()) { 1315b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Stream not found for ssrc: " << ssrc; 1316b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1317b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1318d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström DeleteReceiveStream(stream->second); 1319b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_streams_.erase(stream); 1320b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1321b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1322b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1323b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1324b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRenderer(uint32 ssrc, VideoRenderer* renderer) { 1325b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetRenderer: ssrc:" << ssrc << " " 1326b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (renderer ? "(ptr)" : "NULL"); 1327b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1328afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org default_unsignalled_ssrc_handler_.SetDefaultRenderer(this, renderer); 1329d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return true; 1330b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1331b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1332575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1333d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1334d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.find(ssrc); 1335d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (it == receive_streams_.end()) { 1336d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return false; 1337b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1338b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1339b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->SetRenderer(renderer); 1340b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1341b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1342b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1343b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::GetRenderer(uint32 ssrc, VideoRenderer** renderer) { 1344b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1345afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org *renderer = default_unsignalled_ssrc_handler_.GetDefaultRenderer(); 1346afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return *renderer != NULL; 1347b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1348b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1349575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1350d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1351d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.find(ssrc); 1352d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (it == receive_streams_.end()) { 1353b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1354b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1355b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *renderer = it->second->GetRenderer(); 1356b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1357b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1358b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1359058b1f17ac43b1fe69a8c18aaa7999ba88733dfdpbos@webrtc.orgbool WebRtcVideoChannel2::GetStats(VideoMediaInfo* info) { 1360e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info->Clear(); 1361e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org FillSenderStats(info); 1362e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org FillReceiverStats(info); 13632b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org webrtc::Call::Stats stats = call_->GetStats(); 13642b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org FillBandwidthEstimationStats(stats, info); 13652b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org if (stats.rtt_ms != -1) { 13662b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org for (size_t i = 0; i < info->senders.size(); ++i) { 13672b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org info->senders[i].rtt_ms = stats.rtt_ms; 13682b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org } 13692b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org } 1370b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1371b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1372b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1373e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgvoid WebRtcVideoChannel2::FillSenderStats(VideoMediaInfo* video_media_info) { 1374575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1375e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1376e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org send_streams_.begin(); 1377e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org it != send_streams_.end(); 1378e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org ++it) { 1379e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org video_media_info->senders.push_back(it->second->GetVideoSenderInfo()); 1380e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1381e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1382e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1383e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgvoid WebRtcVideoChannel2::FillReceiverStats(VideoMediaInfo* video_media_info) { 1384575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1385e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1386e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org receive_streams_.begin(); 1387e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org it != receive_streams_.end(); 1388e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org ++it) { 1389e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org video_media_info->receivers.push_back(it->second->GetVideoReceiverInfo()); 1390e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1391e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1392e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1393e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgvoid WebRtcVideoChannel2::FillBandwidthEstimationStats( 13942b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org const webrtc::Call::Stats& stats, 1395e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoMediaInfo* video_media_info) { 13960bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org BandwidthEstimationInfo bwe_info; 13970bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org bwe_info.available_send_bandwidth = stats.send_bandwidth_bps; 13980bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org bwe_info.available_recv_bandwidth = stats.recv_bandwidth_bps; 13990bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org bwe_info.bucket_delay = stats.pacer_delay_ms; 14000bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org 14010bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org // Get send stream bitrate stats. 14020bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 14030bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator stream = 14040bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org send_streams_.begin(); 14050bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org stream != send_streams_.end(); 14060bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org ++stream) { 14070bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org stream->second->FillBandwidthEstimationInfo(&bwe_info); 14080bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org } 14090bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org video_media_info->bw_estimations.push_back(bwe_info); 1410e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1411e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1412b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetCapturer(uint32 ssrc, VideoCapturer* capturer) { 1413b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetCapturer: " << ssrc << " -> " 1414b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (capturer != NULL ? "(capturer)" : "NULL"); 1415d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(ssrc != 0); 1416e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström { 1417e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström rtc::CritScope stream_lock(&stream_crit_); 1418e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström if (send_streams_.find(ssrc) == send_streams_.end()) { 1419e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström LOG(LS_ERROR) << "No sending stream on ssrc " << ssrc; 1420e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström return false; 1421e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström } 1422e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström if (!send_streams_[ssrc]->SetCapturer(capturer)) { 1423e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström return false; 1424e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström } 142564c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh } 142664c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh 142764c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh if (capturer) { 142864c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh capturer->SetApplyRotation( 142964c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh !FindHeaderExtension(send_rtp_extensions_, 143064c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh kRtpVideoRotationHeaderExtension)); 143164c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh } 1432e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström { 1433e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström rtc::CritScope lock(&capturer_crit_); 1434e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström capturers_[ssrc] = capturer; 1435e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström } 143664c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh return true; 1437b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1438b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1439b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendIntraFrame() { 1440b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1441b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SendIntraFrame()."; 1442b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1443b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1444b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1445b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::RequestIntraFrame() { 1446b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1447b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SendIntraFrame()."; 1448b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1449b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1450b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1451b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnPacketReceived( 1452d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer* packet, 1453d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org const rtc::PacketTime& packet_time) { 14544e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org const webrtc::PacketReceiver::DeliveryStatus delivery_result = 145523fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg call_->Receiver()->DeliverPacket(webrtc::MediaType::VIDEO, 1456eebcab5ce99d3e8641dd92a569916b0d24e29fcakwiberg@webrtc.org reinterpret_cast<const uint8_t*>(packet->data()), packet->size()); 14574e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org switch (delivery_result) { 14584e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_OK: 14594e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org return; 14604e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_PACKET_ERROR: 14614e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org return; 14624e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_UNKNOWN_SSRC: 14634e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org break; 1464b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1465b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1466b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint32 ssrc = 0; 1467eebcab5ce99d3e8641dd92a569916b0d24e29fcakwiberg@webrtc.org if (!GetRtpSsrc(packet->data(), packet->size(), &ssrc)) { 1468b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1469b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1470b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1471d10a68e7974a29b26d6c926e6f137255f3c173benoahric int payload_type = 0; 1472d10a68e7974a29b26d6c926e6f137255f3c173benoahric if (!GetRtpPayloadType(packet->data(), packet->size(), &payload_type)) { 1473d10a68e7974a29b26d6c926e6f137255f3c173benoahric return; 1474d10a68e7974a29b26d6c926e6f137255f3c173benoahric } 1475d10a68e7974a29b26d6c926e6f137255f3c173benoahric 1476d10a68e7974a29b26d6c926e6f137255f3c173benoahric // See if this payload_type is registered as one that usually gets its own 1477d10a68e7974a29b26d6c926e6f137255f3c173benoahric // SSRC (RTX) or at least is safe to drop either way (ULPFEC). If it is, and 1478d10a68e7974a29b26d6c926e6f137255f3c173benoahric // it wasn't handled above by DeliverPacket, that means we don't know what 1479d10a68e7974a29b26d6c926e6f137255f3c173benoahric // stream it associates with, and we shouldn't ever create an implicit channel 1480d10a68e7974a29b26d6c926e6f137255f3c173benoahric // for these. 1481d10a68e7974a29b26d6c926e6f137255f3c173benoahric for (auto& codec : recv_codecs_) { 1482d10a68e7974a29b26d6c926e6f137255f3c173benoahric if (payload_type == codec.rtx_payload_type || 1483d10a68e7974a29b26d6c926e6f137255f3c173benoahric payload_type == codec.fec.red_rtx_payload_type || 1484d10a68e7974a29b26d6c926e6f137255f3c173benoahric payload_type == codec.fec.ulpfec_payload_type) { 1485d10a68e7974a29b26d6c926e6f137255f3c173benoahric return; 1486d10a68e7974a29b26d6c926e6f137255f3c173benoahric } 1487d10a68e7974a29b26d6c926e6f137255f3c173benoahric } 1488d10a68e7974a29b26d6c926e6f137255f3c173benoahric 1489afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org switch (unsignalled_ssrc_handler_->OnUnsignalledSsrc(this, ssrc)) { 1490afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org case UnsignalledSsrcHandler::kDropPacket: 1491afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return; 1492afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org case UnsignalledSsrcHandler::kDeliverPacket: 1493afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org break; 1494afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 1495b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 149623fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg if (call_->Receiver()->DeliverPacket(webrtc::MediaType::VIDEO, 1497eebcab5ce99d3e8641dd92a569916b0d24e29fcakwiberg@webrtc.org reinterpret_cast<const uint8_t*>(packet->data()), packet->size()) != 14981e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org webrtc::PacketReceiver::DELIVERY_OK) { 1499afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_WARNING) << "Failed to deliver RTP packet on re-delivery."; 1500b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1501b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1502b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1503b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1504b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnRtcpReceived( 1505d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer* packet, 1506d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org const rtc::PacketTime& packet_time) { 150723fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg if (call_->Receiver()->DeliverPacket(webrtc::MediaType::VIDEO, 1508eebcab5ce99d3e8641dd92a569916b0d24e29fcakwiberg@webrtc.org reinterpret_cast<const uint8_t*>(packet->data()), packet->size()) != 15091e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org webrtc::PacketReceiver::DELIVERY_OK) { 1510b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "Failed to deliver RTCP packet."; 1511b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1512b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1513b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1514b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnReadyToSend(bool ready) { 151526c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org LOG(LS_VERBOSE) << "OnReadyToSend: " << (ready ? "Ready." : "Not ready."); 1516cd6702282a49448adda470934f4bd9e6181cab22Jelena Marusic call_->SignalNetworkState(ready ? webrtc::kNetworkUp : webrtc::kNetworkDown); 1517b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1518b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1519b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::MuteStream(uint32 ssrc, bool mute) { 1520b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "MuteStream: " << ssrc << " -> " 1521b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (mute ? "mute" : "unmute"); 1522d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(ssrc != 0); 1523575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1524b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 1525b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No sending stream on ssrc " << ssrc; 1526b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1527b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1528ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.org 1529ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.org send_streams_[ssrc]->MuteStream(mute); 1530ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.org return true; 1531b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1532b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1533b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRecvRtpHeaderExtensions( 1534b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 153550fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetRecvRtpHeaderExtensions"); 1536587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org LOG(LS_INFO) << "SetRecvRtpHeaderExtensions: " 1537587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org << RtpExtensionsToString(extensions); 15383c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (!ValidateRtpHeaderExtensionIds(extensions)) 15393c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return false; 1540d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1541c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org std::vector<webrtc::RtpExtension> filtered_extensions = 1542c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org FilterRtpExtensions(extensions); 1543874ca3af5b163e1b3fd8802171e44ee252557842deadbeef if (!RtpExtensionsHaveChanged(recv_rtp_extensions_, filtered_extensions)) { 1544874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "Ignoring call to SetRecvRtpHeaderExtensions because " 1545874ca3af5b163e1b3fd8802171e44ee252557842deadbeef "header extensions haven't changed."; 1546c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return true; 1547874ca3af5b163e1b3fd8802171e44ee252557842deadbeef } 1548c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org 1549c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org recv_rtp_extensions_ = filtered_extensions; 1550c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org 1551575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1552d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1553d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.begin(); 1554d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != receive_streams_.end(); 1555d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 1556d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetRtpExtensions(recv_rtp_extensions_); 1557d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1558b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1559b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1560b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1561b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendRtpHeaderExtensions( 1562b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 156350fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetSendRtpHeaderExtensions"); 1564587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org LOG(LS_INFO) << "SetSendRtpHeaderExtensions: " 1565587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org << RtpExtensionsToString(extensions); 15663c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (!ValidateRtpHeaderExtensionIds(extensions)) 15673c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return false; 15683c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org 1569c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org std::vector<webrtc::RtpExtension> filtered_extensions = 1570c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org FilterRtpExtensions(extensions); 1571874ca3af5b163e1b3fd8802171e44ee252557842deadbeef if (!RtpExtensionsHaveChanged(send_rtp_extensions_, filtered_extensions)) { 1572874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "Ignoring call to SetSendRtpHeaderExtensions because " 1573874ca3af5b163e1b3fd8802171e44ee252557842deadbeef "header extensions haven't changed."; 1574c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return true; 1575874ca3af5b163e1b3fd8802171e44ee252557842deadbeef } 1576c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org 1577c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org send_rtp_extensions_ = filtered_extensions; 1578a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 157964c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh const webrtc::RtpExtension* cvo_extension = FindHeaderExtension( 158064c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh send_rtp_extensions_, kRtpVideoRotationHeaderExtension); 158164c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh 1582575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1583d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1584d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org send_streams_.begin(); 1585d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != send_streams_.end(); 1586d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 1587d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetRtpExtensions(send_rtp_extensions_); 158864c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh it->second->SetApplyRotation(!cvo_extension); 1589d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1590b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1591b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1592b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1593dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström// Counter-intuitively this method doesn't only set global bitrate caps but also 1594dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström// per-stream codec max bitrates. This is to permit SetMaxSendBitrate (b=AS) to 1595dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström// raise bitrates above the 2000k default bitrate cap. 1596008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.orgbool WebRtcVideoChannel2::SetMaxSendBandwidth(int max_bitrate_bps) { 1597dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström // TODO(pbos): Figure out whether b=AS means max bitrate for this 1598dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström // WebRtcVideoChannel2 (in which case we're good), or per sender (SSRC), in 1599dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström // which case this should not set a Call::BitrateConfig but rather reconfigure 1600dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström // all senders. 1601008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org LOG(LS_INFO) << "SetMaxSendBandwidth: " << max_bitrate_bps << "bps."; 1602dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström if (max_bitrate_bps == bitrate_config_.max_bitrate_bps) 1603dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström return true; 1604dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström 1605008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org if (max_bitrate_bps <= 0) { 1606008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org // Unsetting max bitrate. 1607008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org max_bitrate_bps = -1; 1608008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } 1609008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.start_bitrate_bps = -1; 1610008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.max_bitrate_bps = max_bitrate_bps; 1611008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org if (max_bitrate_bps > 0 && 1612008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.min_bitrate_bps > max_bitrate_bps) { 1613008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.min_bitrate_bps = max_bitrate_bps; 1614008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } 1615008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org call_->SetBitrateConfig(bitrate_config_); 1616dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström rtc::CritScope stream_lock(&stream_crit_); 1617dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström for (auto& kv : send_streams_) 1618dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström kv.second->SetMaxBitrateBps(max_bitrate_bps); 1619b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1620b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1621b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1622b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetOptions(const VideoOptions& options) { 162350fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetOptions"); 1624a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org LOG(LS_INFO) << "SetOptions: " << options.ToString(); 1625a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org VideoOptions old_options = options_; 1626b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org options_.SetAll(options); 1627a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (options_ == old_options) { 1628a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org // No new options to set. 1629a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org return true; 1630a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } 1631e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström { 1632e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström rtc::CritScope lock(&capturer_crit_); 1633e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström options_.cpu_overuse_detection.Get(&signal_cpu_adaptation_); 1634e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström } 1635d819803d4570564a9800a7dd54f4593e6e21a6e7pbos@webrtc.org rtc::DiffServCodePoint dscp = options_.dscp.GetWithDefaultIfUnset(false) 1636d819803d4570564a9800a7dd54f4593e6e21a6e7pbos@webrtc.org ? rtc::DSCP_AF41 1637d819803d4570564a9800a7dd54f4593e6e21a6e7pbos@webrtc.org : rtc::DSCP_DEFAULT; 1638d819803d4570564a9800a7dd54f4593e6e21a6e7pbos@webrtc.org MediaChannel::SetDscp(dscp); 1639575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 16405301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 16415301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org send_streams_.begin(); 16425301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org it != send_streams_.end(); 16435301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org ++it) { 16445301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org it->second->SetOptions(options_); 16455301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1646b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1647b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1648b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1649b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::SetInterface(NetworkInterface* iface) { 1650b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org MediaChannel::SetInterface(iface); 1651b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Set the RTP recv/send buffer to a bigger size 1652b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org MediaChannel::SetOption(NetworkInterface::ST_RTP, 1653d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Socket::OPT_RCVBUF, 1654b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org kVideoRtpBufferSize); 1655b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1656ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org // Speculative change to increase the outbound socket buffer size. 1657ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org // In b/15152257, we are seeing a significant number of packets discarded 1658ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org // due to lack of socket buffer space, although it's not yet clear what the 1659ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org // ideal value should be. 1660ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org MediaChannel::SetOption(NetworkInterface::ST_RTP, 1661ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org rtc::Socket::OPT_SNDBUF, 1662ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org kVideoRtpBufferSize); 1663b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1664b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1665b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::UpdateAspectRatio(int ratio_w, int ratio_h) { 1666b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1667b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1668b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1669d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.orgvoid WebRtcVideoChannel2::OnMessage(rtc::Message* msg) { 1670b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Ignored. 1671b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1672b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 167342684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.orgvoid WebRtcVideoChannel2::OnLoadUpdate(Load load) { 1674e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström // OnLoadUpdate can not take any locks that are held while creating streams 1675e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström // etc. Doing so establishes lock-order inversions between the webrtc process 1676e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström // thread on stream creation and locks such as stream_crit_ while calling out. 1677e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström rtc::CritScope stream_lock(&capturer_crit_); 1678e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström if (!signal_cpu_adaptation_) 1679e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström return; 1680efbde3775b5eed8015d7e2e86ddcea3e6033d321Erik SprĂ¥ng // Do not adapt resolution for screen content as this will likely result in 1681efbde3775b5eed8015d7e2e86ddcea3e6033d321Erik SprĂ¥ng // blurry and unreadable text. 1682e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström for (auto& kv : capturers_) { 1683efbde3775b5eed8015d7e2e86ddcea3e6033d321Erik SprĂ¥ng if (kv.second != nullptr 1684efbde3775b5eed8015d7e2e86ddcea3e6033d321Erik SprĂ¥ng && !kv.second->IsScreencast() 1685efbde3775b5eed8015d7e2e86ddcea3e6033d321Erik SprĂ¥ng && kv.second->video_adapter() != nullptr) { 1686e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström kv.second->video_adapter()->OnCpuResolutionRequest( 1687e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström load == kOveruse ? CoordinatedVideoAdapter::DOWNGRADE 1688e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström : CoordinatedVideoAdapter::UPGRADE); 1689e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström } 169042684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org } 169142684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org} 169242684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org 1693b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendRtp(const uint8_t* data, size_t len) { 1694d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer packet(data, len, kMaxRtpPacketLen); 1695b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return MediaChannel::SendPacket(&packet); 1696b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1697b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1698b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendRtcp(const uint8_t* data, size_t len) { 1699d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer packet(data, len, kMaxRtpPacketLen); 1700b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return MediaChannel::SendRtcp(&packet); 1701b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1702b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1703b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::StartAllSendStreams() { 1704575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1705b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1706b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.begin(); 1707b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != send_streams_.end(); 1708b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 1709b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->Start(); 1710b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1711b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1712b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1713b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::StopAllSendStreams() { 1714575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1715b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1716b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.begin(); 1717b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != send_streams_.end(); 1718b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 1719b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->Stop(); 1720b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1721b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1722b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 17236ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::VideoSendStreamParameters:: 17246ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org VideoSendStreamParameters( 17256ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const webrtc::VideoSendStream::Config& config, 17266ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const VideoOptions& options, 1727dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström int max_bitrate_bps, 17285301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const Settable<VideoCodecSettings>& codec_settings) 1729dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström : config(config), 1730dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström options(options), 1731dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström max_bitrate_bps(max_bitrate_bps), 1732dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström codec_settings(codec_settings) { 17336ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org} 17346ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 17354d71edef45afa38b3f68b6af0519ac0f21d327dfPeter BoströmWebRtcVideoChannel2::WebRtcVideoSendStream::AllocatedEncoder::AllocatedEncoder( 17364d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström webrtc::VideoEncoder* encoder, 17374d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström webrtc::VideoCodecType type, 17384d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström bool external) 17394d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström : encoder(encoder), 17404d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström external_encoder(nullptr), 17414d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström type(type), 17424d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström external(external) { 17434d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström if (external) { 17444d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström external_encoder = encoder; 17454d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström this->encoder = 17464d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström new webrtc::VideoEncoderSoftwareFallbackWrapper(type, encoder); 17474d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström } 17484d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström} 17494d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström 1750b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::WebRtcVideoSendStream( 1751b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::Call* call, 17524fbae2b79134572135d9d5fe35a7d1ccdeea3a4dsolenberg const StreamParams& sp, 17534fbae2b79134572135d9d5fe35a7d1ccdeea3a4dsolenberg const webrtc::VideoSendStream::Config& config, 17547fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org WebRtcVideoEncoderFactory* external_encoder_factory, 17556ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const VideoOptions& options, 1756dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström int max_bitrate_bps, 17575301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const Settable<VideoCodecSettings>& codec_settings, 17585301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const std::vector<webrtc::RtpExtension>& rtp_extensions) 17597c027b64ae53a29bc528b4241cc540694c239304Henrik Kjellander : ssrcs_(sp.ssrcs), 1760259bd2034c3d3ee7f2dc4d481e9bf896a3a4d6efPeter Boström ssrc_groups_(sp.ssrc_groups), 17617c027b64ae53a29bc528b4241cc540694c239304Henrik Kjellander call_(call), 17627fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_(external_encoder_factory), 1763b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_(NULL), 17644fbae2b79134572135d9d5fe35a7d1ccdeea3a4dsolenberg parameters_(config, options, max_bitrate_bps, codec_settings), 17657fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org allocated_encoder_(NULL, webrtc::kVideoCodecUnknown, false), 1766b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org capturer_(NULL), 1767b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_(false), 17689a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org muted_(false), 1769c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen old_adapt_changes_(0), 1770c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen first_frame_timestamp_ms_(0), 1771c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen last_frame_timestamp_ms_(0) { 17725301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.max_packet_size = kVideoMtu; 17735301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 17745301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetPrimarySsrcs(¶meters_.config.rtp.ssrcs); 17755301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetFidSsrcs(parameters_.config.rtp.ssrcs, 17765301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org ¶meters_.config.rtp.rtx.ssrcs); 17775301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.c_name = sp.cname; 17785301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.extensions = rtp_extensions; 17795301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 17805301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org VideoCodecSettings params; 17815301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (codec_settings.Get(¶ms)) { 17825301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org SetCodec(params); 17835301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1784b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1785b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1786b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::~WebRtcVideoSendStream() { 1787b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org DisconnectCapturer(); 17885301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (stream_ != NULL) { 17895301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org call_->DestroyVideoSendStream(stream_); 17905301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 17917fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org DestroyVideoEncoder(&allocated_encoder_); 1792b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1793b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 17944765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchezstatic void CreateBlackFrame(webrtc::VideoFrame* video_frame, 1795b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int width, 1796b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int height) { 1797b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org video_frame->CreateEmptyFrame(width, height, width, (width + 1) / 2, 1798b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org (width + 1) / 2); 1799b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org memset(video_frame->buffer(webrtc::kYPlane), 16, 1800b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org video_frame->allocated_size(webrtc::kYPlane)); 1801b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org memset(video_frame->buffer(webrtc::kUPlane), 128, 1802b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org video_frame->allocated_size(webrtc::kUPlane)); 1803b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org memset(video_frame->buffer(webrtc::kVPlane), 128, 1804b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org video_frame->allocated_size(webrtc::kVPlane)); 1805b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1806b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1807b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::InputFrame( 1808b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCapturer* capturer, 1809b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFrame* frame) { 181086196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::InputFrame"); 18114765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez webrtc::VideoFrame video_frame(frame->GetVideoFrameBuffer(), 0, 0, 18124765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez frame->GetVideoRotation()); 1813d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 18145301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (stream_ == NULL) { 1815ad1f9b61a3107ca27ee023990dc576abc38f05acPeter Boström // Frame input before send codecs are configured, dropping frame. 18165301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org return; 18175301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 181886196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org 181986196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org // Not sending, abort early to prevent expensive reconfigurations while 182086196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org // setting up codecs etc. 182186196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org if (!sending_) 182286196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org return; 182386196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org 1824b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (format_.width == 0) { // Dropping frames. 1825d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(format_.height == 0); 1826b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "VideoFormat 0x0 set, Dropping frame."; 1827b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1828b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1829d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org if (muted_) { 1830d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org // Create a black frame to transmit instead. 1831afdd5dd372d69be7244a3d90d70de9d5ecd60eb9magjed@webrtc.org CreateBlackFrame(&video_frame, 1832d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org static_cast<int>(frame->GetWidth()), 1833d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org static_cast<int>(frame->GetHeight())); 1834d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org } 1835c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen 1836c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen int64_t frame_delta_ms = frame->GetTimeStamp() / rtc::kNumNanosecsPerMillisec; 1837c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen // frame->GetTimeStamp() is essentially a delta, align to webrtc time 1838c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen if (first_frame_timestamp_ms_ == 0) { 1839c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen first_frame_timestamp_ms_ = rtc::Time() - frame_delta_ms; 1840c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen } 1841c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen 1842c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen last_frame_timestamp_ms_ = first_frame_timestamp_ms_ + frame_delta_ms; 1843c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen video_frame.set_render_time_ms(last_frame_timestamp_ms_); 1844b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Reconfigure codec if necessary. 1845c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org SetDimensions( 1846afdd5dd372d69be7244a3d90d70de9d5ecd60eb9magjed@webrtc.org video_frame.width(), video_frame.height(), capturer->IsScreencast()); 1847c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org 1848af612d5e0769571544952cbe55e675748afa9bddperkj@webrtc.org stream_->Input()->IncomingCapturedFrame(video_frame); 1849b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1850b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1851b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::SetCapturer( 1852b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCapturer* capturer) { 1853b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::SetCapturer"); 1854b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!DisconnectCapturer() && capturer == NULL) { 1855b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1856b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1857b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1858b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org { 1859d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1860b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 18619359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org if (capturer == NULL) { 18629359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org if (stream_ != NULL) { 18639359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org LOG(LS_VERBOSE) << "Disabling capturer, sending black frame."; 18644765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez webrtc::VideoFrame black_frame; 18659359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org 1866b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org CreateBlackFrame(&black_frame, last_dimensions_.width, 1867b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org last_dimensions_.height); 1868c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen 1869c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen // Force this black frame not to be dropped due to timestamp order 1870c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen // check. As IncomingCapturedFrame will drop the frame if this frame's 1871c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen // timestamp is less than or equal to last frame's timestamp, it is 1872c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen // necessary to give this black frame a larger timestamp than the 1873c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen // previous one. 1874c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen last_frame_timestamp_ms_ += 1875c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen format_.interval / rtc::kNumNanosecsPerMillisec; 1876c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen black_frame.set_render_time_ms(last_frame_timestamp_ms_); 1877af612d5e0769571544952cbe55e675748afa9bddperkj@webrtc.org stream_->Input()->IncomingCapturedFrame(black_frame); 18789359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org } 1879b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1880b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_ = NULL; 1881b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1882b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1883b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1884b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_ = capturer; 1885b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1886b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Lock cannot be held while connecting the capturer to prevent lock-order 1887b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // violations. 1888b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer->SignalVideoFrame.connect(this, &WebRtcVideoSendStream::InputFrame); 1889b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1890b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1891b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1892b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::SetVideoFormat( 1893b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFormat& format) { 1894b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if ((format.width == 0 || format.height == 0) && 1895b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org format.width != format.height) { 1896b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Can't set VideoFormat, width or height is zero (but not " 1897b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org "both, 0x0 drops frames)."; 1898b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1899b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1900b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1901d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1902b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (format.width == 0 && format.height == 0) { 1903b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) 1904b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << "0x0 resolution selected. Captured frames will be dropped for ssrc: " 19056ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org << parameters_.config.rtp.ssrcs[0] << "."; 1906b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 1907b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Fix me, this only affects the last stream! 1908bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config.streams.back().max_framerate = 1909b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoFormat::IntervalToFps(format.interval); 1910c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org SetDimensions(format.width, format.height, false); 1911b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1912b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1913b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org format_ = format; 1914b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1915b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1916b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1917ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::MuteStream(bool mute) { 1918d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1919b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org muted_ = mute; 1920b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1921b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1922b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::DisconnectCapturer() { 1923963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org cricket::VideoCapturer* capturer; 1924963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org { 1925963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org rtc::CritScope cs(&lock_); 19269a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (capturer_ == NULL) 1927963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org return false; 19289a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org 19299a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (capturer_->video_adapter() != nullptr) 19309a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org old_adapt_changes_ += capturer_->video_adapter()->adaptation_changes(); 19319a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org 1932963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org capturer = capturer_; 1933963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org capturer_ = NULL; 1934b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1935963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org capturer->SignalVideoFrame.disconnect(this); 1936b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1937b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1938b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1939d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boströmconst std::vector<uint32>& 1940d6f4c25eedcfd502920f1b2a24744badd9da80bePeter BoströmWebRtcVideoChannel2::WebRtcVideoSendStream::GetSsrcs() const { 1941d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström return ssrcs_; 1942d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström} 1943d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 194464c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shiehvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetApplyRotation( 194564c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh bool apply_rotation) { 194664c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh rtc::CritScope cs(&lock_); 194764c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh if (capturer_ == NULL) 194864c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh return; 194964c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh 195064c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh capturer_->SetApplyRotation(apply_rotation); 195164c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh} 195264c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh 19535301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetOptions( 19545301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoOptions& options) { 1955d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 19565301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org VideoCodecSettings codec_settings; 19575301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (parameters_.codec_settings.Get(&codec_settings)) { 1958874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "SetCodecAndOptions because of SetOptions; options=" 1959874ca3af5b163e1b3fd8802171e44ee252557842deadbeef << options.ToString(); 19605301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org SetCodecAndOptions(codec_settings, options); 19615301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } else { 19625301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.options = options; 19635301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 19645301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org} 19657fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 1966b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodec( 19675301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoCodecSettings& codec_settings) { 1968d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1969874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "SetCodecAndOptions because of SetCodec."; 19705301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org SetCodecAndOptions(codec_settings, parameters_.options); 19715301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org} 19727fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 19737fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgwebrtc::VideoCodecType CodecTypeFromName(const std::string& name) { 1974e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (CodecNamesEq(name, kVp8CodecName)) { 19757fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return webrtc::kVideoCodecVP8; 1976e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin } else if (CodecNamesEq(name, kVp9CodecName)) { 1977188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org return webrtc::kVideoCodecVP9; 1978e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin } else if (CodecNamesEq(name, kH264CodecName)) { 19797fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return webrtc::kVideoCodecH264; 19807fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 19817fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return webrtc::kVideoCodecUnknown; 19827fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 19837fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 19847fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::AllocatedEncoder 19857fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoder( 19867fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org const VideoCodec& codec) { 19877fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org webrtc::VideoCodecType type = CodecTypeFromName(codec.name); 19887fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 19897fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org // Do not re-create encoders of the same type. 19907fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (type == allocated_encoder_.type && allocated_encoder_.encoder != NULL) { 19917fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return allocated_encoder_; 19927fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 19937fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 19947fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (external_encoder_factory_ != NULL) { 19957fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org webrtc::VideoEncoder* encoder = 19967fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_->CreateVideoEncoder(type); 19977fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (encoder != NULL) { 19987fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return AllocatedEncoder(encoder, type, true); 19997fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 20007fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 20017fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 20027fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (type == webrtc::kVideoCodecVP8) { 20037fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return AllocatedEncoder( 20047fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org webrtc::VideoEncoder::Create(webrtc::VideoEncoder::kVp8), type, false); 2005188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org } else if (type == webrtc::kVideoCodecVP9) { 2006188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org return AllocatedEncoder( 2007188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org webrtc::VideoEncoder::Create(webrtc::VideoEncoder::kVp9), type, false); 200871f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin } else if (type == webrtc::kVideoCodecH264) { 200971f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin return AllocatedEncoder( 201071f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin webrtc::VideoEncoder::Create(webrtc::VideoEncoder::kH264), type, false); 20117fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 20127fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 20137fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org // This shouldn't happen, we should not be trying to create something we don't 20147fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org // support. 2015d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(false); 20167fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return AllocatedEncoder(NULL, webrtc::kVideoCodecUnknown, false); 20177fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 20187fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 20197fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::DestroyVideoEncoder( 20207fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org AllocatedEncoder* encoder) { 20217fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (encoder->external) { 20224d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström external_encoder_factory_->DestroyVideoEncoder(encoder->external_encoder); 20237fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 20244d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström delete encoder->encoder; 20257fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 20267fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 20275301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodecAndOptions( 20285301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoCodecSettings& codec_settings, 20295301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoOptions& options) { 2030a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org parameters_.encoder_config = 2031a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org CreateVideoEncoderConfig(last_dimensions_, codec_settings.codec); 203286196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org if (parameters_.encoder_config.streams.empty()) 2033b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 2034a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 20355301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org format_ = VideoFormat(codec_settings.codec.width, 20365301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org codec_settings.codec.height, 2037b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoFormat::FpsToInterval(30), 2038b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org FOURCC_I420); 20396ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 20407fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org AllocatedEncoder new_encoder = CreateVideoEncoder(codec_settings.codec); 20417fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org parameters_.config.encoder_settings.encoder = new_encoder.encoder; 20425301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.encoder_settings.payload_name = codec_settings.codec.name; 20435301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.encoder_settings.payload_type = codec_settings.codec.id; 204447d78cc8ad54baabc9042c2b848ae3afd9b80d2esophiechang if (new_encoder.external) { 204547d78cc8ad54baabc9042c2b848ae3afd9b80d2esophiechang webrtc::VideoCodecType type = CodecTypeFromName(codec_settings.codec.name); 204647d78cc8ad54baabc9042c2b848ae3afd9b80d2esophiechang parameters_.config.encoder_settings.internal_source = 204747d78cc8ad54baabc9042c2b848ae3afd9b80d2esophiechang external_encoder_factory_->EncoderTypeHasInternalSource(type); 204847d78cc8ad54baabc9042c2b848ae3afd9b80d2esophiechang } 20495301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.fec = codec_settings.fec; 20505301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 20515301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org // Set RTX payload type if RTX is enabled. 20525301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (!parameters_.config.rtp.rtx.ssrcs.empty()) { 2053b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org if (codec_settings.rtx_payload_type == -1) { 2054b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX " 2055b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org "payload type. Ignoring."; 2056b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org parameters_.config.rtp.rtx.ssrcs.clear(); 2057b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org } else { 2058b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org parameters_.config.rtp.rtx.payload_type = codec_settings.rtx_payload_type; 2059b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org } 20605301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 20615301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 206267c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström parameters_.config.rtp.nack.rtp_history_ms = 206367c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström HasNack(codec_settings.codec) ? kNackHistoryMs : 0; 20645301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 20655ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org options.suspend_below_min_bitrate.Get( 20665ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org ¶meters_.config.suspend_below_min_bitrate); 20675ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org 20685301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.codec_settings.Set(codec_settings); 20696ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.options = options; 2070543e589205af006f6b999a2c5df51d3fb722d925pbos@webrtc.org 2071874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) 2072874ca3af5b163e1b3fd8802171e44ee252557842deadbeef << "RecreateWebRtcStream (send) because of SetCodecAndOptions; options=" 2073874ca3af5b163e1b3fd8802171e44ee252557842deadbeef << options.ToString(); 2074b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org RecreateWebRtcStream(); 20757fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (allocated_encoder_.encoder != new_encoder.encoder) { 20767fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org DestroyVideoEncoder(&allocated_encoder_); 20777fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org allocated_encoder_ = new_encoder; 20787fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 2079b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 2080b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2081d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetRtpExtensions( 2082d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<webrtc::RtpExtension>& rtp_extensions) { 2083d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 2084d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org parameters_.config.rtp.extensions = rtp_extensions; 2085874ca3af5b163e1b3fd8802171e44ee252557842deadbeef if (stream_ != nullptr) { 2086874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "RecreateWebRtcStream (send) because of SetRtpExtensions"; 20873c3f6460646183914629e5dab8ae5fcede4f0e80Peter Boström RecreateWebRtcStream(); 2088874ca3af5b163e1b3fd8802171e44ee252557842deadbeef } 2089d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2090d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2091a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.orgwebrtc::VideoEncoderConfig 2092a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoderConfig( 2093a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org const Dimensions& dimensions, 2094a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org const VideoCodec& codec) const { 2095a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org webrtc::VideoEncoderConfig encoder_config; 2096a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (dimensions.is_screencast) { 2097a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org int screencast_min_bitrate_kbps; 2098a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org parameters_.options.screencast_min_bitrate.Get( 2099a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org &screencast_min_bitrate_kbps); 2100a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org encoder_config.min_transmit_bitrate_bps = 2101a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org screencast_min_bitrate_kbps * 1000; 2102143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng encoder_config.content_type = 2103143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng webrtc::VideoEncoderConfig::ContentType::kScreen; 2104a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } else { 2105a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org encoder_config.min_transmit_bitrate_bps = 0; 2106143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng encoder_config.content_type = 2107143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo; 2108a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } 2109a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 2110a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org // Restrict dimensions according to codec max. 2111a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org int width = dimensions.width; 2112a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org int height = dimensions.height; 2113a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (!dimensions.is_screencast) { 2114a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (codec.width < width) 2115a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org width = codec.width; 2116a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (codec.height < height) 2117a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org height = codec.height; 2118a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } 2119a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 2120a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org VideoCodec clamped_codec = codec; 2121a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org clamped_codec.width = width; 2122a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org clamped_codec.height = height; 2123a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 2124fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric // By default, the stream count for the codec configuration should match the 2125fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric // number of negotiated ssrcs. But if the codec is blacklisted for simulcast 2126fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric // or a screencast, only configure a single stream. 2127fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric size_t stream_count = parameters_.config.rtp.ssrcs.size(); 2128fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric if (IsCodecBlacklistedForSimulcast(codec.name) || dimensions.is_screencast) { 2129fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric stream_count = 1; 2130fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric } 2131fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric 2132fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric encoder_config.streams = 2133fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric CreateVideoStreams(clamped_codec, parameters_.options, 2134fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric parameters_.max_bitrate_bps, stream_count); 2135a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 2136a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org // Conference mode screencast uses 2 temporal layers split at 100kbit. 2137a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (parameters_.options.conference_mode.GetWithDefaultIfUnset(false) && 2138a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org dimensions.is_screencast && encoder_config.streams.size() == 1) { 213946d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org ScreenshareLayerConfig config = ScreenshareLayerConfig::GetDefault(); 214046d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org 214146d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org // For screenshare in conference mode, tl0 and tl1 bitrates are piggybacked 214246d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org // on the VideoCodec struct as target and max bitrates, respectively. 214346d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org // See eg. webrtc::VP8EncoderImpl::SetRates(). 214446d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org encoder_config.streams[0].target_bitrate_bps = 214546d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org config.tl0_bitrate_kbps * 1000; 214646d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org encoder_config.streams[0].max_bitrate_bps = config.tl1_bitrate_kbps * 1000; 2147a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org encoder_config.streams[0].temporal_layer_thresholds_bps.clear(); 2148a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org encoder_config.streams[0].temporal_layer_thresholds_bps.push_back( 214946d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org config.tl0_bitrate_kbps * 1000); 2150a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } 2151a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org return encoder_config; 2152a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org} 2153a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 2154c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetDimensions( 2155c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org int width, 2156c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org int height, 2157efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org bool is_screencast) { 2158efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org if (last_dimensions_.width == width && last_dimensions_.height == height && 2159efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org last_dimensions_.is_screencast == is_screencast) { 2160efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org // Configured using the same parameters, do not reconfigure. 2161efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org return; 2162efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org } 2163a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org LOG(LS_INFO) << "SetDimensions: " << width << "x" << height 2164a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org << (is_screencast ? " (screencast)" : " (not screencast)"); 2165efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org 2166efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org last_dimensions_.width = width; 2167efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org last_dimensions_.height = height; 2168efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org last_dimensions_.is_screencast = is_screencast; 2169efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org 2170d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(!parameters_.encoder_config.streams.empty()); 2171c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org 2172c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org VideoCodecSettings codec_settings; 2173c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org parameters_.codec_settings.Get(&codec_settings); 2174c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org 2175a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org webrtc::VideoEncoderConfig encoder_config = 2176a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org CreateVideoEncoderConfig(last_dimensions_, codec_settings.codec); 2177a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 2178143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng encoder_config.encoder_specific_settings = ConfigureVideoEncoderSettings( 2179143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng codec_settings.codec, parameters_.options, is_screencast); 21806f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 2181bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org bool stream_reconfigured = stream_->ReconfigureVideoEncoder(encoder_config); 2182bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org 2183bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org encoder_config.encoder_specific_settings = NULL; 21846f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 21856f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org if (!stream_reconfigured) { 2186b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "Failed to reconfigure video encoder for dimensions: " 2187b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << width << "x" << height; 2188b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 2189b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2190cddd17c0f89cfaa9d2f21118ae90b45dae3b4aeepbos@webrtc.org 2191bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config = encoder_config; 2192b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 2193b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2194b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::Start() { 2195d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 2196d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(stream_ != NULL); 2197b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_->Start(); 2198b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = true; 2199b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 2200b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2201b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::Stop() { 2202d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 22035301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (stream_ != NULL) { 22045301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org stream_->Stop(); 22055301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 2206b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = false; 2207b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 2208b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2209e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgVideoSenderInfo 2210e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo() { 2211e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoSenderInfo info; 221277e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org webrtc::VideoSendStream::Stats stats; 221377e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org { 221477e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org rtc::CritScope cs(&lock_); 221577e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org for (uint32_t ssrc : parameters_.config.rtp.ssrcs) 221677e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org info.add_ssrc(ssrc); 221777e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org 221874d9ed7d853677d297807021436467a4f97584acPeter Boström VideoCodecSettings codec_settings; 221974d9ed7d853677d297807021436467a4f97584acPeter Boström if (parameters_.codec_settings.Get(&codec_settings)) 222074d9ed7d853677d297807021436467a4f97584acPeter Boström info.codec_name = codec_settings.codec.name; 222177e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org for (size_t i = 0; i < parameters_.encoder_config.streams.size(); ++i) { 222277e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org if (i == parameters_.encoder_config.streams.size() - 1) { 222377e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org info.preferred_bitrate += 222477e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org parameters_.encoder_config.streams[i].max_bitrate_bps; 222577e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org } else { 222677e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org info.preferred_bitrate += 222777e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org parameters_.encoder_config.streams[i].target_bitrate_bps; 222877e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org } 222977e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org } 2230e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 223177e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org if (stream_ == NULL) 223277e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org return info; 2233c3d2bd28a3e8badc434a5081dd36f4ac41b4e3f2pbos@webrtc.org 223477e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org stats = stream_->GetStats(); 223577e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org 22369a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.adapt_changes = old_adapt_changes_; 22379a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.adapt_reason = CoordinatedVideoAdapter::ADAPTREASON_NONE; 22389a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org 22399a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (capturer_ != NULL) { 22409a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (!capturer_->IsMuted()) { 22419a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org VideoFormat last_captured_frame_format; 22429a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org capturer_->GetStats(&info.adapt_frame_drops, &info.effects_frame_drops, 22439a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org &info.capturer_frame_time, 22449a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org &last_captured_frame_format); 22459a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.input_frame_width = last_captured_frame_format.width; 22469a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.input_frame_height = last_captured_frame_format.height; 22479a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org } 22489a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (capturer_->video_adapter() != nullptr) { 22499a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.adapt_changes += capturer_->video_adapter()->adaptation_changes(); 22509a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.adapt_reason = capturer_->video_adapter()->adapt_reason(); 22519a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org } 225277e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org } 225377e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org } 2254259bd2034c3d3ee7f2dc4d481e9bf896a3a4d6efPeter Boström info.ssrc_groups = ssrc_groups_; 2255e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_input = stats.input_frame_rate; 2256e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_sent = stats.encode_frame_rate; 22573e6e271ec3253e78ae0eb72156e5236d43f8731dpbos@webrtc.org info.avg_encode_ms = stats.avg_encode_time_ms; 22583e6e271ec3253e78ae0eb72156e5236d43f8731dpbos@webrtc.org info.encode_usage_percent = stats.encode_usage_percent; 2259e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 226077e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org info.nominal_bitrate = stats.media_bitrate_bps; 226177e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org 2262273a414b0ec2e58fdf3b817ad8b1a02f4ce15287pbos@webrtc.org info.send_frame_width = 0; 2263273a414b0ec2e58fdf3b817ad8b1a02f4ce15287pbos@webrtc.org info.send_frame_height = 0; 226409c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org for (std::map<uint32_t, webrtc::VideoSendStream::StreamStats>::iterator it = 2265e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org stats.substreams.begin(); 226609c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org it != stats.substreams.end(); ++it) { 2267e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Wire up additional stats, such as padding bytes. 226809c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org webrtc::VideoSendStream::StreamStats stream_stats = it->second; 2269cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org info.bytes_sent += stream_stats.rtp_stats.transmitted.payload_bytes + 2270cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org stream_stats.rtp_stats.transmitted.header_bytes + 2271cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org stream_stats.rtp_stats.transmitted.padding_bytes; 2272cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org info.packets_sent += stream_stats.rtp_stats.transmitted.packets; 2273e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.packets_lost += stream_stats.rtcp_stats.cumulative_lost; 227409c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org if (stream_stats.width > info.send_frame_width) 227509c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.send_frame_width = stream_stats.width; 227609c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org if (stream_stats.height > info.send_frame_height) 227709c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.send_frame_height = stream_stats.height; 22781d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.firs_rcvd += stream_stats.rtcp_packet_type_counts.fir_packets; 22791d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.nacks_rcvd += stream_stats.rtcp_packet_type_counts.nack_packets; 22801d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.plis_rcvd += stream_stats.rtcp_packet_type_counts.pli_packets; 2281e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 2282e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 2283e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org if (!stats.substreams.empty()) { 2284e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Report fraction lost per SSRC. 228509c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org webrtc::VideoSendStream::StreamStats first_stream_stats = 228609c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org stats.substreams.begin()->second; 2287e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.fraction_lost = 2288e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org static_cast<float>(first_stream_stats.rtcp_stats.fraction_lost) / 2289e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org (1 << 8); 2290e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 2291e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 2292e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org return info; 2293e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 2294e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 22950bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::FillBandwidthEstimationInfo( 22960bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org BandwidthEstimationInfo* bwe_info) { 22970bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org rtc::CritScope cs(&lock_); 22980bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org if (stream_ == NULL) { 22990bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org return; 23000bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org } 23010bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org webrtc::VideoSendStream::Stats stats = stream_->GetStats(); 230209c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org for (std::map<uint32_t, webrtc::VideoSendStream::StreamStats>::iterator it = 23030bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org stats.substreams.begin(); 230409c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org it != stats.substreams.end(); ++it) { 23050bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org bwe_info->transmit_bitrate += it->second.total_bitrate_bps; 23060bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org bwe_info->retransmit_bitrate += it->second.retransmit_bitrate_bps; 23070bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org } 2308891d48393e5ccd2f5e03d509c544c00a3d88cbbcpbos@webrtc.org bwe_info->target_enc_bitrate += stats.target_media_bitrate_bps; 230977e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org bwe_info->actual_enc_bitrate += stats.media_bitrate_bps; 23100bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org} 23110bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org 2312dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boströmvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetMaxBitrateBps( 2313dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström int max_bitrate_bps) { 2314dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström rtc::CritScope cs(&lock_); 2315dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström parameters_.max_bitrate_bps = max_bitrate_bps; 2316dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström 2317dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström // No need to reconfigure if the stream hasn't been configured yet. 2318dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström if (parameters_.encoder_config.streams.empty()) 2319dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström return; 2320dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström 2321dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström // Force a stream reconfigure to set the new max bitrate. 2322dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström int width = last_dimensions_.width; 2323dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström last_dimensions_.width = 0; 2324dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström SetDimensions(width, last_dimensions_.height, last_dimensions_.is_screencast); 2325dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström} 232642684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org 2327b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::RecreateWebRtcStream() { 2328b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (stream_ != NULL) { 2329b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org call_->DestroyVideoSendStream(stream_); 2330b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 23316ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 23326f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org VideoCodecSettings codec_settings; 23336f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org parameters_.codec_settings.Get(&codec_settings); 2334bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config.encoder_specific_settings = 2335143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng ConfigureVideoEncoderSettings( 2336143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng codec_settings.codec, parameters_.options, 2337143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng parameters_.encoder_config.content_type == 2338143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng webrtc::VideoEncoderConfig::ContentType::kScreen); 2339bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org 2340b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org webrtc::VideoSendStream::Config config = parameters_.config; 2341b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org if (!config.rtp.rtx.ssrcs.empty() && config.rtp.rtx.payload_type == -1) { 2342b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX " 2343b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org "payload type the set codec. Ignoring RTX."; 2344b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org config.rtp.rtx.ssrcs.clear(); 2345b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org } 2346b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org stream_ = call_->CreateVideoSendStream(config, parameters_.encoder_config); 23476f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 2348bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config.encoder_specific_settings = NULL; 23496f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 2350b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sending_) { 2351b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_->Start(); 2352b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2353b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 2354b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2355d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream( 2356d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org webrtc::Call* call, 2357259bd2034c3d3ee7f2dc4d481e9bf896a3a4d6efPeter Boström const StreamParams& sp, 23584fbae2b79134572135d9d5fe35a7d1ccdeea3a4dsolenberg const webrtc::VideoReceiveStream::Config& config, 2359776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org WebRtcVideoDecoderFactory* external_decoder_factory, 2360a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org bool default_stream, 2361d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<VideoCodecSettings>& recv_codecs) 2362d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org : call_(call), 2363259bd2034c3d3ee7f2dc4d481e9bf896a3a4d6efPeter Boström ssrcs_(sp.ssrcs), 2364259bd2034c3d3ee7f2dc4d481e9bf896a3a4d6efPeter Boström ssrc_groups_(sp.ssrc_groups), 2365d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org stream_(NULL), 2366a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org default_stream_(default_stream), 2367b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org config_(config), 2368776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org external_decoder_factory_(external_decoder_factory), 2369b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org renderer_(NULL), 2370d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_width_(-1), 2371fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org last_height_(-1), 2372fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org first_frame_timestamp_(-1), 2373fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org estimated_remote_start_ntp_time_ms_(0) { 2374d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.renderer = this; 2375d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // SetRecvCodecs will also reset (start) the VideoReceiveStream. 2376874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "SetRecvCodecs (recv) because we are creating the receive " 2377874ca3af5b163e1b3fd8802171e44ee252557842deadbeef "stream for the first time: " 2378874ca3af5b163e1b3fd8802171e44ee252557842deadbeef << CodecSettingsVectorToString(recv_codecs); 2379d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetRecvCodecs(recv_codecs); 2380d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2381d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 23827252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter BoströmWebRtcVideoChannel2::WebRtcVideoReceiveStream::AllocatedDecoder:: 23837252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström AllocatedDecoder(webrtc::VideoDecoder* decoder, 23847252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström webrtc::VideoCodecType type, 23857252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström bool external) 23867252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström : decoder(decoder), 23877252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström external_decoder(nullptr), 23887252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström type(type), 23897252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström external(external) { 23907252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström if (external) { 23917252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström external_decoder = decoder; 23927252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström this->decoder = 23937252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström new webrtc::VideoDecoderSoftwareFallbackWrapper(type, external_decoder); 23947252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström } 23957252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström} 23967252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström 2397d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::~WebRtcVideoReceiveStream() { 2398d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org call_->DestroyVideoReceiveStream(stream_); 239996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org ClearDecoders(&allocated_decoders_); 2400d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2401d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2402d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boströmconst std::vector<uint32>& 2403d6f4c25eedcfd502920f1b2a24744badd9da80bePeter BoströmWebRtcVideoChannel2::WebRtcVideoReceiveStream::GetSsrcs() const { 2404d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström return ssrcs_; 2405d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström} 2406d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 240796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::AllocatedDecoder 240896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::CreateOrReuseVideoDecoder( 240996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org std::vector<AllocatedDecoder>* old_decoders, 241096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const VideoCodec& codec) { 241196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org webrtc::VideoCodecType type = CodecTypeFromName(codec.name); 2412776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 241396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org for (size_t i = 0; i < old_decoders->size(); ++i) { 241496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if ((*old_decoders)[i].type == type) { 241596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org AllocatedDecoder decoder = (*old_decoders)[i]; 241696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org (*old_decoders)[i] = old_decoders->back(); 241796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org old_decoders->pop_back(); 241896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return decoder; 241996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 242096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 2421776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 242296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (external_decoder_factory_ != NULL) { 242396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org webrtc::VideoDecoder* decoder = 242496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org external_decoder_factory_->CreateVideoDecoder(type); 242596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (decoder != NULL) { 242696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return AllocatedDecoder(decoder, type, true); 242796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 242896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 2429776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 243096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (type == webrtc::kVideoCodecVP8) { 243196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return AllocatedDecoder( 243296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org webrtc::VideoDecoder::Create(webrtc::VideoDecoder::kVp8), type, false); 243396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 2434d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2435b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org if (type == webrtc::kVideoCodecVP9) { 2436b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org return AllocatedDecoder( 2437b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org webrtc::VideoDecoder::Create(webrtc::VideoDecoder::kVp9), type, false); 2438b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org } 2439b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org 244071f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin if (type == webrtc::kVideoCodecH264) { 244171f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin return AllocatedDecoder( 244271f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin webrtc::VideoDecoder::Create(webrtc::VideoDecoder::kH264), type, false); 244371f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin } 244471f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin 244596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org // This shouldn't happen, we should not be trying to create something we don't 244696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org // support. 2447d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(false); 244896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return AllocatedDecoder(NULL, webrtc::kVideoCodecUnknown, false); 244996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org} 245096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 245196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRecvCodecs( 245296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const std::vector<VideoCodecSettings>& recv_codecs) { 245396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org std::vector<AllocatedDecoder> old_decoders = allocated_decoders_; 245496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org allocated_decoders_.clear(); 245596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org config_.decoders.clear(); 245696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org for (size_t i = 0; i < recv_codecs.size(); ++i) { 245796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org AllocatedDecoder allocated_decoder = 245896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org CreateOrReuseVideoDecoder(&old_decoders, recv_codecs[i].codec); 245996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org allocated_decoders_.push_back(allocated_decoder); 2460d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 246196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org webrtc::VideoReceiveStream::Decoder decoder; 246296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org decoder.decoder = allocated_decoder.decoder; 246396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org decoder.payload_type = recv_codecs[i].codec.id; 246496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org decoder.payload_name = recv_codecs[i].codec.name; 246596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org config_.decoders.push_back(decoder); 246696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 246796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 246896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org // TODO(pbos): Reconfigure RTX based on incoming recv_codecs. 246996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org config_.rtp.fec = recv_codecs.front().fec; 2470257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org config_.rtp.nack.rtp_history_ms = 2471e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin HasNack(recv_codecs.begin()->codec) ? kNackHistoryMs : 0; 2472257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org 247396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org ClearDecoders(&old_decoders); 2474874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "RecreateWebRtcStream (recv) because of SetRecvCodecs: " 2475874ca3af5b163e1b3fd8802171e44ee252557842deadbeef << CodecSettingsVectorToString(recv_codecs); 2476d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org RecreateWebRtcStream(); 2477d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2478d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 24793548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boströmvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetLocalSsrc( 24803548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström uint32_t local_ssrc) { 24813548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström // TODO(pbos): Consider turning this sanity check into a DCHECK. You should 24823548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström // not be able to create a sender with the same SSRC as a receiver, but right 24833548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström // now this can't be done due to unittests depending on receiving what they 24843548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström // are sending from the same MediaChannel. 2485874ca3af5b163e1b3fd8802171e44ee252557842deadbeef if (local_ssrc == config_.rtp.remote_ssrc) { 2486874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "Ignoring call to SetLocalSsrc because parameters are " 2487874ca3af5b163e1b3fd8802171e44ee252557842deadbeef "unchanged; local_ssrc=" << local_ssrc; 24883548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström return; 2489874ca3af5b163e1b3fd8802171e44ee252557842deadbeef } 24903548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström 24913548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström config_.rtp.local_ssrc = local_ssrc; 2492874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) 2493874ca3af5b163e1b3fd8802171e44ee252557842deadbeef << "RecreateWebRtcStream (recv) because of SetLocalSsrc; local_ssrc=" 2494874ca3af5b163e1b3fd8802171e44ee252557842deadbeef << local_ssrc; 24953548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström RecreateWebRtcStream(); 24963548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström} 24973548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström 249867c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boströmvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetNackAndRemb( 249967c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström bool nack_enabled, bool remb_enabled) { 250067c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström int nack_history_ms = nack_enabled ? kNackHistoryMs : 0; 250167c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström if (config_.rtp.nack.rtp_history_ms == nack_history_ms && 250267c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström config_.rtp.remb == remb_enabled) { 2503874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "Ignoring call to SetNackAndRemb because parameters are " 2504874ca3af5b163e1b3fd8802171e44ee252557842deadbeef "unchanged; nack=" << nack_enabled 2505874ca3af5b163e1b3fd8802171e44ee252557842deadbeef << ", remb=" << remb_enabled; 2506126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström return; 250767c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström } 250867c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström config_.rtp.remb = remb_enabled; 250967c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström config_.rtp.nack.rtp_history_ms = nack_history_ms; 2510874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "RecreateWebRtcStream (recv) because of SetNackAndRemb; nack=" 2511874ca3af5b163e1b3fd8802171e44ee252557842deadbeef << nack_enabled << ", remb=" << remb_enabled; 2512126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström RecreateWebRtcStream(); 2513126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström} 2514126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström 2515d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRtpExtensions( 2516d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<webrtc::RtpExtension>& extensions) { 2517d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.rtp.extensions = extensions; 2518874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "RecreateWebRtcStream (recv) because of SetRtpExtensions"; 25193548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström RecreateWebRtcStream(); 2520d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2521d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2522d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::RecreateWebRtcStream() { 2523d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (stream_ != NULL) { 2524d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org call_->DestroyVideoReceiveStream(stream_); 2525d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 2526d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org stream_ = call_->CreateVideoReceiveStream(config_); 2527d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org stream_->Start(); 2528d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2529d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 253096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::ClearDecoders( 253196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org std::vector<AllocatedDecoder>* allocated_decoders) { 253296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org for (size_t i = 0; i < allocated_decoders->size(); ++i) { 253396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if ((*allocated_decoders)[i].external) { 2534776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org external_decoder_factory_->DestroyVideoDecoder( 25357252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström (*allocated_decoders)[i].external_decoder); 2536776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org } 25377252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström delete (*allocated_decoders)[i].decoder; 2538776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org } 253996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org allocated_decoders->clear(); 2540776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org} 2541776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 2542d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::RenderFrame( 25434765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez const webrtc::VideoFrame& frame, 2544d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org int time_to_render_ms) { 2545d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 2546fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org 2547fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org if (first_frame_timestamp_ < 0) 2548fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org first_frame_timestamp_ = frame.timestamp(); 2549fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org int64_t rtp_time_elapsed_since_first_frame = 2550fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org (timestamp_wraparound_handler_.Unwrap(frame.timestamp()) - 2551fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org first_frame_timestamp_); 2552fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org int64_t elapsed_time_ms = rtp_time_elapsed_since_first_frame / 2553fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org (cricket::kVideoCodecClockrate / 1000); 2554fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org if (frame.ntp_time_ms() > 0) 2555fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org estimated_remote_start_ntp_time_ms_ = frame.ntp_time_ms() - elapsed_time_ms; 2556fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org 2557d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (renderer_ == NULL) { 2558d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org LOG(LS_WARNING) << "VideoReceiveStream not connected to a VideoRenderer."; 2559d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return; 2560d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 2561d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2562d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (frame.width() != last_width_ || frame.height() != last_height_) { 2563d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetSize(frame.width(), frame.height()); 2564d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 2565d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 25662386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org const WebRtcVideoFrame render_frame( 25672386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org frame.video_frame_buffer(), 25682386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org elapsed_time_ms * rtc::kNumNanosecsPerMillisec, 256964c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh frame.render_time_ms() * rtc::kNumNanosecsPerMillisec, frame.rotation()); 2570d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org renderer_->RenderFrame(&render_frame); 2571d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2572d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 25730d852d5c27a759fe7aadc500bd7b3cadfae3deb8pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoReceiveStream::IsTextureSupported() const { 25740d852d5c27a759fe7aadc500bd7b3cadfae3deb8pbos@webrtc.org return true; 25750d852d5c27a759fe7aadc500bd7b3cadfae3deb8pbos@webrtc.org} 25760d852d5c27a759fe7aadc500bd7b3cadfae3deb8pbos@webrtc.org 2577a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoReceiveStream::IsDefaultStream() const { 2578a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org return default_stream_; 2579a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org} 2580a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org 2581d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRenderer( 2582d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org cricket::VideoRenderer* renderer) { 2583d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 2584d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org renderer_ = renderer; 2585d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (renderer_ != NULL && last_width_ != -1) { 2586d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetSize(last_width_, last_height_); 2587d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 2588d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2589d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2590d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgVideoRenderer* WebRtcVideoChannel2::WebRtcVideoReceiveStream::GetRenderer() { 2591d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // TODO(pbos): Remove GetRenderer and all uses of it, it's thread-unsafe by 2592d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // design. 2593d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 2594d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return renderer_; 2595d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2596d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2597d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetSize(int width, 2598d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org int height) { 2599d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 2600d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (!renderer_->SetSize(width, height, 0)) { 2601d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org LOG(LS_ERROR) << "Could not set renderer size."; 2602d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 2603d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_width_ = width; 2604d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_height_ = height; 2605d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2606d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2607f42376c60111edba6f29060bf3dd79e75d8dbb97pbosstd::string 2608f42376c60111edba6f29060bf3dd79e75d8dbb97pbosWebRtcVideoChannel2::WebRtcVideoReceiveStream::GetCodecNameFromPayloadType( 2609f42376c60111edba6f29060bf3dd79e75d8dbb97pbos int payload_type) { 2610f42376c60111edba6f29060bf3dd79e75d8dbb97pbos for (const webrtc::VideoReceiveStream::Decoder& decoder : config_.decoders) { 2611f42376c60111edba6f29060bf3dd79e75d8dbb97pbos if (decoder.payload_type == payload_type) { 2612f42376c60111edba6f29060bf3dd79e75d8dbb97pbos return decoder.payload_name; 2613f42376c60111edba6f29060bf3dd79e75d8dbb97pbos } 2614f42376c60111edba6f29060bf3dd79e75d8dbb97pbos } 2615f42376c60111edba6f29060bf3dd79e75d8dbb97pbos return ""; 2616f42376c60111edba6f29060bf3dd79e75d8dbb97pbos} 2617f42376c60111edba6f29060bf3dd79e75d8dbb97pbos 2618e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgVideoReceiverInfo 2619e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::GetVideoReceiverInfo() { 2620e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoReceiverInfo info; 2621259bd2034c3d3ee7f2dc4d481e9bf896a3a4d6efPeter Boström info.ssrc_groups = ssrc_groups_; 2622e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.add_ssrc(config_.rtp.remote_ssrc); 2623e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org webrtc::VideoReceiveStream::Stats stats = stream_->GetStats(); 2624cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org info.bytes_rcvd = stats.rtp_stats.transmitted.payload_bytes + 2625cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org stats.rtp_stats.transmitted.header_bytes + 2626cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org stats.rtp_stats.transmitted.padding_bytes; 2627cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org info.packets_rcvd = stats.rtp_stats.transmitted.packets; 2628393347ff988708df5037ddcd181fe204bd1ab37ePeter Boström info.packets_lost = stats.rtcp_stats.cumulative_lost; 2629393347ff988708df5037ddcd181fe204bd1ab37ePeter Boström info.fraction_lost = 2630393347ff988708df5037ddcd181fe204bd1ab37ePeter Boström static_cast<float>(stats.rtcp_stats.fraction_lost) / (1 << 8); 2631e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 2632e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_rcvd = stats.network_frame_rate; 2633e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_decoded = stats.decode_frame_rate; 2634e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_output = stats.render_frame_rate; 2635e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 26361d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org { 26371d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org rtc::CritScope frame_cs(&renderer_lock_); 26381d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.frame_width = last_width_; 26391d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.frame_height = last_height_; 26401d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.capture_start_ntp_time_ms = estimated_remote_start_ntp_time_ms_; 26411d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org } 26421d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org 264309c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.decode_ms = stats.decode_ms; 264409c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.max_decode_ms = stats.max_decode_ms; 264509c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.current_delay_ms = stats.current_delay_ms; 264609c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.target_delay_ms = stats.target_delay_ms; 264709c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.jitter_buffer_ms = stats.jitter_buffer_ms; 264809c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.min_playout_delay_ms = stats.min_playout_delay_ms; 264909c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.render_delay_ms = stats.render_delay_ms; 265009c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org 2651f42376c60111edba6f29060bf3dd79e75d8dbb97pbos info.codec_name = GetCodecNameFromPayloadType(stats.current_payload_type); 2652f42376c60111edba6f29060bf3dd79e75d8dbb97pbos 26531d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.firs_sent = stats.rtcp_packet_type_counts.fir_packets; 26541d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.plis_sent = stats.rtcp_packet_type_counts.pli_packets; 26551d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.nacks_sent = stats.rtcp_packet_type_counts.nack_packets; 2656e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 2657e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org return info; 2658e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 2659e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 2660b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::VideoCodecSettings::VideoCodecSettings() 2661b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : rtx_payload_type(-1) {} 2662b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2663a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.orgbool WebRtcVideoChannel2::VideoCodecSettings::operator==( 2664a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org const WebRtcVideoChannel2::VideoCodecSettings& other) const { 2665a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org return codec == other.codec && 2666a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org fec.ulpfec_payload_type == other.fec.ulpfec_payload_type && 2667a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org fec.red_payload_type == other.fec.red_payload_type && 2668e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin fec.red_rtx_payload_type == other.fec.red_rtx_payload_type && 2669a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org rtx_payload_type == other.rtx_payload_type; 2670a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org} 2671a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 2672ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boströmbool WebRtcVideoChannel2::VideoCodecSettings::operator!=( 2673ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström const WebRtcVideoChannel2::VideoCodecSettings& other) const { 2674ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström return !(*this == other); 2675ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström} 2676ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström 2677b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstd::vector<WebRtcVideoChannel2::VideoCodecSettings> 2678b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::MapCodecs(const std::vector<VideoCodec>& codecs) { 2679d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(!codecs.empty()); 2680b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2681b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::vector<VideoCodecSettings> video_codecs; 2682b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::map<int, bool> payload_used; 2683e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org std::map<int, VideoCodec::CodecType> payload_codec_type; 2684d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org // |rtx_mapping| maps video payload type to rtx payload type. 2685d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org std::map<int, int> rtx_mapping; 2686b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2687b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::FecConfig fec_settings; 2688b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2689b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 2690b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& in_codec = codecs[i]; 2691b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int payload_type = in_codec.id; 2692b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2693b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (payload_used[payload_type]) { 2694b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Payload type already registered: " 2695b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << in_codec.ToString(); 2696b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return std::vector<VideoCodecSettings>(); 2697b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2698b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org payload_used[payload_type] = true; 2699e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org payload_codec_type[payload_type] = in_codec.GetCodecType(); 2700b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2701b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org switch (in_codec.GetCodecType()) { 2702b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_RED: { 2703b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // RED payload type, should not have duplicates. 2704d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(fec_settings.red_payload_type == -1); 2705b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org fec_settings.red_payload_type = in_codec.id; 2706b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 2707b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2708b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2709b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_ULPFEC: { 2710b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // ULPFEC payload type, should not have duplicates. 2711d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(fec_settings.ulpfec_payload_type == -1); 2712b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org fec_settings.ulpfec_payload_type = in_codec.id; 2713b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 2714b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2715b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2716b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_RTX: { 2717b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int associated_payload_type; 2718b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!in_codec.GetParam(kCodecParamAssociatedPayloadType, 2719e9facf8bb32a1688f2156009c755caa2904e1ac9pkasting@chromium.org &associated_payload_type) || 2720e9facf8bb32a1688f2156009c755caa2904e1ac9pkasting@chromium.org !IsValidRtpPayloadType(associated_payload_type)) { 2721e9facf8bb32a1688f2156009c755caa2904e1ac9pkasting@chromium.org LOG(LS_ERROR) 2722e9facf8bb32a1688f2156009c755caa2904e1ac9pkasting@chromium.org << "RTX codec with invalid or no associated payload type: " 2723e9facf8bb32a1688f2156009c755caa2904e1ac9pkasting@chromium.org << in_codec.ToString(); 2724b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return std::vector<VideoCodecSettings>(); 2725b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2726b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtx_mapping[associated_payload_type] = in_codec.id; 2727b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 2728b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2729b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2730b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_VIDEO: 2731b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org break; 2732b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2733b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2734b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs.push_back(VideoCodecSettings()); 2735b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs.back().codec = in_codec; 2736b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2737b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2738b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // One of these codecs should have been a video codec. Only having FEC 2739b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // parameters into this code is a logic error. 2740d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(!video_codecs.empty()); 2741b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2742e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org for (std::map<int, int>::const_iterator it = rtx_mapping.begin(); 2743e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org it != rtx_mapping.end(); 2744e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org ++it) { 2745e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org if (!payload_used[it->first]) { 2746e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org LOG(LS_ERROR) << "RTX mapped to payload not in codec list."; 2747e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return std::vector<VideoCodecSettings>(); 2748e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 2749e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (payload_codec_type[it->first] != VideoCodec::CODEC_VIDEO && 2750e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin payload_codec_type[it->first] != VideoCodec::CODEC_RED) { 2751e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin LOG(LS_ERROR) << "RTX not mapped to regular video codec or RED codec."; 2752e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return std::vector<VideoCodecSettings>(); 2753e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 2754e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin 2755e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (it->first == fec_settings.red_payload_type) { 2756e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin fec_settings.red_rtx_payload_type = it->second; 2757e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin } 2758e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 2759e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org 2760b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < video_codecs.size(); ++i) { 2761b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs[i].fec = fec_settings; 2762e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (rtx_mapping[video_codecs[i].codec.id] != 0 && 2763e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin rtx_mapping[video_codecs[i].codec.id] != 2764e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin fec_settings.red_payload_type) { 2765b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; 2766b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2767b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2768b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2769b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return video_codecs; 2770b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 2771b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2772b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} // namespace cricket 2773b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2774b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#endif // HAVE_WEBRTC_VIDEO 2775