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" 39bbaf3633c54e3d49aa4c762b8eaa34e09de01c45Stefan Holmer#include "talk/media/webrtc/webrtcmediaengine.h" 4081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström#include "talk/media/webrtc/webrtcvideoencoderfactory.h" 41b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/webrtc/webrtcvideoframe.h" 42b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/webrtc/webrtcvoiceengine.h" 43a09a99950ec40aef6421e4ba35eee7196b7a6e68buildbot@webrtc.org#include "webrtc/base/buffer.h" 44a09a99950ec40aef6421e4ba35eee7196b7a6e68buildbot@webrtc.org#include "webrtc/base/logging.h" 45a09a99950ec40aef6421e4ba35eee7196b7a6e68buildbot@webrtc.org#include "webrtc/base/stringutils.h" 46c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen#include "webrtc/base/timeutils.h" 47e4f96501fc5b3e6de0d1ccd262372afcda1f5b4ftommi#include "webrtc/base/trace_event.h" 48b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "webrtc/call.h" 4971f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin#include "webrtc/modules/video_coding/codecs/h264/include/h264.h" 5081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström#include "webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.h" 5198f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/field_trial.h" 52776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org#include "webrtc/video_decoder.h" 53ab990ae43a2b84b103cb3c50bc38502375c13e68pbos@webrtc.org#include "webrtc/video_encoder.h" 54b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 55b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgnamespace cricket { 567fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgnamespace { 5781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 5881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström// Wrap cricket::WebRtcVideoEncoderFactory as a webrtc::VideoEncoderFactory. 5981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmclass EncoderFactoryAdapter : public webrtc::VideoEncoderFactory { 6081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström public: 6181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // EncoderFactoryAdapter doesn't take ownership of |factory|, which is owned 6281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // by e.g. PeerConnectionFactory. 6381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström explicit EncoderFactoryAdapter(cricket::WebRtcVideoEncoderFactory* factory) 6481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström : factory_(factory) {} 6581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström virtual ~EncoderFactoryAdapter() {} 6681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 6781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // Implement webrtc::VideoEncoderFactory. 6881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström webrtc::VideoEncoder* Create() override { 6981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return factory_->CreateVideoEncoder(webrtc::kVideoCodecVP8); 7081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 7181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 7281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström void Destroy(webrtc::VideoEncoder* encoder) override { 7381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return factory_->DestroyVideoEncoder(encoder); 7481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 7581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 7681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström private: 7781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström cricket::WebRtcVideoEncoderFactory* const factory_; 7881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström}; 7981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 8081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström// An encoder factory that wraps Create requests for simulcastable codec types 8181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström// with a webrtc::SimulcastEncoderAdapter. Non simulcastable codec type 8281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström// requests are just passed through to the contained encoder factory. 8381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmclass WebRtcSimulcastEncoderFactory 8481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström : public cricket::WebRtcVideoEncoderFactory { 8581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström public: 8681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // WebRtcSimulcastEncoderFactory doesn't take ownership of |factory|, which is 8781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // owned by e.g. PeerConnectionFactory. 8881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström explicit WebRtcSimulcastEncoderFactory( 8981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström cricket::WebRtcVideoEncoderFactory* factory) 9081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström : factory_(factory) {} 9181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 9281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström static bool UseSimulcastEncoderFactory( 9381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström const std::vector<VideoCodec>& codecs) { 9481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // If any codec is VP8, use the simulcast factory. If asked to create a 9581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // non-VP8 codec, we'll just return a contained factory encoder directly. 9681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström for (const auto& codec : codecs) { 9781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if (codec.type == webrtc::kVideoCodecVP8) { 9881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return true; 9981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 10081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 10181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return false; 10281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 10381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 10481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström webrtc::VideoEncoder* CreateVideoEncoder( 10581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström webrtc::VideoCodecType type) override { 10691d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(factory_ != NULL); 10781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // If it's a codec type we can simulcast, create a wrapped encoder. 10881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if (type == webrtc::kVideoCodecVP8) { 10981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return new webrtc::SimulcastEncoderAdapter( 11081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström new EncoderFactoryAdapter(factory_)); 11181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 11281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström webrtc::VideoEncoder* encoder = factory_->CreateVideoEncoder(type); 11381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if (encoder) { 11481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström non_simulcast_encoders_.push_back(encoder); 11581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 11681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return encoder; 11781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 11881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 11981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström const std::vector<VideoCodec>& codecs() const override { 12081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return factory_->codecs(); 12181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 12281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 12381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström bool EncoderTypeHasInternalSource( 12481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström webrtc::VideoCodecType type) const override { 12581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return factory_->EncoderTypeHasInternalSource(type); 12681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 12781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 12881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström void DestroyVideoEncoder(webrtc::VideoEncoder* encoder) override { 12981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // Check first to see if the encoder wasn't wrapped in a 13081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // SimulcastEncoderAdapter. In that case, ask the factory to destroy it. 13181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if (std::remove(non_simulcast_encoders_.begin(), 13281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström non_simulcast_encoders_.end(), 13381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström encoder) != non_simulcast_encoders_.end()) { 13481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström factory_->DestroyVideoEncoder(encoder); 13581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return; 13681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 13781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 13881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // Otherwise, SimulcastEncoderAdapter can be deleted directly, and will call 13981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // DestroyVideoEncoder on the factory for individual encoder instances. 14081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström delete encoder; 14181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 14281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 14381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström private: 14481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström cricket::WebRtcVideoEncoderFactory* factory_; 14581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // A list of encoders that were created without being wrapped in a 14681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // SimulcastEncoderAdapter. 14781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström std::vector<webrtc::VideoEncoder*> non_simulcast_encoders_; 14881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström}; 14981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 15081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmbool CodecIsInternallySupported(const std::string& codec_name) { 15181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if (CodecNamesEq(codec_name, kVp8CodecName)) { 15281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return true; 15381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 15481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if (CodecNamesEq(codec_name, kVp9CodecName)) { 1553ed348707e93980fd74246f7a1dfab011f841087asapersson return true; 15681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 15771f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin if (CodecNamesEq(codec_name, kH264CodecName)) { 15871f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin return webrtc::H264Encoder::IsSupported() && 15971f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin webrtc::H264Decoder::IsSupported(); 16071f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin } 16181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return false; 16281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström} 16381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 16481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmvoid AddDefaultFeedbackParams(VideoCodec* codec) { 16581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamCcm, kRtcpFbCcmParamFir)); 16681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kParamValueEmpty)); 16781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kRtcpFbNackParamPli)); 16881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamRemb, kParamValueEmpty)); 16943edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan codec->AddFeedbackParam( 17043edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan FeedbackParam(kRtcpFbParamTransportCc, kParamValueEmpty)); 17181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström} 17281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 17381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmstatic VideoCodec MakeVideoCodecWithDefaultFeedbackParams(int payload_type, 17481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström const char* name) { 17581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström VideoCodec codec(payload_type, name, kDefaultVideoMaxWidth, 17681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström kDefaultVideoMaxHeight, kDefaultVideoMaxFramerate, 0); 17781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström AddDefaultFeedbackParams(&codec); 17881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return codec; 17981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström} 18081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 1817fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgstatic std::string CodecVectorToString(const std::vector<VideoCodec>& codecs) { 1827fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org std::stringstream out; 1837fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << '{'; 1847fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 1857fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << codecs[i].ToString(); 1867fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (i != codecs.size() - 1) { 1877fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << ", "; 1887fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 1897fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 1907fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << '}'; 1917fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return out.str(); 1927fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 1937fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 1947fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgstatic bool ValidateCodecFormats(const std::vector<VideoCodec>& codecs) { 1957fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org bool has_video = false; 1967fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 1977fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (!codecs[i].ValidateCodecFormat()) { 1987fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return false; 1997fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 2007fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (codecs[i].GetCodecType() == VideoCodec::CODEC_VIDEO) { 2017fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org has_video = true; 2027fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 2037fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 2047fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (!has_video) { 2057fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org LOG(LS_ERROR) << "Setting codecs without a video codec is invalid: " 2067fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org << CodecVectorToString(codecs); 2077fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return false; 2087fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 2097fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return true; 2107fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 2117fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 212d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boströmstatic bool ValidateStreamParams(const StreamParams& sp) { 213d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström if (sp.ssrcs.empty()) { 214d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström LOG(LS_ERROR) << "No SSRCs in stream parameters: " << sp.ToString(); 215d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström return false; 216d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström } 217d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström 2180c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström std::vector<uint32_t> primary_ssrcs; 219d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström sp.GetPrimarySsrcs(&primary_ssrcs); 2200c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström std::vector<uint32_t> rtx_ssrcs; 221d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström sp.GetFidSsrcs(primary_ssrcs, &rtx_ssrcs); 222d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström for (uint32_t rtx_ssrc : rtx_ssrcs) { 223d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström bool rtx_ssrc_present = false; 224d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström for (uint32_t sp_ssrc : sp.ssrcs) { 225d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström if (sp_ssrc == rtx_ssrc) { 226d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström rtx_ssrc_present = true; 227d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström break; 228d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström } 229d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström } 230d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström if (!rtx_ssrc_present) { 231d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström LOG(LS_ERROR) << "RTX SSRC '" << rtx_ssrc 232d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström << "' missing from StreamParams ssrcs: " << sp.ToString(); 233d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström return false; 234d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström } 235d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström } 236d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström if (!rtx_ssrcs.empty() && primary_ssrcs.size() != rtx_ssrcs.size()) { 237d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström LOG(LS_ERROR) 238d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström << "RTX SSRCs exist, but don't cover all SSRCs (unsupported): " 239d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström << sp.ToString(); 240d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström return false; 241d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström } 242d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström 243d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström return true; 244d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström} 245d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström 24664c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shiehinline const webrtc::RtpExtension* FindHeaderExtension( 24764c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh const std::vector<webrtc::RtpExtension>& extensions, 24864c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh const std::string& name) { 24964c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh for (const auto& kv : extensions) { 25064c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh if (kv.name == name) { 25164c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh return &kv; 25264c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh } 25364c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh } 25464c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh return NULL; 25564c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh} 25664c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh 25782775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org// Merges two fec configs and logs an error if a conflict arises 258e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin// such that merging in different order would trigger a different output. 25982775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.orgstatic void MergeFecConfig(const webrtc::FecConfig& other, 26082775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org webrtc::FecConfig* output) { 26182775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org if (other.ulpfec_payload_type != -1) { 26282775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org if (output->ulpfec_payload_type != -1 && 26382775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org output->ulpfec_payload_type != other.ulpfec_payload_type) { 26482775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org LOG(LS_WARNING) << "Conflict merging ulpfec_payload_type configs: " 26582775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org << output->ulpfec_payload_type << " and " 26682775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org << other.ulpfec_payload_type; 26782775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 26882775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org output->ulpfec_payload_type = other.ulpfec_payload_type; 26982775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 27082775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org if (other.red_payload_type != -1) { 27182775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org if (output->red_payload_type != -1 && 27282775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org output->red_payload_type != other.red_payload_type) { 27382775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org LOG(LS_WARNING) << "Conflict merging red_payload_type configs: " 27482775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org << output->red_payload_type << " and " 27582775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org << other.red_payload_type; 27682775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 27782775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org output->red_payload_type = other.red_payload_type; 27882775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 279e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (other.red_rtx_payload_type != -1) { 280e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (output->red_rtx_payload_type != -1 && 281e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin output->red_rtx_payload_type != other.red_rtx_payload_type) { 282e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin LOG(LS_WARNING) << "Conflict merging red_rtx_payload_type configs: " 283e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin << output->red_rtx_payload_type << " and " 284e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin << other.red_rtx_payload_type; 285e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin } 286e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin output->red_rtx_payload_type = other.red_rtx_payload_type; 287e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin } 28882775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org} 289fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric 290fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric// Returns true if the given codec is disallowed from doing simulcast. 291fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahricbool IsCodecBlacklistedForSimulcast(const std::string& codec_name) { 2923ed348707e93980fd74246f7a1dfab011f841087asapersson return CodecNamesEq(codec_name, kH264CodecName) || 2933ed348707e93980fd74246f7a1dfab011f841087asapersson CodecNamesEq(codec_name, kVp9CodecName); 294fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric} 295fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric 2961c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ã…sa Persson// The selected thresholds for QVGA and VGA corresponded to a QP around 10. 2971c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ã…sa Persson// The change in QP declined above the selected bitrates. 2981c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ã…sa Perssonstatic int GetMaxDefaultVideoBitrateKbps(int width, int height) { 2991c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ã…sa Persson if (width * height <= 320 * 240) { 3001c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ã…sa Persson return 600; 3011c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ã…sa Persson } else if (width * height <= 640 * 480) { 3021c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ã…sa Persson return 1700; 3031c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ã…sa Persson } else if (width * height <= 960 * 540) { 3041c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ã…sa Persson return 2000; 3051c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ã…sa Persson } else { 3061c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ã…sa Persson return 2500; 3071c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ã…sa Persson } 3081c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ã…sa Persson} 3097fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} // namespace 310b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 31181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström// Constants defined in talk/media/webrtc/constants.h 31281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström// TODO(pbos): Move these to a separate constants.cc file. 31381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmconst int kMinVideoBitrate = 30; 31481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmconst int kStartVideoBitrate = 300; 31581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 31681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmconst int kVideoMtu = 1200; 31781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmconst int kVideoRtpBufferSize = 65536; 31881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 319b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// This constant is really an on/off, lower-level configurable NACK history 320b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// duration hasn't been implemented. 321b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic const int kNackHistoryMs = 1000; 322b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 323933d88af58b00517570ef78f38852bfd7fb1bb02buildbot@webrtc.orgstatic const int kDefaultQpMax = 56; 324933d88af58b00517570ef78f38852bfd7fb1bb02buildbot@webrtc.org 325b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic const int kDefaultRtcpReceiverReportSsrc = 1; 326b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 32781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmstd::vector<VideoCodec> DefaultVideoCodecList() { 32881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström std::vector<VideoCodec> codecs; 3293ed348707e93980fd74246f7a1dfab011f841087asapersson codecs.push_back(MakeVideoCodecWithDefaultFeedbackParams(kDefaultVp8PlType, 3303ed348707e93980fd74246f7a1dfab011f841087asapersson kVp8CodecName)); 33181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if (CodecIsInternallySupported(kVp9CodecName)) { 33281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström codecs.push_back(MakeVideoCodecWithDefaultFeedbackParams(kDefaultVp9PlType, 33381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström kVp9CodecName)); 33481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // TODO(andresp): Add rtx codec for vp9 and verify it works. 33581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 33671f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin if (CodecIsInternallySupported(kH264CodecName)) { 33771f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin codecs.push_back(MakeVideoCodecWithDefaultFeedbackParams(kDefaultH264PlType, 33871f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin kH264CodecName)); 33971f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin } 34081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström codecs.push_back( 34181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström VideoCodec::CreateRtxCodec(kDefaultRtxVp8PlType, kDefaultVp8PlType)); 34281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström codecs.push_back(VideoCodec(kDefaultRedPlType, kRedCodecName)); 34381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström codecs.push_back(VideoCodec(kDefaultUlpfecType, kUlpfecCodecName)); 34481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return codecs; 34581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström} 34681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 347a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.orgstd::vector<webrtc::VideoStream> 348f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::CreateSimulcastVideoStreams( 349d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoCodec& codec, 350d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoOptions& options, 351dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström int max_bitrate_bps, 352d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org size_t num_streams) { 353a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org int max_qp = kDefaultQpMax; 354a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org codec.GetParam(kCodecParamMaxQuantization, &max_qp); 355a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org 356a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org return GetSimulcastConfig( 357be16f79818d7c21b747189b3e86d8d98add3e6b1pbos num_streams, codec.width, codec.height, max_bitrate_bps, max_qp, 358a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org codec.framerate != 0 ? codec.framerate : kDefaultVideoMaxFramerate); 359a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org} 360a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org 361f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.orgstd::vector<webrtc::VideoStream> 362f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoStreams( 363a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org const VideoCodec& codec, 364a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org const VideoOptions& options, 365dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström int max_bitrate_bps, 366a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org size_t num_streams) { 367dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström int codec_max_bitrate_kbps; 368dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström if (codec.GetParam(kCodecParamMaxBitrate, &codec_max_bitrate_kbps)) { 369dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström max_bitrate_bps = codec_max_bitrate_kbps * 1000; 370dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström } 371dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström if (num_streams != 1) { 372dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström return CreateSimulcastVideoStreams(codec, options, max_bitrate_bps, 373dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström num_streams); 374dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström } 375dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström 376dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström // For unset max bitrates set default bitrate for non-simulcast. 3771c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ã…sa Persson if (max_bitrate_bps <= 0) { 3781c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ã…sa Persson max_bitrate_bps = 3791c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ã…sa Persson GetMaxDefaultVideoBitrateKbps(codec.width, codec.height) * 1000; 3801c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ã…sa Persson } 381a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org 382d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org webrtc::VideoStream stream; 383d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.width = codec.width; 384d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.height = codec.height; 385d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.max_framerate = 38682775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org codec.framerate != 0 ? codec.framerate : kDefaultVideoMaxFramerate; 387d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org 388008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org stream.min_bitrate_bps = kMinVideoBitrate * 1000; 389dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström stream.target_bitrate_bps = stream.max_bitrate_bps = max_bitrate_bps; 390d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org 391933d88af58b00517570ef78f38852bfd7fb1bb02buildbot@webrtc.org int max_qp = kDefaultQpMax; 392d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org codec.GetParam(kCodecParamMaxQuantization, &max_qp); 393d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.max_qp = max_qp; 394d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org std::vector<webrtc::VideoStream> streams; 395d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org streams.push_back(stream); 396d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org return streams; 397d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org} 398b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 399f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.orgvoid* WebRtcVideoChannel2::WebRtcVideoSendStream::ConfigureVideoEncoderSettings( 4006f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org const VideoCodec& codec, 401143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprÃ¥ng const VideoOptions& options, 402143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprÃ¥ng bool is_screencast) { 4032feafdb742226f57588d9c95bc25b2202166688fPeter Boström // No automatic resizing when using simulcast or screencast. 4042feafdb742226f57588d9c95bc25b2202166688fPeter Boström bool automatic_resize = 4052feafdb742226f57588d9c95bc25b2202166688fPeter Boström !is_screencast && parameters_.config.rtp.ssrcs.size() == 1; 406143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprÃ¥ng bool frame_dropping = !is_screencast; 407143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprÃ¥ng bool denoising; 4084cba4eba596706f2238d14f96f4e181f47e5034cpbos bool codec_default_denoising = false; 409143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprÃ¥ng if (is_screencast) { 410143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprÃ¥ng denoising = false; 411143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprÃ¥ng } else { 4124cba4eba596706f2238d14f96f4e181f47e5034cpbos // Use codec default if video_noise_reduction is unset. 413102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg codec_default_denoising = !options.video_noise_reduction; 414102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg denoising = options.video_noise_reduction.value_or(false); 415143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprÃ¥ng } 416143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprÃ¥ng 417e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (CodecNamesEq(codec.name, kVp8CodecName)) { 418f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org encoder_settings_.vp8 = webrtc::VideoEncoder::GetDefaultVp8Settings(); 419143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprÃ¥ng encoder_settings_.vp8.automaticResizeOn = automatic_resize; 4204cba4eba596706f2238d14f96f4e181f47e5034cpbos // VP8 denoising is enabled by default. 4214cba4eba596706f2238d14f96f4e181f47e5034cpbos encoder_settings_.vp8.denoisingOn = 4224cba4eba596706f2238d14f96f4e181f47e5034cpbos codec_default_denoising ? true : denoising; 423143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprÃ¥ng encoder_settings_.vp8.frameDroppingOn = frame_dropping; 424f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org return &encoder_settings_.vp8; 4256f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org } 426e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (CodecNamesEq(codec.name, kVp9CodecName)) { 427f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org encoder_settings_.vp9 = webrtc::VideoEncoder::GetDefaultVp9Settings(); 4284cba4eba596706f2238d14f96f4e181f47e5034cpbos // VP9 denoising is disabled by default. 4294cba4eba596706f2238d14f96f4e181f47e5034cpbos encoder_settings_.vp9.denoisingOn = 4304cba4eba596706f2238d14f96f4e181f47e5034cpbos codec_default_denoising ? false : denoising; 431143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprÃ¥ng encoder_settings_.vp9.frameDroppingOn = frame_dropping; 432f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org return &encoder_settings_.vp9; 433188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org } 4346f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org return NULL; 4356f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org} 4366f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 437afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgDefaultUnsignalledSsrcHandler::DefaultUnsignalledSsrcHandler() 438afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org : default_recv_ssrc_(0), default_renderer_(NULL) {} 439afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 440afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgUnsignalledSsrcHandler::Action DefaultUnsignalledSsrcHandler::OnUnsignalledSsrc( 441a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org WebRtcVideoChannel2* channel, 442afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org uint32_t ssrc) { 443afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org if (default_recv_ssrc_ != 0) { // Already one default stream. 444afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_WARNING) << "Unknown SSRC, but default receive stream already set."; 445afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return kDropPacket; 446afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 447afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 448afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org StreamParams sp; 449afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org sp.ssrcs.push_back(ssrc); 450afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_INFO) << "Creating default receive stream for SSRC=" << ssrc << "."; 451a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org if (!channel->AddRecvStream(sp, true)) { 452afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_WARNING) << "Could not create default receive stream."; 453afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 454afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 455afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org channel->SetRenderer(ssrc, default_renderer_); 456afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org default_recv_ssrc_ = ssrc; 457afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return kDeliverPacket; 458afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org} 459afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 460afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgVideoRenderer* DefaultUnsignalledSsrcHandler::GetDefaultRenderer() const { 461afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return default_renderer_; 462afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org} 463afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 464afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgvoid DefaultUnsignalledSsrcHandler::SetDefaultRenderer( 465afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org VideoMediaChannel* channel, 466afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org VideoRenderer* renderer) { 467afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org default_renderer_ = renderer; 468afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org if (default_recv_ssrc_ != 0) { 469afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org channel->SetRenderer(default_recv_ssrc_, default_renderer_); 470afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 471afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org} 472afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 473709ed67c38d0a942f3bf3e68e337cc27a27bc353Fredrik SolenbergWebRtcVideoEngine2::WebRtcVideoEngine2() 474709ed67c38d0a942f3bf3e68e337cc27a27bc353Fredrik Solenberg : initialized_(false), 4750a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_decoder_factory_(NULL), 4760a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_encoder_factory_(NULL) { 477b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::WebRtcVideoEngine2()"; 4787fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org video_codecs_ = GetSupportedCodecs(); 479b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 480b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 481b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoEngine2::~WebRtcVideoEngine2() { 482b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::~WebRtcVideoEngine2"; 483b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 484b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 4859a416bd14ee225d8f1a1ada627a1dd7daf275032Fredrik Solenbergvoid WebRtcVideoEngine2::Init() { 486b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::Init"; 487b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org initialized_ = true; 488b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 489b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 490b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2* WebRtcVideoEngine2::CreateChannel( 491709ed67c38d0a942f3bf3e68e337cc27a27bc353Fredrik Solenberg webrtc::Call* call, 492709ed67c38d0a942f3bf3e68e337cc27a27bc353Fredrik Solenberg const VideoOptions& options) { 49391d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(initialized_); 494709ed67c38d0a942f3bf3e68e337cc27a27bc353Fredrik Solenberg LOG(LS_INFO) << "CreateChannel. Options: " << options.ToString(); 495b071a19019a0a2173cc139c960d6ef6946a1c581Fredrik Solenberg return new WebRtcVideoChannel2(call, options, video_codecs_, 496709ed67c38d0a942f3bf3e68e337cc27a27bc353Fredrik Solenberg external_encoder_factory_, external_decoder_factory_); 497b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 498b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 499b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgconst std::vector<VideoCodec>& WebRtcVideoEngine2::codecs() const { 500b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return video_codecs_; 501b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 502b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 5039d69c3f4d99240c27d997c37950b561605d403bdStefan HolmerRtpCapabilities WebRtcVideoEngine2::GetCapabilities() const { 5049d69c3f4d99240c27d997c37950b561605d403bdStefan Holmer RtpCapabilities capabilities; 5059d69c3f4d99240c27d997c37950b561605d403bdStefan Holmer capabilities.header_extensions.push_back( 5069d69c3f4d99240c27d997c37950b561605d403bdStefan Holmer RtpHeaderExtension(kRtpTimestampOffsetHeaderExtension, 5079d69c3f4d99240c27d997c37950b561605d403bdStefan Holmer kRtpTimestampOffsetHeaderExtensionDefaultId)); 5089d69c3f4d99240c27d997c37950b561605d403bdStefan Holmer capabilities.header_extensions.push_back( 5099d69c3f4d99240c27d997c37950b561605d403bdStefan Holmer RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, 5109d69c3f4d99240c27d997c37950b561605d403bdStefan Holmer kRtpAbsoluteSenderTimeHeaderExtensionDefaultId)); 5119d69c3f4d99240c27d997c37950b561605d403bdStefan Holmer capabilities.header_extensions.push_back( 5129d69c3f4d99240c27d997c37950b561605d403bdStefan Holmer RtpHeaderExtension(kRtpVideoRotationHeaderExtension, 5139d69c3f4d99240c27d997c37950b561605d403bdStefan Holmer kRtpVideoRotationHeaderExtensionDefaultId)); 5149d69c3f4d99240c27d997c37950b561605d403bdStefan Holmer if (webrtc::field_trial::FindFullName("WebRTC-SendSideBwe") == "Enabled") { 5159d69c3f4d99240c27d997c37950b561605d403bdStefan Holmer capabilities.header_extensions.push_back(RtpHeaderExtension( 5169d69c3f4d99240c27d997c37950b561605d403bdStefan Holmer kRtpTransportSequenceNumberHeaderExtension, 5179d69c3f4d99240c27d997c37950b561605d403bdStefan Holmer kRtpTransportSequenceNumberHeaderExtensionDefaultId)); 5189d69c3f4d99240c27d997c37950b561605d403bdStefan Holmer } 5199d69c3f4d99240c27d997c37950b561605d403bdStefan Holmer return capabilities; 520b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 521b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 5220a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.orgvoid WebRtcVideoEngine2::SetExternalDecoderFactory( 5230a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org WebRtcVideoDecoderFactory* decoder_factory) { 52491d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(!initialized_); 5250a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_decoder_factory_ = decoder_factory; 5260a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org} 5270a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org 5280a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.orgvoid WebRtcVideoEngine2::SetExternalEncoderFactory( 5290a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org WebRtcVideoEncoderFactory* encoder_factory) { 53091d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(!initialized_); 531f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org if (external_encoder_factory_ == encoder_factory) 532f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org return; 533f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org 534f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org // No matter what happens we shouldn't hold on to a stale 535f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org // WebRtcSimulcastEncoderFactory. 536f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org simulcast_encoder_factory_.reset(); 537f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org 538f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org if (encoder_factory && 539f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org WebRtcSimulcastEncoderFactory::UseSimulcastEncoderFactory( 540f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org encoder_factory->codecs())) { 541f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org simulcast_encoder_factory_.reset( 542f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org new WebRtcSimulcastEncoderFactory(encoder_factory)); 543f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org encoder_factory = simulcast_encoder_factory_.get(); 544f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org } 5450a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_encoder_factory_ = encoder_factory; 5467fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 5477fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org video_codecs_ = GetSupportedCodecs(); 5480a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org} 5490a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org 550b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::EnableTimedRender() { 551b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Figure out whether this can be removed. 552b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 553b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 554b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 555b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Checks to see whether we comprehend and could receive a particular codec 556b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::FindCodec(const VideoCodec& in) { 557b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Probe encoder factory to figure out that the codec is supported 558b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // if supported by the encoder factory. Add a corresponding test that fails 559b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // with this code (that doesn't ask the factory). 5608fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org for (size_t j = 0; j < video_codecs_.size(); ++j) { 5618fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org VideoCodec codec(video_codecs_[j].id, video_codecs_[j].name, 0, 0, 0, 0); 5628fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org if (codec.Matches(in)) { 5638fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return true; 564b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 565b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 566b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 567b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 568b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 569b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Ignore spammy trace messages, mostly from the stats API when we haven't 570b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// gotten RTCP info yet from the remote side. 571b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::ShouldIgnoreTrace(const std::string& trace) { 572b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static const char* const kTracesToIgnore[] = {NULL}; 573b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (const char* const* p = kTracesToIgnore; *p; ++p) { 574b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (trace.find(*p) == 0) { 575b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 576b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 577b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 578b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 579b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 580b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 5817fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgstd::vector<VideoCodec> WebRtcVideoEngine2::GetSupportedCodecs() const { 58282775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org std::vector<VideoCodec> supported_codecs = DefaultVideoCodecList(); 5837fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 5847fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (external_encoder_factory_ == NULL) { 5857fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return supported_codecs; 5867fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 5877fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 5887fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org const std::vector<WebRtcVideoEncoderFactory::VideoCodec>& codecs = 5897fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_->codecs(); 5907fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 5917fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org // Don't add internally-supported codecs twice. 5927fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (CodecIsInternallySupported(codecs[i].name)) { 5937fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org continue; 5947fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 5957fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 596d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org // External video encoders are given payloads 120-127. This also means that 597d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org // we only support up to 8 external payload types. 598d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org const int kExternalVideoPayloadTypeBase = 120; 599d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org size_t payload_type = kExternalVideoPayloadTypeBase + i; 60091d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(payload_type < 128); 601d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org VideoCodec codec(static_cast<int>(payload_type), 6027fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org codecs[i].name, 6037fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org codecs[i].max_width, 6047fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org codecs[i].max_height, 6057fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org codecs[i].max_fps, 6067fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 0); 6077fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 6087fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org AddDefaultFeedbackParams(&codec); 6097fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org supported_codecs.push_back(codec); 6107fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 6117fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return supported_codecs; 6127fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 6137fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 614b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoChannel2( 615709ed67c38d0a942f3bf3e68e337cc27a27bc353Fredrik Solenberg webrtc::Call* call, 616fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org const VideoOptions& options, 617b071a19019a0a2173cc139c960d6ef6946a1c581Fredrik Solenberg const std::vector<VideoCodec>& recv_codecs, 6187fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org WebRtcVideoEncoderFactory* external_encoder_factory, 619f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org WebRtcVideoDecoderFactory* external_decoder_factory) 620709ed67c38d0a942f3bf3e68e337cc27a27bc353Fredrik Solenberg : call_(call), 621709ed67c38d0a942f3bf3e68e337cc27a27bc353Fredrik Solenberg unsignalled_ssrc_handler_(&default_unsignalled_ssrc_handler_), 6227fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_(external_encoder_factory), 623f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org external_decoder_factory_(external_decoder_factory) { 62491d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(thread_checker_.CalledOnValidThread()); 625fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org SetDefaultOptions(); 626fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org options_.SetAll(options); 627102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg if (options_.cpu_overuse_detection) 628102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg signal_cpu_adaptation_ = *options_.cpu_overuse_detection; 629b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtcp_receiver_report_ssrc_ = kDefaultRtcpReceiverReportSsrc; 630b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = false; 631b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = 0; 632b071a19019a0a2173cc139c960d6ef6946a1c581Fredrik Solenberg SetRecvCodecs(recv_codecs); 6336f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org} 6346f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 6356f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.orgvoid WebRtcVideoChannel2::SetDefaultOptions() { 636be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg options_.cpu_overuse_detection = rtc::Optional<bool>(true); 637be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg options_.dscp = rtc::Optional<bool>(false); 638be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg options_.suspend_below_min_bitrate = rtc::Optional<bool>(false); 639be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg options_.screencast_min_bitrate = rtc::Optional<int>(0); 640b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 641b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 642b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::~WebRtcVideoChannel2() { 643dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström for (auto& kv : send_streams_) 644dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström delete kv.second; 645dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström for (auto& kv : receive_streams_) 646dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström delete kv.second; 647b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 648b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 64996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgbool WebRtcVideoChannel2::CodecIsExternallySupported( 65096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const std::string& name) const { 65196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (external_encoder_factory_ == NULL) { 65296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return false; 65396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 65496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 65596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const std::vector<WebRtcVideoEncoderFactory::VideoCodec> external_codecs = 65696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org external_encoder_factory_->codecs(); 65796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org for (size_t c = 0; c < external_codecs.size(); ++c) { 658e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (CodecNamesEq(name, external_codecs[c].name)) { 65996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return true; 66096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 66196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 66296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return false; 66396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org} 66496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 66596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgstd::vector<WebRtcVideoChannel2::VideoCodecSettings> 66696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgWebRtcVideoChannel2::FilterSupportedCodecs( 66796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const std::vector<WebRtcVideoChannel2::VideoCodecSettings>& mapped_codecs) 66896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const { 66996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org std::vector<VideoCodecSettings> supported_codecs; 67096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org for (size_t i = 0; i < mapped_codecs.size(); ++i) { 67196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const VideoCodecSettings& codec = mapped_codecs[i]; 67296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (CodecIsInternallySupported(codec.codec.name) || 67396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org CodecIsExternallySupported(codec.codec.name)) { 67496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org supported_codecs.push_back(codec); 67596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 67696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 67796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return supported_codecs; 67896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org} 67996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 680874ca3af5b163e1b3fd8802171e44ee252557842deadbeefbool WebRtcVideoChannel2::ReceiveCodecsHaveChanged( 681874ca3af5b163e1b3fd8802171e44ee252557842deadbeef std::vector<VideoCodecSettings> before, 682874ca3af5b163e1b3fd8802171e44ee252557842deadbeef std::vector<VideoCodecSettings> after) { 683874ca3af5b163e1b3fd8802171e44ee252557842deadbeef if (before.size() != after.size()) { 684874ca3af5b163e1b3fd8802171e44ee252557842deadbeef return true; 685874ca3af5b163e1b3fd8802171e44ee252557842deadbeef } 686874ca3af5b163e1b3fd8802171e44ee252557842deadbeef // The receive codec order doesn't matter, so we sort the codecs before 687874ca3af5b163e1b3fd8802171e44ee252557842deadbeef // comparing. This is necessary because currently the 688874ca3af5b163e1b3fd8802171e44ee252557842deadbeef // only way to change the send codec is to munge SDP, which causes 689874ca3af5b163e1b3fd8802171e44ee252557842deadbeef // the receive codec list to change order, which causes the streams 690874ca3af5b163e1b3fd8802171e44ee252557842deadbeef // to be recreates which causes a "blink" of black video. In order 691874ca3af5b163e1b3fd8802171e44ee252557842deadbeef // to support munging the SDP in this way without recreating receive 692874ca3af5b163e1b3fd8802171e44ee252557842deadbeef // streams, we ignore the order of the received codecs so that 693874ca3af5b163e1b3fd8802171e44ee252557842deadbeef // changing the order doesn't cause this "blink". 694874ca3af5b163e1b3fd8802171e44ee252557842deadbeef auto comparison = 695874ca3af5b163e1b3fd8802171e44ee252557842deadbeef [](const VideoCodecSettings& codec1, const VideoCodecSettings& codec2) { 696874ca3af5b163e1b3fd8802171e44ee252557842deadbeef return codec1.codec.id > codec2.codec.id; 697874ca3af5b163e1b3fd8802171e44ee252557842deadbeef }; 698874ca3af5b163e1b3fd8802171e44ee252557842deadbeef std::sort(before.begin(), before.end(), comparison); 699874ca3af5b163e1b3fd8802171e44ee252557842deadbeef std::sort(after.begin(), after.end(), comparison); 700874ca3af5b163e1b3fd8802171e44ee252557842deadbeef for (size_t i = 0; i < before.size(); ++i) { 701874ca3af5b163e1b3fd8802171e44ee252557842deadbeef // For the same reason that we sort the codecs, we also ignore the 702874ca3af5b163e1b3fd8802171e44ee252557842deadbeef // preference. We don't want a preference change on the receive 703874ca3af5b163e1b3fd8802171e44ee252557842deadbeef // side to cause recreation of the stream. 704874ca3af5b163e1b3fd8802171e44ee252557842deadbeef before[i].codec.preference = 0; 705874ca3af5b163e1b3fd8802171e44ee252557842deadbeef after[i].codec.preference = 0; 706874ca3af5b163e1b3fd8802171e44ee252557842deadbeef if (before[i] != after[i]) { 707874ca3af5b163e1b3fd8802171e44ee252557842deadbeef return true; 708874ca3af5b163e1b3fd8802171e44ee252557842deadbeef } 709874ca3af5b163e1b3fd8802171e44ee252557842deadbeef } 710874ca3af5b163e1b3fd8802171e44ee252557842deadbeef return false; 711874ca3af5b163e1b3fd8802171e44ee252557842deadbeef} 712874ca3af5b163e1b3fd8802171e44ee252557842deadbeef 713c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcherbool WebRtcVideoChannel2::SetSendParameters(const VideoSendParameters& params) { 7149f45a45a628100d973111b3aac66dede57454b6aPeter Boström TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetSendParameters"); 7157e4e01a4413fa98644b94ab9d8a9dccc664f39f2solenberg LOG(LS_INFO) << "SetSendParameters: " << params.ToString(); 716c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher // TODO(pbos): Refactor this to only recreate the send streams once 717c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher // instead of 4 times. 7181387149ad1669365ac05278bf779a407bec08a4edeadbeef if (!SetSendCodecs(params.codecs) || 7191387149ad1669365ac05278bf779a407bec08a4edeadbeef !SetSendRtpHeaderExtensions(params.extensions) || 7201387149ad1669365ac05278bf779a407bec08a4edeadbeef !SetMaxSendBandwidth(params.max_bandwidth_bps) || 7211387149ad1669365ac05278bf779a407bec08a4edeadbeef !SetOptions(params.options)) { 7221387149ad1669365ac05278bf779a407bec08a4edeadbeef return false; 7231387149ad1669365ac05278bf779a407bec08a4edeadbeef } 7241387149ad1669365ac05278bf779a407bec08a4edeadbeef if (send_params_.rtcp.reduced_size != params.rtcp.reduced_size) { 7251387149ad1669365ac05278bf779a407bec08a4edeadbeef rtc::CritScope stream_lock(&stream_crit_); 7261387149ad1669365ac05278bf779a407bec08a4edeadbeef for (auto& kv : send_streams_) { 7271387149ad1669365ac05278bf779a407bec08a4edeadbeef kv.second->SetSendParameters(params); 7281387149ad1669365ac05278bf779a407bec08a4edeadbeef } 7291387149ad1669365ac05278bf779a407bec08a4edeadbeef } 7301387149ad1669365ac05278bf779a407bec08a4edeadbeef send_params_ = params; 7311387149ad1669365ac05278bf779a407bec08a4edeadbeef return true; 732c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher} 733c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher 734c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcherbool WebRtcVideoChannel2::SetRecvParameters(const VideoRecvParameters& params) { 7359f45a45a628100d973111b3aac66dede57454b6aPeter Boström TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetRecvParameters"); 7367e4e01a4413fa98644b94ab9d8a9dccc664f39f2solenberg LOG(LS_INFO) << "SetRecvParameters: " << params.ToString(); 737c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher // TODO(pbos): Refactor this to only recreate the recv streams once 738c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher // instead of twice. 7391387149ad1669365ac05278bf779a407bec08a4edeadbeef if (!SetRecvCodecs(params.codecs) || 7401387149ad1669365ac05278bf779a407bec08a4edeadbeef !SetRecvRtpHeaderExtensions(params.extensions)) { 7411387149ad1669365ac05278bf779a407bec08a4edeadbeef return false; 7421387149ad1669365ac05278bf779a407bec08a4edeadbeef } 7431387149ad1669365ac05278bf779a407bec08a4edeadbeef if (recv_params_.rtcp.reduced_size != params.rtcp.reduced_size) { 7441387149ad1669365ac05278bf779a407bec08a4edeadbeef rtc::CritScope stream_lock(&stream_crit_); 7451387149ad1669365ac05278bf779a407bec08a4edeadbeef for (auto& kv : receive_streams_) { 7461387149ad1669365ac05278bf779a407bec08a4edeadbeef kv.second->SetRecvParameters(params); 7471387149ad1669365ac05278bf779a407bec08a4edeadbeef } 7481387149ad1669365ac05278bf779a407bec08a4edeadbeef } 7491387149ad1669365ac05278bf779a407bec08a4edeadbeef recv_params_ = params; 7501387149ad1669365ac05278bf779a407bec08a4edeadbeef return true; 751c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher} 752c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher 753874ca3af5b163e1b3fd8802171e44ee252557842deadbeefstd::string WebRtcVideoChannel2::CodecSettingsVectorToString( 754874ca3af5b163e1b3fd8802171e44ee252557842deadbeef const std::vector<VideoCodecSettings>& codecs) { 755874ca3af5b163e1b3fd8802171e44ee252557842deadbeef std::stringstream out; 756874ca3af5b163e1b3fd8802171e44ee252557842deadbeef out << '{'; 757874ca3af5b163e1b3fd8802171e44ee252557842deadbeef for (size_t i = 0; i < codecs.size(); ++i) { 758874ca3af5b163e1b3fd8802171e44ee252557842deadbeef out << codecs[i].codec.ToString(); 759874ca3af5b163e1b3fd8802171e44ee252557842deadbeef if (i != codecs.size() - 1) { 760874ca3af5b163e1b3fd8802171e44ee252557842deadbeef out << ", "; 761874ca3af5b163e1b3fd8802171e44ee252557842deadbeef } 762874ca3af5b163e1b3fd8802171e44ee252557842deadbeef } 763874ca3af5b163e1b3fd8802171e44ee252557842deadbeef out << '}'; 764874ca3af5b163e1b3fd8802171e44ee252557842deadbeef return out.str(); 765874ca3af5b163e1b3fd8802171e44ee252557842deadbeef} 766874ca3af5b163e1b3fd8802171e44ee252557842deadbeef 767b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRecvCodecs(const std::vector<VideoCodec>& codecs) { 76850fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetRecvCodecs"); 769b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetRecvCodecs: " << CodecVectorToString(codecs); 770b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!ValidateCodecFormats(codecs)) { 771b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 772b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 773b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 774b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<VideoCodecSettings> mapped_codecs = MapCodecs(codecs); 775b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (mapped_codecs.empty()) { 77696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org LOG(LS_ERROR) << "SetRecvCodecs called without any video codecs."; 777b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 778b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 779b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 780874ca3af5b163e1b3fd8802171e44ee252557842deadbeef std::vector<VideoCodecSettings> supported_codecs = 78196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org FilterSupportedCodecs(mapped_codecs); 78296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 78396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (mapped_codecs.size() != supported_codecs.size()) { 78496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org LOG(LS_ERROR) << "SetRecvCodecs called with unsupported video codecs."; 78596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return false; 786b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 787b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 788ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström // Prevent reconfiguration when setting identical receive codecs. 789874ca3af5b163e1b3fd8802171e44ee252557842deadbeef if (!ReceiveCodecsHaveChanged(recv_codecs_, supported_codecs)) { 790874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) 791874ca3af5b163e1b3fd8802171e44ee252557842deadbeef << "Ignoring call to SetRecvCodecs because codecs haven't changed."; 792874ca3af5b163e1b3fd8802171e44ee252557842deadbeef return true; 793ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström } 794ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström 795874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "Changing recv codecs from " 796874ca3af5b163e1b3fd8802171e44ee252557842deadbeef << CodecSettingsVectorToString(recv_codecs_) << " to " 797874ca3af5b163e1b3fd8802171e44ee252557842deadbeef << CodecSettingsVectorToString(supported_codecs); 79896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org recv_codecs_ = supported_codecs; 799d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 800575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 8010c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström for (std::map<uint32_t, WebRtcVideoReceiveStream*>::iterator it = 802d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.begin(); 8030c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström it != receive_streams_.end(); ++it) { 804d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetRecvCodecs(recv_codecs_); 805d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 806d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 807b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 808b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 809b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 810b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendCodecs(const std::vector<VideoCodec>& codecs) { 81150fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetSendCodecs"); 812b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetSendCodecs: " << CodecVectorToString(codecs); 813b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!ValidateCodecFormats(codecs)) { 814b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 815b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 816b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 817b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<VideoCodecSettings> supported_codecs = 818b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org FilterSupportedCodecs(MapCodecs(codecs)); 819b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 820b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (supported_codecs.empty()) { 8213c3f6460646183914629e5dab8ae5fcede4f0e80Peter Boström LOG(LS_ERROR) << "No video codecs supported."; 822b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 823b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 824b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 825b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "Using codec: " << supported_codecs.front().codec.ToString(); 826b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 827102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg if (send_codec_ && supported_codecs.front() == *send_codec_) { 828874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "Ignore call to SetSendCodecs because first supported " 829874ca3af5b163e1b3fd8802171e44ee252557842deadbeef "codec hasn't changed."; 830a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org // Using same codec, avoid reconfiguring. 831a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org return true; 832a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } 833a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 834be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg send_codec_ = rtc::Optional<WebRtcVideoChannel2::VideoCodecSettings>( 835102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg supported_codecs.front()); 836a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 837575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 838874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "Change the send codec because SetSendCodecs has a different " 839874ca3af5b163e1b3fd8802171e44ee252557842deadbeef "first supported codec."; 840126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström for (auto& kv : send_streams_) { 84191d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(kv.second != nullptr); 842126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström kv.second->SetCodec(supported_codecs.front()); 843126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström } 84443edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan LOG(LS_INFO) 84543edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan << "SetFeedbackOptions on all the receive streams because the send " 84643edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan "codec has changed."; 847126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström for (auto& kv : receive_streams_) { 84891d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(kv.second != nullptr); 84943edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan kv.second->SetFeedbackParameters( 85043edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan HasNack(supported_codecs.front().codec), 85143edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan HasRemb(supported_codecs.front().codec), 85243edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan HasTransportCc(supported_codecs.front().codec)); 853d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 854b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 855e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer // TODO(holmer): Changing the codec parameters shouldn't necessarily mean that 856e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer // we change the min/max of bandwidth estimation. Reevaluate this. 857008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org VideoCodec codec = supported_codecs.front().codec; 858008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org int bitrate_kbps; 859008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org if (codec.GetParam(kCodecParamMinBitrate, &bitrate_kbps) && 860008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_kbps > 0) { 861008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.min_bitrate_bps = bitrate_kbps * 1000; 862008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } else { 863008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.min_bitrate_bps = 0; 864008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } 865008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org if (codec.GetParam(kCodecParamStartBitrate, &bitrate_kbps) && 866008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_kbps > 0) { 867008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.start_bitrate_bps = bitrate_kbps * 1000; 868008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } else { 869008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org // Do not reconfigure start bitrate unless it's specified and positive. 870008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.start_bitrate_bps = -1; 871008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } 872008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org if (codec.GetParam(kCodecParamMaxBitrate, &bitrate_kbps) && 873008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_kbps > 0) { 874008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.max_bitrate_bps = bitrate_kbps * 1000; 875008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } else { 876008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.max_bitrate_bps = -1; 877008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } 878008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org call_->SetBitrateConfig(bitrate_config_); 879008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org 880b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 881b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 882b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 883b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::GetSendCodec(VideoCodec* codec) { 884102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg if (!send_codec_) { 885b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "GetSendCodec: No send codec set."; 886b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 887b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 888102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg *codec = send_codec_->codec; 889b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 890b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 891b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 8920c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmbool WebRtcVideoChannel2::SetSendStreamFormat(uint32_t ssrc, 893b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFormat& format) { 894b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetSendStreamFormat:" << ssrc << " -> " 895b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << format.ToString(); 896575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 897b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 898b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 899b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 900b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return send_streams_[ssrc]->SetVideoFormat(format); 901b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 902b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 903b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSend(bool send) { 904b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetSend: " << (send ? "true" : "false"); 905102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg if (send && !send_codec_) { 906b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "SetSend(true) called before setting codec."; 907b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 908b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 909b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send) { 910b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org StartAllSendStreams(); 911b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 912b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org StopAllSendStreams(); 913b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 914b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = send; 915b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 916b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 917b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 9180c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmbool WebRtcVideoChannel2::SetVideoSend(uint32_t ssrc, bool enable, 9191dd98f321920c1442dd5b3f791ea0fca133c2756solenberg const VideoOptions* options) { 9201dd98f321920c1442dd5b3f791ea0fca133c2756solenberg // TODO(solenberg): The state change should be fully rolled back if any one of 9211dd98f321920c1442dd5b3f791ea0fca133c2756solenberg // these calls fail. 922dfc8f4ff8731390828884a0a91b99e51f2950275solenberg if (!MuteStream(ssrc, !enable)) { 9231dd98f321920c1442dd5b3f791ea0fca133c2756solenberg return false; 9241dd98f321920c1442dd5b3f791ea0fca133c2756solenberg } 925dfc8f4ff8731390828884a0a91b99e51f2950275solenberg if (enable && options) { 9261dd98f321920c1442dd5b3f791ea0fca133c2756solenberg return SetOptions(*options); 9271dd98f321920c1442dd5b3f791ea0fca133c2756solenberg } else { 9281dd98f321920c1442dd5b3f791ea0fca133c2756solenberg return true; 9291dd98f321920c1442dd5b3f791ea0fca133c2756solenberg } 9301dd98f321920c1442dd5b3f791ea0fca133c2756solenberg} 9311dd98f321920c1442dd5b3f791ea0fca133c2756solenberg 932d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boströmbool WebRtcVideoChannel2::ValidateSendSsrcAvailability( 933d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström const StreamParams& sp) const { 934d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström for (uint32_t ssrc: sp.ssrcs) { 935d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström if (send_ssrcs_.find(ssrc) != send_ssrcs_.end()) { 936d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström LOG(LS_ERROR) << "Send stream with SSRC '" << ssrc << "' already exists."; 937d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström return false; 938d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström } 939d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström } 940d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström return true; 941d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström} 942d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 943d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boströmbool WebRtcVideoChannel2::ValidateReceiveSsrcAvailability( 944d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström const StreamParams& sp) const { 945d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström for (uint32_t ssrc: sp.ssrcs) { 946d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström if (receive_ssrcs_.find(ssrc) != receive_ssrcs_.end()) { 947d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström LOG(LS_ERROR) << "Receive stream with SSRC '" << ssrc 948d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström << "' already exists."; 949d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström return false; 950d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström } 951d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström } 952d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström return true; 953d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström} 954d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 955b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::AddSendStream(const StreamParams& sp) { 956b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "AddSendStream: " << sp.ToString(); 957d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström if (!ValidateStreamParams(sp)) 958b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 959b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 960575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 961d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 962d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström if (!ValidateSendSsrcAvailability(sp)) 963b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 964d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 9650c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström for (uint32_t used_ssrc : sp.ssrcs) 966d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström send_ssrcs_.insert(used_ssrc); 967b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 968e5269747595864eedd604f153df5d7bcbe1b475asolenberg webrtc::VideoSendStream::Config config(this); 969e5269747595864eedd604f153df5d7bcbe1b475asolenberg config.overuse_callback = this; 970e5269747595864eedd604f153df5d7bcbe1b475asolenberg 9711387149ad1669365ac05278bf779a407bec08a4edeadbeef WebRtcVideoSendStream* stream = new WebRtcVideoSendStream( 9721387149ad1669365ac05278bf779a407bec08a4edeadbeef call_, sp, config, external_encoder_factory_, options_, 9731387149ad1669365ac05278bf779a407bec08a4edeadbeef bitrate_config_.max_bitrate_bps, send_codec_, send_rtp_extensions_, 9741387149ad1669365ac05278bf779a407bec08a4edeadbeef send_params_); 9755301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 9760c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint32_t ssrc = sp.first_ssrc(); 97791d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(ssrc != 0); 978b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_[ssrc] = stream; 979b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 980b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (rtcp_receiver_report_ssrc_ == kDefaultRtcpReceiverReportSsrc) { 981b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtcp_receiver_report_ssrc_ = ssrc; 982874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "SetLocalSsrc on all the receive streams because we added " 983874ca3af5b163e1b3fd8802171e44ee252557842deadbeef "a send stream."; 9843548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström for (auto& kv : receive_streams_) 9853548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström kv.second->SetLocalSsrc(ssrc); 986b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 987b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (default_send_ssrc_ == 0) { 988b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = ssrc; 989b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 990b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sending_) { 991b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream->Start(); 992b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 993b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 994b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 995b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 996b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 9970c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmbool WebRtcVideoChannel2::RemoveSendStream(uint32_t ssrc) { 998b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "RemoveSendStream: " << ssrc; 999b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1000b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1001b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (default_send_ssrc_ == 0) { 1002b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No default send stream active."; 1003b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1004b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1005b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1006b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "Removing default stream: " << default_send_ssrc_; 1007b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ssrc = default_send_ssrc_; 1008b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1009b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1010575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org WebRtcVideoSendStream* removed_stream; 1011575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org { 1012575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 10130c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström std::map<uint32_t, WebRtcVideoSendStream*>::iterator it = 1014575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org send_streams_.find(ssrc); 1015575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org if (it == send_streams_.end()) { 1016575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org return false; 1017575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org } 1018575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org 10190c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström for (uint32_t old_ssrc : it->second->GetSsrcs()) 1020d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström send_ssrcs_.erase(old_ssrc); 1021d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 1022575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org removed_stream = it->second; 1023575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org send_streams_.erase(it); 1024dfa2815b4f606a58ede5c0214e08a1d5d26d3639Peter Boström 1025dfa2815b4f606a58ede5c0214e08a1d5d26d3639Peter Boström // Switch receiver report SSRCs, the one in use is no longer valid. 1026dfa2815b4f606a58ede5c0214e08a1d5d26d3639Peter Boström if (rtcp_receiver_report_ssrc_ == ssrc) { 1027dfa2815b4f606a58ede5c0214e08a1d5d26d3639Peter Boström rtcp_receiver_report_ssrc_ = send_streams_.empty() 1028dfa2815b4f606a58ede5c0214e08a1d5d26d3639Peter Boström ? kDefaultRtcpReceiverReportSsrc 1029dfa2815b4f606a58ede5c0214e08a1d5d26d3639Peter Boström : send_streams_.begin()->first; 1030dfa2815b4f606a58ede5c0214e08a1d5d26d3639Peter Boström LOG(LS_INFO) << "SetLocalSsrc on all the receive streams because the " 1031dfa2815b4f606a58ede5c0214e08a1d5d26d3639Peter Boström "previous local SSRC was removed."; 1032dfa2815b4f606a58ede5c0214e08a1d5d26d3639Peter Boström 1033dfa2815b4f606a58ede5c0214e08a1d5d26d3639Peter Boström for (auto& kv : receive_streams_) { 1034dfa2815b4f606a58ede5c0214e08a1d5d26d3639Peter Boström kv.second->SetLocalSsrc(rtcp_receiver_report_ssrc_); 1035dfa2815b4f606a58ede5c0214e08a1d5d26d3639Peter Boström } 1036dfa2815b4f606a58ede5c0214e08a1d5d26d3639Peter Boström } 1037b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1038b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1039575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org delete removed_stream; 1040b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1041b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == default_send_ssrc_) { 1042b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = 0; 1043b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1044b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1045b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1046b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1047b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1048d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boströmvoid WebRtcVideoChannel2::DeleteReceiveStream( 1049d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström WebRtcVideoChannel2::WebRtcVideoReceiveStream* stream) { 10500c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström for (uint32_t old_ssrc : stream->GetSsrcs()) 1051d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström receive_ssrcs_.erase(old_ssrc); 1052d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström delete stream; 1053d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström} 1054d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 1055b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::AddRecvStream(const StreamParams& sp) { 1056a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org return AddRecvStream(sp, false); 1057a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org} 1058a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org 1059a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.orgbool WebRtcVideoChannel2::AddRecvStream(const StreamParams& sp, 1060a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org bool default_stream) { 106191d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(thread_checker_.CalledOnValidThread()); 10624b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg 1063d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström LOG(LS_INFO) << "AddRecvStream" << (default_stream ? " (default stream)" : "") 1064d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström << ": " << sp.ToString(); 1065d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström if (!ValidateStreamParams(sp)) 1066d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström return false; 1067b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 10680c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint32_t ssrc = sp.first_ssrc(); 106991d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(ssrc != 0); // TODO(pbos): Is this ever valid? 1070b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1071575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1072d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström // Remove running stream if this was a default stream. 1073d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström auto prev_stream = receive_streams_.find(ssrc); 1074d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström if (prev_stream != receive_streams_.end()) { 1075d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström if (default_stream || !prev_stream->second->IsDefaultStream()) { 1076d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström LOG(LS_ERROR) << "Receive stream for SSRC '" << ssrc 1077d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström << "' already exists."; 1078d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström return false; 1079a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org } 1080d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström DeleteReceiveStream(prev_stream->second); 1081d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström receive_streams_.erase(prev_stream); 1082b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1083b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1084d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström if (!ValidateReceiveSsrcAvailability(sp)) 1085d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström return false; 1086d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 10870c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström for (uint32_t used_ssrc : sp.ssrcs) 1088d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström receive_ssrcs_.insert(used_ssrc); 1089d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 10904fbae2b79134572135d9d5fe35a7d1ccdeea3a4dsolenberg webrtc::VideoReceiveStream::Config config(this); 1091d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ConfigureReceiverRtp(&config, sp); 10923bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org 10938fc7fa798f7a36955f1b933980401afad2aff592pbos // Set up A/V sync group based on sync label. 10948fc7fa798f7a36955f1b933980401afad2aff592pbos config.sync_group = sp.sync_label; 10953bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org 1096102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg config.rtp.remb = send_codec_ ? HasRemb(send_codec_->codec) : false; 109743edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan config.rtp.transport_cc = 109843edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan send_codec_ ? HasTransportCc(send_codec_->codec) : false; 1099126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström 1100d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström receive_streams_[ssrc] = new WebRtcVideoReceiveStream( 1101709ed67c38d0a942f3bf3e68e337cc27a27bc353Fredrik Solenberg call_, sp, config, external_decoder_factory_, default_stream, 1102444682acf9804c5fcbddaded9e900ba3cc6921fcqiangchen recv_codecs_, options_.disable_prerenderer_smoothing.value_or(false)); 1103d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1104d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return true; 1105d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1106d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1107d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::ConfigureReceiverRtp( 1108d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org webrtc::VideoReceiveStream::Config* config, 1109d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const StreamParams& sp) const { 11100c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint32_t ssrc = sp.first_ssrc(); 1111d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1112d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.remote_ssrc = ssrc; 1113d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.local_ssrc = rtcp_receiver_report_ssrc_; 1114b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1115d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.extensions = recv_rtp_extensions_; 11161387149ad1669365ac05278bf779a407bec08a4edeadbeef config->rtp.rtcp_mode = recv_params_.rtcp.reduced_size 11171387149ad1669365ac05278bf779a407bec08a4edeadbeef ? webrtc::RtcpMode::kReducedSize 11181387149ad1669365ac05278bf779a407bec08a4edeadbeef : webrtc::RtcpMode::kCompound; 1119257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org 1120b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): This protection is against setting the same local ssrc as 1121b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // remote which is not permitted by the lower-level API. RTCP requires a 1122b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // corresponding sender SSRC. Figure out what to do when we don't have 1123b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // (receive-only) or know a good local SSRC. 1124d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (config->rtp.remote_ssrc == config->rtp.local_ssrc) { 1125d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (config->rtp.local_ssrc != kDefaultRtcpReceiverReportSsrc) { 1126d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc; 1127b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 1128d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc + 1; 1129b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1130b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1131b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1132d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (size_t i = 0; i < recv_codecs_.size(); ++i) { 113382775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org MergeFecConfig(recv_codecs_[i].fec, &config->rtp.fec); 1134b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1135b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 113682775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org for (size_t i = 0; i < recv_codecs_.size(); ++i) { 11370c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint32_t rtx_ssrc; 113882775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org if (recv_codecs_[i].rtx_payload_type != -1 && 113982775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org sp.GetFidSsrc(ssrc, &rtx_ssrc)) { 114082775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org webrtc::VideoReceiveStream::Config::Rtp::Rtx& rtx = 114182775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org config->rtp.rtx[recv_codecs_[i].codec.id]; 114282775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org rtx.ssrc = rtx_ssrc; 114382775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org rtx.payload_type = recv_codecs_[i].rtx_payload_type; 114482775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 114582775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 1146b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1147b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 11480c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmbool WebRtcVideoChannel2::RemoveRecvStream(uint32_t ssrc) { 1149b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; 1150b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1151afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_ERROR) << "RemoveRecvStream with 0 ssrc is not supported."; 1152afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return false; 1153b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1154b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1155575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 11560c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström std::map<uint32_t, WebRtcVideoReceiveStream*>::iterator stream = 1157b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_streams_.find(ssrc); 1158b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (stream == receive_streams_.end()) { 1159b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Stream not found for ssrc: " << ssrc; 1160b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1161b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1162d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström DeleteReceiveStream(stream->second); 1163b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_streams_.erase(stream); 1164b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1165b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1166b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1167b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 11680c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmbool WebRtcVideoChannel2::SetRenderer(uint32_t ssrc, VideoRenderer* renderer) { 1169b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetRenderer: ssrc:" << ssrc << " " 1170b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (renderer ? "(ptr)" : "NULL"); 1171b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1172afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org default_unsignalled_ssrc_handler_.SetDefaultRenderer(this, renderer); 1173d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return true; 1174b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1175b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1176575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 11770c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström std::map<uint32_t, WebRtcVideoReceiveStream*>::iterator it = 1178d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.find(ssrc); 1179d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (it == receive_streams_.end()) { 1180d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return false; 1181b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1182b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1183b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->SetRenderer(renderer); 1184b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1185b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1186b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 11870c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmbool WebRtcVideoChannel2::GetRenderer(uint32_t ssrc, VideoRenderer** renderer) { 1188b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1189afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org *renderer = default_unsignalled_ssrc_handler_.GetDefaultRenderer(); 1190afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return *renderer != NULL; 1191b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1192b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1193575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 11940c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström std::map<uint32_t, WebRtcVideoReceiveStream*>::iterator it = 1195d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.find(ssrc); 1196d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (it == receive_streams_.end()) { 1197b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1198b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1199b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *renderer = it->second->GetRenderer(); 1200b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1201b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1202b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1203058b1f17ac43b1fe69a8c18aaa7999ba88733dfdpbos@webrtc.orgbool WebRtcVideoChannel2::GetStats(VideoMediaInfo* info) { 1204e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info->Clear(); 1205e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org FillSenderStats(info); 1206e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org FillReceiverStats(info); 12072b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org webrtc::Call::Stats stats = call_->GetStats(); 12082b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org FillBandwidthEstimationStats(stats, info); 12092b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org if (stats.rtt_ms != -1) { 12102b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org for (size_t i = 0; i < info->senders.size(); ++i) { 12112b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org info->senders[i].rtt_ms = stats.rtt_ms; 12122b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org } 12132b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org } 1214b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1215b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1216b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1217e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgvoid WebRtcVideoChannel2::FillSenderStats(VideoMediaInfo* video_media_info) { 1218575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 12190c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström for (std::map<uint32_t, WebRtcVideoSendStream*>::iterator it = 1220e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org send_streams_.begin(); 12210c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström it != send_streams_.end(); ++it) { 1222e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org video_media_info->senders.push_back(it->second->GetVideoSenderInfo()); 1223e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1224e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1225e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1226e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgvoid WebRtcVideoChannel2::FillReceiverStats(VideoMediaInfo* video_media_info) { 1227575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 12280c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström for (std::map<uint32_t, WebRtcVideoReceiveStream*>::iterator it = 1229e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org receive_streams_.begin(); 12300c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström it != receive_streams_.end(); ++it) { 1231e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org video_media_info->receivers.push_back(it->second->GetVideoReceiverInfo()); 1232e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1233e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1234e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1235e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgvoid WebRtcVideoChannel2::FillBandwidthEstimationStats( 12362b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org const webrtc::Call::Stats& stats, 1237e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoMediaInfo* video_media_info) { 12380bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org BandwidthEstimationInfo bwe_info; 12390bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org bwe_info.available_send_bandwidth = stats.send_bandwidth_bps; 12400bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org bwe_info.available_recv_bandwidth = stats.recv_bandwidth_bps; 12410bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org bwe_info.bucket_delay = stats.pacer_delay_ms; 12420bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org 12430bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org // Get send stream bitrate stats. 12440bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 12450c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström for (std::map<uint32_t, WebRtcVideoSendStream*>::iterator stream = 12460bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org send_streams_.begin(); 12470c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström stream != send_streams_.end(); ++stream) { 12480bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org stream->second->FillBandwidthEstimationInfo(&bwe_info); 12490bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org } 12500bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org video_media_info->bw_estimations.push_back(bwe_info); 1251e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1252e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 12530c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmbool WebRtcVideoChannel2::SetCapturer(uint32_t ssrc, VideoCapturer* capturer) { 1254b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetCapturer: " << ssrc << " -> " 1255b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (capturer != NULL ? "(capturer)" : "NULL"); 125691d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(ssrc != 0); 1257e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström { 1258e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström rtc::CritScope stream_lock(&stream_crit_); 1259e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström if (send_streams_.find(ssrc) == send_streams_.end()) { 1260e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström LOG(LS_ERROR) << "No sending stream on ssrc " << ssrc; 1261e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström return false; 1262e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström } 1263e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström if (!send_streams_[ssrc]->SetCapturer(capturer)) { 1264e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström return false; 1265e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström } 126664c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh } 126764c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh 126864c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh if (capturer) { 126964c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh capturer->SetApplyRotation( 127064c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh !FindHeaderExtension(send_rtp_extensions_, 127164c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh kRtpVideoRotationHeaderExtension)); 127264c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh } 1273e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström { 1274e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström rtc::CritScope lock(&capturer_crit_); 1275e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström capturers_[ssrc] = capturer; 1276e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström } 127764c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh return true; 1278b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1279b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1280b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendIntraFrame() { 1281b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1282b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SendIntraFrame()."; 1283b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1284b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1285b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1286b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::RequestIntraFrame() { 1287b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1288b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SendIntraFrame()."; 1289b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1290b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1291b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1292b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnPacketReceived( 1293d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer* packet, 1294d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org const rtc::PacketTime& packet_time) { 129568786d20400f1f3744ad83549325665c18ea9e5bstefan const webrtc::PacketTime webrtc_packet_time(packet_time.timestamp, 129668786d20400f1f3744ad83549325665c18ea9e5bstefan packet_time.not_before); 12974e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org const webrtc::PacketReceiver::DeliveryStatus delivery_result = 129868786d20400f1f3744ad83549325665c18ea9e5bstefan call_->Receiver()->DeliverPacket( 129968786d20400f1f3744ad83549325665c18ea9e5bstefan webrtc::MediaType::VIDEO, 130068786d20400f1f3744ad83549325665c18ea9e5bstefan reinterpret_cast<const uint8_t*>(packet->data()), packet->size(), 130168786d20400f1f3744ad83549325665c18ea9e5bstefan webrtc_packet_time); 13024e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org switch (delivery_result) { 13034e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_OK: 13044e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org return; 13054e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_PACKET_ERROR: 13064e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org return; 13074e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_UNKNOWN_SSRC: 13084e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org break; 1309b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1310b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 13110c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint32_t ssrc = 0; 1312eebcab5ce99d3e8641dd92a569916b0d24e29fcakwiberg@webrtc.org if (!GetRtpSsrc(packet->data(), packet->size(), &ssrc)) { 1313b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1314b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1315b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1316d10a68e7974a29b26d6c926e6f137255f3c173benoahric int payload_type = 0; 1317d10a68e7974a29b26d6c926e6f137255f3c173benoahric if (!GetRtpPayloadType(packet->data(), packet->size(), &payload_type)) { 1318d10a68e7974a29b26d6c926e6f137255f3c173benoahric return; 1319d10a68e7974a29b26d6c926e6f137255f3c173benoahric } 1320d10a68e7974a29b26d6c926e6f137255f3c173benoahric 1321d10a68e7974a29b26d6c926e6f137255f3c173benoahric // See if this payload_type is registered as one that usually gets its own 1322d10a68e7974a29b26d6c926e6f137255f3c173benoahric // SSRC (RTX) or at least is safe to drop either way (ULPFEC). If it is, and 1323d10a68e7974a29b26d6c926e6f137255f3c173benoahric // it wasn't handled above by DeliverPacket, that means we don't know what 1324d10a68e7974a29b26d6c926e6f137255f3c173benoahric // stream it associates with, and we shouldn't ever create an implicit channel 1325d10a68e7974a29b26d6c926e6f137255f3c173benoahric // for these. 1326d10a68e7974a29b26d6c926e6f137255f3c173benoahric for (auto& codec : recv_codecs_) { 1327d10a68e7974a29b26d6c926e6f137255f3c173benoahric if (payload_type == codec.rtx_payload_type || 1328d10a68e7974a29b26d6c926e6f137255f3c173benoahric payload_type == codec.fec.red_rtx_payload_type || 1329d10a68e7974a29b26d6c926e6f137255f3c173benoahric payload_type == codec.fec.ulpfec_payload_type) { 1330d10a68e7974a29b26d6c926e6f137255f3c173benoahric return; 1331d10a68e7974a29b26d6c926e6f137255f3c173benoahric } 1332d10a68e7974a29b26d6c926e6f137255f3c173benoahric } 1333d10a68e7974a29b26d6c926e6f137255f3c173benoahric 1334afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org switch (unsignalled_ssrc_handler_->OnUnsignalledSsrc(this, ssrc)) { 1335afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org case UnsignalledSsrcHandler::kDropPacket: 1336afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return; 1337afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org case UnsignalledSsrcHandler::kDeliverPacket: 1338afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org break; 1339afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 1340b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 134168786d20400f1f3744ad83549325665c18ea9e5bstefan if (call_->Receiver()->DeliverPacket( 134268786d20400f1f3744ad83549325665c18ea9e5bstefan webrtc::MediaType::VIDEO, 134368786d20400f1f3744ad83549325665c18ea9e5bstefan reinterpret_cast<const uint8_t*>(packet->data()), packet->size(), 134468786d20400f1f3744ad83549325665c18ea9e5bstefan webrtc_packet_time) != webrtc::PacketReceiver::DELIVERY_OK) { 1345afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_WARNING) << "Failed to deliver RTP packet on re-delivery."; 1346b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1347b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1348b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1349b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1350b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnRtcpReceived( 1351d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer* packet, 1352d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org const rtc::PacketTime& packet_time) { 135368786d20400f1f3744ad83549325665c18ea9e5bstefan const webrtc::PacketTime webrtc_packet_time(packet_time.timestamp, 135468786d20400f1f3744ad83549325665c18ea9e5bstefan packet_time.not_before); 13552aff615bd7c7c24a6e7a35163112f169ff4f9246Peter Boström // TODO(pbos): Check webrtc::PacketReceiver::DELIVERY_OK once we deliver 13562aff615bd7c7c24a6e7a35163112f169ff4f9246Peter Boström // for both audio and video on the same path. Since BundleFilter doesn't 13572aff615bd7c7c24a6e7a35163112f169ff4f9246Peter Boström // filter RTCP anymore incoming RTCP packets could've been going to audio (so 13582aff615bd7c7c24a6e7a35163112f169ff4f9246Peter Boström // logging failures spam the log). 13592aff615bd7c7c24a6e7a35163112f169ff4f9246Peter Boström call_->Receiver()->DeliverPacket( 13602aff615bd7c7c24a6e7a35163112f169ff4f9246Peter Boström webrtc::MediaType::VIDEO, 13612aff615bd7c7c24a6e7a35163112f169ff4f9246Peter Boström reinterpret_cast<const uint8_t*>(packet->data()), packet->size(), 13622aff615bd7c7c24a6e7a35163112f169ff4f9246Peter Boström webrtc_packet_time); 1363b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1364b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1365b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnReadyToSend(bool ready) { 136626c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org LOG(LS_VERBOSE) << "OnReadyToSend: " << (ready ? "Ready." : "Not ready."); 1367cd6702282a49448adda470934f4bd9e6181cab22Jelena Marusic call_->SignalNetworkState(ready ? webrtc::kNetworkUp : webrtc::kNetworkDown); 1368b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1369b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 13700c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmbool WebRtcVideoChannel2::MuteStream(uint32_t ssrc, bool mute) { 1371b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "MuteStream: " << ssrc << " -> " 1372b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (mute ? "mute" : "unmute"); 137391d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(ssrc != 0); 1374575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1375b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 1376b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No sending stream on ssrc " << ssrc; 1377b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1378b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1379ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.org 1380ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.org send_streams_[ssrc]->MuteStream(mute); 1381ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.org return true; 1382b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1383b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1384b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRecvRtpHeaderExtensions( 1385b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 138650fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetRecvRtpHeaderExtensions"); 13877e4e01a4413fa98644b94ab9d8a9dccc664f39f2solenberg if (!ValidateRtpExtensions(extensions)) { 13883c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return false; 13897e4e01a4413fa98644b94ab9d8a9dccc664f39f2solenberg } 13907e4e01a4413fa98644b94ab9d8a9dccc664f39f2solenberg std::vector<webrtc::RtpExtension> filtered_extensions = FilterRtpExtensions( 13917e4e01a4413fa98644b94ab9d8a9dccc664f39f2solenberg extensions, webrtc::RtpExtension::IsSupportedForVideo, false); 13927e4e01a4413fa98644b94ab9d8a9dccc664f39f2solenberg if (recv_rtp_extensions_ == filtered_extensions) { 1393874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "Ignoring call to SetRecvRtpHeaderExtensions because " 1394874ca3af5b163e1b3fd8802171e44ee252557842deadbeef "header extensions haven't changed."; 1395c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return true; 1396874ca3af5b163e1b3fd8802171e44ee252557842deadbeef } 13977e4e01a4413fa98644b94ab9d8a9dccc664f39f2solenberg recv_rtp_extensions_.swap(filtered_extensions); 1398c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org 1399575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 14000c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström for (std::map<uint32_t, WebRtcVideoReceiveStream*>::iterator it = 1401d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.begin(); 14020c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström it != receive_streams_.end(); ++it) { 1403d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetRtpExtensions(recv_rtp_extensions_); 1404d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1405b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1406b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1407b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1408b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendRtpHeaderExtensions( 1409b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 141050fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetSendRtpHeaderExtensions"); 14117e4e01a4413fa98644b94ab9d8a9dccc664f39f2solenberg if (!ValidateRtpExtensions(extensions)) { 14123c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return false; 14137e4e01a4413fa98644b94ab9d8a9dccc664f39f2solenberg } 14147e4e01a4413fa98644b94ab9d8a9dccc664f39f2solenberg std::vector<webrtc::RtpExtension> filtered_extensions = FilterRtpExtensions( 14157e4e01a4413fa98644b94ab9d8a9dccc664f39f2solenberg extensions, webrtc::RtpExtension::IsSupportedForVideo, true); 14167e4e01a4413fa98644b94ab9d8a9dccc664f39f2solenberg if (send_rtp_extensions_ == filtered_extensions) { 14177e4e01a4413fa98644b94ab9d8a9dccc664f39f2solenberg LOG(LS_INFO) << "Ignoring call to SetRecvRtpHeaderExtensions because " 1418874ca3af5b163e1b3fd8802171e44ee252557842deadbeef "header extensions haven't changed."; 1419c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return true; 1420874ca3af5b163e1b3fd8802171e44ee252557842deadbeef } 14217e4e01a4413fa98644b94ab9d8a9dccc664f39f2solenberg send_rtp_extensions_.swap(filtered_extensions); 1422a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 142364c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh const webrtc::RtpExtension* cvo_extension = FindHeaderExtension( 142464c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh send_rtp_extensions_, kRtpVideoRotationHeaderExtension); 142564c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh 1426575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 14270c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström for (std::map<uint32_t, WebRtcVideoSendStream*>::iterator it = 1428d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org send_streams_.begin(); 14290c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström it != send_streams_.end(); ++it) { 1430d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetRtpExtensions(send_rtp_extensions_); 143164c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh it->second->SetApplyRotation(!cvo_extension); 1432d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1433b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1434b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1435b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1436dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström// Counter-intuitively this method doesn't only set global bitrate caps but also 1437dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström// per-stream codec max bitrates. This is to permit SetMaxSendBitrate (b=AS) to 1438dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström// raise bitrates above the 2000k default bitrate cap. 1439008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.orgbool WebRtcVideoChannel2::SetMaxSendBandwidth(int max_bitrate_bps) { 1440dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström // TODO(pbos): Figure out whether b=AS means max bitrate for this 1441dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström // WebRtcVideoChannel2 (in which case we're good), or per sender (SSRC), in 1442dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström // which case this should not set a Call::BitrateConfig but rather reconfigure 1443dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström // all senders. 1444008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org LOG(LS_INFO) << "SetMaxSendBandwidth: " << max_bitrate_bps << "bps."; 1445dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström if (max_bitrate_bps == bitrate_config_.max_bitrate_bps) 1446dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström return true; 1447dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström 1448b071a19019a0a2173cc139c960d6ef6946a1c581Fredrik Solenberg if (max_bitrate_bps < 0) { 1449b071a19019a0a2173cc139c960d6ef6946a1c581Fredrik Solenberg // Option not set. 1450b071a19019a0a2173cc139c960d6ef6946a1c581Fredrik Solenberg return true; 1451b071a19019a0a2173cc139c960d6ef6946a1c581Fredrik Solenberg } 1452b071a19019a0a2173cc139c960d6ef6946a1c581Fredrik Solenberg if (max_bitrate_bps == 0) { 1453008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org // Unsetting max bitrate. 1454008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org max_bitrate_bps = -1; 1455008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } 1456008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.start_bitrate_bps = -1; 1457008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.max_bitrate_bps = max_bitrate_bps; 1458008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org if (max_bitrate_bps > 0 && 1459008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.min_bitrate_bps > max_bitrate_bps) { 1460008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.min_bitrate_bps = max_bitrate_bps; 1461008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } 1462008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org call_->SetBitrateConfig(bitrate_config_); 1463dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström rtc::CritScope stream_lock(&stream_crit_); 1464dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström for (auto& kv : send_streams_) 1465dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström kv.second->SetMaxBitrateBps(max_bitrate_bps); 1466b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1467b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1468b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1469b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetOptions(const VideoOptions& options) { 147050fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetOptions"); 1471a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org LOG(LS_INFO) << "SetOptions: " << options.ToString(); 1472a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org VideoOptions old_options = options_; 1473b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org options_.SetAll(options); 1474a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (options_ == old_options) { 1475a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org // No new options to set. 1476a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org return true; 1477a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } 1478e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström { 1479e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström rtc::CritScope lock(&capturer_crit_); 1480102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg if (options_.cpu_overuse_detection) 1481102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg signal_cpu_adaptation_ = *options_.cpu_overuse_detection; 1482e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström } 1483102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg rtc::DiffServCodePoint dscp = 1484102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg options_.dscp.value_or(false) ? rtc::DSCP_AF41 : rtc::DSCP_DEFAULT; 1485d819803d4570564a9800a7dd54f4593e6e21a6e7pbos@webrtc.org MediaChannel::SetDscp(dscp); 1486575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 14870c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström for (std::map<uint32_t, WebRtcVideoSendStream*>::iterator it = 14885301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org send_streams_.begin(); 14890c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström it != send_streams_.end(); ++it) { 14905301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org it->second->SetOptions(options_); 14915301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1492b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1493b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1494b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1495b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::SetInterface(NetworkInterface* iface) { 1496b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org MediaChannel::SetInterface(iface); 1497b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Set the RTP recv/send buffer to a bigger size 1498b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org MediaChannel::SetOption(NetworkInterface::ST_RTP, 1499d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Socket::OPT_RCVBUF, 1500b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org kVideoRtpBufferSize); 1501b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1502ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org // Speculative change to increase the outbound socket buffer size. 1503ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org // In b/15152257, we are seeing a significant number of packets discarded 1504ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org // due to lack of socket buffer space, although it's not yet clear what the 1505ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org // ideal value should be. 1506ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org MediaChannel::SetOption(NetworkInterface::ST_RTP, 1507ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org rtc::Socket::OPT_SNDBUF, 1508ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org kVideoRtpBufferSize); 1509b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1510b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1511b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::UpdateAspectRatio(int ratio_w, int ratio_h) { 1512b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1513b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1514b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1515d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.orgvoid WebRtcVideoChannel2::OnMessage(rtc::Message* msg) { 1516b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Ignored. 1517b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1518b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 151942684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.orgvoid WebRtcVideoChannel2::OnLoadUpdate(Load load) { 1520e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström // OnLoadUpdate can not take any locks that are held while creating streams 1521e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström // etc. Doing so establishes lock-order inversions between the webrtc process 1522e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström // thread on stream creation and locks such as stream_crit_ while calling out. 1523e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström rtc::CritScope stream_lock(&capturer_crit_); 1524e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström if (!signal_cpu_adaptation_) 1525e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström return; 1526efbde3775b5eed8015d7e2e86ddcea3e6033d321Erik SprÃ¥ng // Do not adapt resolution for screen content as this will likely result in 1527efbde3775b5eed8015d7e2e86ddcea3e6033d321Erik SprÃ¥ng // blurry and unreadable text. 1528e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström for (auto& kv : capturers_) { 1529efbde3775b5eed8015d7e2e86ddcea3e6033d321Erik SprÃ¥ng if (kv.second != nullptr 1530efbde3775b5eed8015d7e2e86ddcea3e6033d321Erik SprÃ¥ng && !kv.second->IsScreencast() 1531efbde3775b5eed8015d7e2e86ddcea3e6033d321Erik SprÃ¥ng && kv.second->video_adapter() != nullptr) { 1532e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström kv.second->video_adapter()->OnCpuResolutionRequest( 1533e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström load == kOveruse ? CoordinatedVideoAdapter::DOWNGRADE 1534e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström : CoordinatedVideoAdapter::UPGRADE); 1535e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström } 153642684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org } 153742684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org} 153842684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org 15391d8a506405734d0cef9653704b036ca4f1388960stefanbool WebRtcVideoChannel2::SendRtp(const uint8_t* data, 15401d8a506405734d0cef9653704b036ca4f1388960stefan size_t len, 15411d8a506405734d0cef9653704b036ca4f1388960stefan const webrtc::PacketOptions& options) { 1542d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer packet(data, len, kMaxRtpPacketLen); 1543c1aeaf0dc37d96f31c92f893f4e30e7a5f7cc2b7stefan rtc::PacketOptions rtc_options; 1544c1aeaf0dc37d96f31c92f893f4e30e7a5f7cc2b7stefan rtc_options.packet_id = options.packet_id; 1545c1aeaf0dc37d96f31c92f893f4e30e7a5f7cc2b7stefan return MediaChannel::SendPacket(&packet, rtc_options); 1546b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1547b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1548b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendRtcp(const uint8_t* data, size_t len) { 1549d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer packet(data, len, kMaxRtpPacketLen); 1550c1aeaf0dc37d96f31c92f893f4e30e7a5f7cc2b7stefan return MediaChannel::SendRtcp(&packet, rtc::PacketOptions()); 1551b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1552b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1553b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::StartAllSendStreams() { 1554575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 15550c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström for (std::map<uint32_t, WebRtcVideoSendStream*>::iterator it = 1556b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.begin(); 15570c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström it != send_streams_.end(); ++it) { 1558b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->Start(); 1559b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1560b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1561b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1562b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::StopAllSendStreams() { 1563575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 15640c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström for (std::map<uint32_t, WebRtcVideoSendStream*>::iterator it = 1565b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.begin(); 15660c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström it != send_streams_.end(); ++it) { 1567b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->Stop(); 1568b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1569b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1570b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 15716ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::VideoSendStreamParameters:: 15726ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org VideoSendStreamParameters( 15736ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const webrtc::VideoSendStream::Config& config, 15746ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const VideoOptions& options, 1575dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström int max_bitrate_bps, 1576be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg const rtc::Optional<VideoCodecSettings>& codec_settings) 1577dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström : config(config), 1578dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström options(options), 1579dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström max_bitrate_bps(max_bitrate_bps), 1580102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg codec_settings(codec_settings) {} 15816ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 15824d71edef45afa38b3f68b6af0519ac0f21d327dfPeter BoströmWebRtcVideoChannel2::WebRtcVideoSendStream::AllocatedEncoder::AllocatedEncoder( 15834d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström webrtc::VideoEncoder* encoder, 15844d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström webrtc::VideoCodecType type, 15854d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström bool external) 15864d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström : encoder(encoder), 15874d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström external_encoder(nullptr), 15884d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström type(type), 15894d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström external(external) { 15904d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström if (external) { 15914d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström external_encoder = encoder; 15924d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström this->encoder = 15934d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström new webrtc::VideoEncoderSoftwareFallbackWrapper(type, encoder); 15944d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström } 15954d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström} 15964d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström 1597b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::WebRtcVideoSendStream( 1598b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::Call* call, 15994fbae2b79134572135d9d5fe35a7d1ccdeea3a4dsolenberg const StreamParams& sp, 16004fbae2b79134572135d9d5fe35a7d1ccdeea3a4dsolenberg const webrtc::VideoSendStream::Config& config, 16017fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org WebRtcVideoEncoderFactory* external_encoder_factory, 16026ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const VideoOptions& options, 1603dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström int max_bitrate_bps, 1604be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg const rtc::Optional<VideoCodecSettings>& codec_settings, 16051387149ad1669365ac05278bf779a407bec08a4edeadbeef const std::vector<webrtc::RtpExtension>& rtp_extensions, 16061387149ad1669365ac05278bf779a407bec08a4edeadbeef // TODO(deadbeef): Don't duplicate information between send_params, 16071387149ad1669365ac05278bf779a407bec08a4edeadbeef // rtp_extensions, options, etc. 16081387149ad1669365ac05278bf779a407bec08a4edeadbeef const VideoSendParameters& send_params) 16097c027b64ae53a29bc528b4241cc540694c239304Henrik Kjellander : ssrcs_(sp.ssrcs), 1610259bd2034c3d3ee7f2dc4d481e9bf896a3a4d6efPeter Boström ssrc_groups_(sp.ssrc_groups), 16117c027b64ae53a29bc528b4241cc540694c239304Henrik Kjellander call_(call), 16127fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_(external_encoder_factory), 1613b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_(NULL), 16144fbae2b79134572135d9d5fe35a7d1ccdeea3a4dsolenberg parameters_(config, options, max_bitrate_bps, codec_settings), 16157fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org allocated_encoder_(NULL, webrtc::kVideoCodecUnknown, false), 1616b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org capturer_(NULL), 1617b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_(false), 16189a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org muted_(false), 1619c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen old_adapt_changes_(0), 1620c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen first_frame_timestamp_ms_(0), 1621c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen last_frame_timestamp_ms_(0) { 16225301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.max_packet_size = kVideoMtu; 16235301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 16245301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetPrimarySsrcs(¶meters_.config.rtp.ssrcs); 16255301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetFidSsrcs(parameters_.config.rtp.ssrcs, 16265301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org ¶meters_.config.rtp.rtx.ssrcs); 16275301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.c_name = sp.cname; 16285301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.extensions = rtp_extensions; 16291387149ad1669365ac05278bf779a407bec08a4edeadbeef parameters_.config.rtp.rtcp_mode = send_params.rtcp.reduced_size 16301387149ad1669365ac05278bf779a407bec08a4edeadbeef ? webrtc::RtcpMode::kReducedSize 16311387149ad1669365ac05278bf779a407bec08a4edeadbeef : webrtc::RtcpMode::kCompound; 16325301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 1633102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg if (codec_settings) { 1634102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg SetCodec(*codec_settings); 16355301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1636b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1637b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1638b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::~WebRtcVideoSendStream() { 1639b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org DisconnectCapturer(); 16405301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (stream_ != NULL) { 16415301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org call_->DestroyVideoSendStream(stream_); 16425301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 16437fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org DestroyVideoEncoder(&allocated_encoder_); 1644b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1645b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 16464765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchezstatic void CreateBlackFrame(webrtc::VideoFrame* video_frame, 1647b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int width, 1648b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int height) { 1649b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org video_frame->CreateEmptyFrame(width, height, width, (width + 1) / 2, 1650b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org (width + 1) / 2); 1651b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org memset(video_frame->buffer(webrtc::kYPlane), 16, 1652b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org video_frame->allocated_size(webrtc::kYPlane)); 1653b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org memset(video_frame->buffer(webrtc::kUPlane), 128, 1654b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org video_frame->allocated_size(webrtc::kUPlane)); 1655b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org memset(video_frame->buffer(webrtc::kVPlane), 128, 1656b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org video_frame->allocated_size(webrtc::kVPlane)); 1657b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1658b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1659b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::InputFrame( 1660b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCapturer* capturer, 1661b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFrame* frame) { 166286196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::InputFrame"); 16634765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez webrtc::VideoFrame video_frame(frame->GetVideoFrameBuffer(), 0, 0, 16644765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez frame->GetVideoRotation()); 1665d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 16665301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (stream_ == NULL) { 1667ad1f9b61a3107ca27ee023990dc576abc38f05acPeter Boström // Frame input before send codecs are configured, dropping frame. 16685301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org return; 16695301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 167086196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org 167186196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org // Not sending, abort early to prevent expensive reconfigurations while 167286196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org // setting up codecs etc. 167386196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org if (!sending_) 167486196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org return; 167586196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org 1676b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (format_.width == 0) { // Dropping frames. 167791d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(format_.height == 0); 1678b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "VideoFormat 0x0 set, Dropping frame."; 1679b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1680b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1681d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org if (muted_) { 1682d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org // Create a black frame to transmit instead. 1683afdd5dd372d69be7244a3d90d70de9d5ecd60eb9magjed@webrtc.org CreateBlackFrame(&video_frame, 1684d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org static_cast<int>(frame->GetWidth()), 1685d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org static_cast<int>(frame->GetHeight())); 1686d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org } 1687c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen 1688c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen int64_t frame_delta_ms = frame->GetTimeStamp() / rtc::kNumNanosecsPerMillisec; 1689c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen // frame->GetTimeStamp() is essentially a delta, align to webrtc time 1690c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen if (first_frame_timestamp_ms_ == 0) { 1691c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen first_frame_timestamp_ms_ = rtc::Time() - frame_delta_ms; 1692c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen } 1693c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen 1694c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen last_frame_timestamp_ms_ = first_frame_timestamp_ms_ + frame_delta_ms; 1695c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen video_frame.set_render_time_ms(last_frame_timestamp_ms_); 1696b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Reconfigure codec if necessary. 1697c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org SetDimensions( 1698afdd5dd372d69be7244a3d90d70de9d5ecd60eb9magjed@webrtc.org video_frame.width(), video_frame.height(), capturer->IsScreencast()); 1699c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org 1700af612d5e0769571544952cbe55e675748afa9bddperkj@webrtc.org stream_->Input()->IncomingCapturedFrame(video_frame); 1701b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1702b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1703b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::SetCapturer( 1704b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCapturer* capturer) { 1705b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::SetCapturer"); 1706b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!DisconnectCapturer() && capturer == NULL) { 1707b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1708b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1709b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1710b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org { 1711d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1712b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 17131cb121dea478a4bb4f88e76cf92719e2853543cfpbos // Reset timestamps to realign new incoming frames to a webrtc timestamp. A 17141cb121dea478a4bb4f88e76cf92719e2853543cfpbos // new capturer may have a different timestamp delta than the previous one. 17151cb121dea478a4bb4f88e76cf92719e2853543cfpbos first_frame_timestamp_ms_ = 0; 17161cb121dea478a4bb4f88e76cf92719e2853543cfpbos 17179359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org if (capturer == NULL) { 17189359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org if (stream_ != NULL) { 17199359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org LOG(LS_VERBOSE) << "Disabling capturer, sending black frame."; 17204765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez webrtc::VideoFrame black_frame; 17219359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org 1722b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org CreateBlackFrame(&black_frame, last_dimensions_.width, 1723b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org last_dimensions_.height); 1724c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen 1725c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen // Force this black frame not to be dropped due to timestamp order 1726c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen // check. As IncomingCapturedFrame will drop the frame if this frame's 1727c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen // timestamp is less than or equal to last frame's timestamp, it is 1728c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen // necessary to give this black frame a larger timestamp than the 1729c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen // previous one. 1730c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen last_frame_timestamp_ms_ += 1731c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen format_.interval / rtc::kNumNanosecsPerMillisec; 1732c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen black_frame.set_render_time_ms(last_frame_timestamp_ms_); 1733af612d5e0769571544952cbe55e675748afa9bddperkj@webrtc.org stream_->Input()->IncomingCapturedFrame(black_frame); 17349359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org } 1735b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1736b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_ = NULL; 1737b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1738b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1739b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1740b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_ = capturer; 1741b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1742b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Lock cannot be held while connecting the capturer to prevent lock-order 1743b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // violations. 1744b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer->SignalVideoFrame.connect(this, &WebRtcVideoSendStream::InputFrame); 1745b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1746b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1747b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1748b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::SetVideoFormat( 1749b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFormat& format) { 1750b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if ((format.width == 0 || format.height == 0) && 1751b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org format.width != format.height) { 1752b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Can't set VideoFormat, width or height is zero (but not " 1753b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org "both, 0x0 drops frames)."; 1754b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1755b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1756b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1757d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1758b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (format.width == 0 && format.height == 0) { 1759b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) 1760b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << "0x0 resolution selected. Captured frames will be dropped for ssrc: " 17616ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org << parameters_.config.rtp.ssrcs[0] << "."; 1762b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 1763b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Fix me, this only affects the last stream! 1764bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config.streams.back().max_framerate = 1765b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoFormat::IntervalToFps(format.interval); 1766c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org SetDimensions(format.width, format.height, false); 1767b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1768b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1769b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org format_ = format; 1770b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1771b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1772b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1773ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::MuteStream(bool mute) { 1774d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1775b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org muted_ = mute; 1776b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1777b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1778b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::DisconnectCapturer() { 1779963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org cricket::VideoCapturer* capturer; 1780963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org { 1781963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org rtc::CritScope cs(&lock_); 17829a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (capturer_ == NULL) 1783963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org return false; 17849a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org 17859a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (capturer_->video_adapter() != nullptr) 17869a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org old_adapt_changes_ += capturer_->video_adapter()->adaptation_changes(); 17879a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org 1788963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org capturer = capturer_; 1789963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org capturer_ = NULL; 1790b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1791963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org capturer->SignalVideoFrame.disconnect(this); 1792b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1793b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1794b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 17950c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmconst std::vector<uint32_t>& 1796d6f4c25eedcfd502920f1b2a24744badd9da80bePeter BoströmWebRtcVideoChannel2::WebRtcVideoSendStream::GetSsrcs() const { 1797d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström return ssrcs_; 1798d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström} 1799d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 180064c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shiehvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetApplyRotation( 180164c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh bool apply_rotation) { 180264c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh rtc::CritScope cs(&lock_); 180364c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh if (capturer_ == NULL) 180464c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh return; 180564c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh 180664c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh capturer_->SetApplyRotation(apply_rotation); 180764c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh} 180864c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh 18095301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetOptions( 18105301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoOptions& options) { 1811d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1812102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg if (parameters_.codec_settings) { 1813874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "SetCodecAndOptions because of SetOptions; options=" 1814874ca3af5b163e1b3fd8802171e44ee252557842deadbeef << options.ToString(); 1815102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg SetCodecAndOptions(*parameters_.codec_settings, options); 18165301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } else { 18175301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.options = options; 18185301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 18195301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org} 18207fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 1821b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodec( 18225301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoCodecSettings& codec_settings) { 1823d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1824874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "SetCodecAndOptions because of SetCodec."; 18255301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org SetCodecAndOptions(codec_settings, parameters_.options); 18265301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org} 18277fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 18287fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgwebrtc::VideoCodecType CodecTypeFromName(const std::string& name) { 1829e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (CodecNamesEq(name, kVp8CodecName)) { 18307fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return webrtc::kVideoCodecVP8; 1831e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin } else if (CodecNamesEq(name, kVp9CodecName)) { 1832188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org return webrtc::kVideoCodecVP9; 1833e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin } else if (CodecNamesEq(name, kH264CodecName)) { 18347fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return webrtc::kVideoCodecH264; 18357fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 18367fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return webrtc::kVideoCodecUnknown; 18377fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 18387fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 18397fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::AllocatedEncoder 18407fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoder( 18417fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org const VideoCodec& codec) { 18427fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org webrtc::VideoCodecType type = CodecTypeFromName(codec.name); 18437fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 18447fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org // Do not re-create encoders of the same type. 18457fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (type == allocated_encoder_.type && allocated_encoder_.encoder != NULL) { 18467fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return allocated_encoder_; 18477fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 18487fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 18497fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (external_encoder_factory_ != NULL) { 18507fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org webrtc::VideoEncoder* encoder = 18517fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_->CreateVideoEncoder(type); 18527fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (encoder != NULL) { 18537fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return AllocatedEncoder(encoder, type, true); 18547fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 18557fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 18567fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 18577fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (type == webrtc::kVideoCodecVP8) { 18587fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return AllocatedEncoder( 18597fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org webrtc::VideoEncoder::Create(webrtc::VideoEncoder::kVp8), type, false); 1860188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org } else if (type == webrtc::kVideoCodecVP9) { 1861188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org return AllocatedEncoder( 1862188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org webrtc::VideoEncoder::Create(webrtc::VideoEncoder::kVp9), type, false); 186371f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin } else if (type == webrtc::kVideoCodecH264) { 186471f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin return AllocatedEncoder( 186571f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin webrtc::VideoEncoder::Create(webrtc::VideoEncoder::kH264), type, false); 18667fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 18677fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 18687fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org // This shouldn't happen, we should not be trying to create something we don't 18697fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org // support. 187091d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(false); 18717fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return AllocatedEncoder(NULL, webrtc::kVideoCodecUnknown, false); 18727fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 18737fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 18747fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::DestroyVideoEncoder( 18757fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org AllocatedEncoder* encoder) { 18767fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (encoder->external) { 18774d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström external_encoder_factory_->DestroyVideoEncoder(encoder->external_encoder); 18787fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 18794d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström delete encoder->encoder; 18807fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 18817fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 18825301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodecAndOptions( 18835301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoCodecSettings& codec_settings, 18845301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoOptions& options) { 1885a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org parameters_.encoder_config = 1886a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org CreateVideoEncoderConfig(last_dimensions_, codec_settings.codec); 188786196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org if (parameters_.encoder_config.streams.empty()) 1888b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1889a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 18905301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org format_ = VideoFormat(codec_settings.codec.width, 18915301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org codec_settings.codec.height, 1892b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoFormat::FpsToInterval(30), 1893b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org FOURCC_I420); 18946ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 18957fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org AllocatedEncoder new_encoder = CreateVideoEncoder(codec_settings.codec); 18967fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org parameters_.config.encoder_settings.encoder = new_encoder.encoder; 18975301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.encoder_settings.payload_name = codec_settings.codec.name; 18985301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.encoder_settings.payload_type = codec_settings.codec.id; 189947d78cc8ad54baabc9042c2b848ae3afd9b80d2esophiechang if (new_encoder.external) { 190047d78cc8ad54baabc9042c2b848ae3afd9b80d2esophiechang webrtc::VideoCodecType type = CodecTypeFromName(codec_settings.codec.name); 190147d78cc8ad54baabc9042c2b848ae3afd9b80d2esophiechang parameters_.config.encoder_settings.internal_source = 190247d78cc8ad54baabc9042c2b848ae3afd9b80d2esophiechang external_encoder_factory_->EncoderTypeHasInternalSource(type); 190347d78cc8ad54baabc9042c2b848ae3afd9b80d2esophiechang } 19045301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.fec = codec_settings.fec; 19055301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 19065301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org // Set RTX payload type if RTX is enabled. 19075301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (!parameters_.config.rtp.rtx.ssrcs.empty()) { 1908b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org if (codec_settings.rtx_payload_type == -1) { 1909b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX " 1910b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org "payload type. Ignoring."; 1911b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org parameters_.config.rtp.rtx.ssrcs.clear(); 1912b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org } else { 1913b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org parameters_.config.rtp.rtx.payload_type = codec_settings.rtx_payload_type; 1914b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org } 19155301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 19165301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 191767c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström parameters_.config.rtp.nack.rtp_history_ms = 191867c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström HasNack(codec_settings.codec) ? kNackHistoryMs : 0; 19195301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 1920102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg RTC_CHECK(options.suspend_below_min_bitrate); 1921102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg parameters_.config.suspend_below_min_bitrate = 1922102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg *options.suspend_below_min_bitrate; 19235ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org 1924102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg parameters_.codec_settings = 1925be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg rtc::Optional<WebRtcVideoChannel2::VideoCodecSettings>(codec_settings); 19266ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.options = options; 1927543e589205af006f6b999a2c5df51d3fb722d925pbos@webrtc.org 1928874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) 1929874ca3af5b163e1b3fd8802171e44ee252557842deadbeef << "RecreateWebRtcStream (send) because of SetCodecAndOptions; options=" 1930874ca3af5b163e1b3fd8802171e44ee252557842deadbeef << options.ToString(); 1931b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org RecreateWebRtcStream(); 19327fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (allocated_encoder_.encoder != new_encoder.encoder) { 19337fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org DestroyVideoEncoder(&allocated_encoder_); 19347fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org allocated_encoder_ = new_encoder; 19357fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 1936b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1937b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1938d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetRtpExtensions( 1939d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<webrtc::RtpExtension>& rtp_extensions) { 1940d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1941d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org parameters_.config.rtp.extensions = rtp_extensions; 1942874ca3af5b163e1b3fd8802171e44ee252557842deadbeef if (stream_ != nullptr) { 1943874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "RecreateWebRtcStream (send) because of SetRtpExtensions"; 19443c3f6460646183914629e5dab8ae5fcede4f0e80Peter Boström RecreateWebRtcStream(); 1945874ca3af5b163e1b3fd8802171e44ee252557842deadbeef } 1946d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1947d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 19481387149ad1669365ac05278bf779a407bec08a4edeadbeefvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetSendParameters( 19491387149ad1669365ac05278bf779a407bec08a4edeadbeef const VideoSendParameters& send_params) { 19501387149ad1669365ac05278bf779a407bec08a4edeadbeef rtc::CritScope cs(&lock_); 19511387149ad1669365ac05278bf779a407bec08a4edeadbeef parameters_.config.rtp.rtcp_mode = send_params.rtcp.reduced_size 19521387149ad1669365ac05278bf779a407bec08a4edeadbeef ? webrtc::RtcpMode::kReducedSize 19531387149ad1669365ac05278bf779a407bec08a4edeadbeef : webrtc::RtcpMode::kCompound; 19541387149ad1669365ac05278bf779a407bec08a4edeadbeef if (stream_ != nullptr) { 19551387149ad1669365ac05278bf779a407bec08a4edeadbeef LOG(LS_INFO) << "RecreateWebRtcStream (send) because of SetSendParameters"; 19561387149ad1669365ac05278bf779a407bec08a4edeadbeef RecreateWebRtcStream(); 19571387149ad1669365ac05278bf779a407bec08a4edeadbeef } 19581387149ad1669365ac05278bf779a407bec08a4edeadbeef} 19591387149ad1669365ac05278bf779a407bec08a4edeadbeef 1960a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.orgwebrtc::VideoEncoderConfig 1961a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoderConfig( 1962a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org const Dimensions& dimensions, 1963a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org const VideoCodec& codec) const { 1964a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org webrtc::VideoEncoderConfig encoder_config; 1965a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (dimensions.is_screencast) { 1966102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg RTC_CHECK(parameters_.options.screencast_min_bitrate); 1967a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org encoder_config.min_transmit_bitrate_bps = 1968102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg *parameters_.options.screencast_min_bitrate * 1000; 1969143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprÃ¥ng encoder_config.content_type = 1970143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprÃ¥ng webrtc::VideoEncoderConfig::ContentType::kScreen; 1971a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } else { 1972a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org encoder_config.min_transmit_bitrate_bps = 0; 1973143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprÃ¥ng encoder_config.content_type = 1974143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprÃ¥ng webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo; 1975a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } 1976a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 1977a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org // Restrict dimensions according to codec max. 1978a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org int width = dimensions.width; 1979a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org int height = dimensions.height; 1980a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (!dimensions.is_screencast) { 1981a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (codec.width < width) 1982a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org width = codec.width; 1983a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (codec.height < height) 1984a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org height = codec.height; 1985a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } 1986a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 1987a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org VideoCodec clamped_codec = codec; 1988a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org clamped_codec.width = width; 1989a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org clamped_codec.height = height; 1990a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 1991fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric // By default, the stream count for the codec configuration should match the 1992fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric // number of negotiated ssrcs. But if the codec is blacklisted for simulcast 1993fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric // or a screencast, only configure a single stream. 1994fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric size_t stream_count = parameters_.config.rtp.ssrcs.size(); 1995fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric if (IsCodecBlacklistedForSimulcast(codec.name) || dimensions.is_screencast) { 1996fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric stream_count = 1; 1997fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric } 1998fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric 1999fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric encoder_config.streams = 2000fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric CreateVideoStreams(clamped_codec, parameters_.options, 2001fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric parameters_.max_bitrate_bps, stream_count); 2002a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 2003a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org // Conference mode screencast uses 2 temporal layers split at 100kbit. 2004102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg if (parameters_.options.conference_mode.value_or(false) && 2005a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org dimensions.is_screencast && encoder_config.streams.size() == 1) { 200646d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org ScreenshareLayerConfig config = ScreenshareLayerConfig::GetDefault(); 200746d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org 200846d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org // For screenshare in conference mode, tl0 and tl1 bitrates are piggybacked 200946d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org // on the VideoCodec struct as target and max bitrates, respectively. 201046d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org // See eg. webrtc::VP8EncoderImpl::SetRates(). 201146d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org encoder_config.streams[0].target_bitrate_bps = 201246d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org config.tl0_bitrate_kbps * 1000; 201346d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org encoder_config.streams[0].max_bitrate_bps = config.tl1_bitrate_kbps * 1000; 2014a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org encoder_config.streams[0].temporal_layer_thresholds_bps.clear(); 2015a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org encoder_config.streams[0].temporal_layer_thresholds_bps.push_back( 201646d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org config.tl0_bitrate_kbps * 1000); 2017a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } 2018a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org return encoder_config; 2019a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org} 2020a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 2021c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetDimensions( 2022c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org int width, 2023c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org int height, 2024efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org bool is_screencast) { 2025efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org if (last_dimensions_.width == width && last_dimensions_.height == height && 2026efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org last_dimensions_.is_screencast == is_screencast) { 2027efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org // Configured using the same parameters, do not reconfigure. 2028efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org return; 2029efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org } 2030a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org LOG(LS_INFO) << "SetDimensions: " << width << "x" << height 2031a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org << (is_screencast ? " (screencast)" : " (not screencast)"); 2032efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org 2033efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org last_dimensions_.width = width; 2034efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org last_dimensions_.height = height; 2035efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org last_dimensions_.is_screencast = is_screencast; 2036efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org 203791d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(!parameters_.encoder_config.streams.empty()); 2038c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org 2039102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg RTC_CHECK(parameters_.codec_settings); 2040102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg VideoCodecSettings codec_settings = *parameters_.codec_settings; 2041c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org 2042a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org webrtc::VideoEncoderConfig encoder_config = 2043a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org CreateVideoEncoderConfig(last_dimensions_, codec_settings.codec); 2044a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 2045143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprÃ¥ng encoder_config.encoder_specific_settings = ConfigureVideoEncoderSettings( 2046143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprÃ¥ng codec_settings.codec, parameters_.options, is_screencast); 20476f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 2048bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org bool stream_reconfigured = stream_->ReconfigureVideoEncoder(encoder_config); 2049bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org 2050bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org encoder_config.encoder_specific_settings = NULL; 20516f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 20526f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org if (!stream_reconfigured) { 2053b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "Failed to reconfigure video encoder for dimensions: " 2054b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << width << "x" << height; 2055b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 2056b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2057cddd17c0f89cfaa9d2f21118ae90b45dae3b4aeepbos@webrtc.org 2058bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config = encoder_config; 2059b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 2060b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2061b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::Start() { 2062d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 206391d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(stream_ != NULL); 2064b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_->Start(); 2065b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = true; 2066b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 2067b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2068b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::Stop() { 2069d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 20705301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (stream_ != NULL) { 20715301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org stream_->Stop(); 20725301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 2073b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = false; 2074b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 2075b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2076e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgVideoSenderInfo 2077e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo() { 2078e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoSenderInfo info; 207977e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org webrtc::VideoSendStream::Stats stats; 208077e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org { 208177e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org rtc::CritScope cs(&lock_); 208277e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org for (uint32_t ssrc : parameters_.config.rtp.ssrcs) 208377e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org info.add_ssrc(ssrc); 208477e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org 2085102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg if (parameters_.codec_settings) 2086102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg info.codec_name = parameters_.codec_settings->codec.name; 208777e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org for (size_t i = 0; i < parameters_.encoder_config.streams.size(); ++i) { 208877e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org if (i == parameters_.encoder_config.streams.size() - 1) { 208977e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org info.preferred_bitrate += 209077e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org parameters_.encoder_config.streams[i].max_bitrate_bps; 209177e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org } else { 209277e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org info.preferred_bitrate += 209377e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org parameters_.encoder_config.streams[i].target_bitrate_bps; 209477e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org } 209577e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org } 2096e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 209777e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org if (stream_ == NULL) 209877e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org return info; 2099c3d2bd28a3e8badc434a5081dd36f4ac41b4e3f2pbos@webrtc.org 210077e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org stats = stream_->GetStats(); 210177e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org 21029a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.adapt_changes = old_adapt_changes_; 21039a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.adapt_reason = CoordinatedVideoAdapter::ADAPTREASON_NONE; 21049a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org 21059a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (capturer_ != NULL) { 21069a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (!capturer_->IsMuted()) { 21079a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org VideoFormat last_captured_frame_format; 21089a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org capturer_->GetStats(&info.adapt_frame_drops, &info.effects_frame_drops, 21099a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org &info.capturer_frame_time, 21109a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org &last_captured_frame_format); 21119a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.input_frame_width = last_captured_frame_format.width; 21129a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.input_frame_height = last_captured_frame_format.height; 21139a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org } 21149a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (capturer_->video_adapter() != nullptr) { 21159a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.adapt_changes += capturer_->video_adapter()->adaptation_changes(); 21169a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.adapt_reason = capturer_->video_adapter()->adapt_reason(); 21179a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org } 211877e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org } 211977e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org } 212017821db19702aca15d0d93cb60515ca70823fad7asapersson 212117821db19702aca15d0d93cb60515ca70823fad7asapersson // Get bandwidth limitation info from stream_->GetStats(). 212217821db19702aca15d0d93cb60515ca70823fad7asapersson // Input resolution (output from video_adapter) can be further scaled down or 212317821db19702aca15d0d93cb60515ca70823fad7asapersson // higher video layer(s) can be dropped due to bitrate constraints. 212417821db19702aca15d0d93cb60515ca70823fad7asapersson // Note, adapt_changes only include changes from the video_adapter. 212517821db19702aca15d0d93cb60515ca70823fad7asapersson if (stats.bw_limited_resolution) 212617821db19702aca15d0d93cb60515ca70823fad7asapersson info.adapt_reason |= CoordinatedVideoAdapter::ADAPTREASON_BANDWIDTH; 212717821db19702aca15d0d93cb60515ca70823fad7asapersson 2128b7d9a97ce41022e984348efb5f28bf6dd6c6b779Peter Boström info.encoder_implementation_name = stats.encoder_implementation_name; 2129259bd2034c3d3ee7f2dc4d481e9bf896a3a4d6efPeter Boström info.ssrc_groups = ssrc_groups_; 2130e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_input = stats.input_frame_rate; 2131e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_sent = stats.encode_frame_rate; 21323e6e271ec3253e78ae0eb72156e5236d43f8731dpbos@webrtc.org info.avg_encode_ms = stats.avg_encode_time_ms; 21333e6e271ec3253e78ae0eb72156e5236d43f8731dpbos@webrtc.org info.encode_usage_percent = stats.encode_usage_percent; 2134e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 213577e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org info.nominal_bitrate = stats.media_bitrate_bps; 213677e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org 2137273a414b0ec2e58fdf3b817ad8b1a02f4ce15287pbos@webrtc.org info.send_frame_width = 0; 2138273a414b0ec2e58fdf3b817ad8b1a02f4ce15287pbos@webrtc.org info.send_frame_height = 0; 213909c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org for (std::map<uint32_t, webrtc::VideoSendStream::StreamStats>::iterator it = 2140e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org stats.substreams.begin(); 214109c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org it != stats.substreams.end(); ++it) { 2142e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Wire up additional stats, such as padding bytes. 214309c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org webrtc::VideoSendStream::StreamStats stream_stats = it->second; 2144cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org info.bytes_sent += stream_stats.rtp_stats.transmitted.payload_bytes + 2145cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org stream_stats.rtp_stats.transmitted.header_bytes + 2146cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org stream_stats.rtp_stats.transmitted.padding_bytes; 2147cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org info.packets_sent += stream_stats.rtp_stats.transmitted.packets; 2148e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.packets_lost += stream_stats.rtcp_stats.cumulative_lost; 214909c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org if (stream_stats.width > info.send_frame_width) 215009c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.send_frame_width = stream_stats.width; 215109c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org if (stream_stats.height > info.send_frame_height) 215209c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.send_frame_height = stream_stats.height; 21531d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.firs_rcvd += stream_stats.rtcp_packet_type_counts.fir_packets; 21541d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.nacks_rcvd += stream_stats.rtcp_packet_type_counts.nack_packets; 21551d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.plis_rcvd += stream_stats.rtcp_packet_type_counts.pli_packets; 2156e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 2157e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 2158e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org if (!stats.substreams.empty()) { 2159e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Report fraction lost per SSRC. 216009c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org webrtc::VideoSendStream::StreamStats first_stream_stats = 216109c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org stats.substreams.begin()->second; 2162e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.fraction_lost = 2163e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org static_cast<float>(first_stream_stats.rtcp_stats.fraction_lost) / 2164e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org (1 << 8); 2165e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 2166e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 2167e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org return info; 2168e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 2169e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 21700bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::FillBandwidthEstimationInfo( 21710bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org BandwidthEstimationInfo* bwe_info) { 21720bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org rtc::CritScope cs(&lock_); 21730bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org if (stream_ == NULL) { 21740bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org return; 21750bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org } 21760bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org webrtc::VideoSendStream::Stats stats = stream_->GetStats(); 217709c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org for (std::map<uint32_t, webrtc::VideoSendStream::StreamStats>::iterator it = 21780bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org stats.substreams.begin(); 217909c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org it != stats.substreams.end(); ++it) { 21800bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org bwe_info->transmit_bitrate += it->second.total_bitrate_bps; 21810bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org bwe_info->retransmit_bitrate += it->second.retransmit_bitrate_bps; 21820bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org } 2183891d48393e5ccd2f5e03d509c544c00a3d88cbbcpbos@webrtc.org bwe_info->target_enc_bitrate += stats.target_media_bitrate_bps; 218477e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org bwe_info->actual_enc_bitrate += stats.media_bitrate_bps; 21850bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org} 21860bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org 2187dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boströmvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetMaxBitrateBps( 2188dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström int max_bitrate_bps) { 2189dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström rtc::CritScope cs(&lock_); 2190dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström parameters_.max_bitrate_bps = max_bitrate_bps; 2191dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström 2192dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström // No need to reconfigure if the stream hasn't been configured yet. 2193dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström if (parameters_.encoder_config.streams.empty()) 2194dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström return; 2195dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström 2196dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström // Force a stream reconfigure to set the new max bitrate. 2197dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström int width = last_dimensions_.width; 2198dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström last_dimensions_.width = 0; 2199dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström SetDimensions(width, last_dimensions_.height, last_dimensions_.is_screencast); 2200dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström} 220142684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org 2202b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::RecreateWebRtcStream() { 2203b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (stream_ != NULL) { 2204b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org call_->DestroyVideoSendStream(stream_); 2205b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 22066ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 2207102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg RTC_CHECK(parameters_.codec_settings); 2208bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config.encoder_specific_settings = 2209143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprÃ¥ng ConfigureVideoEncoderSettings( 2210102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg parameters_.codec_settings->codec, parameters_.options, 2211143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprÃ¥ng parameters_.encoder_config.content_type == 2212143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprÃ¥ng webrtc::VideoEncoderConfig::ContentType::kScreen); 2213bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org 2214b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org webrtc::VideoSendStream::Config config = parameters_.config; 2215b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org if (!config.rtp.rtx.ssrcs.empty() && config.rtp.rtx.payload_type == -1) { 2216b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX " 2217b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org "payload type the set codec. Ignoring RTX."; 2218b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org config.rtp.rtx.ssrcs.clear(); 2219b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org } 2220b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org stream_ = call_->CreateVideoSendStream(config, parameters_.encoder_config); 22216f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 2222bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config.encoder_specific_settings = NULL; 22236f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 2224b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sending_) { 2225b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_->Start(); 2226b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2227b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 2228b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2229d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream( 2230d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org webrtc::Call* call, 2231259bd2034c3d3ee7f2dc4d481e9bf896a3a4d6efPeter Boström const StreamParams& sp, 22324fbae2b79134572135d9d5fe35a7d1ccdeea3a4dsolenberg const webrtc::VideoReceiveStream::Config& config, 2233776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org WebRtcVideoDecoderFactory* external_decoder_factory, 2234a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org bool default_stream, 2235444682acf9804c5fcbddaded9e900ba3cc6921fcqiangchen const std::vector<VideoCodecSettings>& recv_codecs, 2236444682acf9804c5fcbddaded9e900ba3cc6921fcqiangchen bool disable_prerenderer_smoothing) 2237d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org : call_(call), 2238259bd2034c3d3ee7f2dc4d481e9bf896a3a4d6efPeter Boström ssrcs_(sp.ssrcs), 2239259bd2034c3d3ee7f2dc4d481e9bf896a3a4d6efPeter Boström ssrc_groups_(sp.ssrc_groups), 2240d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org stream_(NULL), 2241a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org default_stream_(default_stream), 2242b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org config_(config), 2243776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org external_decoder_factory_(external_decoder_factory), 2244444682acf9804c5fcbddaded9e900ba3cc6921fcqiangchen disable_prerenderer_smoothing_(disable_prerenderer_smoothing), 2245b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org renderer_(NULL), 2246d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_width_(-1), 2247fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org last_height_(-1), 2248fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org first_frame_timestamp_(-1), 2249fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org estimated_remote_start_ntp_time_ms_(0) { 2250d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.renderer = this; 2251d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // SetRecvCodecs will also reset (start) the VideoReceiveStream. 2252874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "SetRecvCodecs (recv) because we are creating the receive " 2253874ca3af5b163e1b3fd8802171e44ee252557842deadbeef "stream for the first time: " 2254874ca3af5b163e1b3fd8802171e44ee252557842deadbeef << CodecSettingsVectorToString(recv_codecs); 2255d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetRecvCodecs(recv_codecs); 2256d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2257d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 22587252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter BoströmWebRtcVideoChannel2::WebRtcVideoReceiveStream::AllocatedDecoder:: 22597252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström AllocatedDecoder(webrtc::VideoDecoder* decoder, 22607252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström webrtc::VideoCodecType type, 22617252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström bool external) 22627252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström : decoder(decoder), 22637252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström external_decoder(nullptr), 22647252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström type(type), 22657252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström external(external) { 22667252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström if (external) { 22677252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström external_decoder = decoder; 22687252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström this->decoder = 22697252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström new webrtc::VideoDecoderSoftwareFallbackWrapper(type, external_decoder); 22707252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström } 22717252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström} 22727252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström 2273d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::~WebRtcVideoReceiveStream() { 2274d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org call_->DestroyVideoReceiveStream(stream_); 227596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org ClearDecoders(&allocated_decoders_); 2276d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2277d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 22780c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmconst std::vector<uint32_t>& 2279d6f4c25eedcfd502920f1b2a24744badd9da80bePeter BoströmWebRtcVideoChannel2::WebRtcVideoReceiveStream::GetSsrcs() const { 2280d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström return ssrcs_; 2281d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström} 2282d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 228396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::AllocatedDecoder 228496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::CreateOrReuseVideoDecoder( 228596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org std::vector<AllocatedDecoder>* old_decoders, 228696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const VideoCodec& codec) { 228796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org webrtc::VideoCodecType type = CodecTypeFromName(codec.name); 2288776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 228996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org for (size_t i = 0; i < old_decoders->size(); ++i) { 229096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if ((*old_decoders)[i].type == type) { 229196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org AllocatedDecoder decoder = (*old_decoders)[i]; 229296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org (*old_decoders)[i] = old_decoders->back(); 229396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org old_decoders->pop_back(); 229496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return decoder; 229596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 229696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 2297776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 229896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (external_decoder_factory_ != NULL) { 229996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org webrtc::VideoDecoder* decoder = 230096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org external_decoder_factory_->CreateVideoDecoder(type); 230196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (decoder != NULL) { 230296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return AllocatedDecoder(decoder, type, true); 230396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 230496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 2305776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 230696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (type == webrtc::kVideoCodecVP8) { 230796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return AllocatedDecoder( 230896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org webrtc::VideoDecoder::Create(webrtc::VideoDecoder::kVp8), type, false); 230996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 2310d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2311b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org if (type == webrtc::kVideoCodecVP9) { 2312b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org return AllocatedDecoder( 2313b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org webrtc::VideoDecoder::Create(webrtc::VideoDecoder::kVp9), type, false); 2314b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org } 2315b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org 231671f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin if (type == webrtc::kVideoCodecH264) { 231771f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin return AllocatedDecoder( 231871f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin webrtc::VideoDecoder::Create(webrtc::VideoDecoder::kH264), type, false); 231971f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin } 232071f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin 232196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org // This shouldn't happen, we should not be trying to create something we don't 232296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org // support. 232391d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(false); 232496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return AllocatedDecoder(NULL, webrtc::kVideoCodecUnknown, false); 232596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org} 232696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 232796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRecvCodecs( 232896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const std::vector<VideoCodecSettings>& recv_codecs) { 232996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org std::vector<AllocatedDecoder> old_decoders = allocated_decoders_; 233096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org allocated_decoders_.clear(); 233196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org config_.decoders.clear(); 233296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org for (size_t i = 0; i < recv_codecs.size(); ++i) { 233396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org AllocatedDecoder allocated_decoder = 233496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org CreateOrReuseVideoDecoder(&old_decoders, recv_codecs[i].codec); 233596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org allocated_decoders_.push_back(allocated_decoder); 2336d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 233796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org webrtc::VideoReceiveStream::Decoder decoder; 233896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org decoder.decoder = allocated_decoder.decoder; 233996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org decoder.payload_type = recv_codecs[i].codec.id; 234096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org decoder.payload_name = recv_codecs[i].codec.name; 234196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org config_.decoders.push_back(decoder); 234296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 234396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 234496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org // TODO(pbos): Reconfigure RTX based on incoming recv_codecs. 234596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org config_.rtp.fec = recv_codecs.front().fec; 2346257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org config_.rtp.nack.rtp_history_ms = 2347e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin HasNack(recv_codecs.begin()->codec) ? kNackHistoryMs : 0; 2348257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org 2349874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "RecreateWebRtcStream (recv) because of SetRecvCodecs: " 2350874ca3af5b163e1b3fd8802171e44ee252557842deadbeef << CodecSettingsVectorToString(recv_codecs); 2351d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org RecreateWebRtcStream(); 23529e1b992f74470aecfeb216e26b455982ddc4a6d5Peter Boström ClearDecoders(&old_decoders); 2353d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2354d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 23553548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boströmvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetLocalSsrc( 23563548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström uint32_t local_ssrc) { 235791d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg // TODO(pbos): Consider turning this sanity check into a RTC_DCHECK. You 235891d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg // should not be able to create a sender with the same SSRC as a receiver, but 235991d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg // right now this can't be done due to unittests depending on receiving what 236091d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg // they are sending from the same MediaChannel. 2361874ca3af5b163e1b3fd8802171e44ee252557842deadbeef if (local_ssrc == config_.rtp.remote_ssrc) { 2362874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "Ignoring call to SetLocalSsrc because parameters are " 2363874ca3af5b163e1b3fd8802171e44ee252557842deadbeef "unchanged; local_ssrc=" << local_ssrc; 23643548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström return; 2365874ca3af5b163e1b3fd8802171e44ee252557842deadbeef } 23663548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström 23673548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström config_.rtp.local_ssrc = local_ssrc; 2368874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) 2369874ca3af5b163e1b3fd8802171e44ee252557842deadbeef << "RecreateWebRtcStream (recv) because of SetLocalSsrc; local_ssrc=" 2370874ca3af5b163e1b3fd8802171e44ee252557842deadbeef << local_ssrc; 23713548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström RecreateWebRtcStream(); 23723548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström} 23733548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström 237443edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefanvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetFeedbackParameters( 237543edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan bool nack_enabled, 237643edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan bool remb_enabled, 237743edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan bool transport_cc_enabled) { 237867c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström int nack_history_ms = nack_enabled ? kNackHistoryMs : 0; 237967c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström if (config_.rtp.nack.rtp_history_ms == nack_history_ms && 238043edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan config_.rtp.remb == remb_enabled && 238143edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan config_.rtp.transport_cc == transport_cc_enabled) { 238243edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan LOG(LS_INFO) 238343edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan << "Ignoring call to SetFeedbackParameters because parameters are " 238443edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan "unchanged; nack=" 238543edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan << nack_enabled << ", remb=" << remb_enabled 238643edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan << ", transport_cc=" << transport_cc_enabled; 2387126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström return; 238867c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström } 238967c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström config_.rtp.remb = remb_enabled; 239067c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström config_.rtp.nack.rtp_history_ms = nack_history_ms; 239143edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan config_.rtp.transport_cc = transport_cc_enabled; 239243edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan LOG(LS_INFO) 239343edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan << "RecreateWebRtcStream (recv) because of SetFeedbackParameters; nack=" 239443edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan << nack_enabled << ", remb=" << remb_enabled 239543edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan << ", transport_cc=" << transport_cc_enabled; 2396126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström RecreateWebRtcStream(); 2397126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström} 2398126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström 2399d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRtpExtensions( 2400d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<webrtc::RtpExtension>& extensions) { 2401d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.rtp.extensions = extensions; 2402874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "RecreateWebRtcStream (recv) because of SetRtpExtensions"; 24033548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström RecreateWebRtcStream(); 2404d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2405d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 24061387149ad1669365ac05278bf779a407bec08a4edeadbeefvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRecvParameters( 24071387149ad1669365ac05278bf779a407bec08a4edeadbeef const VideoRecvParameters& recv_params) { 24081387149ad1669365ac05278bf779a407bec08a4edeadbeef config_.rtp.rtcp_mode = recv_params.rtcp.reduced_size 24091387149ad1669365ac05278bf779a407bec08a4edeadbeef ? webrtc::RtcpMode::kReducedSize 24101387149ad1669365ac05278bf779a407bec08a4edeadbeef : webrtc::RtcpMode::kCompound; 24111387149ad1669365ac05278bf779a407bec08a4edeadbeef LOG(LS_INFO) << "RecreateWebRtcStream (recv) because of SetRecvParameters"; 24121387149ad1669365ac05278bf779a407bec08a4edeadbeef RecreateWebRtcStream(); 24131387149ad1669365ac05278bf779a407bec08a4edeadbeef} 24141387149ad1669365ac05278bf779a407bec08a4edeadbeef 2415d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::RecreateWebRtcStream() { 2416d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (stream_ != NULL) { 2417d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org call_->DestroyVideoReceiveStream(stream_); 2418d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 2419d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org stream_ = call_->CreateVideoReceiveStream(config_); 2420d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org stream_->Start(); 2421d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2422d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 242396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::ClearDecoders( 242496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org std::vector<AllocatedDecoder>* allocated_decoders) { 242596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org for (size_t i = 0; i < allocated_decoders->size(); ++i) { 242696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if ((*allocated_decoders)[i].external) { 2427776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org external_decoder_factory_->DestroyVideoDecoder( 24287252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström (*allocated_decoders)[i].external_decoder); 2429776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org } 24307252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström delete (*allocated_decoders)[i].decoder; 2431776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org } 243296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org allocated_decoders->clear(); 2433776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org} 2434776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 2435d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::RenderFrame( 24364765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez const webrtc::VideoFrame& frame, 2437d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org int time_to_render_ms) { 2438d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 2439fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org 2440fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org if (first_frame_timestamp_ < 0) 2441fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org first_frame_timestamp_ = frame.timestamp(); 2442fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org int64_t rtp_time_elapsed_since_first_frame = 2443fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org (timestamp_wraparound_handler_.Unwrap(frame.timestamp()) - 2444fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org first_frame_timestamp_); 2445fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org int64_t elapsed_time_ms = rtp_time_elapsed_since_first_frame / 2446fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org (cricket::kVideoCodecClockrate / 1000); 2447fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org if (frame.ntp_time_ms() > 0) 2448fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org estimated_remote_start_ntp_time_ms_ = frame.ntp_time_ms() - elapsed_time_ms; 2449fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org 2450d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (renderer_ == NULL) { 2451d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org LOG(LS_WARNING) << "VideoReceiveStream not connected to a VideoRenderer."; 2452d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return; 2453d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 2454d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2455d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (frame.width() != last_width_ || frame.height() != last_height_) { 2456d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetSize(frame.width(), frame.height()); 2457d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 2458d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 24592386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org const WebRtcVideoFrame render_frame( 24602386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org frame.video_frame_buffer(), 246164c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh frame.render_time_ms() * rtc::kNumNanosecsPerMillisec, frame.rotation()); 2462d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org renderer_->RenderFrame(&render_frame); 2463d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2464d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 24650d852d5c27a759fe7aadc500bd7b3cadfae3deb8pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoReceiveStream::IsTextureSupported() const { 24660d852d5c27a759fe7aadc500bd7b3cadfae3deb8pbos@webrtc.org return true; 24670d852d5c27a759fe7aadc500bd7b3cadfae3deb8pbos@webrtc.org} 24680d852d5c27a759fe7aadc500bd7b3cadfae3deb8pbos@webrtc.org 2469444682acf9804c5fcbddaded9e900ba3cc6921fcqiangchenbool WebRtcVideoChannel2::WebRtcVideoReceiveStream::SmoothsRenderedFrames() 2470444682acf9804c5fcbddaded9e900ba3cc6921fcqiangchen const { 2471444682acf9804c5fcbddaded9e900ba3cc6921fcqiangchen return disable_prerenderer_smoothing_; 2472444682acf9804c5fcbddaded9e900ba3cc6921fcqiangchen} 2473444682acf9804c5fcbddaded9e900ba3cc6921fcqiangchen 2474a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoReceiveStream::IsDefaultStream() const { 2475a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org return default_stream_; 2476a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org} 2477a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org 2478d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRenderer( 2479d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org cricket::VideoRenderer* renderer) { 2480d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 2481d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org renderer_ = renderer; 2482d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (renderer_ != NULL && last_width_ != -1) { 2483d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetSize(last_width_, last_height_); 2484d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 2485d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2486d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2487d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgVideoRenderer* WebRtcVideoChannel2::WebRtcVideoReceiveStream::GetRenderer() { 2488d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // TODO(pbos): Remove GetRenderer and all uses of it, it's thread-unsafe by 2489d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // design. 2490d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 2491d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return renderer_; 2492d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2493d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2494d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetSize(int width, 2495d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org int height) { 2496d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 2497d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (!renderer_->SetSize(width, height, 0)) { 2498d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org LOG(LS_ERROR) << "Could not set renderer size."; 2499d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 2500d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_width_ = width; 2501d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_height_ = height; 2502d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2503d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2504f42376c60111edba6f29060bf3dd79e75d8dbb97pbosstd::string 2505f42376c60111edba6f29060bf3dd79e75d8dbb97pbosWebRtcVideoChannel2::WebRtcVideoReceiveStream::GetCodecNameFromPayloadType( 2506f42376c60111edba6f29060bf3dd79e75d8dbb97pbos int payload_type) { 2507f42376c60111edba6f29060bf3dd79e75d8dbb97pbos for (const webrtc::VideoReceiveStream::Decoder& decoder : config_.decoders) { 2508f42376c60111edba6f29060bf3dd79e75d8dbb97pbos if (decoder.payload_type == payload_type) { 2509f42376c60111edba6f29060bf3dd79e75d8dbb97pbos return decoder.payload_name; 2510f42376c60111edba6f29060bf3dd79e75d8dbb97pbos } 2511f42376c60111edba6f29060bf3dd79e75d8dbb97pbos } 2512f42376c60111edba6f29060bf3dd79e75d8dbb97pbos return ""; 2513f42376c60111edba6f29060bf3dd79e75d8dbb97pbos} 2514f42376c60111edba6f29060bf3dd79e75d8dbb97pbos 2515e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgVideoReceiverInfo 2516e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::GetVideoReceiverInfo() { 2517e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoReceiverInfo info; 2518259bd2034c3d3ee7f2dc4d481e9bf896a3a4d6efPeter Boström info.ssrc_groups = ssrc_groups_; 2519e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.add_ssrc(config_.rtp.remote_ssrc); 2520e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org webrtc::VideoReceiveStream::Stats stats = stream_->GetStats(); 2521b7d9a97ce41022e984348efb5f28bf6dd6c6b779Peter Boström info.decoder_implementation_name = stats.decoder_implementation_name; 2522cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org info.bytes_rcvd = stats.rtp_stats.transmitted.payload_bytes + 2523cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org stats.rtp_stats.transmitted.header_bytes + 2524cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org stats.rtp_stats.transmitted.padding_bytes; 2525cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org info.packets_rcvd = stats.rtp_stats.transmitted.packets; 2526393347ff988708df5037ddcd181fe204bd1ab37ePeter Boström info.packets_lost = stats.rtcp_stats.cumulative_lost; 2527393347ff988708df5037ddcd181fe204bd1ab37ePeter Boström info.fraction_lost = 2528393347ff988708df5037ddcd181fe204bd1ab37ePeter Boström static_cast<float>(stats.rtcp_stats.fraction_lost) / (1 << 8); 2529e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 2530e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_rcvd = stats.network_frame_rate; 2531e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_decoded = stats.decode_frame_rate; 2532e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_output = stats.render_frame_rate; 2533e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 25341d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org { 25351d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org rtc::CritScope frame_cs(&renderer_lock_); 25361d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.frame_width = last_width_; 25371d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.frame_height = last_height_; 25381d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.capture_start_ntp_time_ms = estimated_remote_start_ntp_time_ms_; 25391d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org } 25401d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org 254109c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.decode_ms = stats.decode_ms; 254209c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.max_decode_ms = stats.max_decode_ms; 254309c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.current_delay_ms = stats.current_delay_ms; 254409c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.target_delay_ms = stats.target_delay_ms; 254509c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.jitter_buffer_ms = stats.jitter_buffer_ms; 254609c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.min_playout_delay_ms = stats.min_playout_delay_ms; 254709c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.render_delay_ms = stats.render_delay_ms; 254809c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org 2549f42376c60111edba6f29060bf3dd79e75d8dbb97pbos info.codec_name = GetCodecNameFromPayloadType(stats.current_payload_type); 2550f42376c60111edba6f29060bf3dd79e75d8dbb97pbos 25511d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.firs_sent = stats.rtcp_packet_type_counts.fir_packets; 25521d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.plis_sent = stats.rtcp_packet_type_counts.pli_packets; 25531d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.nacks_sent = stats.rtcp_packet_type_counts.nack_packets; 2554e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 2555e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org return info; 2556e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 2557e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 2558b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::VideoCodecSettings::VideoCodecSettings() 2559b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : rtx_payload_type(-1) {} 2560b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2561a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.orgbool WebRtcVideoChannel2::VideoCodecSettings::operator==( 2562a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org const WebRtcVideoChannel2::VideoCodecSettings& other) const { 2563a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org return codec == other.codec && 2564a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org fec.ulpfec_payload_type == other.fec.ulpfec_payload_type && 2565a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org fec.red_payload_type == other.fec.red_payload_type && 2566e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin fec.red_rtx_payload_type == other.fec.red_rtx_payload_type && 2567a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org rtx_payload_type == other.rtx_payload_type; 2568a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org} 2569a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 2570ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boströmbool WebRtcVideoChannel2::VideoCodecSettings::operator!=( 2571ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström const WebRtcVideoChannel2::VideoCodecSettings& other) const { 2572ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström return !(*this == other); 2573ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström} 2574ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström 2575b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstd::vector<WebRtcVideoChannel2::VideoCodecSettings> 2576b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::MapCodecs(const std::vector<VideoCodec>& codecs) { 257791d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(!codecs.empty()); 2578b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2579b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::vector<VideoCodecSettings> video_codecs; 2580b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::map<int, bool> payload_used; 2581e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org std::map<int, VideoCodec::CodecType> payload_codec_type; 2582d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org // |rtx_mapping| maps video payload type to rtx payload type. 2583d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org std::map<int, int> rtx_mapping; 2584b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2585b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::FecConfig fec_settings; 2586b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2587b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 2588b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& in_codec = codecs[i]; 2589b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int payload_type = in_codec.id; 2590b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2591b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (payload_used[payload_type]) { 2592b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Payload type already registered: " 2593b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << in_codec.ToString(); 2594b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return std::vector<VideoCodecSettings>(); 2595b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2596b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org payload_used[payload_type] = true; 2597e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org payload_codec_type[payload_type] = in_codec.GetCodecType(); 2598b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2599b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org switch (in_codec.GetCodecType()) { 2600b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_RED: { 2601b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // RED payload type, should not have duplicates. 260291d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(fec_settings.red_payload_type == -1); 2603b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org fec_settings.red_payload_type = in_codec.id; 2604b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 2605b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2606b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2607b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_ULPFEC: { 2608b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // ULPFEC payload type, should not have duplicates. 260991d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(fec_settings.ulpfec_payload_type == -1); 2610b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org fec_settings.ulpfec_payload_type = in_codec.id; 2611b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 2612b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2613b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2614b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_RTX: { 2615b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int associated_payload_type; 2616b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!in_codec.GetParam(kCodecParamAssociatedPayloadType, 2617e9facf8bb32a1688f2156009c755caa2904e1ac9pkasting@chromium.org &associated_payload_type) || 2618e9facf8bb32a1688f2156009c755caa2904e1ac9pkasting@chromium.org !IsValidRtpPayloadType(associated_payload_type)) { 2619e9facf8bb32a1688f2156009c755caa2904e1ac9pkasting@chromium.org LOG(LS_ERROR) 2620e9facf8bb32a1688f2156009c755caa2904e1ac9pkasting@chromium.org << "RTX codec with invalid or no associated payload type: " 2621e9facf8bb32a1688f2156009c755caa2904e1ac9pkasting@chromium.org << in_codec.ToString(); 2622b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return std::vector<VideoCodecSettings>(); 2623b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2624b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtx_mapping[associated_payload_type] = in_codec.id; 2625b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 2626b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2627b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2628b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_VIDEO: 2629b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org break; 2630b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2631b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2632b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs.push_back(VideoCodecSettings()); 2633b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs.back().codec = in_codec; 2634b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2635b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2636b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // One of these codecs should have been a video codec. Only having FEC 2637b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // parameters into this code is a logic error. 263891d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(!video_codecs.empty()); 2639b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2640e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org for (std::map<int, int>::const_iterator it = rtx_mapping.begin(); 2641e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org it != rtx_mapping.end(); 2642e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org ++it) { 2643e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org if (!payload_used[it->first]) { 2644e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org LOG(LS_ERROR) << "RTX mapped to payload not in codec list."; 2645e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return std::vector<VideoCodecSettings>(); 2646e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 2647e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (payload_codec_type[it->first] != VideoCodec::CODEC_VIDEO && 2648e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin payload_codec_type[it->first] != VideoCodec::CODEC_RED) { 2649e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin LOG(LS_ERROR) << "RTX not mapped to regular video codec or RED codec."; 2650e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return std::vector<VideoCodecSettings>(); 2651e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 2652e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin 2653e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (it->first == fec_settings.red_payload_type) { 2654e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin fec_settings.red_rtx_payload_type = it->second; 2655e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin } 2656e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 2657e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org 2658b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < video_codecs.size(); ++i) { 2659b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs[i].fec = fec_settings; 2660e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (rtx_mapping[video_codecs[i].codec.id] != 0 && 2661e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin rtx_mapping[video_codecs[i].codec.id] != 2662e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin fec_settings.red_payload_type) { 2663b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; 2664b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2665b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2666b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2667b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return video_codecs; 2668b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 2669b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2670b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} // namespace cricket 2671b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2672b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#endif // HAVE_WEBRTC_VIDEO 2673